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)
98 (UNSPEC_NOP 48) ; prevents combiner cleverness
109 ; Generic math support
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
127 (UNSPEC_FRNDINT_FLOOR 70)
128 (UNSPEC_FRNDINT_CEIL 71)
129 (UNSPEC_FRNDINT_TRUNC 72)
130 (UNSPEC_FRNDINT_MASK_PM 73)
131 (UNSPEC_FIST_FLOOR 74)
132 (UNSPEC_FIST_CEIL 75)
134 ; x87 Double output FP
135 (UNSPEC_SINCOS_COS 80)
136 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
151 (UNSPEC_SP_TLS_SET 102)
152 (UNSPEC_SP_TLS_TEST 103)
162 (UNSPEC_INSERTQI 132)
167 (UNSPEC_INSERTPS 135)
169 (UNSPEC_MOVNTDQA 137)
171 (UNSPEC_PHMINPOSUW 139)
177 (UNSPEC_PCMPESTR 144)
178 (UNSPEC_PCMPISTR 145)
181 (UNSPEC_SSE5_INTRINSIC 150)
182 (UNSPEC_SSE5_UNSIGNED_CMP 151)
183 (UNSPEC_SSE5_TRUEFALSE 152)
184 (UNSPEC_SSE5_PERMUTE 153)
185 (UNSPEC_SSE5_ASHIFT 154)
186 (UNSPEC_SSE5_LSHIFT 155)
188 (UNSPEC_CVTPH2PS 157)
189 (UNSPEC_CVTPS2PH 158)
193 [(UNSPECV_BLOCKAGE 0)
194 (UNSPECV_STACK_PROBE 1)
203 (UNSPECV_CMPXCHG_1 10)
204 (UNSPECV_CMPXCHG_2 11)
207 (UNSPECV_PROLOGUE_USE 14)
210 ;; Constants to represent pcomtrue/pcomfalse variants
220 ;; Registers by name.
236 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
239 ;; In C guard expressions, put expressions which may be compile-time
240 ;; constants first. This allows for better optimization. For
241 ;; example, write "TARGET_64BIT && reload_completed", not
242 ;; "reload_completed && TARGET_64BIT".
245 ;; Processor type. This attribute must exactly match the processor_type
246 ;; enumeration in i386.h.
247 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
248 nocona,core2,generic32,generic64,amdfam10"
249 (const (symbol_ref "ix86_tune")))
251 ;; A basic instruction type. Refinements due to arguments to be
252 ;; provided in other attributes.
255 alu,alu1,negnot,imov,imovx,lea,
256 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
257 icmp,test,ibr,setcc,icmov,
258 push,pop,call,callv,leave,
260 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
261 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
262 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
264 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
265 (const_string "other"))
267 ;; Main data type used by the insn
269 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
270 (const_string "unknown"))
272 ;; The CPU unit operations uses.
273 (define_attr "unit" "integer,i387,sse,mmx,unknown"
274 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
275 (const_string "i387")
276 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
277 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
278 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
280 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
282 (eq_attr "type" "other")
283 (const_string "unknown")]
284 (const_string "integer")))
286 ;; The (bounding maximum) length of an instruction immediate.
287 (define_attr "length_immediate" ""
288 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
291 (eq_attr "unit" "i387,sse,mmx")
293 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
295 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
296 (eq_attr "type" "imov,test")
297 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
298 (eq_attr "type" "call")
299 (if_then_else (match_operand 0 "constant_call_address_operand" "")
302 (eq_attr "type" "callv")
303 (if_then_else (match_operand 1 "constant_call_address_operand" "")
306 ;; We don't know the size before shorten_branches. Expect
307 ;; the instruction to fit for better scheduling.
308 (eq_attr "type" "ibr")
311 (symbol_ref "/* Update immediate_length and other attributes! */
312 gcc_unreachable (),1")))
314 ;; The (bounding maximum) length of an instruction address.
315 (define_attr "length_address" ""
316 (cond [(eq_attr "type" "str,other,multi,fxch")
318 (and (eq_attr "type" "call")
319 (match_operand 0 "constant_call_address_operand" ""))
321 (and (eq_attr "type" "callv")
322 (match_operand 1 "constant_call_address_operand" ""))
325 (symbol_ref "ix86_attr_length_address_default (insn)")))
327 ;; Set when length prefix is used.
328 (define_attr "prefix_data16" ""
329 (if_then_else (ior (eq_attr "mode" "HI")
330 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
334 ;; Set when string REP prefix is used.
335 (define_attr "prefix_rep" ""
336 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
340 ;; Set when 0f opcode prefix is used.
341 (define_attr "prefix_0f" ""
343 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
344 (eq_attr "unit" "sse,mmx"))
348 ;; Set when REX opcode prefix is used.
349 (define_attr "prefix_rex" ""
350 (cond [(and (eq_attr "mode" "DI")
351 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
353 (and (eq_attr "mode" "QI")
354 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
357 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
363 ;; There are also additional prefixes in SSSE3.
364 (define_attr "prefix_extra" "" (const_int 0))
366 ;; Set when modrm byte is used.
367 (define_attr "modrm" ""
368 (cond [(eq_attr "type" "str,leave")
370 (eq_attr "unit" "i387")
372 (and (eq_attr "type" "incdec")
373 (ior (match_operand:SI 1 "register_operand" "")
374 (match_operand:HI 1 "register_operand" "")))
376 (and (eq_attr "type" "push")
377 (not (match_operand 1 "memory_operand" "")))
379 (and (eq_attr "type" "pop")
380 (not (match_operand 0 "memory_operand" "")))
382 (and (eq_attr "type" "imov")
383 (ior (and (match_operand 0 "register_operand" "")
384 (match_operand 1 "immediate_operand" ""))
385 (ior (and (match_operand 0 "ax_reg_operand" "")
386 (match_operand 1 "memory_displacement_only_operand" ""))
387 (and (match_operand 0 "memory_displacement_only_operand" "")
388 (match_operand 1 "ax_reg_operand" "")))))
390 (and (eq_attr "type" "call")
391 (match_operand 0 "constant_call_address_operand" ""))
393 (and (eq_attr "type" "callv")
394 (match_operand 1 "constant_call_address_operand" ""))
399 ;; The (bounding maximum) length of an instruction in bytes.
400 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
401 ;; Later we may want to split them and compute proper length as for
403 (define_attr "length" ""
404 (cond [(eq_attr "type" "other,multi,fistp,frndint")
406 (eq_attr "type" "fcmp")
408 (eq_attr "unit" "i387")
410 (plus (attr "prefix_data16")
411 (attr "length_address")))]
412 (plus (plus (attr "modrm")
413 (plus (attr "prefix_0f")
414 (plus (attr "prefix_rex")
415 (plus (attr "prefix_extra")
417 (plus (attr "prefix_rep")
418 (plus (attr "prefix_data16")
419 (plus (attr "length_immediate")
420 (attr "length_address")))))))
422 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
423 ;; `store' if there is a simple memory reference therein, or `unknown'
424 ;; if the instruction is complex.
426 (define_attr "memory" "none,load,store,both,unknown"
427 (cond [(eq_attr "type" "other,multi,str")
428 (const_string "unknown")
429 (eq_attr "type" "lea,fcmov,fpspc")
430 (const_string "none")
431 (eq_attr "type" "fistp,leave")
432 (const_string "both")
433 (eq_attr "type" "frndint")
434 (const_string "load")
435 (eq_attr "type" "push")
436 (if_then_else (match_operand 1 "memory_operand" "")
437 (const_string "both")
438 (const_string "store"))
439 (eq_attr "type" "pop")
440 (if_then_else (match_operand 0 "memory_operand" "")
441 (const_string "both")
442 (const_string "load"))
443 (eq_attr "type" "setcc")
444 (if_then_else (match_operand 0 "memory_operand" "")
445 (const_string "store")
446 (const_string "none"))
447 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
448 (if_then_else (ior (match_operand 0 "memory_operand" "")
449 (match_operand 1 "memory_operand" ""))
450 (const_string "load")
451 (const_string "none"))
452 (eq_attr "type" "ibr")
453 (if_then_else (match_operand 0 "memory_operand" "")
454 (const_string "load")
455 (const_string "none"))
456 (eq_attr "type" "call")
457 (if_then_else (match_operand 0 "constant_call_address_operand" "")
458 (const_string "none")
459 (const_string "load"))
460 (eq_attr "type" "callv")
461 (if_then_else (match_operand 1 "constant_call_address_operand" "")
462 (const_string "none")
463 (const_string "load"))
464 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
465 (match_operand 1 "memory_operand" ""))
466 (const_string "both")
467 (and (match_operand 0 "memory_operand" "")
468 (match_operand 1 "memory_operand" ""))
469 (const_string "both")
470 (match_operand 0 "memory_operand" "")
471 (const_string "store")
472 (match_operand 1 "memory_operand" "")
473 (const_string "load")
475 "!alu1,negnot,ishift1,
476 imov,imovx,icmp,test,bitmanip,
478 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
479 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
480 (match_operand 2 "memory_operand" ""))
481 (const_string "load")
482 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
483 (match_operand 3 "memory_operand" ""))
484 (const_string "load")
486 (const_string "none")))
488 ;; Indicates if an instruction has both an immediate and a displacement.
490 (define_attr "imm_disp" "false,true,unknown"
491 (cond [(eq_attr "type" "other,multi")
492 (const_string "unknown")
493 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
494 (and (match_operand 0 "memory_displacement_operand" "")
495 (match_operand 1 "immediate_operand" "")))
496 (const_string "true")
497 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
498 (and (match_operand 0 "memory_displacement_operand" "")
499 (match_operand 2 "immediate_operand" "")))
500 (const_string "true")
502 (const_string "false")))
504 ;; Indicates if an FP operation has an integer source.
506 (define_attr "fp_int_src" "false,true"
507 (const_string "false"))
509 ;; Defines rounding mode of an FP operation.
511 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
512 (const_string "any"))
514 ;; Describe a user's asm statement.
515 (define_asm_attributes
516 [(set_attr "length" "128")
517 (set_attr "type" "multi")])
519 (define_code_iterator plusminus [plus minus])
521 ;; Base name for define_insn and insn mnemonic.
522 (define_code_attr addsub [(plus "add") (minus "sub")])
524 ;; Mark commutative operators as such in constraints.
525 (define_code_attr comm [(plus "%") (minus "")])
527 ;; All single word integer modes.
528 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
530 ;; Instruction suffix for integer modes.
531 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
533 ;; Register class for integer modes.
534 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
536 ;; Immediate operand constraint for integer modes.
537 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
539 ;; General operand predicate for integer modes.
540 (define_mode_attr general_operand
541 [(QI "general_operand")
542 (HI "general_operand")
543 (SI "general_operand")
544 (DI "x86_64_general_operand")])
546 ;; SSE and x87 SFmode and DFmode floating point modes
547 (define_mode_iterator MODEF [SF DF])
549 ;; All x87 floating point modes
550 (define_mode_iterator X87MODEF [SF DF XF])
552 ;; All integer modes handled by x87 fisttp operator.
553 (define_mode_iterator X87MODEI [HI SI DI])
555 ;; All integer modes handled by integer x87 operators.
556 (define_mode_iterator X87MODEI12 [HI SI])
558 ;; All integer modes handled by SSE cvtts?2si* operators.
559 (define_mode_iterator SSEMODEI24 [SI DI])
561 ;; SSE asm suffix for floating point modes
562 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
564 ;; SSE vector mode corresponding to a scalar mode
565 (define_mode_attr ssevecmode
566 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
568 ;; Scheduling descriptions
570 (include "pentium.md")
573 (include "athlon.md")
577 ;; Operand and operator predicates and constraints
579 (include "predicates.md")
580 (include "constraints.md")
583 ;; Compare instructions.
585 ;; All compare insns have expanders that save the operands away without
586 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
587 ;; after the cmp) will actually emit the cmpM.
589 (define_expand "cmpti"
590 [(set (reg:CC FLAGS_REG)
591 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
592 (match_operand:TI 1 "x86_64_general_operand" "")))]
595 if (MEM_P (operands[0]) && MEM_P (operands[1]))
596 operands[0] = force_reg (TImode, operands[0]);
597 ix86_compare_op0 = operands[0];
598 ix86_compare_op1 = operands[1];
602 (define_expand "cmpdi"
603 [(set (reg:CC FLAGS_REG)
604 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
605 (match_operand:DI 1 "x86_64_general_operand" "")))]
608 if (MEM_P (operands[0]) && MEM_P (operands[1]))
609 operands[0] = force_reg (DImode, operands[0]);
610 ix86_compare_op0 = operands[0];
611 ix86_compare_op1 = operands[1];
615 (define_expand "cmpsi"
616 [(set (reg:CC FLAGS_REG)
617 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
618 (match_operand:SI 1 "general_operand" "")))]
621 if (MEM_P (operands[0]) && MEM_P (operands[1]))
622 operands[0] = force_reg (SImode, operands[0]);
623 ix86_compare_op0 = operands[0];
624 ix86_compare_op1 = operands[1];
628 (define_expand "cmphi"
629 [(set (reg:CC FLAGS_REG)
630 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
631 (match_operand:HI 1 "general_operand" "")))]
634 if (MEM_P (operands[0]) && MEM_P (operands[1]))
635 operands[0] = force_reg (HImode, operands[0]);
636 ix86_compare_op0 = operands[0];
637 ix86_compare_op1 = operands[1];
641 (define_expand "cmpqi"
642 [(set (reg:CC FLAGS_REG)
643 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
644 (match_operand:QI 1 "general_operand" "")))]
647 if (MEM_P (operands[0]) && MEM_P (operands[1]))
648 operands[0] = force_reg (QImode, operands[0]);
649 ix86_compare_op0 = operands[0];
650 ix86_compare_op1 = operands[1];
654 (define_insn "cmpdi_ccno_1_rex64"
655 [(set (reg FLAGS_REG)
656 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
657 (match_operand:DI 1 "const0_operand" "n,n")))]
658 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
661 cmp{q}\t{%1, %0|%0, %1}"
662 [(set_attr "type" "test,icmp")
663 (set_attr "length_immediate" "0,1")
664 (set_attr "mode" "DI")])
666 (define_insn "*cmpdi_minus_1_rex64"
667 [(set (reg FLAGS_REG)
668 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
669 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
671 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
672 "cmp{q}\t{%1, %0|%0, %1}"
673 [(set_attr "type" "icmp")
674 (set_attr "mode" "DI")])
676 (define_expand "cmpdi_1_rex64"
677 [(set (reg:CC FLAGS_REG)
678 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
679 (match_operand:DI 1 "general_operand" "")))]
683 (define_insn "cmpdi_1_insn_rex64"
684 [(set (reg FLAGS_REG)
685 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
686 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
687 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
688 "cmp{q}\t{%1, %0|%0, %1}"
689 [(set_attr "type" "icmp")
690 (set_attr "mode" "DI")])
693 (define_insn "*cmpsi_ccno_1"
694 [(set (reg FLAGS_REG)
695 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
696 (match_operand:SI 1 "const0_operand" "n,n")))]
697 "ix86_match_ccmode (insn, CCNOmode)"
700 cmp{l}\t{%1, %0|%0, %1}"
701 [(set_attr "type" "test,icmp")
702 (set_attr "length_immediate" "0,1")
703 (set_attr "mode" "SI")])
705 (define_insn "*cmpsi_minus_1"
706 [(set (reg FLAGS_REG)
707 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
708 (match_operand:SI 1 "general_operand" "ri,mr"))
710 "ix86_match_ccmode (insn, CCGOCmode)"
711 "cmp{l}\t{%1, %0|%0, %1}"
712 [(set_attr "type" "icmp")
713 (set_attr "mode" "SI")])
715 (define_expand "cmpsi_1"
716 [(set (reg:CC FLAGS_REG)
717 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
718 (match_operand:SI 1 "general_operand" "")))]
722 (define_insn "*cmpsi_1_insn"
723 [(set (reg FLAGS_REG)
724 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
725 (match_operand:SI 1 "general_operand" "ri,mr")))]
726 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
727 && ix86_match_ccmode (insn, CCmode)"
728 "cmp{l}\t{%1, %0|%0, %1}"
729 [(set_attr "type" "icmp")
730 (set_attr "mode" "SI")])
732 (define_insn "*cmphi_ccno_1"
733 [(set (reg FLAGS_REG)
734 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
735 (match_operand:HI 1 "const0_operand" "n,n")))]
736 "ix86_match_ccmode (insn, CCNOmode)"
739 cmp{w}\t{%1, %0|%0, %1}"
740 [(set_attr "type" "test,icmp")
741 (set_attr "length_immediate" "0,1")
742 (set_attr "mode" "HI")])
744 (define_insn "*cmphi_minus_1"
745 [(set (reg FLAGS_REG)
746 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
747 (match_operand:HI 1 "general_operand" "ri,mr"))
749 "ix86_match_ccmode (insn, CCGOCmode)"
750 "cmp{w}\t{%1, %0|%0, %1}"
751 [(set_attr "type" "icmp")
752 (set_attr "mode" "HI")])
754 (define_insn "*cmphi_1"
755 [(set (reg FLAGS_REG)
756 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
757 (match_operand:HI 1 "general_operand" "ri,mr")))]
758 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
759 && ix86_match_ccmode (insn, CCmode)"
760 "cmp{w}\t{%1, %0|%0, %1}"
761 [(set_attr "type" "icmp")
762 (set_attr "mode" "HI")])
764 (define_insn "*cmpqi_ccno_1"
765 [(set (reg FLAGS_REG)
766 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
767 (match_operand:QI 1 "const0_operand" "n,n")))]
768 "ix86_match_ccmode (insn, CCNOmode)"
771 cmp{b}\t{$0, %0|%0, 0}"
772 [(set_attr "type" "test,icmp")
773 (set_attr "length_immediate" "0,1")
774 (set_attr "mode" "QI")])
776 (define_insn "*cmpqi_1"
777 [(set (reg FLAGS_REG)
778 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
779 (match_operand:QI 1 "general_operand" "qi,mq")))]
780 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
781 && ix86_match_ccmode (insn, CCmode)"
782 "cmp{b}\t{%1, %0|%0, %1}"
783 [(set_attr "type" "icmp")
784 (set_attr "mode" "QI")])
786 (define_insn "*cmpqi_minus_1"
787 [(set (reg FLAGS_REG)
788 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
789 (match_operand:QI 1 "general_operand" "qi,mq"))
791 "ix86_match_ccmode (insn, CCGOCmode)"
792 "cmp{b}\t{%1, %0|%0, %1}"
793 [(set_attr "type" "icmp")
794 (set_attr "mode" "QI")])
796 (define_insn "*cmpqi_ext_1"
797 [(set (reg FLAGS_REG)
799 (match_operand:QI 0 "general_operand" "Qm")
802 (match_operand 1 "ext_register_operand" "Q")
805 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
806 "cmp{b}\t{%h1, %0|%0, %h1}"
807 [(set_attr "type" "icmp")
808 (set_attr "mode" "QI")])
810 (define_insn "*cmpqi_ext_1_rex64"
811 [(set (reg FLAGS_REG)
813 (match_operand:QI 0 "register_operand" "Q")
816 (match_operand 1 "ext_register_operand" "Q")
819 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
820 "cmp{b}\t{%h1, %0|%0, %h1}"
821 [(set_attr "type" "icmp")
822 (set_attr "mode" "QI")])
824 (define_insn "*cmpqi_ext_2"
825 [(set (reg FLAGS_REG)
829 (match_operand 0 "ext_register_operand" "Q")
832 (match_operand:QI 1 "const0_operand" "n")))]
833 "ix86_match_ccmode (insn, CCNOmode)"
835 [(set_attr "type" "test")
836 (set_attr "length_immediate" "0")
837 (set_attr "mode" "QI")])
839 (define_expand "cmpqi_ext_3"
840 [(set (reg:CC FLAGS_REG)
844 (match_operand 0 "ext_register_operand" "")
847 (match_operand:QI 1 "general_operand" "")))]
851 (define_insn "cmpqi_ext_3_insn"
852 [(set (reg FLAGS_REG)
856 (match_operand 0 "ext_register_operand" "Q")
859 (match_operand:QI 1 "general_operand" "Qmn")))]
860 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
861 "cmp{b}\t{%1, %h0|%h0, %1}"
862 [(set_attr "type" "icmp")
863 (set_attr "mode" "QI")])
865 (define_insn "cmpqi_ext_3_insn_rex64"
866 [(set (reg FLAGS_REG)
870 (match_operand 0 "ext_register_operand" "Q")
873 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
874 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
875 "cmp{b}\t{%1, %h0|%h0, %1}"
876 [(set_attr "type" "icmp")
877 (set_attr "mode" "QI")])
879 (define_insn "*cmpqi_ext_4"
880 [(set (reg FLAGS_REG)
884 (match_operand 0 "ext_register_operand" "Q")
889 (match_operand 1 "ext_register_operand" "Q")
892 "ix86_match_ccmode (insn, CCmode)"
893 "cmp{b}\t{%h1, %h0|%h0, %h1}"
894 [(set_attr "type" "icmp")
895 (set_attr "mode" "QI")])
897 ;; These implement float point compares.
898 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
899 ;; which would allow mix and match FP modes on the compares. Which is what
900 ;; the old patterns did, but with many more of them.
902 (define_expand "cmpxf"
903 [(set (reg:CC FLAGS_REG)
904 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
905 (match_operand:XF 1 "nonmemory_operand" "")))]
908 ix86_compare_op0 = operands[0];
909 ix86_compare_op1 = operands[1];
913 (define_expand "cmp<mode>"
914 [(set (reg:CC FLAGS_REG)
915 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
916 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
917 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
919 ix86_compare_op0 = operands[0];
920 ix86_compare_op1 = operands[1];
924 ;; FP compares, step 1:
925 ;; Set the FP condition codes.
927 ;; CCFPmode compare with exceptions
928 ;; CCFPUmode compare with no exceptions
930 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
931 ;; used to manage the reg stack popping would not be preserved.
933 (define_insn "*cmpfp_0"
934 [(set (match_operand:HI 0 "register_operand" "=a")
937 (match_operand 1 "register_operand" "f")
938 (match_operand 2 "const0_operand" "X"))]
940 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
941 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
942 "* return output_fp_compare (insn, operands, 0, 0);"
943 [(set_attr "type" "multi")
944 (set_attr "unit" "i387")
946 (cond [(match_operand:SF 1 "" "")
948 (match_operand:DF 1 "" "")
951 (const_string "XF")))])
953 (define_insn_and_split "*cmpfp_0_cc"
954 [(set (reg:CCFP FLAGS_REG)
956 (match_operand 1 "register_operand" "f")
957 (match_operand 2 "const0_operand" "X")))
958 (clobber (match_operand:HI 0 "register_operand" "=a"))]
959 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
960 && TARGET_SAHF && !TARGET_CMOVE
961 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
963 "&& reload_completed"
966 [(compare:CCFP (match_dup 1)(match_dup 2))]
968 (set (reg:CC FLAGS_REG)
969 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
971 [(set_attr "type" "multi")
972 (set_attr "unit" "i387")
974 (cond [(match_operand:SF 1 "" "")
976 (match_operand:DF 1 "" "")
979 (const_string "XF")))])
981 (define_insn "*cmpfp_xf"
982 [(set (match_operand:HI 0 "register_operand" "=a")
985 (match_operand:XF 1 "register_operand" "f")
986 (match_operand:XF 2 "register_operand" "f"))]
989 "* return output_fp_compare (insn, operands, 0, 0);"
990 [(set_attr "type" "multi")
991 (set_attr "unit" "i387")
992 (set_attr "mode" "XF")])
994 (define_insn_and_split "*cmpfp_xf_cc"
995 [(set (reg:CCFP FLAGS_REG)
997 (match_operand:XF 1 "register_operand" "f")
998 (match_operand:XF 2 "register_operand" "f")))
999 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1001 && TARGET_SAHF && !TARGET_CMOVE"
1003 "&& reload_completed"
1006 [(compare:CCFP (match_dup 1)(match_dup 2))]
1008 (set (reg:CC FLAGS_REG)
1009 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1011 [(set_attr "type" "multi")
1012 (set_attr "unit" "i387")
1013 (set_attr "mode" "XF")])
1015 (define_insn "*cmpfp_<mode>"
1016 [(set (match_operand:HI 0 "register_operand" "=a")
1019 (match_operand:MODEF 1 "register_operand" "f")
1020 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1023 "* return output_fp_compare (insn, operands, 0, 0);"
1024 [(set_attr "type" "multi")
1025 (set_attr "unit" "i387")
1026 (set_attr "mode" "<MODE>")])
1028 (define_insn_and_split "*cmpfp_<mode>_cc"
1029 [(set (reg:CCFP FLAGS_REG)
1031 (match_operand:MODEF 1 "register_operand" "f")
1032 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1033 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1035 && TARGET_SAHF && !TARGET_CMOVE"
1037 "&& reload_completed"
1040 [(compare:CCFP (match_dup 1)(match_dup 2))]
1042 (set (reg:CC FLAGS_REG)
1043 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1045 [(set_attr "type" "multi")
1046 (set_attr "unit" "i387")
1047 (set_attr "mode" "<MODE>")])
1049 (define_insn "*cmpfp_u"
1050 [(set (match_operand:HI 0 "register_operand" "=a")
1053 (match_operand 1 "register_operand" "f")
1054 (match_operand 2 "register_operand" "f"))]
1056 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1057 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1058 "* return output_fp_compare (insn, operands, 0, 1);"
1059 [(set_attr "type" "multi")
1060 (set_attr "unit" "i387")
1062 (cond [(match_operand:SF 1 "" "")
1064 (match_operand:DF 1 "" "")
1067 (const_string "XF")))])
1069 (define_insn_and_split "*cmpfp_u_cc"
1070 [(set (reg:CCFPU FLAGS_REG)
1072 (match_operand 1 "register_operand" "f")
1073 (match_operand 2 "register_operand" "f")))
1074 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1075 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1076 && TARGET_SAHF && !TARGET_CMOVE
1077 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1079 "&& reload_completed"
1082 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1084 (set (reg:CC FLAGS_REG)
1085 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1087 [(set_attr "type" "multi")
1088 (set_attr "unit" "i387")
1090 (cond [(match_operand:SF 1 "" "")
1092 (match_operand:DF 1 "" "")
1095 (const_string "XF")))])
1097 (define_insn "*cmpfp_<mode>"
1098 [(set (match_operand:HI 0 "register_operand" "=a")
1101 (match_operand 1 "register_operand" "f")
1102 (match_operator 3 "float_operator"
1103 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1105 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1106 && TARGET_USE_<MODE>MODE_FIOP
1107 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1108 "* return output_fp_compare (insn, operands, 0, 0);"
1109 [(set_attr "type" "multi")
1110 (set_attr "unit" "i387")
1111 (set_attr "fp_int_src" "true")
1112 (set_attr "mode" "<MODE>")])
1114 (define_insn_and_split "*cmpfp_<mode>_cc"
1115 [(set (reg:CCFP FLAGS_REG)
1117 (match_operand 1 "register_operand" "f")
1118 (match_operator 3 "float_operator"
1119 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1120 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1121 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1122 && TARGET_SAHF && !TARGET_CMOVE
1123 && TARGET_USE_<MODE>MODE_FIOP
1124 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1126 "&& reload_completed"
1131 (match_op_dup 3 [(match_dup 2)]))]
1133 (set (reg:CC FLAGS_REG)
1134 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1136 [(set_attr "type" "multi")
1137 (set_attr "unit" "i387")
1138 (set_attr "fp_int_src" "true")
1139 (set_attr "mode" "<MODE>")])
1141 ;; FP compares, step 2
1142 ;; Move the fpsw to ax.
1144 (define_insn "x86_fnstsw_1"
1145 [(set (match_operand:HI 0 "register_operand" "=a")
1146 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1149 [(set_attr "length" "2")
1150 (set_attr "mode" "SI")
1151 (set_attr "unit" "i387")])
1153 ;; FP compares, step 3
1154 ;; Get ax into flags, general case.
1156 (define_insn "x86_sahf_1"
1157 [(set (reg:CC FLAGS_REG)
1158 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1162 #ifdef HAVE_AS_IX86_SAHF
1165 return ".byte\t0x9e";
1168 [(set_attr "length" "1")
1169 (set_attr "athlon_decode" "vector")
1170 (set_attr "amdfam10_decode" "direct")
1171 (set_attr "mode" "SI")])
1173 ;; Pentium Pro can do steps 1 through 3 in one go.
1174 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1175 (define_insn "*cmpfp_i_mixed"
1176 [(set (reg:CCFP FLAGS_REG)
1177 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1178 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1179 "TARGET_MIX_SSE_I387
1180 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1181 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1182 "* return output_fp_compare (insn, operands, 1, 0);"
1183 [(set_attr "type" "fcmp,ssecomi")
1185 (if_then_else (match_operand:SF 1 "" "")
1187 (const_string "DF")))
1188 (set_attr "athlon_decode" "vector")
1189 (set_attr "amdfam10_decode" "direct")])
1191 (define_insn "*cmpfp_i_sse"
1192 [(set (reg:CCFP FLAGS_REG)
1193 (compare:CCFP (match_operand 0 "register_operand" "x")
1194 (match_operand 1 "nonimmediate_operand" "xm")))]
1196 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1197 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1198 "* return output_fp_compare (insn, operands, 1, 0);"
1199 [(set_attr "type" "ssecomi")
1201 (if_then_else (match_operand:SF 1 "" "")
1203 (const_string "DF")))
1204 (set_attr "athlon_decode" "vector")
1205 (set_attr "amdfam10_decode" "direct")])
1207 (define_insn "*cmpfp_i_i387"
1208 [(set (reg:CCFP FLAGS_REG)
1209 (compare:CCFP (match_operand 0 "register_operand" "f")
1210 (match_operand 1 "register_operand" "f")))]
1211 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1213 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1214 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1215 "* return output_fp_compare (insn, operands, 1, 0);"
1216 [(set_attr "type" "fcmp")
1218 (cond [(match_operand:SF 1 "" "")
1220 (match_operand:DF 1 "" "")
1223 (const_string "XF")))
1224 (set_attr "athlon_decode" "vector")
1225 (set_attr "amdfam10_decode" "direct")])
1227 (define_insn "*cmpfp_iu_mixed"
1228 [(set (reg:CCFPU FLAGS_REG)
1229 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1230 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1231 "TARGET_MIX_SSE_I387
1232 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1233 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1234 "* return output_fp_compare (insn, operands, 1, 1);"
1235 [(set_attr "type" "fcmp,ssecomi")
1237 (if_then_else (match_operand:SF 1 "" "")
1239 (const_string "DF")))
1240 (set_attr "athlon_decode" "vector")
1241 (set_attr "amdfam10_decode" "direct")])
1243 (define_insn "*cmpfp_iu_sse"
1244 [(set (reg:CCFPU FLAGS_REG)
1245 (compare:CCFPU (match_operand 0 "register_operand" "x")
1246 (match_operand 1 "nonimmediate_operand" "xm")))]
1248 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1249 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1250 "* return output_fp_compare (insn, operands, 1, 1);"
1251 [(set_attr "type" "ssecomi")
1253 (if_then_else (match_operand:SF 1 "" "")
1255 (const_string "DF")))
1256 (set_attr "athlon_decode" "vector")
1257 (set_attr "amdfam10_decode" "direct")])
1259 (define_insn "*cmpfp_iu_387"
1260 [(set (reg:CCFPU FLAGS_REG)
1261 (compare:CCFPU (match_operand 0 "register_operand" "f")
1262 (match_operand 1 "register_operand" "f")))]
1263 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1265 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1266 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1267 "* return output_fp_compare (insn, operands, 1, 1);"
1268 [(set_attr "type" "fcmp")
1270 (cond [(match_operand:SF 1 "" "")
1272 (match_operand:DF 1 "" "")
1275 (const_string "XF")))
1276 (set_attr "athlon_decode" "vector")
1277 (set_attr "amdfam10_decode" "direct")])
1279 ;; Move instructions.
1281 ;; General case of fullword move.
1283 (define_expand "movsi"
1284 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1285 (match_operand:SI 1 "general_operand" ""))]
1287 "ix86_expand_move (SImode, operands); DONE;")
1289 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1292 ;; %%% We don't use a post-inc memory reference because x86 is not a
1293 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1294 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1295 ;; targets without our curiosities, and it is just as easy to represent
1296 ;; this differently.
1298 (define_insn "*pushsi2"
1299 [(set (match_operand:SI 0 "push_operand" "=<")
1300 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1303 [(set_attr "type" "push")
1304 (set_attr "mode" "SI")])
1306 ;; For 64BIT abi we always round up to 8 bytes.
1307 (define_insn "*pushsi2_rex64"
1308 [(set (match_operand:SI 0 "push_operand" "=X")
1309 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1312 [(set_attr "type" "push")
1313 (set_attr "mode" "SI")])
1315 (define_insn "*pushsi2_prologue"
1316 [(set (match_operand:SI 0 "push_operand" "=<")
1317 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1318 (clobber (mem:BLK (scratch)))]
1321 [(set_attr "type" "push")
1322 (set_attr "mode" "SI")])
1324 (define_insn "*popsi1_epilogue"
1325 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1326 (mem:SI (reg:SI SP_REG)))
1327 (set (reg:SI SP_REG)
1328 (plus:SI (reg:SI SP_REG) (const_int 4)))
1329 (clobber (mem:BLK (scratch)))]
1332 [(set_attr "type" "pop")
1333 (set_attr "mode" "SI")])
1335 (define_insn "popsi1"
1336 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1337 (mem:SI (reg:SI SP_REG)))
1338 (set (reg:SI SP_REG)
1339 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1342 [(set_attr "type" "pop")
1343 (set_attr "mode" "SI")])
1345 (define_insn "*movsi_xor"
1346 [(set (match_operand:SI 0 "register_operand" "=r")
1347 (match_operand:SI 1 "const0_operand" "i"))
1348 (clobber (reg:CC FLAGS_REG))]
1349 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1351 [(set_attr "type" "alu1")
1352 (set_attr "mode" "SI")
1353 (set_attr "length_immediate" "0")])
1355 (define_insn "*movsi_or"
1356 [(set (match_operand:SI 0 "register_operand" "=r")
1357 (match_operand:SI 1 "immediate_operand" "i"))
1358 (clobber (reg:CC FLAGS_REG))]
1360 && operands[1] == constm1_rtx
1361 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1363 operands[1] = constm1_rtx;
1364 return "or{l}\t{%1, %0|%0, %1}";
1366 [(set_attr "type" "alu1")
1367 (set_attr "mode" "SI")
1368 (set_attr "length_immediate" "1")])
1370 (define_insn "*movsi_1"
1371 [(set (match_operand:SI 0 "nonimmediate_operand"
1372 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1373 (match_operand:SI 1 "general_operand"
1374 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1375 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1377 switch (get_attr_type (insn))
1380 if (get_attr_mode (insn) == MODE_TI)
1381 return "pxor\t%0, %0";
1382 return "xorps\t%0, %0";
1385 switch (get_attr_mode (insn))
1388 return "movdqa\t{%1, %0|%0, %1}";
1390 return "movaps\t{%1, %0|%0, %1}";
1392 return "movd\t{%1, %0|%0, %1}";
1394 return "movss\t{%1, %0|%0, %1}";
1400 return "pxor\t%0, %0";
1403 if (get_attr_mode (insn) == MODE_DI)
1404 return "movq\t{%1, %0|%0, %1}";
1405 return "movd\t{%1, %0|%0, %1}";
1408 return "lea{l}\t{%1, %0|%0, %1}";
1411 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1412 return "mov{l}\t{%1, %0|%0, %1}";
1416 (cond [(eq_attr "alternative" "2")
1417 (const_string "mmxadd")
1418 (eq_attr "alternative" "3,4,5")
1419 (const_string "mmxmov")
1420 (eq_attr "alternative" "6")
1421 (const_string "sselog1")
1422 (eq_attr "alternative" "7,8,9,10,11")
1423 (const_string "ssemov")
1424 (match_operand:DI 1 "pic_32bit_operand" "")
1425 (const_string "lea")
1427 (const_string "imov")))
1429 (cond [(eq_attr "alternative" "2,3")
1431 (eq_attr "alternative" "6,7")
1433 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1434 (const_string "V4SF")
1435 (const_string "TI"))
1436 (and (eq_attr "alternative" "8,9,10,11")
1437 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1440 (const_string "SI")))])
1442 ;; Stores and loads of ax to arbitrary constant address.
1443 ;; We fake an second form of instruction to force reload to load address
1444 ;; into register when rax is not available
1445 (define_insn "*movabssi_1_rex64"
1446 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1447 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1448 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1450 movabs{l}\t{%1, %P0|%P0, %1}
1451 mov{l}\t{%1, %a0|%a0, %1}"
1452 [(set_attr "type" "imov")
1453 (set_attr "modrm" "0,*")
1454 (set_attr "length_address" "8,0")
1455 (set_attr "length_immediate" "0,*")
1456 (set_attr "memory" "store")
1457 (set_attr "mode" "SI")])
1459 (define_insn "*movabssi_2_rex64"
1460 [(set (match_operand:SI 0 "register_operand" "=a,r")
1461 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1462 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1464 movabs{l}\t{%P1, %0|%0, %P1}
1465 mov{l}\t{%a1, %0|%0, %a1}"
1466 [(set_attr "type" "imov")
1467 (set_attr "modrm" "0,*")
1468 (set_attr "length_address" "8,0")
1469 (set_attr "length_immediate" "0")
1470 (set_attr "memory" "load")
1471 (set_attr "mode" "SI")])
1473 (define_insn "*swapsi"
1474 [(set (match_operand:SI 0 "register_operand" "+r")
1475 (match_operand:SI 1 "register_operand" "+r"))
1480 [(set_attr "type" "imov")
1481 (set_attr "mode" "SI")
1482 (set_attr "pent_pair" "np")
1483 (set_attr "athlon_decode" "vector")
1484 (set_attr "amdfam10_decode" "double")])
1486 (define_expand "movhi"
1487 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1488 (match_operand:HI 1 "general_operand" ""))]
1490 "ix86_expand_move (HImode, operands); DONE;")
1492 (define_insn "*pushhi2"
1493 [(set (match_operand:HI 0 "push_operand" "=X")
1494 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1497 [(set_attr "type" "push")
1498 (set_attr "mode" "SI")])
1500 ;; For 64BIT abi we always round up to 8 bytes.
1501 (define_insn "*pushhi2_rex64"
1502 [(set (match_operand:HI 0 "push_operand" "=X")
1503 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1506 [(set_attr "type" "push")
1507 (set_attr "mode" "DI")])
1509 (define_insn "*movhi_1"
1510 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1511 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1512 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1514 switch (get_attr_type (insn))
1517 /* movzwl is faster than movw on p2 due to partial word stalls,
1518 though not as fast as an aligned movl. */
1519 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1521 if (get_attr_mode (insn) == MODE_SI)
1522 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1524 return "mov{w}\t{%1, %0|%0, %1}";
1528 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1529 (const_string "imov")
1530 (and (eq_attr "alternative" "0")
1531 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1533 (eq (symbol_ref "TARGET_HIMODE_MATH")
1535 (const_string "imov")
1536 (and (eq_attr "alternative" "1,2")
1537 (match_operand:HI 1 "aligned_operand" ""))
1538 (const_string "imov")
1539 (and (ne (symbol_ref "TARGET_MOVX")
1541 (eq_attr "alternative" "0,2"))
1542 (const_string "imovx")
1544 (const_string "imov")))
1546 (cond [(eq_attr "type" "imovx")
1548 (and (eq_attr "alternative" "1,2")
1549 (match_operand:HI 1 "aligned_operand" ""))
1551 (and (eq_attr "alternative" "0")
1552 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1554 (eq (symbol_ref "TARGET_HIMODE_MATH")
1558 (const_string "HI")))])
1560 ;; Stores and loads of ax to arbitrary constant address.
1561 ;; We fake an second form of instruction to force reload to load address
1562 ;; into register when rax is not available
1563 (define_insn "*movabshi_1_rex64"
1564 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1565 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1566 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1568 movabs{w}\t{%1, %P0|%P0, %1}
1569 mov{w}\t{%1, %a0|%a0, %1}"
1570 [(set_attr "type" "imov")
1571 (set_attr "modrm" "0,*")
1572 (set_attr "length_address" "8,0")
1573 (set_attr "length_immediate" "0,*")
1574 (set_attr "memory" "store")
1575 (set_attr "mode" "HI")])
1577 (define_insn "*movabshi_2_rex64"
1578 [(set (match_operand:HI 0 "register_operand" "=a,r")
1579 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1580 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1582 movabs{w}\t{%P1, %0|%0, %P1}
1583 mov{w}\t{%a1, %0|%0, %a1}"
1584 [(set_attr "type" "imov")
1585 (set_attr "modrm" "0,*")
1586 (set_attr "length_address" "8,0")
1587 (set_attr "length_immediate" "0")
1588 (set_attr "memory" "load")
1589 (set_attr "mode" "HI")])
1591 (define_insn "*swaphi_1"
1592 [(set (match_operand:HI 0 "register_operand" "+r")
1593 (match_operand:HI 1 "register_operand" "+r"))
1596 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1598 [(set_attr "type" "imov")
1599 (set_attr "mode" "SI")
1600 (set_attr "pent_pair" "np")
1601 (set_attr "athlon_decode" "vector")
1602 (set_attr "amdfam10_decode" "double")])
1604 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1605 (define_insn "*swaphi_2"
1606 [(set (match_operand:HI 0 "register_operand" "+r")
1607 (match_operand:HI 1 "register_operand" "+r"))
1610 "TARGET_PARTIAL_REG_STALL"
1612 [(set_attr "type" "imov")
1613 (set_attr "mode" "HI")
1614 (set_attr "pent_pair" "np")
1615 (set_attr "athlon_decode" "vector")])
1617 (define_expand "movstricthi"
1618 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1619 (match_operand:HI 1 "general_operand" ""))]
1620 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1622 /* Don't generate memory->memory moves, go through a register */
1623 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1624 operands[1] = force_reg (HImode, operands[1]);
1627 (define_insn "*movstricthi_1"
1628 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1629 (match_operand:HI 1 "general_operand" "rn,m"))]
1630 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1631 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1632 "mov{w}\t{%1, %0|%0, %1}"
1633 [(set_attr "type" "imov")
1634 (set_attr "mode" "HI")])
1636 (define_insn "*movstricthi_xor"
1637 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1638 (match_operand:HI 1 "const0_operand" "i"))
1639 (clobber (reg:CC FLAGS_REG))]
1641 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1643 [(set_attr "type" "alu1")
1644 (set_attr "mode" "HI")
1645 (set_attr "length_immediate" "0")])
1647 (define_expand "movqi"
1648 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1649 (match_operand:QI 1 "general_operand" ""))]
1651 "ix86_expand_move (QImode, operands); DONE;")
1653 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1654 ;; "push a byte". But actually we use pushl, which has the effect
1655 ;; of rounding the amount pushed up to a word.
1657 (define_insn "*pushqi2"
1658 [(set (match_operand:QI 0 "push_operand" "=X")
1659 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1662 [(set_attr "type" "push")
1663 (set_attr "mode" "SI")])
1665 ;; For 64BIT abi we always round up to 8 bytes.
1666 (define_insn "*pushqi2_rex64"
1667 [(set (match_operand:QI 0 "push_operand" "=X")
1668 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1671 [(set_attr "type" "push")
1672 (set_attr "mode" "DI")])
1674 ;; Situation is quite tricky about when to choose full sized (SImode) move
1675 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1676 ;; partial register dependency machines (such as AMD Athlon), where QImode
1677 ;; moves issue extra dependency and for partial register stalls machines
1678 ;; that don't use QImode patterns (and QImode move cause stall on the next
1681 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1682 ;; register stall machines with, where we use QImode instructions, since
1683 ;; partial register stall can be caused there. Then we use movzx.
1684 (define_insn "*movqi_1"
1685 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1686 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1687 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1689 switch (get_attr_type (insn))
1692 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1693 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1695 if (get_attr_mode (insn) == MODE_SI)
1696 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1698 return "mov{b}\t{%1, %0|%0, %1}";
1702 (cond [(and (eq_attr "alternative" "5")
1703 (not (match_operand:QI 1 "aligned_operand" "")))
1704 (const_string "imovx")
1705 (ne (symbol_ref "optimize_size") (const_int 0))
1706 (const_string "imov")
1707 (and (eq_attr "alternative" "3")
1708 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1710 (eq (symbol_ref "TARGET_QIMODE_MATH")
1712 (const_string "imov")
1713 (eq_attr "alternative" "3,5")
1714 (const_string "imovx")
1715 (and (ne (symbol_ref "TARGET_MOVX")
1717 (eq_attr "alternative" "2"))
1718 (const_string "imovx")
1720 (const_string "imov")))
1722 (cond [(eq_attr "alternative" "3,4,5")
1724 (eq_attr "alternative" "6")
1726 (eq_attr "type" "imovx")
1728 (and (eq_attr "type" "imov")
1729 (and (eq_attr "alternative" "0,1")
1730 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1732 (and (eq (symbol_ref "optimize_size")
1734 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1737 ;; Avoid partial register stalls when not using QImode arithmetic
1738 (and (eq_attr "type" "imov")
1739 (and (eq_attr "alternative" "0,1")
1740 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1742 (eq (symbol_ref "TARGET_QIMODE_MATH")
1746 (const_string "QI")))])
1748 (define_expand "reload_outqi"
1749 [(parallel [(match_operand:QI 0 "" "=m")
1750 (match_operand:QI 1 "register_operand" "r")
1751 (match_operand:QI 2 "register_operand" "=&q")])]
1755 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1757 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1758 if (! q_regs_operand (op1, QImode))
1760 emit_insn (gen_movqi (op2, op1));
1763 emit_insn (gen_movqi (op0, op1));
1767 (define_insn "*swapqi_1"
1768 [(set (match_operand:QI 0 "register_operand" "+r")
1769 (match_operand:QI 1 "register_operand" "+r"))
1772 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1774 [(set_attr "type" "imov")
1775 (set_attr "mode" "SI")
1776 (set_attr "pent_pair" "np")
1777 (set_attr "athlon_decode" "vector")
1778 (set_attr "amdfam10_decode" "vector")])
1780 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1781 (define_insn "*swapqi_2"
1782 [(set (match_operand:QI 0 "register_operand" "+q")
1783 (match_operand:QI 1 "register_operand" "+q"))
1786 "TARGET_PARTIAL_REG_STALL"
1788 [(set_attr "type" "imov")
1789 (set_attr "mode" "QI")
1790 (set_attr "pent_pair" "np")
1791 (set_attr "athlon_decode" "vector")])
1793 (define_expand "movstrictqi"
1794 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1795 (match_operand:QI 1 "general_operand" ""))]
1796 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1798 /* Don't generate memory->memory moves, go through a register. */
1799 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1800 operands[1] = force_reg (QImode, operands[1]);
1803 (define_insn "*movstrictqi_1"
1804 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1805 (match_operand:QI 1 "general_operand" "*qn,m"))]
1806 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1807 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1808 "mov{b}\t{%1, %0|%0, %1}"
1809 [(set_attr "type" "imov")
1810 (set_attr "mode" "QI")])
1812 (define_insn "*movstrictqi_xor"
1813 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1814 (match_operand:QI 1 "const0_operand" "i"))
1815 (clobber (reg:CC FLAGS_REG))]
1816 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1818 [(set_attr "type" "alu1")
1819 (set_attr "mode" "QI")
1820 (set_attr "length_immediate" "0")])
1822 (define_insn "*movsi_extv_1"
1823 [(set (match_operand:SI 0 "register_operand" "=R")
1824 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1828 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1829 [(set_attr "type" "imovx")
1830 (set_attr "mode" "SI")])
1832 (define_insn "*movhi_extv_1"
1833 [(set (match_operand:HI 0 "register_operand" "=R")
1834 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1838 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1839 [(set_attr "type" "imovx")
1840 (set_attr "mode" "SI")])
1842 (define_insn "*movqi_extv_1"
1843 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1844 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1849 switch (get_attr_type (insn))
1852 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1854 return "mov{b}\t{%h1, %0|%0, %h1}";
1858 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1859 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1860 (ne (symbol_ref "TARGET_MOVX")
1862 (const_string "imovx")
1863 (const_string "imov")))
1865 (if_then_else (eq_attr "type" "imovx")
1867 (const_string "QI")))])
1869 (define_insn "*movqi_extv_1_rex64"
1870 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1871 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1876 switch (get_attr_type (insn))
1879 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1881 return "mov{b}\t{%h1, %0|%0, %h1}";
1885 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1886 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1887 (ne (symbol_ref "TARGET_MOVX")
1889 (const_string "imovx")
1890 (const_string "imov")))
1892 (if_then_else (eq_attr "type" "imovx")
1894 (const_string "QI")))])
1896 ;; Stores and loads of ax to arbitrary constant address.
1897 ;; We fake an second form of instruction to force reload to load address
1898 ;; into register when rax is not available
1899 (define_insn "*movabsqi_1_rex64"
1900 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1901 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1902 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1904 movabs{b}\t{%1, %P0|%P0, %1}
1905 mov{b}\t{%1, %a0|%a0, %1}"
1906 [(set_attr "type" "imov")
1907 (set_attr "modrm" "0,*")
1908 (set_attr "length_address" "8,0")
1909 (set_attr "length_immediate" "0,*")
1910 (set_attr "memory" "store")
1911 (set_attr "mode" "QI")])
1913 (define_insn "*movabsqi_2_rex64"
1914 [(set (match_operand:QI 0 "register_operand" "=a,r")
1915 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1916 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1918 movabs{b}\t{%P1, %0|%0, %P1}
1919 mov{b}\t{%a1, %0|%0, %a1}"
1920 [(set_attr "type" "imov")
1921 (set_attr "modrm" "0,*")
1922 (set_attr "length_address" "8,0")
1923 (set_attr "length_immediate" "0")
1924 (set_attr "memory" "load")
1925 (set_attr "mode" "QI")])
1927 (define_insn "*movdi_extzv_1"
1928 [(set (match_operand:DI 0 "register_operand" "=R")
1929 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1933 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1934 [(set_attr "type" "imovx")
1935 (set_attr "mode" "DI")])
1937 (define_insn "*movsi_extzv_1"
1938 [(set (match_operand:SI 0 "register_operand" "=R")
1939 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1943 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1944 [(set_attr "type" "imovx")
1945 (set_attr "mode" "SI")])
1947 (define_insn "*movqi_extzv_2"
1948 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1949 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1954 switch (get_attr_type (insn))
1957 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1959 return "mov{b}\t{%h1, %0|%0, %h1}";
1963 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1964 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1965 (ne (symbol_ref "TARGET_MOVX")
1967 (const_string "imovx")
1968 (const_string "imov")))
1970 (if_then_else (eq_attr "type" "imovx")
1972 (const_string "QI")))])
1974 (define_insn "*movqi_extzv_2_rex64"
1975 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1976 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1981 switch (get_attr_type (insn))
1984 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1986 return "mov{b}\t{%h1, %0|%0, %h1}";
1990 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1991 (ne (symbol_ref "TARGET_MOVX")
1993 (const_string "imovx")
1994 (const_string "imov")))
1996 (if_then_else (eq_attr "type" "imovx")
1998 (const_string "QI")))])
2000 (define_insn "movsi_insv_1"
2001 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2004 (match_operand:SI 1 "general_operand" "Qmn"))]
2006 "mov{b}\t{%b1, %h0|%h0, %b1}"
2007 [(set_attr "type" "imov")
2008 (set_attr "mode" "QI")])
2010 (define_insn "*movsi_insv_1_rex64"
2011 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2014 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2016 "mov{b}\t{%b1, %h0|%h0, %b1}"
2017 [(set_attr "type" "imov")
2018 (set_attr "mode" "QI")])
2020 (define_insn "movdi_insv_1_rex64"
2021 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2024 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2026 "mov{b}\t{%b1, %h0|%h0, %b1}"
2027 [(set_attr "type" "imov")
2028 (set_attr "mode" "QI")])
2030 (define_insn "*movqi_insv_2"
2031 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2034 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2037 "mov{b}\t{%h1, %h0|%h0, %h1}"
2038 [(set_attr "type" "imov")
2039 (set_attr "mode" "QI")])
2041 (define_expand "movdi"
2042 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2043 (match_operand:DI 1 "general_operand" ""))]
2045 "ix86_expand_move (DImode, operands); DONE;")
2047 (define_insn "*pushdi"
2048 [(set (match_operand:DI 0 "push_operand" "=<")
2049 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2053 (define_insn "*pushdi2_rex64"
2054 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2055 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2060 [(set_attr "type" "push,multi")
2061 (set_attr "mode" "DI")])
2063 ;; Convert impossible pushes of immediate to existing instructions.
2064 ;; First try to get scratch register and go through it. In case this
2065 ;; fails, push sign extended lower part first and then overwrite
2066 ;; upper part by 32bit move.
2068 [(match_scratch:DI 2 "r")
2069 (set (match_operand:DI 0 "push_operand" "")
2070 (match_operand:DI 1 "immediate_operand" ""))]
2071 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2072 && !x86_64_immediate_operand (operands[1], DImode)"
2073 [(set (match_dup 2) (match_dup 1))
2074 (set (match_dup 0) (match_dup 2))]
2077 ;; We need to define this as both peepholer and splitter for case
2078 ;; peephole2 pass is not run.
2079 ;; "&& 1" is needed to keep it from matching the previous pattern.
2081 [(set (match_operand:DI 0 "push_operand" "")
2082 (match_operand:DI 1 "immediate_operand" ""))]
2083 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2084 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2085 [(set (match_dup 0) (match_dup 1))
2086 (set (match_dup 2) (match_dup 3))]
2087 "split_di (operands + 1, 1, operands + 2, operands + 3);
2088 operands[1] = gen_lowpart (DImode, operands[2]);
2089 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2094 [(set (match_operand:DI 0 "push_operand" "")
2095 (match_operand:DI 1 "immediate_operand" ""))]
2096 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2097 ? epilogue_completed : reload_completed)
2098 && !symbolic_operand (operands[1], DImode)
2099 && !x86_64_immediate_operand (operands[1], DImode)"
2100 [(set (match_dup 0) (match_dup 1))
2101 (set (match_dup 2) (match_dup 3))]
2102 "split_di (operands + 1, 1, operands + 2, operands + 3);
2103 operands[1] = gen_lowpart (DImode, operands[2]);
2104 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2108 (define_insn "*pushdi2_prologue_rex64"
2109 [(set (match_operand:DI 0 "push_operand" "=<")
2110 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2111 (clobber (mem:BLK (scratch)))]
2114 [(set_attr "type" "push")
2115 (set_attr "mode" "DI")])
2117 (define_insn "*popdi1_epilogue_rex64"
2118 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2119 (mem:DI (reg:DI SP_REG)))
2120 (set (reg:DI SP_REG)
2121 (plus:DI (reg:DI SP_REG) (const_int 8)))
2122 (clobber (mem:BLK (scratch)))]
2125 [(set_attr "type" "pop")
2126 (set_attr "mode" "DI")])
2128 (define_insn "popdi1"
2129 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2130 (mem:DI (reg:DI SP_REG)))
2131 (set (reg:DI SP_REG)
2132 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2135 [(set_attr "type" "pop")
2136 (set_attr "mode" "DI")])
2138 (define_insn "*movdi_xor_rex64"
2139 [(set (match_operand:DI 0 "register_operand" "=r")
2140 (match_operand:DI 1 "const0_operand" "i"))
2141 (clobber (reg:CC FLAGS_REG))]
2142 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2143 && reload_completed"
2145 [(set_attr "type" "alu1")
2146 (set_attr "mode" "SI")
2147 (set_attr "length_immediate" "0")])
2149 (define_insn "*movdi_or_rex64"
2150 [(set (match_operand:DI 0 "register_operand" "=r")
2151 (match_operand:DI 1 "const_int_operand" "i"))
2152 (clobber (reg:CC FLAGS_REG))]
2153 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2155 && operands[1] == constm1_rtx"
2157 operands[1] = constm1_rtx;
2158 return "or{q}\t{%1, %0|%0, %1}";
2160 [(set_attr "type" "alu1")
2161 (set_attr "mode" "DI")
2162 (set_attr "length_immediate" "1")])
2164 (define_insn "*movdi_2"
2165 [(set (match_operand:DI 0 "nonimmediate_operand"
2166 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2167 (match_operand:DI 1 "general_operand"
2168 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2169 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2174 movq\t{%1, %0|%0, %1}
2175 movq\t{%1, %0|%0, %1}
2177 movq\t{%1, %0|%0, %1}
2178 movdqa\t{%1, %0|%0, %1}
2179 movq\t{%1, %0|%0, %1}
2181 movlps\t{%1, %0|%0, %1}
2182 movaps\t{%1, %0|%0, %1}
2183 movlps\t{%1, %0|%0, %1}"
2184 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2185 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2188 [(set (match_operand:DI 0 "push_operand" "")
2189 (match_operand:DI 1 "general_operand" ""))]
2190 "!TARGET_64BIT && reload_completed
2191 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2193 "ix86_split_long_move (operands); DONE;")
2195 ;; %%% This multiword shite has got to go.
2197 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2198 (match_operand:DI 1 "general_operand" ""))]
2199 "!TARGET_64BIT && reload_completed
2200 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2201 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2203 "ix86_split_long_move (operands); DONE;")
2205 (define_insn "*movdi_1_rex64"
2206 [(set (match_operand:DI 0 "nonimmediate_operand"
2207 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2208 (match_operand:DI 1 "general_operand"
2209 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2210 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2212 switch (get_attr_type (insn))
2215 if (SSE_REG_P (operands[0]))
2216 return "movq2dq\t{%1, %0|%0, %1}";
2218 return "movdq2q\t{%1, %0|%0, %1}";
2221 if (get_attr_mode (insn) == MODE_TI)
2222 return "movdqa\t{%1, %0|%0, %1}";
2226 /* Moves from and into integer register is done using movd
2227 opcode with REX prefix. */
2228 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2229 return "movd\t{%1, %0|%0, %1}";
2230 return "movq\t{%1, %0|%0, %1}";
2234 return "pxor\t%0, %0";
2240 return "lea{q}\t{%a1, %0|%0, %a1}";
2243 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2244 if (get_attr_mode (insn) == MODE_SI)
2245 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2246 else if (which_alternative == 2)
2247 return "movabs{q}\t{%1, %0|%0, %1}";
2249 return "mov{q}\t{%1, %0|%0, %1}";
2253 (cond [(eq_attr "alternative" "5")
2254 (const_string "mmxadd")
2255 (eq_attr "alternative" "6,7,8,9,10")
2256 (const_string "mmxmov")
2257 (eq_attr "alternative" "11")
2258 (const_string "sselog1")
2259 (eq_attr "alternative" "12,13,14,15,16")
2260 (const_string "ssemov")
2261 (eq_attr "alternative" "17,18")
2262 (const_string "ssecvt")
2263 (eq_attr "alternative" "4")
2264 (const_string "multi")
2265 (match_operand:DI 1 "pic_32bit_operand" "")
2266 (const_string "lea")
2268 (const_string "imov")))
2269 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2270 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2271 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2273 ;; Stores and loads of ax to arbitrary constant address.
2274 ;; We fake an second form of instruction to force reload to load address
2275 ;; into register when rax is not available
2276 (define_insn "*movabsdi_1_rex64"
2277 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2278 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2279 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2281 movabs{q}\t{%1, %P0|%P0, %1}
2282 mov{q}\t{%1, %a0|%a0, %1}"
2283 [(set_attr "type" "imov")
2284 (set_attr "modrm" "0,*")
2285 (set_attr "length_address" "8,0")
2286 (set_attr "length_immediate" "0,*")
2287 (set_attr "memory" "store")
2288 (set_attr "mode" "DI")])
2290 (define_insn "*movabsdi_2_rex64"
2291 [(set (match_operand:DI 0 "register_operand" "=a,r")
2292 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2293 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2295 movabs{q}\t{%P1, %0|%0, %P1}
2296 mov{q}\t{%a1, %0|%0, %a1}"
2297 [(set_attr "type" "imov")
2298 (set_attr "modrm" "0,*")
2299 (set_attr "length_address" "8,0")
2300 (set_attr "length_immediate" "0")
2301 (set_attr "memory" "load")
2302 (set_attr "mode" "DI")])
2304 ;; Convert impossible stores of immediate to existing instructions.
2305 ;; First try to get scratch register and go through it. In case this
2306 ;; fails, move by 32bit parts.
2308 [(match_scratch:DI 2 "r")
2309 (set (match_operand:DI 0 "memory_operand" "")
2310 (match_operand:DI 1 "immediate_operand" ""))]
2311 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2312 && !x86_64_immediate_operand (operands[1], DImode)"
2313 [(set (match_dup 2) (match_dup 1))
2314 (set (match_dup 0) (match_dup 2))]
2317 ;; We need to define this as both peepholer and splitter for case
2318 ;; peephole2 pass is not run.
2319 ;; "&& 1" is needed to keep it from matching the previous pattern.
2321 [(set (match_operand:DI 0 "memory_operand" "")
2322 (match_operand:DI 1 "immediate_operand" ""))]
2323 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2324 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2325 [(set (match_dup 2) (match_dup 3))
2326 (set (match_dup 4) (match_dup 5))]
2327 "split_di (operands, 2, operands + 2, operands + 4);")
2330 [(set (match_operand:DI 0 "memory_operand" "")
2331 (match_operand:DI 1 "immediate_operand" ""))]
2332 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2333 ? epilogue_completed : reload_completed)
2334 && !symbolic_operand (operands[1], DImode)
2335 && !x86_64_immediate_operand (operands[1], DImode)"
2336 [(set (match_dup 2) (match_dup 3))
2337 (set (match_dup 4) (match_dup 5))]
2338 "split_di (operands, 2, operands + 2, operands + 4);")
2340 (define_insn "*swapdi_rex64"
2341 [(set (match_operand:DI 0 "register_operand" "+r")
2342 (match_operand:DI 1 "register_operand" "+r"))
2347 [(set_attr "type" "imov")
2348 (set_attr "mode" "DI")
2349 (set_attr "pent_pair" "np")
2350 (set_attr "athlon_decode" "vector")
2351 (set_attr "amdfam10_decode" "double")])
2353 (define_expand "movti"
2354 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2355 (match_operand:TI 1 "nonimmediate_operand" ""))]
2356 "TARGET_SSE || TARGET_64BIT"
2359 ix86_expand_move (TImode, operands);
2360 else if (push_operand (operands[0], TImode))
2361 ix86_expand_push (TImode, operands[1]);
2363 ix86_expand_vector_move (TImode, operands);
2367 (define_insn "*movti_internal"
2368 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2369 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2370 "TARGET_SSE && !TARGET_64BIT
2371 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2373 switch (which_alternative)
2376 if (get_attr_mode (insn) == MODE_V4SF)
2377 return "xorps\t%0, %0";
2379 return "pxor\t%0, %0";
2382 if (get_attr_mode (insn) == MODE_V4SF)
2383 return "movaps\t{%1, %0|%0, %1}";
2385 return "movdqa\t{%1, %0|%0, %1}";
2390 [(set_attr "type" "sselog1,ssemov,ssemov")
2392 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2393 (ne (symbol_ref "optimize_size") (const_int 0)))
2394 (const_string "V4SF")
2395 (and (eq_attr "alternative" "2")
2396 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2398 (const_string "V4SF")]
2399 (const_string "TI")))])
2401 (define_insn "*movti_rex64"
2402 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2403 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2405 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2407 switch (which_alternative)
2413 if (get_attr_mode (insn) == MODE_V4SF)
2414 return "xorps\t%0, %0";
2416 return "pxor\t%0, %0";
2419 if (get_attr_mode (insn) == MODE_V4SF)
2420 return "movaps\t{%1, %0|%0, %1}";
2422 return "movdqa\t{%1, %0|%0, %1}";
2427 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2429 (cond [(eq_attr "alternative" "2,3")
2431 (ne (symbol_ref "optimize_size")
2433 (const_string "V4SF")
2434 (const_string "TI"))
2435 (eq_attr "alternative" "4")
2437 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2439 (ne (symbol_ref "optimize_size")
2441 (const_string "V4SF")
2442 (const_string "TI"))]
2443 (const_string "DI")))])
2446 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2447 (match_operand:TI 1 "general_operand" ""))]
2448 "reload_completed && !SSE_REG_P (operands[0])
2449 && !SSE_REG_P (operands[1])"
2451 "ix86_split_long_move (operands); DONE;")
2453 ;; This expands to what emit_move_complex would generate if we didn't
2454 ;; have a movti pattern. Having this avoids problems with reload on
2455 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2456 ;; to have around all the time.
2457 (define_expand "movcdi"
2458 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2459 (match_operand:CDI 1 "general_operand" ""))]
2462 if (push_operand (operands[0], CDImode))
2463 emit_move_complex_push (CDImode, operands[0], operands[1]);
2465 emit_move_complex_parts (operands[0], operands[1]);
2469 (define_expand "movsf"
2470 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2471 (match_operand:SF 1 "general_operand" ""))]
2473 "ix86_expand_move (SFmode, operands); DONE;")
2475 (define_insn "*pushsf"
2476 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2477 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2480 /* Anything else should be already split before reg-stack. */
2481 gcc_assert (which_alternative == 1);
2482 return "push{l}\t%1";
2484 [(set_attr "type" "multi,push,multi")
2485 (set_attr "unit" "i387,*,*")
2486 (set_attr "mode" "SF,SI,SF")])
2488 (define_insn "*pushsf_rex64"
2489 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2490 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2493 /* Anything else should be already split before reg-stack. */
2494 gcc_assert (which_alternative == 1);
2495 return "push{q}\t%q1";
2497 [(set_attr "type" "multi,push,multi")
2498 (set_attr "unit" "i387,*,*")
2499 (set_attr "mode" "SF,DI,SF")])
2502 [(set (match_operand:SF 0 "push_operand" "")
2503 (match_operand:SF 1 "memory_operand" ""))]
2505 && MEM_P (operands[1])
2506 && (operands[2] = find_constant_src (insn))"
2511 ;; %%% Kill this when call knows how to work this out.
2513 [(set (match_operand:SF 0 "push_operand" "")
2514 (match_operand:SF 1 "any_fp_register_operand" ""))]
2516 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2517 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2520 [(set (match_operand:SF 0 "push_operand" "")
2521 (match_operand:SF 1 "any_fp_register_operand" ""))]
2523 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2524 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2526 (define_insn "*movsf_1"
2527 [(set (match_operand:SF 0 "nonimmediate_operand"
2528 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2529 (match_operand:SF 1 "general_operand"
2530 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2531 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2532 && (reload_in_progress || reload_completed
2533 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2534 || (!TARGET_SSE_MATH && optimize_size
2535 && standard_80387_constant_p (operands[1]))
2536 || GET_CODE (operands[1]) != CONST_DOUBLE
2537 || memory_operand (operands[0], SFmode))"
2539 switch (which_alternative)
2543 return output_387_reg_move (insn, operands);
2546 return standard_80387_constant_opcode (operands[1]);
2550 return "mov{l}\t{%1, %0|%0, %1}";
2552 if (get_attr_mode (insn) == MODE_TI)
2553 return "pxor\t%0, %0";
2555 return "xorps\t%0, %0";
2557 if (get_attr_mode (insn) == MODE_V4SF)
2558 return "movaps\t{%1, %0|%0, %1}";
2560 return "movss\t{%1, %0|%0, %1}";
2562 return "movss\t{%1, %0|%0, %1}";
2565 case 12: case 13: case 14: case 15:
2566 return "movd\t{%1, %0|%0, %1}";
2569 return "movq\t{%1, %0|%0, %1}";
2575 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2577 (cond [(eq_attr "alternative" "3,4,9,10")
2579 (eq_attr "alternative" "5")
2581 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2583 (ne (symbol_ref "TARGET_SSE2")
2585 (eq (symbol_ref "optimize_size")
2588 (const_string "V4SF"))
2589 /* For architectures resolving dependencies on
2590 whole SSE registers use APS move to break dependency
2591 chains, otherwise use short move to avoid extra work.
2593 Do the same for architectures resolving dependencies on
2594 the parts. While in DF mode it is better to always handle
2595 just register parts, the SF mode is different due to lack
2596 of instructions to load just part of the register. It is
2597 better to maintain the whole registers in single format
2598 to avoid problems on using packed logical operations. */
2599 (eq_attr "alternative" "6")
2601 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2603 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2605 (const_string "V4SF")
2606 (const_string "SF"))
2607 (eq_attr "alternative" "11")
2608 (const_string "DI")]
2609 (const_string "SF")))])
2611 (define_insn "*swapsf"
2612 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2613 (match_operand:SF 1 "fp_register_operand" "+f"))
2616 "reload_completed || TARGET_80387"
2618 if (STACK_TOP_P (operands[0]))
2623 [(set_attr "type" "fxch")
2624 (set_attr "mode" "SF")])
2626 (define_expand "movdf"
2627 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2628 (match_operand:DF 1 "general_operand" ""))]
2630 "ix86_expand_move (DFmode, operands); DONE;")
2632 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2633 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2634 ;; On the average, pushdf using integers can be still shorter. Allow this
2635 ;; pattern for optimize_size too.
2637 (define_insn "*pushdf_nointeger"
2638 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2639 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2640 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2642 /* This insn should be already split before reg-stack. */
2645 [(set_attr "type" "multi")
2646 (set_attr "unit" "i387,*,*,*")
2647 (set_attr "mode" "DF,SI,SI,DF")])
2649 (define_insn "*pushdf_integer"
2650 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2651 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2652 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2654 /* This insn should be already split before reg-stack. */
2657 [(set_attr "type" "multi")
2658 (set_attr "unit" "i387,*,*")
2659 (set_attr "mode" "DF,SI,DF")])
2661 ;; %%% Kill this when call knows how to work this out.
2663 [(set (match_operand:DF 0 "push_operand" "")
2664 (match_operand:DF 1 "any_fp_register_operand" ""))]
2665 "!TARGET_64BIT && reload_completed"
2666 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2667 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2671 [(set (match_operand:DF 0 "push_operand" "")
2672 (match_operand:DF 1 "any_fp_register_operand" ""))]
2673 "TARGET_64BIT && reload_completed"
2674 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2675 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2679 [(set (match_operand:DF 0 "push_operand" "")
2680 (match_operand:DF 1 "general_operand" ""))]
2683 "ix86_split_long_move (operands); DONE;")
2685 ;; Moving is usually shorter when only FP registers are used. This separate
2686 ;; movdf pattern avoids the use of integer registers for FP operations
2687 ;; when optimizing for size.
2689 (define_insn "*movdf_nointeger"
2690 [(set (match_operand:DF 0 "nonimmediate_operand"
2691 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2692 (match_operand:DF 1 "general_operand"
2693 "fm,f,G,*roF,F*r,C ,Y2*x,mY2*x,Y2*x"))]
2694 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2695 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2696 && (reload_in_progress || reload_completed
2697 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2698 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2699 && standard_80387_constant_p (operands[1]))
2700 || GET_CODE (operands[1]) != CONST_DOUBLE
2701 || memory_operand (operands[0], DFmode))"
2703 switch (which_alternative)
2707 return output_387_reg_move (insn, operands);
2710 return standard_80387_constant_opcode (operands[1]);
2716 switch (get_attr_mode (insn))
2719 return "xorps\t%0, %0";
2721 return "xorpd\t%0, %0";
2723 return "pxor\t%0, %0";
2730 switch (get_attr_mode (insn))
2733 return "movaps\t{%1, %0|%0, %1}";
2735 return "movapd\t{%1, %0|%0, %1}";
2737 return "movdqa\t{%1, %0|%0, %1}";
2739 return "movq\t{%1, %0|%0, %1}";
2741 return "movsd\t{%1, %0|%0, %1}";
2743 return "movlpd\t{%1, %0|%0, %1}";
2745 return "movlps\t{%1, %0|%0, %1}";
2754 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2756 (cond [(eq_attr "alternative" "0,1,2")
2758 (eq_attr "alternative" "3,4")
2761 /* For SSE1, we have many fewer alternatives. */
2762 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2763 (cond [(eq_attr "alternative" "5,6")
2764 (const_string "V4SF")
2766 (const_string "V2SF"))
2768 /* xorps is one byte shorter. */
2769 (eq_attr "alternative" "5")
2770 (cond [(ne (symbol_ref "optimize_size")
2772 (const_string "V4SF")
2773 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2777 (const_string "V2DF"))
2779 /* For architectures resolving dependencies on
2780 whole SSE registers use APD move to break dependency
2781 chains, otherwise use short move to avoid extra work.
2783 movaps encodes one byte shorter. */
2784 (eq_attr "alternative" "6")
2786 [(ne (symbol_ref "optimize_size")
2788 (const_string "V4SF")
2789 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2791 (const_string "V2DF")
2793 (const_string "DF"))
2794 /* For architectures resolving dependencies on register
2795 parts we may avoid extra work to zero out upper part
2797 (eq_attr "alternative" "7")
2799 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2801 (const_string "V1DF")
2802 (const_string "DF"))
2804 (const_string "DF")))])
2806 (define_insn "*movdf_integer_rex64"
2807 [(set (match_operand:DF 0 "nonimmediate_operand"
2808 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2809 (match_operand:DF 1 "general_operand"
2810 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2811 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2812 && (reload_in_progress || reload_completed
2813 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2814 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2815 && standard_80387_constant_p (operands[1]))
2816 || GET_CODE (operands[1]) != CONST_DOUBLE
2817 || memory_operand (operands[0], DFmode))"
2819 switch (which_alternative)
2823 return output_387_reg_move (insn, operands);
2826 return standard_80387_constant_opcode (operands[1]);
2833 switch (get_attr_mode (insn))
2836 return "xorps\t%0, %0";
2838 return "xorpd\t%0, %0";
2840 return "pxor\t%0, %0";
2847 switch (get_attr_mode (insn))
2850 return "movaps\t{%1, %0|%0, %1}";
2852 return "movapd\t{%1, %0|%0, %1}";
2854 return "movdqa\t{%1, %0|%0, %1}";
2856 return "movq\t{%1, %0|%0, %1}";
2858 return "movsd\t{%1, %0|%0, %1}";
2860 return "movlpd\t{%1, %0|%0, %1}";
2862 return "movlps\t{%1, %0|%0, %1}";
2869 return "movd\t{%1, %0|%0, %1}";
2875 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2877 (cond [(eq_attr "alternative" "0,1,2")
2879 (eq_attr "alternative" "3,4,9,10")
2882 /* For SSE1, we have many fewer alternatives. */
2883 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2884 (cond [(eq_attr "alternative" "5,6")
2885 (const_string "V4SF")
2887 (const_string "V2SF"))
2889 /* xorps is one byte shorter. */
2890 (eq_attr "alternative" "5")
2891 (cond [(ne (symbol_ref "optimize_size")
2893 (const_string "V4SF")
2894 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2898 (const_string "V2DF"))
2900 /* For architectures resolving dependencies on
2901 whole SSE registers use APD move to break dependency
2902 chains, otherwise use short move to avoid extra work.
2904 movaps encodes one byte shorter. */
2905 (eq_attr "alternative" "6")
2907 [(ne (symbol_ref "optimize_size")
2909 (const_string "V4SF")
2910 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2912 (const_string "V2DF")
2914 (const_string "DF"))
2915 /* For architectures resolving dependencies on register
2916 parts we may avoid extra work to zero out upper part
2918 (eq_attr "alternative" "7")
2920 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2922 (const_string "V1DF")
2923 (const_string "DF"))
2925 (const_string "DF")))])
2927 (define_insn "*movdf_integer"
2928 [(set (match_operand:DF 0 "nonimmediate_operand"
2929 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2930 (match_operand:DF 1 "general_operand"
2931 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2932 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2933 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2934 && (reload_in_progress || reload_completed
2935 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2936 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2937 && standard_80387_constant_p (operands[1]))
2938 || GET_CODE (operands[1]) != CONST_DOUBLE
2939 || memory_operand (operands[0], DFmode))"
2941 switch (which_alternative)
2945 return output_387_reg_move (insn, operands);
2948 return standard_80387_constant_opcode (operands[1]);
2955 switch (get_attr_mode (insn))
2958 return "xorps\t%0, %0";
2960 return "xorpd\t%0, %0";
2962 return "pxor\t%0, %0";
2969 switch (get_attr_mode (insn))
2972 return "movaps\t{%1, %0|%0, %1}";
2974 return "movapd\t{%1, %0|%0, %1}";
2976 return "movdqa\t{%1, %0|%0, %1}";
2978 return "movq\t{%1, %0|%0, %1}";
2980 return "movsd\t{%1, %0|%0, %1}";
2982 return "movlpd\t{%1, %0|%0, %1}";
2984 return "movlps\t{%1, %0|%0, %1}";
2993 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2995 (cond [(eq_attr "alternative" "0,1,2")
2997 (eq_attr "alternative" "3,4")
3000 /* For SSE1, we have many fewer alternatives. */
3001 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3002 (cond [(eq_attr "alternative" "5,6")
3003 (const_string "V4SF")
3005 (const_string "V2SF"))
3007 /* xorps is one byte shorter. */
3008 (eq_attr "alternative" "5")
3009 (cond [(ne (symbol_ref "optimize_size")
3011 (const_string "V4SF")
3012 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3016 (const_string "V2DF"))
3018 /* For architectures resolving dependencies on
3019 whole SSE registers use APD move to break dependency
3020 chains, otherwise use short move to avoid extra work.
3022 movaps encodes one byte shorter. */
3023 (eq_attr "alternative" "6")
3025 [(ne (symbol_ref "optimize_size")
3027 (const_string "V4SF")
3028 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3030 (const_string "V2DF")
3032 (const_string "DF"))
3033 /* For architectures resolving dependencies on register
3034 parts we may avoid extra work to zero out upper part
3036 (eq_attr "alternative" "7")
3038 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3040 (const_string "V1DF")
3041 (const_string "DF"))
3043 (const_string "DF")))])
3046 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3047 (match_operand:DF 1 "general_operand" ""))]
3049 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3050 && ! (ANY_FP_REG_P (operands[0]) ||
3051 (GET_CODE (operands[0]) == SUBREG
3052 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3053 && ! (ANY_FP_REG_P (operands[1]) ||
3054 (GET_CODE (operands[1]) == SUBREG
3055 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3057 "ix86_split_long_move (operands); DONE;")
3059 (define_insn "*swapdf"
3060 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3061 (match_operand:DF 1 "fp_register_operand" "+f"))
3064 "reload_completed || TARGET_80387"
3066 if (STACK_TOP_P (operands[0]))
3071 [(set_attr "type" "fxch")
3072 (set_attr "mode" "DF")])
3074 (define_expand "movxf"
3075 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3076 (match_operand:XF 1 "general_operand" ""))]
3078 "ix86_expand_move (XFmode, operands); DONE;")
3080 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3081 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3082 ;; Pushing using integer instructions is longer except for constants
3083 ;; and direct memory references.
3084 ;; (assuming that any given constant is pushed only once, but this ought to be
3085 ;; handled elsewhere).
3087 (define_insn "*pushxf_nointeger"
3088 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3089 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3092 /* This insn should be already split before reg-stack. */
3095 [(set_attr "type" "multi")
3096 (set_attr "unit" "i387,*,*")
3097 (set_attr "mode" "XF,SI,SI")])
3099 (define_insn "*pushxf_integer"
3100 [(set (match_operand:XF 0 "push_operand" "=<,<")
3101 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3104 /* This insn should be already split before reg-stack. */
3107 [(set_attr "type" "multi")
3108 (set_attr "unit" "i387,*")
3109 (set_attr "mode" "XF,SI")])
3112 [(set (match_operand 0 "push_operand" "")
3113 (match_operand 1 "general_operand" ""))]
3115 && (GET_MODE (operands[0]) == XFmode
3116 || GET_MODE (operands[0]) == DFmode)
3117 && !ANY_FP_REG_P (operands[1])"
3119 "ix86_split_long_move (operands); DONE;")
3122 [(set (match_operand:XF 0 "push_operand" "")
3123 (match_operand:XF 1 "any_fp_register_operand" ""))]
3125 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3126 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3127 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3130 [(set (match_operand:XF 0 "push_operand" "")
3131 (match_operand:XF 1 "any_fp_register_operand" ""))]
3133 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3134 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3135 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3137 ;; Do not use integer registers when optimizing for size
3138 (define_insn "*movxf_nointeger"
3139 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3140 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3142 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3143 && (reload_in_progress || reload_completed
3144 || (optimize_size && standard_80387_constant_p (operands[1]))
3145 || GET_CODE (operands[1]) != CONST_DOUBLE
3146 || memory_operand (operands[0], XFmode))"
3148 switch (which_alternative)
3152 return output_387_reg_move (insn, operands);
3155 return standard_80387_constant_opcode (operands[1]);
3163 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3164 (set_attr "mode" "XF,XF,XF,SI,SI")])
3166 (define_insn "*movxf_integer"
3167 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3168 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3170 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3171 && (reload_in_progress || reload_completed
3172 || (optimize_size && standard_80387_constant_p (operands[1]))
3173 || GET_CODE (operands[1]) != CONST_DOUBLE
3174 || memory_operand (operands[0], XFmode))"
3176 switch (which_alternative)
3180 return output_387_reg_move (insn, operands);
3183 return standard_80387_constant_opcode (operands[1]);
3192 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3193 (set_attr "mode" "XF,XF,XF,SI,SI")])
3195 (define_expand "movtf"
3196 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3197 (match_operand:TF 1 "nonimmediate_operand" ""))]
3200 ix86_expand_move (TFmode, operands);
3204 (define_insn "*movtf_internal"
3205 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3206 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3208 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3210 switch (which_alternative)
3214 if (get_attr_mode (insn) == MODE_V4SF)
3215 return "movaps\t{%1, %0|%0, %1}";
3217 return "movdqa\t{%1, %0|%0, %1}";
3219 if (get_attr_mode (insn) == MODE_V4SF)
3220 return "xorps\t%0, %0";
3222 return "pxor\t%0, %0";
3230 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3232 (cond [(eq_attr "alternative" "0,2")
3234 (ne (symbol_ref "optimize_size")
3236 (const_string "V4SF")
3237 (const_string "TI"))
3238 (eq_attr "alternative" "1")
3240 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3242 (ne (symbol_ref "optimize_size")
3244 (const_string "V4SF")
3245 (const_string "TI"))]
3246 (const_string "DI")))])
3249 [(set (match_operand 0 "nonimmediate_operand" "")
3250 (match_operand 1 "general_operand" ""))]
3252 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3253 && GET_MODE (operands[0]) == XFmode
3254 && ! (ANY_FP_REG_P (operands[0]) ||
3255 (GET_CODE (operands[0]) == SUBREG
3256 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3257 && ! (ANY_FP_REG_P (operands[1]) ||
3258 (GET_CODE (operands[1]) == SUBREG
3259 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3261 "ix86_split_long_move (operands); DONE;")
3264 [(set (match_operand 0 "register_operand" "")
3265 (match_operand 1 "memory_operand" ""))]
3267 && MEM_P (operands[1])
3268 && (GET_MODE (operands[0]) == TFmode
3269 || GET_MODE (operands[0]) == XFmode
3270 || GET_MODE (operands[0]) == SFmode
3271 || GET_MODE (operands[0]) == DFmode)
3272 && (operands[2] = find_constant_src (insn))"
3273 [(set (match_dup 0) (match_dup 2))]
3275 rtx c = operands[2];
3276 rtx r = operands[0];
3278 if (GET_CODE (r) == SUBREG)
3283 if (!standard_sse_constant_p (c))
3286 else if (FP_REG_P (r))
3288 if (!standard_80387_constant_p (c))
3291 else if (MMX_REG_P (r))
3296 [(set (match_operand 0 "register_operand" "")
3297 (float_extend (match_operand 1 "memory_operand" "")))]
3299 && MEM_P (operands[1])
3300 && (GET_MODE (operands[0]) == TFmode
3301 || GET_MODE (operands[0]) == XFmode
3302 || GET_MODE (operands[0]) == SFmode
3303 || GET_MODE (operands[0]) == DFmode)
3304 && (operands[2] = find_constant_src (insn))"
3305 [(set (match_dup 0) (match_dup 2))]
3307 rtx c = operands[2];
3308 rtx r = operands[0];
3310 if (GET_CODE (r) == SUBREG)
3315 if (!standard_sse_constant_p (c))
3318 else if (FP_REG_P (r))
3320 if (!standard_80387_constant_p (c))
3323 else if (MMX_REG_P (r))
3327 (define_insn "swapxf"
3328 [(set (match_operand:XF 0 "register_operand" "+f")
3329 (match_operand:XF 1 "register_operand" "+f"))
3334 if (STACK_TOP_P (operands[0]))
3339 [(set_attr "type" "fxch")
3340 (set_attr "mode" "XF")])
3342 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3344 [(set (match_operand:X87MODEF 0 "register_operand" "")
3345 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3346 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3347 && (standard_80387_constant_p (operands[1]) == 8
3348 || standard_80387_constant_p (operands[1]) == 9)"
3349 [(set (match_dup 0)(match_dup 1))
3351 (neg:X87MODEF (match_dup 0)))]
3355 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3356 if (real_isnegzero (&r))
3357 operands[1] = CONST0_RTX (<MODE>mode);
3359 operands[1] = CONST1_RTX (<MODE>mode);
3363 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3364 (match_operand:TF 1 "general_operand" ""))]
3366 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3368 "ix86_split_long_move (operands); DONE;")
3370 ;; Zero extension instructions
3372 (define_expand "zero_extendhisi2"
3373 [(set (match_operand:SI 0 "register_operand" "")
3374 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3377 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3379 operands[1] = force_reg (HImode, operands[1]);
3380 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3385 (define_insn "zero_extendhisi2_and"
3386 [(set (match_operand:SI 0 "register_operand" "=r")
3387 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3388 (clobber (reg:CC FLAGS_REG))]
3389 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3391 [(set_attr "type" "alu1")
3392 (set_attr "mode" "SI")])
3395 [(set (match_operand:SI 0 "register_operand" "")
3396 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3397 (clobber (reg:CC FLAGS_REG))]
3398 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3399 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3400 (clobber (reg:CC FLAGS_REG))])]
3403 (define_insn "*zero_extendhisi2_movzwl"
3404 [(set (match_operand:SI 0 "register_operand" "=r")
3405 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3406 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3407 "movz{wl|x}\t{%1, %0|%0, %1}"
3408 [(set_attr "type" "imovx")
3409 (set_attr "mode" "SI")])
3411 (define_expand "zero_extendqihi2"
3413 [(set (match_operand:HI 0 "register_operand" "")
3414 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3415 (clobber (reg:CC FLAGS_REG))])]
3419 (define_insn "*zero_extendqihi2_and"
3420 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3421 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3422 (clobber (reg:CC FLAGS_REG))]
3423 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3425 [(set_attr "type" "alu1")
3426 (set_attr "mode" "HI")])
3428 (define_insn "*zero_extendqihi2_movzbw_and"
3429 [(set (match_operand:HI 0 "register_operand" "=r,r")
3430 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3431 (clobber (reg:CC FLAGS_REG))]
3432 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3434 [(set_attr "type" "imovx,alu1")
3435 (set_attr "mode" "HI")])
3437 ; zero extend to SImode here to avoid partial register stalls
3438 (define_insn "*zero_extendqihi2_movzbl"
3439 [(set (match_operand:HI 0 "register_operand" "=r")
3440 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3441 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3442 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3443 [(set_attr "type" "imovx")
3444 (set_attr "mode" "SI")])
3446 ;; For the movzbw case strip only the clobber
3448 [(set (match_operand:HI 0 "register_operand" "")
3449 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3450 (clobber (reg:CC FLAGS_REG))]
3452 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3453 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3454 [(set (match_operand:HI 0 "register_operand" "")
3455 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3457 ;; When source and destination does not overlap, clear destination
3458 ;; first and then do the movb
3460 [(set (match_operand:HI 0 "register_operand" "")
3461 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3462 (clobber (reg:CC FLAGS_REG))]
3464 && ANY_QI_REG_P (operands[0])
3465 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3466 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3467 [(set (match_dup 0) (const_int 0))
3468 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3469 "operands[2] = gen_lowpart (QImode, operands[0]);")
3471 ;; Rest is handled by single and.
3473 [(set (match_operand:HI 0 "register_operand" "")
3474 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3475 (clobber (reg:CC FLAGS_REG))]
3477 && true_regnum (operands[0]) == true_regnum (operands[1])"
3478 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3479 (clobber (reg:CC FLAGS_REG))])]
3482 (define_expand "zero_extendqisi2"
3484 [(set (match_operand:SI 0 "register_operand" "")
3485 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3486 (clobber (reg:CC FLAGS_REG))])]
3490 (define_insn "*zero_extendqisi2_and"
3491 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3492 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3493 (clobber (reg:CC FLAGS_REG))]
3494 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3496 [(set_attr "type" "alu1")
3497 (set_attr "mode" "SI")])
3499 (define_insn "*zero_extendqisi2_movzbw_and"
3500 [(set (match_operand:SI 0 "register_operand" "=r,r")
3501 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3502 (clobber (reg:CC FLAGS_REG))]
3503 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3505 [(set_attr "type" "imovx,alu1")
3506 (set_attr "mode" "SI")])
3508 (define_insn "*zero_extendqisi2_movzbw"
3509 [(set (match_operand:SI 0 "register_operand" "=r")
3510 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3511 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3512 "movz{bl|x}\t{%1, %0|%0, %1}"
3513 [(set_attr "type" "imovx")
3514 (set_attr "mode" "SI")])
3516 ;; For the movzbl case strip only the clobber
3518 [(set (match_operand:SI 0 "register_operand" "")
3519 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3520 (clobber (reg:CC FLAGS_REG))]
3522 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3523 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3525 (zero_extend:SI (match_dup 1)))])
3527 ;; When source and destination does not overlap, clear destination
3528 ;; first and then do the movb
3530 [(set (match_operand:SI 0 "register_operand" "")
3531 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3532 (clobber (reg:CC FLAGS_REG))]
3534 && ANY_QI_REG_P (operands[0])
3535 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3536 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3537 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3538 [(set (match_dup 0) (const_int 0))
3539 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3540 "operands[2] = gen_lowpart (QImode, operands[0]);")
3542 ;; Rest is handled by single and.
3544 [(set (match_operand:SI 0 "register_operand" "")
3545 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3546 (clobber (reg:CC FLAGS_REG))]
3548 && true_regnum (operands[0]) == true_regnum (operands[1])"
3549 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3550 (clobber (reg:CC FLAGS_REG))])]
3553 ;; %%% Kill me once multi-word ops are sane.
3554 (define_expand "zero_extendsidi2"
3555 [(set (match_operand:DI 0 "register_operand" "")
3556 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3561 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3566 (define_insn "zero_extendsidi2_32"
3567 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3569 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3570 (clobber (reg:CC FLAGS_REG))]
3576 movd\t{%1, %0|%0, %1}
3577 movd\t{%1, %0|%0, %1}
3578 movd\t{%1, %0|%0, %1}
3579 movd\t{%1, %0|%0, %1}"
3580 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3581 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3583 (define_insn "zero_extendsidi2_rex64"
3584 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3586 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3589 mov\t{%k1, %k0|%k0, %k1}
3591 movd\t{%1, %0|%0, %1}
3592 movd\t{%1, %0|%0, %1}
3593 movd\t{%1, %0|%0, %1}
3594 movd\t{%1, %0|%0, %1}"
3595 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3596 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3599 [(set (match_operand:DI 0 "memory_operand" "")
3600 (zero_extend:DI (match_dup 0)))]
3602 [(set (match_dup 4) (const_int 0))]
3603 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3606 [(set (match_operand:DI 0 "register_operand" "")
3607 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3608 (clobber (reg:CC FLAGS_REG))]
3609 "!TARGET_64BIT && reload_completed
3610 && true_regnum (operands[0]) == true_regnum (operands[1])"
3611 [(set (match_dup 4) (const_int 0))]
3612 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3615 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3616 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3617 (clobber (reg:CC FLAGS_REG))]
3618 "!TARGET_64BIT && reload_completed
3619 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3620 [(set (match_dup 3) (match_dup 1))
3621 (set (match_dup 4) (const_int 0))]
3622 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3624 (define_insn "zero_extendhidi2"
3625 [(set (match_operand:DI 0 "register_operand" "=r")
3626 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3628 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3629 [(set_attr "type" "imovx")
3630 (set_attr "mode" "DI")])
3632 (define_insn "zero_extendqidi2"
3633 [(set (match_operand:DI 0 "register_operand" "=r")
3634 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3636 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3637 [(set_attr "type" "imovx")
3638 (set_attr "mode" "DI")])
3640 ;; Sign extension instructions
3642 (define_expand "extendsidi2"
3643 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3644 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3645 (clobber (reg:CC FLAGS_REG))
3646 (clobber (match_scratch:SI 2 ""))])]
3651 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3656 (define_insn "*extendsidi2_1"
3657 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3658 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3659 (clobber (reg:CC FLAGS_REG))
3660 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3664 (define_insn "extendsidi2_rex64"
3665 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3666 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3670 movs{lq|x}\t{%1,%0|%0, %1}"
3671 [(set_attr "type" "imovx")
3672 (set_attr "mode" "DI")
3673 (set_attr "prefix_0f" "0")
3674 (set_attr "modrm" "0,1")])
3676 (define_insn "extendhidi2"
3677 [(set (match_operand:DI 0 "register_operand" "=r")
3678 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3680 "movs{wq|x}\t{%1,%0|%0, %1}"
3681 [(set_attr "type" "imovx")
3682 (set_attr "mode" "DI")])
3684 (define_insn "extendqidi2"
3685 [(set (match_operand:DI 0 "register_operand" "=r")
3686 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3688 "movs{bq|x}\t{%1,%0|%0, %1}"
3689 [(set_attr "type" "imovx")
3690 (set_attr "mode" "DI")])
3692 ;; Extend to memory case when source register does die.
3694 [(set (match_operand:DI 0 "memory_operand" "")
3695 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3696 (clobber (reg:CC FLAGS_REG))
3697 (clobber (match_operand:SI 2 "register_operand" ""))]
3699 && dead_or_set_p (insn, operands[1])
3700 && !reg_mentioned_p (operands[1], operands[0]))"
3701 [(set (match_dup 3) (match_dup 1))
3702 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3703 (clobber (reg:CC FLAGS_REG))])
3704 (set (match_dup 4) (match_dup 1))]
3705 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3707 ;; Extend to memory case when source register does not die.
3709 [(set (match_operand:DI 0 "memory_operand" "")
3710 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3711 (clobber (reg:CC FLAGS_REG))
3712 (clobber (match_operand:SI 2 "register_operand" ""))]
3716 split_di (&operands[0], 1, &operands[3], &operands[4]);
3718 emit_move_insn (operands[3], operands[1]);
3720 /* Generate a cltd if possible and doing so it profitable. */
3721 if ((optimize_size || TARGET_USE_CLTD)
3722 && true_regnum (operands[1]) == AX_REG
3723 && true_regnum (operands[2]) == DX_REG)
3725 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3729 emit_move_insn (operands[2], operands[1]);
3730 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3732 emit_move_insn (operands[4], operands[2]);
3736 ;; Extend to register case. Optimize case where source and destination
3737 ;; registers match and cases where we can use cltd.
3739 [(set (match_operand:DI 0 "register_operand" "")
3740 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3741 (clobber (reg:CC FLAGS_REG))
3742 (clobber (match_scratch:SI 2 ""))]
3746 split_di (&operands[0], 1, &operands[3], &operands[4]);
3748 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3749 emit_move_insn (operands[3], operands[1]);
3751 /* Generate a cltd if possible and doing so it profitable. */
3752 if ((optimize_size || TARGET_USE_CLTD)
3753 && true_regnum (operands[3]) == AX_REG)
3755 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3759 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3760 emit_move_insn (operands[4], operands[1]);
3762 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3766 (define_insn "extendhisi2"
3767 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3768 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3771 switch (get_attr_prefix_0f (insn))
3774 return "{cwtl|cwde}";
3776 return "movs{wl|x}\t{%1,%0|%0, %1}";
3779 [(set_attr "type" "imovx")
3780 (set_attr "mode" "SI")
3781 (set (attr "prefix_0f")
3782 ;; movsx is short decodable while cwtl is vector decoded.
3783 (if_then_else (and (eq_attr "cpu" "!k6")
3784 (eq_attr "alternative" "0"))
3786 (const_string "1")))
3788 (if_then_else (eq_attr "prefix_0f" "0")
3790 (const_string "1")))])
3792 (define_insn "*extendhisi2_zext"
3793 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3795 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3798 switch (get_attr_prefix_0f (insn))
3801 return "{cwtl|cwde}";
3803 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3806 [(set_attr "type" "imovx")
3807 (set_attr "mode" "SI")
3808 (set (attr "prefix_0f")
3809 ;; movsx is short decodable while cwtl is vector decoded.
3810 (if_then_else (and (eq_attr "cpu" "!k6")
3811 (eq_attr "alternative" "0"))
3813 (const_string "1")))
3815 (if_then_else (eq_attr "prefix_0f" "0")
3817 (const_string "1")))])
3819 (define_insn "extendqihi2"
3820 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3821 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3824 switch (get_attr_prefix_0f (insn))
3827 return "{cbtw|cbw}";
3829 return "movs{bw|x}\t{%1,%0|%0, %1}";
3832 [(set_attr "type" "imovx")
3833 (set_attr "mode" "HI")
3834 (set (attr "prefix_0f")
3835 ;; movsx is short decodable while cwtl is vector decoded.
3836 (if_then_else (and (eq_attr "cpu" "!k6")
3837 (eq_attr "alternative" "0"))
3839 (const_string "1")))
3841 (if_then_else (eq_attr "prefix_0f" "0")
3843 (const_string "1")))])
3845 (define_insn "extendqisi2"
3846 [(set (match_operand:SI 0 "register_operand" "=r")
3847 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3849 "movs{bl|x}\t{%1,%0|%0, %1}"
3850 [(set_attr "type" "imovx")
3851 (set_attr "mode" "SI")])
3853 (define_insn "*extendqisi2_zext"
3854 [(set (match_operand:DI 0 "register_operand" "=r")
3856 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3858 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3859 [(set_attr "type" "imovx")
3860 (set_attr "mode" "SI")])
3862 ;; Conversions between float and double.
3864 ;; These are all no-ops in the model used for the 80387. So just
3867 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3868 (define_insn "*dummy_extendsfdf2"
3869 [(set (match_operand:DF 0 "push_operand" "=<")
3870 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3875 [(set (match_operand:DF 0 "push_operand" "")
3876 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3878 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3879 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3882 [(set (match_operand:DF 0 "push_operand" "")
3883 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3885 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3886 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3888 (define_insn "*dummy_extendsfxf2"
3889 [(set (match_operand:XF 0 "push_operand" "=<")
3890 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3895 [(set (match_operand:XF 0 "push_operand" "")
3896 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3898 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3899 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3900 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3903 [(set (match_operand:XF 0 "push_operand" "")
3904 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3906 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3907 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3908 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3911 [(set (match_operand:XF 0 "push_operand" "")
3912 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3914 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3915 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3916 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3919 [(set (match_operand:XF 0 "push_operand" "")
3920 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3922 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3923 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3924 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3926 (define_expand "extendsfdf2"
3927 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3928 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3929 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3931 /* ??? Needed for compress_float_constant since all fp constants
3932 are LEGITIMATE_CONSTANT_P. */
3933 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3935 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3936 && standard_80387_constant_p (operands[1]) > 0)
3938 operands[1] = simplify_const_unary_operation
3939 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3940 emit_move_insn_1 (operands[0], operands[1]);
3943 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3947 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3949 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3951 We do the conversion post reload to avoid producing of 128bit spills
3952 that might lead to ICE on 32bit target. The sequence unlikely combine
3955 [(set (match_operand:DF 0 "register_operand" "")
3957 (match_operand:SF 1 "nonimmediate_operand" "")))]
3958 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
3959 && reload_completed && SSE_REG_P (operands[0])"
3964 (parallel [(const_int 0) (const_int 1)]))))]
3966 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3967 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3968 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3969 Try to avoid move when unpacking can be done in source. */
3970 if (REG_P (operands[1]))
3972 /* If it is unsafe to overwrite upper half of source, we need
3973 to move to destination and unpack there. */
3974 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3975 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3976 && true_regnum (operands[0]) != true_regnum (operands[1]))
3978 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3979 emit_move_insn (tmp, operands[1]);
3982 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3983 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
3986 emit_insn (gen_vec_setv4sf_0 (operands[3],
3987 CONST0_RTX (V4SFmode), operands[1]));
3990 (define_insn "*extendsfdf2_mixed"
3991 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3993 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3994 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3996 switch (which_alternative)
4000 return output_387_reg_move (insn, operands);
4003 return "cvtss2sd\t{%1, %0|%0, %1}";
4009 [(set_attr "type" "fmov,fmov,ssecvt")
4010 (set_attr "mode" "SF,XF,DF")])
4012 (define_insn "*extendsfdf2_sse"
4013 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4014 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4015 "TARGET_SSE2 && TARGET_SSE_MATH"
4016 "cvtss2sd\t{%1, %0|%0, %1}"
4017 [(set_attr "type" "ssecvt")
4018 (set_attr "mode" "DF")])
4020 (define_insn "*extendsfdf2_i387"
4021 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4022 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4024 "* return output_387_reg_move (insn, operands);"
4025 [(set_attr "type" "fmov")
4026 (set_attr "mode" "SF,XF")])
4028 (define_expand "extend<mode>xf2"
4029 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4030 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4033 /* ??? Needed for compress_float_constant since all fp constants
4034 are LEGITIMATE_CONSTANT_P. */
4035 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4037 if (standard_80387_constant_p (operands[1]) > 0)
4039 operands[1] = simplify_const_unary_operation
4040 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4041 emit_move_insn_1 (operands[0], operands[1]);
4044 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4048 (define_insn "*extend<mode>xf2_i387"
4049 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4051 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4053 "* return output_387_reg_move (insn, operands);"
4054 [(set_attr "type" "fmov")
4055 (set_attr "mode" "<MODE>,XF")])
4057 ;; %%% This seems bad bad news.
4058 ;; This cannot output into an f-reg because there is no way to be sure
4059 ;; of truncating in that case. Otherwise this is just like a simple move
4060 ;; insn. So we pretend we can output to a reg in order to get better
4061 ;; register preferencing, but we really use a stack slot.
4063 ;; Conversion from DFmode to SFmode.
4065 (define_expand "truncdfsf2"
4066 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4068 (match_operand:DF 1 "nonimmediate_operand" "")))]
4069 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4071 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4073 else if (flag_unsafe_math_optimizations)
4077 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4078 rtx temp = assign_386_stack_local (SFmode, slot);
4079 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4084 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4086 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4088 We do the conversion post reload to avoid producing of 128bit spills
4089 that might lead to ICE on 32bit target. The sequence unlikely combine
4092 [(set (match_operand:SF 0 "register_operand" "")
4094 (match_operand:DF 1 "nonimmediate_operand" "")))]
4095 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4096 && reload_completed && SSE_REG_P (operands[0])"
4099 (float_truncate:V2SF
4103 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4104 operands[3] = CONST0_RTX (V2SFmode);
4105 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4106 /* Use movsd for loading from memory, unpcklpd for registers.
4107 Try to avoid move when unpacking can be done in source, or SSE3
4108 movddup is available. */
4109 if (REG_P (operands[1]))
4112 && true_regnum (operands[0]) != true_regnum (operands[1])
4113 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4114 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4116 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4117 emit_move_insn (tmp, operands[1]);
4120 else if (!TARGET_SSE3)
4121 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4122 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4125 emit_insn (gen_sse2_loadlpd (operands[4],
4126 CONST0_RTX (V2DFmode), operands[1]));
4129 (define_expand "truncdfsf2_with_temp"
4130 [(parallel [(set (match_operand:SF 0 "" "")
4131 (float_truncate:SF (match_operand:DF 1 "" "")))
4132 (clobber (match_operand:SF 2 "" ""))])]
4135 (define_insn "*truncdfsf_fast_mixed"
4136 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
4138 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4139 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4141 switch (which_alternative)
4145 return output_387_reg_move (insn, operands);
4147 return "cvtsd2ss\t{%1, %0|%0, %1}";
4152 [(set_attr "type" "fmov,fmov,ssecvt")
4153 (set_attr "mode" "SF")])
4155 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4156 ;; because nothing we do here is unsafe.
4157 (define_insn "*truncdfsf_fast_sse"
4158 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4160 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4161 "TARGET_SSE2 && TARGET_SSE_MATH"
4162 "cvtsd2ss\t{%1, %0|%0, %1}"
4163 [(set_attr "type" "ssecvt")
4164 (set_attr "mode" "SF")])
4166 (define_insn "*truncdfsf_fast_i387"
4167 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4169 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4170 "TARGET_80387 && flag_unsafe_math_optimizations"
4171 "* return output_387_reg_move (insn, operands);"
4172 [(set_attr "type" "fmov")
4173 (set_attr "mode" "SF")])
4175 (define_insn "*truncdfsf_mixed"
4176 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4178 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4179 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4180 "TARGET_MIX_SSE_I387"
4182 switch (which_alternative)
4185 return output_387_reg_move (insn, operands);
4190 return "cvtsd2ss\t{%1, %0|%0, %1}";
4195 [(set_attr "type" "fmov,multi,ssecvt")
4196 (set_attr "unit" "*,i387,*")
4197 (set_attr "mode" "SF")])
4199 (define_insn "*truncdfsf_i387"
4200 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4202 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4203 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4206 switch (which_alternative)
4209 return output_387_reg_move (insn, operands);
4217 [(set_attr "type" "fmov,multi")
4218 (set_attr "unit" "*,i387")
4219 (set_attr "mode" "SF")])
4221 (define_insn "*truncdfsf2_i387_1"
4222 [(set (match_operand:SF 0 "memory_operand" "=m")
4224 (match_operand:DF 1 "register_operand" "f")))]
4226 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4227 && !TARGET_MIX_SSE_I387"
4228 "* return output_387_reg_move (insn, operands);"
4229 [(set_attr "type" "fmov")
4230 (set_attr "mode" "SF")])
4233 [(set (match_operand:SF 0 "register_operand" "")
4235 (match_operand:DF 1 "fp_register_operand" "")))
4236 (clobber (match_operand 2 "" ""))]
4238 [(set (match_dup 2) (match_dup 1))
4239 (set (match_dup 0) (match_dup 2))]
4241 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4244 ;; Conversion from XFmode to {SF,DF}mode
4246 (define_expand "truncxf<mode>2"
4247 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4248 (float_truncate:MODEF
4249 (match_operand:XF 1 "register_operand" "")))
4250 (clobber (match_dup 2))])]
4253 if (flag_unsafe_math_optimizations)
4255 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4256 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4257 if (reg != operands[0])
4258 emit_move_insn (operands[0], reg);
4263 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4264 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4268 (define_insn "*truncxfsf2_mixed"
4269 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4271 (match_operand:XF 1 "register_operand" "f,f")))
4272 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4275 gcc_assert (!which_alternative);
4276 return output_387_reg_move (insn, operands);
4278 [(set_attr "type" "fmov,multi")
4279 (set_attr "unit" "*,i387")
4280 (set_attr "mode" "SF")])
4282 (define_insn "*truncxfdf2_mixed"
4283 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4285 (match_operand:XF 1 "register_operand" "f,f")))
4286 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4289 gcc_assert (!which_alternative);
4290 return output_387_reg_move (insn, operands);
4292 [(set_attr "type" "fmov,multi")
4293 (set_attr "unit" "*,i387")
4294 (set_attr "mode" "DF")])
4296 (define_insn "truncxf<mode>2_i387_noop"
4297 [(set (match_operand:MODEF 0 "register_operand" "=f")
4298 (float_truncate:MODEF
4299 (match_operand:XF 1 "register_operand" "f")))]
4300 "TARGET_80387 && flag_unsafe_math_optimizations"
4301 "* return output_387_reg_move (insn, operands);"
4302 [(set_attr "type" "fmov")
4303 (set_attr "mode" "<MODE>")])
4305 (define_insn "*truncxf<mode>2_i387"
4306 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4307 (float_truncate:MODEF
4308 (match_operand:XF 1 "register_operand" "f")))]
4310 "* return output_387_reg_move (insn, operands);"
4311 [(set_attr "type" "fmov")
4312 (set_attr "mode" "<MODE>")])
4315 [(set (match_operand:MODEF 0 "register_operand" "")
4316 (float_truncate:MODEF
4317 (match_operand:XF 1 "register_operand" "")))
4318 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4319 "TARGET_80387 && reload_completed"
4320 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4321 (set (match_dup 0) (match_dup 2))]
4325 [(set (match_operand:MODEF 0 "memory_operand" "")
4326 (float_truncate:MODEF
4327 (match_operand:XF 1 "register_operand" "")))
4328 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4330 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4333 ;; Signed conversion to DImode.
4335 (define_expand "fix_truncxfdi2"
4336 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4337 (fix:DI (match_operand:XF 1 "register_operand" "")))
4338 (clobber (reg:CC FLAGS_REG))])]
4343 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4348 (define_expand "fix_trunc<mode>di2"
4349 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4350 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4351 (clobber (reg:CC FLAGS_REG))])]
4352 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4355 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4357 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4360 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4362 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4363 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4364 if (out != operands[0])
4365 emit_move_insn (operands[0], out);
4370 ;; Signed conversion to SImode.
4372 (define_expand "fix_truncxfsi2"
4373 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4374 (fix:SI (match_operand:XF 1 "register_operand" "")))
4375 (clobber (reg:CC FLAGS_REG))])]
4380 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4385 (define_expand "fix_trunc<mode>si2"
4386 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4387 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4388 (clobber (reg:CC FLAGS_REG))])]
4389 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4392 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4394 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4397 if (SSE_FLOAT_MODE_P (<MODE>mode))
4399 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4400 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4401 if (out != operands[0])
4402 emit_move_insn (operands[0], out);
4407 ;; Signed conversion to HImode.
4409 (define_expand "fix_trunc<mode>hi2"
4410 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4411 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4412 (clobber (reg:CC FLAGS_REG))])]
4414 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4418 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4423 ;; Unsigned conversion to SImode.
4425 (define_expand "fixuns_trunc<mode>si2"
4427 [(set (match_operand:SI 0 "register_operand" "")
4429 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4431 (clobber (match_scratch:<ssevecmode> 3 ""))
4432 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4433 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4435 enum machine_mode mode = <MODE>mode;
4436 enum machine_mode vecmode = <ssevecmode>mode;
4437 REAL_VALUE_TYPE TWO31r;
4440 real_ldexp (&TWO31r, &dconst1, 31);
4441 two31 = const_double_from_real_value (TWO31r, mode);
4442 two31 = ix86_build_const_vector (mode, true, two31);
4443 operands[2] = force_reg (vecmode, two31);
4446 (define_insn_and_split "*fixuns_trunc<mode>_1"
4447 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4449 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4450 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4451 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4452 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4453 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4455 "&& reload_completed"
4458 ix86_split_convert_uns_si_sse (operands);
4462 ;; Unsigned conversion to HImode.
4463 ;; Without these patterns, we'll try the unsigned SI conversion which
4464 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4466 (define_expand "fixuns_trunc<mode>hi2"
4468 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4469 (set (match_operand:HI 0 "nonimmediate_operand" "")
4470 (subreg:HI (match_dup 2) 0))]
4471 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4472 "operands[2] = gen_reg_rtx (SImode);")
4474 ;; When SSE is available, it is always faster to use it!
4475 (define_insn "fix_trunc<mode>di_sse"
4476 [(set (match_operand:DI 0 "register_operand" "=r,r")
4477 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4478 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4479 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4480 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4481 [(set_attr "type" "sseicvt")
4482 (set_attr "mode" "<MODE>")
4483 (set_attr "athlon_decode" "double,vector")
4484 (set_attr "amdfam10_decode" "double,double")])
4486 (define_insn "fix_trunc<mode>si_sse"
4487 [(set (match_operand:SI 0 "register_operand" "=r,r")
4488 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4489 "SSE_FLOAT_MODE_P (<MODE>mode)
4490 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4491 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4492 [(set_attr "type" "sseicvt")
4493 (set_attr "mode" "<MODE>")
4494 (set_attr "athlon_decode" "double,vector")
4495 (set_attr "amdfam10_decode" "double,double")])
4497 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4499 [(set (match_operand:MODEF 0 "register_operand" "")
4500 (match_operand:MODEF 1 "memory_operand" ""))
4501 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4502 (fix:SSEMODEI24 (match_dup 0)))]
4503 "TARGET_SHORTEN_X87_SSE
4504 && peep2_reg_dead_p (2, operands[0])"
4505 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4508 ;; Avoid vector decoded forms of the instruction.
4510 [(match_scratch:DF 2 "Y2")
4511 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4512 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4513 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4514 [(set (match_dup 2) (match_dup 1))
4515 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4519 [(match_scratch:SF 2 "x")
4520 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4521 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4522 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4523 [(set (match_dup 2) (match_dup 1))
4524 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4527 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4528 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4529 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4530 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4532 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4533 && (TARGET_64BIT || <MODE>mode != DImode))
4535 && !(reload_completed || reload_in_progress)"
4540 if (memory_operand (operands[0], VOIDmode))
4541 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4544 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4545 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4551 [(set_attr "type" "fisttp")
4552 (set_attr "mode" "<MODE>")])
4554 (define_insn "fix_trunc<mode>_i387_fisttp"
4555 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4556 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4557 (clobber (match_scratch:XF 2 "=&1f"))]
4558 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4560 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4561 && (TARGET_64BIT || <MODE>mode != DImode))
4562 && TARGET_SSE_MATH)"
4563 "* return output_fix_trunc (insn, operands, 1);"
4564 [(set_attr "type" "fisttp")
4565 (set_attr "mode" "<MODE>")])
4567 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4568 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4569 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4570 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4571 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4572 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4574 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4575 && (TARGET_64BIT || <MODE>mode != DImode))
4576 && TARGET_SSE_MATH)"
4578 [(set_attr "type" "fisttp")
4579 (set_attr "mode" "<MODE>")])
4582 [(set (match_operand:X87MODEI 0 "register_operand" "")
4583 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4584 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4585 (clobber (match_scratch 3 ""))]
4587 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4588 (clobber (match_dup 3))])
4589 (set (match_dup 0) (match_dup 2))]
4593 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4594 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4595 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4596 (clobber (match_scratch 3 ""))]
4598 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4599 (clobber (match_dup 3))])]
4602 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4603 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4604 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4605 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4606 ;; function in i386.c.
4607 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4608 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4609 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4610 (clobber (reg:CC FLAGS_REG))]
4611 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4613 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4614 && (TARGET_64BIT || <MODE>mode != DImode))
4615 && !(reload_completed || reload_in_progress)"
4620 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4622 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4623 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4624 if (memory_operand (operands[0], VOIDmode))
4625 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4626 operands[2], operands[3]));
4629 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4630 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4631 operands[2], operands[3],
4636 [(set_attr "type" "fistp")
4637 (set_attr "i387_cw" "trunc")
4638 (set_attr "mode" "<MODE>")])
4640 (define_insn "fix_truncdi_i387"
4641 [(set (match_operand:DI 0 "memory_operand" "=m")
4642 (fix:DI (match_operand 1 "register_operand" "f")))
4643 (use (match_operand:HI 2 "memory_operand" "m"))
4644 (use (match_operand:HI 3 "memory_operand" "m"))
4645 (clobber (match_scratch:XF 4 "=&1f"))]
4646 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4648 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4649 "* return output_fix_trunc (insn, operands, 0);"
4650 [(set_attr "type" "fistp")
4651 (set_attr "i387_cw" "trunc")
4652 (set_attr "mode" "DI")])
4654 (define_insn "fix_truncdi_i387_with_temp"
4655 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4656 (fix:DI (match_operand 1 "register_operand" "f,f")))
4657 (use (match_operand:HI 2 "memory_operand" "m,m"))
4658 (use (match_operand:HI 3 "memory_operand" "m,m"))
4659 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4660 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4661 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4663 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4665 [(set_attr "type" "fistp")
4666 (set_attr "i387_cw" "trunc")
4667 (set_attr "mode" "DI")])
4670 [(set (match_operand:DI 0 "register_operand" "")
4671 (fix:DI (match_operand 1 "register_operand" "")))
4672 (use (match_operand:HI 2 "memory_operand" ""))
4673 (use (match_operand:HI 3 "memory_operand" ""))
4674 (clobber (match_operand:DI 4 "memory_operand" ""))
4675 (clobber (match_scratch 5 ""))]
4677 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4680 (clobber (match_dup 5))])
4681 (set (match_dup 0) (match_dup 4))]
4685 [(set (match_operand:DI 0 "memory_operand" "")
4686 (fix:DI (match_operand 1 "register_operand" "")))
4687 (use (match_operand:HI 2 "memory_operand" ""))
4688 (use (match_operand:HI 3 "memory_operand" ""))
4689 (clobber (match_operand:DI 4 "memory_operand" ""))
4690 (clobber (match_scratch 5 ""))]
4692 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4695 (clobber (match_dup 5))])]
4698 (define_insn "fix_trunc<mode>_i387"
4699 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4700 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4701 (use (match_operand:HI 2 "memory_operand" "m"))
4702 (use (match_operand:HI 3 "memory_operand" "m"))]
4703 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4705 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4706 "* return output_fix_trunc (insn, operands, 0);"
4707 [(set_attr "type" "fistp")
4708 (set_attr "i387_cw" "trunc")
4709 (set_attr "mode" "<MODE>")])
4711 (define_insn "fix_trunc<mode>_i387_with_temp"
4712 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4713 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4714 (use (match_operand:HI 2 "memory_operand" "m,m"))
4715 (use (match_operand:HI 3 "memory_operand" "m,m"))
4716 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4717 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4719 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4721 [(set_attr "type" "fistp")
4722 (set_attr "i387_cw" "trunc")
4723 (set_attr "mode" "<MODE>")])
4726 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4727 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4728 (use (match_operand:HI 2 "memory_operand" ""))
4729 (use (match_operand:HI 3 "memory_operand" ""))
4730 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4732 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4734 (use (match_dup 3))])
4735 (set (match_dup 0) (match_dup 4))]
4739 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4740 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4741 (use (match_operand:HI 2 "memory_operand" ""))
4742 (use (match_operand:HI 3 "memory_operand" ""))
4743 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4745 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4747 (use (match_dup 3))])]
4750 (define_insn "x86_fnstcw_1"
4751 [(set (match_operand:HI 0 "memory_operand" "=m")
4752 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4755 [(set_attr "length" "2")
4756 (set_attr "mode" "HI")
4757 (set_attr "unit" "i387")])
4759 (define_insn "x86_fldcw_1"
4760 [(set (reg:HI FPCR_REG)
4761 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4764 [(set_attr "length" "2")
4765 (set_attr "mode" "HI")
4766 (set_attr "unit" "i387")
4767 (set_attr "athlon_decode" "vector")
4768 (set_attr "amdfam10_decode" "vector")])
4770 ;; Conversion between fixed point and floating point.
4772 ;; Even though we only accept memory inputs, the backend _really_
4773 ;; wants to be able to do this between registers.
4775 (define_expand "floathi<mode>2"
4776 [(set (match_operand:MODEF 0 "register_operand" "")
4777 (float:MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4778 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4780 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4783 (gen_floatsi<mode>2 (operands[0],
4784 convert_to_mode (SImode, operands[1], 0)));
4789 (define_insn "*floathi<mode>2_i387"
4790 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4792 (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4794 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4795 || TARGET_MIX_SSE_I387)"
4799 [(set_attr "type" "fmov,multi")
4800 (set_attr "mode" "<MODE>")
4801 (set_attr "unit" "*,i387")
4802 (set_attr "fp_int_src" "true")])
4804 (define_expand "floatsi<mode>2"
4805 [(set (match_operand:MODEF 0 "register_operand" "")
4806 (float:MODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4807 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4809 /* When we use vector converts, we can't have input in memory. */
4810 if (GET_MODE (operands[0]) == DFmode
4811 && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4812 && SSE_FLOAT_MODE_P (DFmode))
4813 operands[1] = force_reg (SImode, operands[1]);
4814 else if (GET_MODE (operands[0]) == SFmode
4815 && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4816 && SSE_FLOAT_MODE_P (SFmode))
4818 /* When !flag_trapping_math, we handle SImode->SFmode vector
4819 conversions same way as SImode->DFmode.
4821 For flat_trapping_math we can't safely use vector conversion without
4822 clearing upper half, otherwise precision exception might occur.
4823 However we can still generate the common sequence converting value
4824 from general register to XMM register as:
4830 because we know that movd clears the upper half.
4832 Sadly in this case we can't rely on reload moving the value to XMM
4833 register, since we need to know if upper half is OK, so we need
4834 to do reloading by hand. We force operand to memory unless target
4835 supports inter unit moves. */
4836 if (!flag_trapping_math)
4837 operands[1] = force_reg (SImode, operands[1]);
4838 else if (!MEM_P (operands[1]))
4840 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4841 rtx tmp = assign_386_stack_local (SImode, slot);
4842 emit_move_insn (tmp, operands[1]);
4846 /* Offload operand of cvtsi2ss and cvtsi2sd into memory for
4847 !TARGET_INTER_UNIT_CONVERSIONS
4848 It is necessary for the patterns to not accept nonmemory operands
4849 as we would optimize out later. */
4850 else if (!TARGET_INTER_UNIT_CONVERSIONS
4851 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
4853 && !MEM_P (operands[1]))
4855 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4856 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
4857 emit_move_insn (tmp, operands[1]);
4862 (define_insn "*floatsisf2_mixed_vector"
4863 [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4864 (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4865 "TARGET_MIX_SSE_I387 && !flag_trapping_math
4866 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4868 cvtdq2ps\t{%1, %0|%0, %1}
4871 [(set_attr "type" "sseicvt,fmov,multi")
4872 (set_attr "mode" "SF")
4873 (set_attr "unit" "*,i387,*")
4874 (set_attr "athlon_decode" "double,*,*")
4875 (set_attr "amdfam10_decode" "double,*,*")
4876 (set_attr "fp_int_src" "false,true,true")])
4878 (define_insn "*floatsisf2_mixed"
4879 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4880 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4881 "TARGET_MIX_SSE_I387
4882 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4887 cvtsi2ss\t{%1, %0|%0, %1}
4888 cvtsi2ss\t{%1, %0|%0, %1}"
4889 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4890 (set_attr "mode" "SF")
4891 (set_attr "unit" "*,i387,*,*")
4892 (set_attr "athlon_decode" "*,*,vector,double")
4893 (set_attr "amdfam10_decode" "*,*,vector,double")
4894 (set_attr "fp_int_src" "true")])
4896 (define_insn "*floatsisf2_mixed_memory"
4897 [(set (match_operand:SF 0 "register_operand" "=f,x")
4898 (float:SF (match_operand:SI 1 "memory_operand" "m,m")))]
4899 "TARGET_MIX_SSE_I387
4900 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4903 cvtsi2ss\t{%1, %0|%0, %1}"
4904 [(set_attr "type" "fmov,sseicvt")
4905 (set_attr "mode" "SF")
4906 (set_attr "athlon_decode" "*,double")
4907 (set_attr "amdfam10_decode" "*,double")
4908 (set_attr "fp_int_src" "true")])
4910 (define_insn "*floatsisf2_sse_vector_nointernunit"
4911 [(set (match_operand:SF 0 "register_operand" "=x")
4912 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4913 "TARGET_SSE_MATH && flag_trapping_math
4914 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4915 && !TARGET_INTER_UNIT_MOVES"
4917 [(set_attr "type" "multi")])
4919 (define_insn "*floatsisf2_sse_vector_internunit"
4920 [(set (match_operand:SF 0 "register_operand" "=x,x")
4921 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4922 "TARGET_SSE_MATH && flag_trapping_math
4923 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4924 && TARGET_INTER_UNIT_MOVES"
4926 [(set_attr "type" "multi")])
4929 [(set (match_operand:SF 0 "register_operand" "")
4930 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4932 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4933 && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4934 && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4936 (float:V4SF (match_dup 2)))]
4938 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4939 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4940 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4944 [(set (match_operand:SF 0 "register_operand" "")
4945 (float:SF (match_operand:SI 1 "register_operand" "")))]
4947 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4948 && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4949 [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4951 (float:V4SF (match_dup 2)))]
4953 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4954 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4957 (define_insn "*floatsisf2_sse_vector"
4958 [(set (match_operand:SF 0 "register_operand" "=x")
4959 (float:SF (match_operand:SI 1 "register_operand" "x")))]
4960 "TARGET_SSE_MATH && !flag_trapping_math
4961 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4962 && !TARGET_INTER_UNIT_MOVES"
4963 "cvtdq2ps\t{%1, %0|%0, %1}"
4964 [(set_attr "type" "sseicvt")
4965 (set_attr "mode" "SF")
4966 (set_attr "athlon_decode" "double")
4967 (set_attr "amdfam10_decode" "double")
4968 (set_attr "fp_int_src" "true")])
4970 (define_insn "*floatsisf2_sse"
4971 [(set (match_operand:SF 0 "register_operand" "=x,x")
4972 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4974 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4976 "cvtsi2ss\t{%1, %0|%0, %1}"
4977 [(set_attr "type" "sseicvt")
4978 (set_attr "mode" "SF")
4979 (set_attr "athlon_decode" "vector,double")
4980 (set_attr "amdfam10_decode" "vector,double")
4981 (set_attr "fp_int_src" "true")])
4983 (define_insn "*floatsisf2_sse_memory"
4984 [(set (match_operand:SF 0 "register_operand" "=x")
4985 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4987 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4988 "cvtsi2ss\t{%1, %0|%0, %1}"
4989 [(set_attr "type" "sseicvt")
4990 (set_attr "mode" "SF")
4991 (set_attr "athlon_decode" "double")
4992 (set_attr "amdfam10_decode" "double")
4993 (set_attr "fp_int_src" "true")])
4995 (define_insn "*floatsidf2_mixed_vector"
4996 [(set (match_operand:DF 0 "register_operand" "=x,f,f")
4997 (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4998 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4999 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5001 cvtdq2pd\t{%1, %0|%0, %1}
5004 [(set_attr "type" "sseicvt,fmov,multi")
5005 (set_attr "mode" "V2DF,DF,DF")
5006 (set_attr "unit" "*,*,i387")
5007 (set_attr "athlon_decode" "double,*,*")
5008 (set_attr "amdfam10_decode" "double,*,*")
5009 (set_attr "fp_int_src" "false,true,true")])
5011 (define_insn "*floatsidf2_mixed"
5012 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
5013 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
5014 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5015 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5020 cvtsi2sd\t{%1, %0|%0, %1}
5021 cvtsi2sd\t{%1, %0|%0, %1}
5022 cvtdq2pd\t{%1, %0|%0, %1}"
5023 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5024 (set_attr "mode" "DF,DF,DF,DF,V2DF")
5025 (set_attr "unit" "*,i387,*,*,*")
5026 (set_attr "athlon_decode" "*,*,double,direct,double")
5027 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5028 (set_attr "fp_int_src" "true,true,true,true,false")])
5030 (define_insn "*floatsidf2_mixed_memory"
5031 [(set (match_operand:DF 0 "register_operand" "=f,x")
5032 (float:DF (match_operand:SI 1 "memory_operand" "m,m")))]
5033 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5034 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5037 cvtsi2sd\t{%1, %0|%0, %1}"
5038 [(set_attr "type" "fmov,sseicvt")
5039 (set_attr "mode" "DF")
5040 (set_attr "athlon_decode" "*,direct")
5041 (set_attr "amdfam10_decode" "*,double")
5042 (set_attr "fp_int_src" "true")])
5044 (define_insn "*floatsidf2_sse_vector"
5045 [(set (match_operand:DF 0 "register_operand" "=x")
5046 (float:DF (match_operand:SI 1 "register_operand" "x")))]
5047 "TARGET_SSE2 && TARGET_SSE_MATH
5048 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5049 "cvtdq2pd\t{%1, %0|%0, %1}"
5050 [(set_attr "type" "sseicvt")
5051 (set_attr "mode" "V2DF")
5052 (set_attr "athlon_decode" "double")
5053 (set_attr "amdfam10_decode" "double")
5054 (set_attr "fp_int_src" "true")])
5057 [(set (match_operand:DF 0 "register_operand" "")
5058 (float:DF (match_operand:SI 1 "memory_operand" "")))]
5059 "TARGET_USE_VECTOR_CONVERTS && reload_completed
5060 && SSE_REG_P (operands[0])"
5065 (parallel [(const_int 0) (const_int 1)]))))]
5067 operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
5068 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
5069 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
5072 (define_insn "*floatsidf2_sse"
5073 [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
5074 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
5075 "TARGET_SSE2 && TARGET_SSE_MATH
5076 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5079 cvtsi2sd\t{%1, %0|%0, %1}
5080 cvtsi2sd\t{%1, %0|%0, %1}
5081 cvtdq2pd\t{%1, %0|%0, %1}"
5082 [(set_attr "type" "sseicvt")
5083 (set_attr "mode" "DF,DF,V2DF")
5084 (set_attr "athlon_decode" "double,direct,double")
5085 (set_attr "amdfam10_decode" "vector,double,double")
5086 (set_attr "fp_int_src" "true")])
5088 (define_insn "*floatsidf2_memory"
5089 [(set (match_operand:DF 0 "register_operand" "=x")
5090 (float:DF (match_operand:SI 1 "memory_operand" "x")))]
5091 "TARGET_SSE2 && TARGET_SSE_MATH
5092 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5094 "cvtsi2sd\t{%1, %0|%0, %1}"
5095 [(set_attr "type" "sseicvt")
5096 (set_attr "mode" "DF")
5097 (set_attr "athlon_decode" "direct")
5098 (set_attr "amdfam10_decode" "double")
5099 (set_attr "fp_int_src" "true")])
5101 (define_insn "*floatsi<mode>2_i387"
5102 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5104 (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5106 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5110 [(set_attr "type" "fmov,multi")
5111 (set_attr "mode" "<MODE>")
5112 (set_attr "unit" "*,i387")
5113 (set_attr "fp_int_src" "true")])
5115 (define_expand "floatdisf2"
5116 [(set (match_operand:SF 0 "register_operand" "")
5117 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5118 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5120 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5121 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (SFmode)
5123 && !MEM_P (operands[1]))
5125 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5126 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5127 emit_move_insn (tmp, operands[1]);
5132 (define_insn "*floatdisf2_mixed"
5133 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5134 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5135 "TARGET_64BIT && TARGET_MIX_SSE_I387
5136 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5140 cvtsi2ss{q}\t{%1, %0|%0, %1}
5141 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5142 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5143 (set_attr "mode" "SF")
5144 (set_attr "unit" "*,i387,*,*")
5145 (set_attr "athlon_decode" "*,*,vector,double")
5146 (set_attr "amdfam10_decode" "*,*,vector,double")
5147 (set_attr "fp_int_src" "true")])
5149 (define_insn "*floatdisf2_mixed"
5150 [(set (match_operand:SF 0 "register_operand" "=f,x")
5151 (float:SF (match_operand:DI 1 "memory_operand" "m,m")))]
5152 "TARGET_64BIT && TARGET_MIX_SSE_I387
5153 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5156 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5157 [(set_attr "type" "fmov,sseicvt")
5158 (set_attr "mode" "SF")
5159 (set_attr "athlon_decode" "*,double")
5160 (set_attr "amdfam10_decode" "*,double")
5161 (set_attr "fp_int_src" "true")])
5163 (define_insn "*floatdisf2_sse"
5164 [(set (match_operand:SF 0 "register_operand" "=x,x")
5165 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5166 "TARGET_64BIT && TARGET_SSE_MATH
5167 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5168 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5169 [(set_attr "type" "sseicvt")
5170 (set_attr "mode" "SF")
5171 (set_attr "athlon_decode" "vector,double")
5172 (set_attr "amdfam10_decode" "vector,double")
5173 (set_attr "fp_int_src" "true")])
5175 (define_insn "*floatdisf2_memory"
5176 [(set (match_operand:SF 0 "register_operand" "=x")
5177 (float:SF (match_operand:DI 1 "memory_operand" "m")))]
5178 "TARGET_64BIT && TARGET_SSE_MATH
5179 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5180 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5181 [(set_attr "type" "sseicvt")
5182 (set_attr "mode" "SF")
5183 (set_attr "athlon_decode" "double")
5184 (set_attr "amdfam10_decode" "double")
5185 (set_attr "fp_int_src" "true")])
5187 (define_expand "floatdidf2"
5188 [(set (match_operand:DF 0 "register_operand" "")
5189 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5190 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5192 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5194 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5197 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5198 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (DFmode)
5200 && !MEM_P (operands[1]))
5202 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5203 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), slot);
5204 emit_move_insn (tmp, operands[1]);
5209 (define_insn "*floatdidf2_mixed"
5210 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5211 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5212 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5213 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5217 cvtsi2sd{q}\t{%1, %0|%0, %1}
5218 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5219 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5220 (set_attr "mode" "DF")
5221 (set_attr "unit" "*,i387,*,*")
5222 (set_attr "athlon_decode" "*,*,double,direct")
5223 (set_attr "amdfam10_decode" "*,*,vector,double")
5224 (set_attr "fp_int_src" "true")])
5226 (define_insn "*floatdidf2_mixed_memory"
5227 [(set (match_operand:DF 0 "register_operand" "=f,x")
5228 (float:DF (match_operand:DI 1 "memory_operand" "m,m")))]
5229 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5230 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5233 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5234 [(set_attr "type" "fmov,sseicvt")
5235 (set_attr "mode" "DF")
5236 (set_attr "athlon_decode" "*,direct")
5237 (set_attr "amdfam10_decode" "*,double")
5238 (set_attr "fp_int_src" "true")])
5240 (define_insn "*floatdidf2_sse"
5241 [(set (match_operand:DF 0 "register_operand" "=x,x")
5242 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5243 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5244 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5245 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5246 [(set_attr "type" "sseicvt")
5247 (set_attr "mode" "DF")
5248 (set_attr "athlon_decode" "double,direct")
5249 (set_attr "amdfam10_decode" "vector,double")
5250 (set_attr "fp_int_src" "true")])
5252 (define_insn "*floatdidf2_sse_memory"
5253 [(set (match_operand:DF 0 "register_operand" "=x")
5254 (float:DF (match_operand:DI 1 "memory_operand" "m")))]
5255 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5256 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5257 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5258 [(set_attr "type" "sseicvt")
5259 (set_attr "mode" "DF")
5260 (set_attr "athlon_decode" "direct")
5261 (set_attr "amdfam10_decode" "double")
5262 (set_attr "fp_int_src" "true")])
5264 (define_insn "*floatdi<mode>2_i387"
5265 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5267 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5269 && (!TARGET_SSE_MATH || !TARGET_64BIT
5270 || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5274 [(set_attr "type" "fmov,multi")
5275 (set_attr "mode" "<MODE>")
5276 (set_attr "unit" "*,i387")
5277 (set_attr "fp_int_src" "true")])
5279 (define_insn "float<mode>xf2"
5280 [(set (match_operand:XF 0 "register_operand" "=f,f")
5281 (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5286 [(set_attr "type" "fmov,multi")
5287 (set_attr "mode" "XF")
5288 (set_attr "unit" "*,i387")
5289 (set_attr "fp_int_src" "true")])
5291 ;; %%% Kill these when reload knows how to do it.
5293 [(set (match_operand 0 "fp_register_operand" "")
5294 (float (match_operand 1 "register_operand" "")))]
5296 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5299 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5300 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5301 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5302 ix86_free_from_memory (GET_MODE (operands[1]));
5306 (define_expand "floatunssisf2"
5307 [(use (match_operand:SF 0 "register_operand" ""))
5308 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5311 if (TARGET_SSE_MATH && TARGET_SSE2)
5312 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5314 x86_emit_floatuns (operands);
5318 (define_expand "floatunssidf2"
5319 [(use (match_operand:DF 0 "register_operand" ""))
5320 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5321 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5322 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5324 (define_expand "floatunsdisf2"
5325 [(use (match_operand:SF 0 "register_operand" ""))
5326 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5327 "TARGET_64BIT && TARGET_SSE_MATH"
5328 "x86_emit_floatuns (operands); DONE;")
5330 (define_expand "floatunsdidf2"
5331 [(use (match_operand:DF 0 "register_operand" ""))
5332 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5333 "TARGET_SSE_MATH && TARGET_SSE2
5334 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5337 x86_emit_floatuns (operands);
5339 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5345 ;; %%% splits for addditi3
5347 (define_expand "addti3"
5348 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5349 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5350 (match_operand:TI 2 "x86_64_general_operand" "")))
5351 (clobber (reg:CC FLAGS_REG))]
5353 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5355 (define_insn "*addti3_1"
5356 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5357 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5358 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5359 (clobber (reg:CC FLAGS_REG))]
5360 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5364 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5365 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5366 (match_operand:TI 2 "x86_64_general_operand" "")))
5367 (clobber (reg:CC FLAGS_REG))]
5368 "TARGET_64BIT && reload_completed"
5369 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5371 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5372 (parallel [(set (match_dup 3)
5373 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5376 (clobber (reg:CC FLAGS_REG))])]
5377 "split_ti (operands+0, 1, operands+0, operands+3);
5378 split_ti (operands+1, 1, operands+1, operands+4);
5379 split_ti (operands+2, 1, operands+2, operands+5);")
5381 ;; %%% splits for addsidi3
5382 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5383 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5384 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5386 (define_expand "adddi3"
5387 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5388 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5389 (match_operand:DI 2 "x86_64_general_operand" "")))
5390 (clobber (reg:CC FLAGS_REG))]
5392 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5394 (define_insn "*adddi3_1"
5395 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5396 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5397 (match_operand:DI 2 "general_operand" "roiF,riF")))
5398 (clobber (reg:CC FLAGS_REG))]
5399 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5403 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5404 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5405 (match_operand:DI 2 "general_operand" "")))
5406 (clobber (reg:CC FLAGS_REG))]
5407 "!TARGET_64BIT && reload_completed"
5408 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5410 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5411 (parallel [(set (match_dup 3)
5412 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5415 (clobber (reg:CC FLAGS_REG))])]
5416 "split_di (operands+0, 1, operands+0, operands+3);
5417 split_di (operands+1, 1, operands+1, operands+4);
5418 split_di (operands+2, 1, operands+2, operands+5);")
5420 (define_insn "adddi3_carry_rex64"
5421 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5422 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5423 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5424 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5425 (clobber (reg:CC FLAGS_REG))]
5426 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5427 "adc{q}\t{%2, %0|%0, %2}"
5428 [(set_attr "type" "alu")
5429 (set_attr "pent_pair" "pu")
5430 (set_attr "mode" "DI")])
5432 (define_insn "*adddi3_cc_rex64"
5433 [(set (reg:CC FLAGS_REG)
5434 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5435 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5437 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5438 (plus:DI (match_dup 1) (match_dup 2)))]
5439 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5440 "add{q}\t{%2, %0|%0, %2}"
5441 [(set_attr "type" "alu")
5442 (set_attr "mode" "DI")])
5444 (define_insn "*<addsub><mode>3_cc_overflow"
5445 [(set (reg:CCC FLAGS_REG)
5448 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5449 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5451 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5452 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5453 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5454 "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5455 [(set_attr "type" "alu")
5456 (set_attr "mode" "<MODE>")])
5458 (define_insn "*add<mode>3_cconly_overflow"
5459 [(set (reg:CCC FLAGS_REG)
5461 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5462 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5464 (clobber (match_scratch:SWI 0 "=<r>"))]
5465 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5466 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5467 [(set_attr "type" "alu")
5468 (set_attr "mode" "<MODE>")])
5470 (define_insn "*sub<mode>3_cconly_overflow"
5471 [(set (reg:CCC FLAGS_REG)
5473 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5474 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5477 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5478 [(set_attr "type" "icmp")
5479 (set_attr "mode" "<MODE>")])
5481 (define_insn "*<addsub>si3_zext_cc_overflow"
5482 [(set (reg:CCC FLAGS_REG)
5484 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5485 (match_operand:SI 2 "general_operand" "g"))
5487 (set (match_operand:DI 0 "register_operand" "=r")
5488 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5489 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5490 "<addsub>{l}\t{%2, %k0|%k0, %2}"
5491 [(set_attr "type" "alu")
5492 (set_attr "mode" "SI")])
5494 (define_insn "addqi3_carry"
5495 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5496 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5497 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5498 (match_operand:QI 2 "general_operand" "qi,qm")))
5499 (clobber (reg:CC FLAGS_REG))]
5500 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5501 "adc{b}\t{%2, %0|%0, %2}"
5502 [(set_attr "type" "alu")
5503 (set_attr "pent_pair" "pu")
5504 (set_attr "mode" "QI")])
5506 (define_insn "addhi3_carry"
5507 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5508 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5509 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5510 (match_operand:HI 2 "general_operand" "ri,rm")))
5511 (clobber (reg:CC FLAGS_REG))]
5512 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5513 "adc{w}\t{%2, %0|%0, %2}"
5514 [(set_attr "type" "alu")
5515 (set_attr "pent_pair" "pu")
5516 (set_attr "mode" "HI")])
5518 (define_insn "addsi3_carry"
5519 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5520 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5521 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5522 (match_operand:SI 2 "general_operand" "ri,rm")))
5523 (clobber (reg:CC FLAGS_REG))]
5524 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5525 "adc{l}\t{%2, %0|%0, %2}"
5526 [(set_attr "type" "alu")
5527 (set_attr "pent_pair" "pu")
5528 (set_attr "mode" "SI")])
5530 (define_insn "*addsi3_carry_zext"
5531 [(set (match_operand:DI 0 "register_operand" "=r")
5533 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5534 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5535 (match_operand:SI 2 "general_operand" "g"))))
5536 (clobber (reg:CC FLAGS_REG))]
5537 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5538 "adc{l}\t{%2, %k0|%k0, %2}"
5539 [(set_attr "type" "alu")
5540 (set_attr "pent_pair" "pu")
5541 (set_attr "mode" "SI")])
5543 (define_insn "*addsi3_cc"
5544 [(set (reg:CC FLAGS_REG)
5545 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5546 (match_operand:SI 2 "general_operand" "ri,rm")]
5548 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5549 (plus:SI (match_dup 1) (match_dup 2)))]
5550 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5551 "add{l}\t{%2, %0|%0, %2}"
5552 [(set_attr "type" "alu")
5553 (set_attr "mode" "SI")])
5555 (define_insn "addqi3_cc"
5556 [(set (reg:CC FLAGS_REG)
5557 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5558 (match_operand:QI 2 "general_operand" "qi,qm")]
5560 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5561 (plus:QI (match_dup 1) (match_dup 2)))]
5562 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5563 "add{b}\t{%2, %0|%0, %2}"
5564 [(set_attr "type" "alu")
5565 (set_attr "mode" "QI")])
5567 (define_expand "addsi3"
5568 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5569 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5570 (match_operand:SI 2 "general_operand" "")))
5571 (clobber (reg:CC FLAGS_REG))])]
5573 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5575 (define_insn "*lea_1"
5576 [(set (match_operand:SI 0 "register_operand" "=r")
5577 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5579 "lea{l}\t{%a1, %0|%0, %a1}"
5580 [(set_attr "type" "lea")
5581 (set_attr "mode" "SI")])
5583 (define_insn "*lea_1_rex64"
5584 [(set (match_operand:SI 0 "register_operand" "=r")
5585 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5587 "lea{l}\t{%a1, %0|%0, %a1}"
5588 [(set_attr "type" "lea")
5589 (set_attr "mode" "SI")])
5591 (define_insn "*lea_1_zext"
5592 [(set (match_operand:DI 0 "register_operand" "=r")
5594 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5596 "lea{l}\t{%a1, %k0|%k0, %a1}"
5597 [(set_attr "type" "lea")
5598 (set_attr "mode" "SI")])
5600 (define_insn "*lea_2_rex64"
5601 [(set (match_operand:DI 0 "register_operand" "=r")
5602 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5604 "lea{q}\t{%a1, %0|%0, %a1}"
5605 [(set_attr "type" "lea")
5606 (set_attr "mode" "DI")])
5608 ;; The lea patterns for non-Pmodes needs to be matched by several
5609 ;; insns converted to real lea by splitters.
5611 (define_insn_and_split "*lea_general_1"
5612 [(set (match_operand 0 "register_operand" "=r")
5613 (plus (plus (match_operand 1 "index_register_operand" "l")
5614 (match_operand 2 "register_operand" "r"))
5615 (match_operand 3 "immediate_operand" "i")))]
5616 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5617 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5618 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5619 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5620 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5621 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5622 || GET_MODE (operands[3]) == VOIDmode)"
5624 "&& reload_completed"
5628 operands[0] = gen_lowpart (SImode, operands[0]);
5629 operands[1] = gen_lowpart (Pmode, operands[1]);
5630 operands[2] = gen_lowpart (Pmode, operands[2]);
5631 operands[3] = gen_lowpart (Pmode, operands[3]);
5632 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5634 if (Pmode != SImode)
5635 pat = gen_rtx_SUBREG (SImode, pat, 0);
5636 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5639 [(set_attr "type" "lea")
5640 (set_attr "mode" "SI")])
5642 (define_insn_and_split "*lea_general_1_zext"
5643 [(set (match_operand:DI 0 "register_operand" "=r")
5645 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5646 (match_operand:SI 2 "register_operand" "r"))
5647 (match_operand:SI 3 "immediate_operand" "i"))))]
5650 "&& reload_completed"
5652 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5654 (match_dup 3)) 0)))]
5656 operands[1] = gen_lowpart (Pmode, operands[1]);
5657 operands[2] = gen_lowpart (Pmode, operands[2]);
5658 operands[3] = gen_lowpart (Pmode, operands[3]);
5660 [(set_attr "type" "lea")
5661 (set_attr "mode" "SI")])
5663 (define_insn_and_split "*lea_general_2"
5664 [(set (match_operand 0 "register_operand" "=r")
5665 (plus (mult (match_operand 1 "index_register_operand" "l")
5666 (match_operand 2 "const248_operand" "i"))
5667 (match_operand 3 "nonmemory_operand" "ri")))]
5668 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5669 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5670 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5671 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5672 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5673 || GET_MODE (operands[3]) == VOIDmode)"
5675 "&& reload_completed"
5679 operands[0] = gen_lowpart (SImode, operands[0]);
5680 operands[1] = gen_lowpart (Pmode, operands[1]);
5681 operands[3] = gen_lowpart (Pmode, operands[3]);
5682 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5684 if (Pmode != SImode)
5685 pat = gen_rtx_SUBREG (SImode, pat, 0);
5686 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5689 [(set_attr "type" "lea")
5690 (set_attr "mode" "SI")])
5692 (define_insn_and_split "*lea_general_2_zext"
5693 [(set (match_operand:DI 0 "register_operand" "=r")
5695 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5696 (match_operand:SI 2 "const248_operand" "n"))
5697 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5700 "&& reload_completed"
5702 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5704 (match_dup 3)) 0)))]
5706 operands[1] = gen_lowpart (Pmode, operands[1]);
5707 operands[3] = gen_lowpart (Pmode, operands[3]);
5709 [(set_attr "type" "lea")
5710 (set_attr "mode" "SI")])
5712 (define_insn_and_split "*lea_general_3"
5713 [(set (match_operand 0 "register_operand" "=r")
5714 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5715 (match_operand 2 "const248_operand" "i"))
5716 (match_operand 3 "register_operand" "r"))
5717 (match_operand 4 "immediate_operand" "i")))]
5718 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5719 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5720 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5721 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5722 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5724 "&& reload_completed"
5728 operands[0] = gen_lowpart (SImode, operands[0]);
5729 operands[1] = gen_lowpart (Pmode, operands[1]);
5730 operands[3] = gen_lowpart (Pmode, operands[3]);
5731 operands[4] = gen_lowpart (Pmode, operands[4]);
5732 pat = gen_rtx_PLUS (Pmode,
5733 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5737 if (Pmode != SImode)
5738 pat = gen_rtx_SUBREG (SImode, pat, 0);
5739 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5742 [(set_attr "type" "lea")
5743 (set_attr "mode" "SI")])
5745 (define_insn_and_split "*lea_general_3_zext"
5746 [(set (match_operand:DI 0 "register_operand" "=r")
5748 (plus:SI (plus:SI (mult:SI
5749 (match_operand:SI 1 "index_register_operand" "l")
5750 (match_operand:SI 2 "const248_operand" "n"))
5751 (match_operand:SI 3 "register_operand" "r"))
5752 (match_operand:SI 4 "immediate_operand" "i"))))]
5755 "&& reload_completed"
5757 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5760 (match_dup 4)) 0)))]
5762 operands[1] = gen_lowpart (Pmode, operands[1]);
5763 operands[3] = gen_lowpart (Pmode, operands[3]);
5764 operands[4] = gen_lowpart (Pmode, operands[4]);
5766 [(set_attr "type" "lea")
5767 (set_attr "mode" "SI")])
5769 (define_insn "*adddi_1_rex64"
5770 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5771 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5772 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5773 (clobber (reg:CC FLAGS_REG))]
5774 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5776 switch (get_attr_type (insn))
5779 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5780 return "lea{q}\t{%a2, %0|%0, %a2}";
5783 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5784 if (operands[2] == const1_rtx)
5785 return "inc{q}\t%0";
5788 gcc_assert (operands[2] == constm1_rtx);
5789 return "dec{q}\t%0";
5793 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5795 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5796 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5797 if (CONST_INT_P (operands[2])
5798 /* Avoid overflows. */
5799 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5800 && (INTVAL (operands[2]) == 128
5801 || (INTVAL (operands[2]) < 0
5802 && INTVAL (operands[2]) != -128)))
5804 operands[2] = GEN_INT (-INTVAL (operands[2]));
5805 return "sub{q}\t{%2, %0|%0, %2}";
5807 return "add{q}\t{%2, %0|%0, %2}";
5811 (cond [(eq_attr "alternative" "2")
5812 (const_string "lea")
5813 ; Current assemblers are broken and do not allow @GOTOFF in
5814 ; ought but a memory context.
5815 (match_operand:DI 2 "pic_symbolic_operand" "")
5816 (const_string "lea")
5817 (match_operand:DI 2 "incdec_operand" "")
5818 (const_string "incdec")
5820 (const_string "alu")))
5821 (set_attr "mode" "DI")])
5823 ;; Convert lea to the lea pattern to avoid flags dependency.
5825 [(set (match_operand:DI 0 "register_operand" "")
5826 (plus:DI (match_operand:DI 1 "register_operand" "")
5827 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5828 (clobber (reg:CC FLAGS_REG))]
5829 "TARGET_64BIT && reload_completed
5830 && true_regnum (operands[0]) != true_regnum (operands[1])"
5832 (plus:DI (match_dup 1)
5836 (define_insn "*adddi_2_rex64"
5837 [(set (reg FLAGS_REG)
5839 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5840 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5842 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5843 (plus:DI (match_dup 1) (match_dup 2)))]
5844 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5845 && ix86_binary_operator_ok (PLUS, DImode, operands)
5846 /* Current assemblers are broken and do not allow @GOTOFF in
5847 ought but a memory context. */
5848 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5850 switch (get_attr_type (insn))
5853 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5854 if (operands[2] == const1_rtx)
5855 return "inc{q}\t%0";
5858 gcc_assert (operands[2] == constm1_rtx);
5859 return "dec{q}\t%0";
5863 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5864 /* ???? We ought to handle there the 32bit case too
5865 - do we need new constraint? */
5866 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5867 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5868 if (CONST_INT_P (operands[2])
5869 /* Avoid overflows. */
5870 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5871 && (INTVAL (operands[2]) == 128
5872 || (INTVAL (operands[2]) < 0
5873 && INTVAL (operands[2]) != -128)))
5875 operands[2] = GEN_INT (-INTVAL (operands[2]));
5876 return "sub{q}\t{%2, %0|%0, %2}";
5878 return "add{q}\t{%2, %0|%0, %2}";
5882 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5883 (const_string "incdec")
5884 (const_string "alu")))
5885 (set_attr "mode" "DI")])
5887 (define_insn "*adddi_3_rex64"
5888 [(set (reg FLAGS_REG)
5889 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5890 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5891 (clobber (match_scratch:DI 0 "=r"))]
5893 && ix86_match_ccmode (insn, CCZmode)
5894 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5895 /* Current assemblers are broken and do not allow @GOTOFF in
5896 ought but a memory context. */
5897 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5899 switch (get_attr_type (insn))
5902 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5903 if (operands[2] == const1_rtx)
5904 return "inc{q}\t%0";
5907 gcc_assert (operands[2] == constm1_rtx);
5908 return "dec{q}\t%0";
5912 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5913 /* ???? We ought to handle there the 32bit case too
5914 - do we need new constraint? */
5915 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5916 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5917 if (CONST_INT_P (operands[2])
5918 /* Avoid overflows. */
5919 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5920 && (INTVAL (operands[2]) == 128
5921 || (INTVAL (operands[2]) < 0
5922 && INTVAL (operands[2]) != -128)))
5924 operands[2] = GEN_INT (-INTVAL (operands[2]));
5925 return "sub{q}\t{%2, %0|%0, %2}";
5927 return "add{q}\t{%2, %0|%0, %2}";
5931 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5932 (const_string "incdec")
5933 (const_string "alu")))
5934 (set_attr "mode" "DI")])
5936 ; For comparisons against 1, -1 and 128, we may generate better code
5937 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5938 ; is matched then. We can't accept general immediate, because for
5939 ; case of overflows, the result is messed up.
5940 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5942 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5943 ; only for comparisons not depending on it.
5944 (define_insn "*adddi_4_rex64"
5945 [(set (reg FLAGS_REG)
5946 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5947 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5948 (clobber (match_scratch:DI 0 "=rm"))]
5950 && ix86_match_ccmode (insn, CCGCmode)"
5952 switch (get_attr_type (insn))
5955 if (operands[2] == constm1_rtx)
5956 return "inc{q}\t%0";
5959 gcc_assert (operands[2] == const1_rtx);
5960 return "dec{q}\t%0";
5964 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5965 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5966 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5967 if ((INTVAL (operands[2]) == -128
5968 || (INTVAL (operands[2]) > 0
5969 && INTVAL (operands[2]) != 128))
5970 /* Avoid overflows. */
5971 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5972 return "sub{q}\t{%2, %0|%0, %2}";
5973 operands[2] = GEN_INT (-INTVAL (operands[2]));
5974 return "add{q}\t{%2, %0|%0, %2}";
5978 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5979 (const_string "incdec")
5980 (const_string "alu")))
5981 (set_attr "mode" "DI")])
5983 (define_insn "*adddi_5_rex64"
5984 [(set (reg FLAGS_REG)
5986 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5987 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5989 (clobber (match_scratch:DI 0 "=r"))]
5991 && ix86_match_ccmode (insn, CCGOCmode)
5992 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5993 /* Current assemblers are broken and do not allow @GOTOFF in
5994 ought but a memory context. */
5995 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5997 switch (get_attr_type (insn))
6000 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6001 if (operands[2] == const1_rtx)
6002 return "inc{q}\t%0";
6005 gcc_assert (operands[2] == constm1_rtx);
6006 return "dec{q}\t%0";
6010 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6011 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6012 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6013 if (CONST_INT_P (operands[2])
6014 /* Avoid overflows. */
6015 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6016 && (INTVAL (operands[2]) == 128
6017 || (INTVAL (operands[2]) < 0
6018 && INTVAL (operands[2]) != -128)))
6020 operands[2] = GEN_INT (-INTVAL (operands[2]));
6021 return "sub{q}\t{%2, %0|%0, %2}";
6023 return "add{q}\t{%2, %0|%0, %2}";
6027 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6028 (const_string "incdec")
6029 (const_string "alu")))
6030 (set_attr "mode" "DI")])
6033 (define_insn "*addsi_1"
6034 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6035 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6036 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6037 (clobber (reg:CC FLAGS_REG))]
6038 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6040 switch (get_attr_type (insn))
6043 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6044 return "lea{l}\t{%a2, %0|%0, %a2}";
6047 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6048 if (operands[2] == const1_rtx)
6049 return "inc{l}\t%0";
6052 gcc_assert (operands[2] == constm1_rtx);
6053 return "dec{l}\t%0";
6057 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6059 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6060 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6061 if (CONST_INT_P (operands[2])
6062 && (INTVAL (operands[2]) == 128
6063 || (INTVAL (operands[2]) < 0
6064 && INTVAL (operands[2]) != -128)))
6066 operands[2] = GEN_INT (-INTVAL (operands[2]));
6067 return "sub{l}\t{%2, %0|%0, %2}";
6069 return "add{l}\t{%2, %0|%0, %2}";
6073 (cond [(eq_attr "alternative" "2")
6074 (const_string "lea")
6075 ; Current assemblers are broken and do not allow @GOTOFF in
6076 ; ought but a memory context.
6077 (match_operand:SI 2 "pic_symbolic_operand" "")
6078 (const_string "lea")
6079 (match_operand:SI 2 "incdec_operand" "")
6080 (const_string "incdec")
6082 (const_string "alu")))
6083 (set_attr "mode" "SI")])
6085 ;; Convert lea to the lea pattern to avoid flags dependency.
6087 [(set (match_operand 0 "register_operand" "")
6088 (plus (match_operand 1 "register_operand" "")
6089 (match_operand 2 "nonmemory_operand" "")))
6090 (clobber (reg:CC FLAGS_REG))]
6092 && true_regnum (operands[0]) != true_regnum (operands[1])"
6096 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6097 may confuse gen_lowpart. */
6098 if (GET_MODE (operands[0]) != Pmode)
6100 operands[1] = gen_lowpart (Pmode, operands[1]);
6101 operands[2] = gen_lowpart (Pmode, operands[2]);
6103 operands[0] = gen_lowpart (SImode, operands[0]);
6104 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6105 if (Pmode != SImode)
6106 pat = gen_rtx_SUBREG (SImode, pat, 0);
6107 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6111 ;; It may seem that nonimmediate operand is proper one for operand 1.
6112 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6113 ;; we take care in ix86_binary_operator_ok to not allow two memory
6114 ;; operands so proper swapping will be done in reload. This allow
6115 ;; patterns constructed from addsi_1 to match.
6116 (define_insn "addsi_1_zext"
6117 [(set (match_operand:DI 0 "register_operand" "=r,r")
6119 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6120 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6121 (clobber (reg:CC FLAGS_REG))]
6122 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6124 switch (get_attr_type (insn))
6127 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6128 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6131 if (operands[2] == const1_rtx)
6132 return "inc{l}\t%k0";
6135 gcc_assert (operands[2] == constm1_rtx);
6136 return "dec{l}\t%k0";
6140 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6141 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6142 if (CONST_INT_P (operands[2])
6143 && (INTVAL (operands[2]) == 128
6144 || (INTVAL (operands[2]) < 0
6145 && INTVAL (operands[2]) != -128)))
6147 operands[2] = GEN_INT (-INTVAL (operands[2]));
6148 return "sub{l}\t{%2, %k0|%k0, %2}";
6150 return "add{l}\t{%2, %k0|%k0, %2}";
6154 (cond [(eq_attr "alternative" "1")
6155 (const_string "lea")
6156 ; Current assemblers are broken and do not allow @GOTOFF in
6157 ; ought but a memory context.
6158 (match_operand:SI 2 "pic_symbolic_operand" "")
6159 (const_string "lea")
6160 (match_operand:SI 2 "incdec_operand" "")
6161 (const_string "incdec")
6163 (const_string "alu")))
6164 (set_attr "mode" "SI")])
6166 ;; Convert lea to the lea pattern to avoid flags dependency.
6168 [(set (match_operand:DI 0 "register_operand" "")
6170 (plus:SI (match_operand:SI 1 "register_operand" "")
6171 (match_operand:SI 2 "nonmemory_operand" ""))))
6172 (clobber (reg:CC FLAGS_REG))]
6173 "TARGET_64BIT && reload_completed
6174 && true_regnum (operands[0]) != true_regnum (operands[1])"
6176 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6178 operands[1] = gen_lowpart (Pmode, operands[1]);
6179 operands[2] = gen_lowpart (Pmode, operands[2]);
6182 (define_insn "*addsi_2"
6183 [(set (reg FLAGS_REG)
6185 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6186 (match_operand:SI 2 "general_operand" "rmni,rni"))
6188 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6189 (plus:SI (match_dup 1) (match_dup 2)))]
6190 "ix86_match_ccmode (insn, CCGOCmode)
6191 && ix86_binary_operator_ok (PLUS, SImode, operands)
6192 /* Current assemblers are broken and do not allow @GOTOFF in
6193 ought but a memory context. */
6194 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6196 switch (get_attr_type (insn))
6199 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6200 if (operands[2] == const1_rtx)
6201 return "inc{l}\t%0";
6204 gcc_assert (operands[2] == constm1_rtx);
6205 return "dec{l}\t%0";
6209 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6210 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6211 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6212 if (CONST_INT_P (operands[2])
6213 && (INTVAL (operands[2]) == 128
6214 || (INTVAL (operands[2]) < 0
6215 && INTVAL (operands[2]) != -128)))
6217 operands[2] = GEN_INT (-INTVAL (operands[2]));
6218 return "sub{l}\t{%2, %0|%0, %2}";
6220 return "add{l}\t{%2, %0|%0, %2}";
6224 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6225 (const_string "incdec")
6226 (const_string "alu")))
6227 (set_attr "mode" "SI")])
6229 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6230 (define_insn "*addsi_2_zext"
6231 [(set (reg FLAGS_REG)
6233 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6234 (match_operand:SI 2 "general_operand" "rmni"))
6236 (set (match_operand:DI 0 "register_operand" "=r")
6237 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6238 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6239 && ix86_binary_operator_ok (PLUS, SImode, operands)
6240 /* Current assemblers are broken and do not allow @GOTOFF in
6241 ought but a memory context. */
6242 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6244 switch (get_attr_type (insn))
6247 if (operands[2] == const1_rtx)
6248 return "inc{l}\t%k0";
6251 gcc_assert (operands[2] == constm1_rtx);
6252 return "dec{l}\t%k0";
6256 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6257 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6258 if (CONST_INT_P (operands[2])
6259 && (INTVAL (operands[2]) == 128
6260 || (INTVAL (operands[2]) < 0
6261 && INTVAL (operands[2]) != -128)))
6263 operands[2] = GEN_INT (-INTVAL (operands[2]));
6264 return "sub{l}\t{%2, %k0|%k0, %2}";
6266 return "add{l}\t{%2, %k0|%k0, %2}";
6270 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6271 (const_string "incdec")
6272 (const_string "alu")))
6273 (set_attr "mode" "SI")])
6275 (define_insn "*addsi_3"
6276 [(set (reg FLAGS_REG)
6277 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6278 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6279 (clobber (match_scratch:SI 0 "=r"))]
6280 "ix86_match_ccmode (insn, CCZmode)
6281 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6282 /* Current assemblers are broken and do not allow @GOTOFF in
6283 ought but a memory context. */
6284 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6286 switch (get_attr_type (insn))
6289 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6290 if (operands[2] == const1_rtx)
6291 return "inc{l}\t%0";
6294 gcc_assert (operands[2] == constm1_rtx);
6295 return "dec{l}\t%0";
6299 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6300 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6301 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6302 if (CONST_INT_P (operands[2])
6303 && (INTVAL (operands[2]) == 128
6304 || (INTVAL (operands[2]) < 0
6305 && INTVAL (operands[2]) != -128)))
6307 operands[2] = GEN_INT (-INTVAL (operands[2]));
6308 return "sub{l}\t{%2, %0|%0, %2}";
6310 return "add{l}\t{%2, %0|%0, %2}";
6314 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6315 (const_string "incdec")
6316 (const_string "alu")))
6317 (set_attr "mode" "SI")])
6319 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6320 (define_insn "*addsi_3_zext"
6321 [(set (reg FLAGS_REG)
6322 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6323 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6324 (set (match_operand:DI 0 "register_operand" "=r")
6325 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6326 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6327 && ix86_binary_operator_ok (PLUS, SImode, operands)
6328 /* Current assemblers are broken and do not allow @GOTOFF in
6329 ought but a memory context. */
6330 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6332 switch (get_attr_type (insn))
6335 if (operands[2] == const1_rtx)
6336 return "inc{l}\t%k0";
6339 gcc_assert (operands[2] == constm1_rtx);
6340 return "dec{l}\t%k0";
6344 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6345 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6346 if (CONST_INT_P (operands[2])
6347 && (INTVAL (operands[2]) == 128
6348 || (INTVAL (operands[2]) < 0
6349 && INTVAL (operands[2]) != -128)))
6351 operands[2] = GEN_INT (-INTVAL (operands[2]));
6352 return "sub{l}\t{%2, %k0|%k0, %2}";
6354 return "add{l}\t{%2, %k0|%k0, %2}";
6358 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6359 (const_string "incdec")
6360 (const_string "alu")))
6361 (set_attr "mode" "SI")])
6363 ; For comparisons against 1, -1 and 128, we may generate better code
6364 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6365 ; is matched then. We can't accept general immediate, because for
6366 ; case of overflows, the result is messed up.
6367 ; This pattern also don't hold of 0x80000000, since the value overflows
6369 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6370 ; only for comparisons not depending on it.
6371 (define_insn "*addsi_4"
6372 [(set (reg FLAGS_REG)
6373 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6374 (match_operand:SI 2 "const_int_operand" "n")))
6375 (clobber (match_scratch:SI 0 "=rm"))]
6376 "ix86_match_ccmode (insn, CCGCmode)
6377 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6379 switch (get_attr_type (insn))
6382 if (operands[2] == constm1_rtx)
6383 return "inc{l}\t%0";
6386 gcc_assert (operands[2] == const1_rtx);
6387 return "dec{l}\t%0";
6391 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6392 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6393 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6394 if ((INTVAL (operands[2]) == -128
6395 || (INTVAL (operands[2]) > 0
6396 && INTVAL (operands[2]) != 128)))
6397 return "sub{l}\t{%2, %0|%0, %2}";
6398 operands[2] = GEN_INT (-INTVAL (operands[2]));
6399 return "add{l}\t{%2, %0|%0, %2}";
6403 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6404 (const_string "incdec")
6405 (const_string "alu")))
6406 (set_attr "mode" "SI")])
6408 (define_insn "*addsi_5"
6409 [(set (reg FLAGS_REG)
6411 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6412 (match_operand:SI 2 "general_operand" "rmni"))
6414 (clobber (match_scratch:SI 0 "=r"))]
6415 "ix86_match_ccmode (insn, CCGOCmode)
6416 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6417 /* Current assemblers are broken and do not allow @GOTOFF in
6418 ought but a memory context. */
6419 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6421 switch (get_attr_type (insn))
6424 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6425 if (operands[2] == const1_rtx)
6426 return "inc{l}\t%0";
6429 gcc_assert (operands[2] == constm1_rtx);
6430 return "dec{l}\t%0";
6434 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6435 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6436 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6437 if (CONST_INT_P (operands[2])
6438 && (INTVAL (operands[2]) == 128
6439 || (INTVAL (operands[2]) < 0
6440 && INTVAL (operands[2]) != -128)))
6442 operands[2] = GEN_INT (-INTVAL (operands[2]));
6443 return "sub{l}\t{%2, %0|%0, %2}";
6445 return "add{l}\t{%2, %0|%0, %2}";
6449 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6450 (const_string "incdec")
6451 (const_string "alu")))
6452 (set_attr "mode" "SI")])
6454 (define_expand "addhi3"
6455 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6456 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6457 (match_operand:HI 2 "general_operand" "")))
6458 (clobber (reg:CC FLAGS_REG))])]
6459 "TARGET_HIMODE_MATH"
6460 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6462 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6463 ;; type optimizations enabled by define-splits. This is not important
6464 ;; for PII, and in fact harmful because of partial register stalls.
6466 (define_insn "*addhi_1_lea"
6467 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6468 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6469 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6470 (clobber (reg:CC FLAGS_REG))]
6471 "!TARGET_PARTIAL_REG_STALL
6472 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6474 switch (get_attr_type (insn))
6479 if (operands[2] == const1_rtx)
6480 return "inc{w}\t%0";
6483 gcc_assert (operands[2] == constm1_rtx);
6484 return "dec{w}\t%0";
6488 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6489 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6490 if (CONST_INT_P (operands[2])
6491 && (INTVAL (operands[2]) == 128
6492 || (INTVAL (operands[2]) < 0
6493 && INTVAL (operands[2]) != -128)))
6495 operands[2] = GEN_INT (-INTVAL (operands[2]));
6496 return "sub{w}\t{%2, %0|%0, %2}";
6498 return "add{w}\t{%2, %0|%0, %2}";
6502 (if_then_else (eq_attr "alternative" "2")
6503 (const_string "lea")
6504 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6505 (const_string "incdec")
6506 (const_string "alu"))))
6507 (set_attr "mode" "HI,HI,SI")])
6509 (define_insn "*addhi_1"
6510 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6511 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6512 (match_operand:HI 2 "general_operand" "ri,rm")))
6513 (clobber (reg:CC FLAGS_REG))]
6514 "TARGET_PARTIAL_REG_STALL
6515 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6517 switch (get_attr_type (insn))
6520 if (operands[2] == const1_rtx)
6521 return "inc{w}\t%0";
6524 gcc_assert (operands[2] == constm1_rtx);
6525 return "dec{w}\t%0";
6529 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6530 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6531 if (CONST_INT_P (operands[2])
6532 && (INTVAL (operands[2]) == 128
6533 || (INTVAL (operands[2]) < 0
6534 && INTVAL (operands[2]) != -128)))
6536 operands[2] = GEN_INT (-INTVAL (operands[2]));
6537 return "sub{w}\t{%2, %0|%0, %2}";
6539 return "add{w}\t{%2, %0|%0, %2}";
6543 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6544 (const_string "incdec")
6545 (const_string "alu")))
6546 (set_attr "mode" "HI")])
6548 (define_insn "*addhi_2"
6549 [(set (reg FLAGS_REG)
6551 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6552 (match_operand:HI 2 "general_operand" "rmni,rni"))
6554 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6555 (plus:HI (match_dup 1) (match_dup 2)))]
6556 "ix86_match_ccmode (insn, CCGOCmode)
6557 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6559 switch (get_attr_type (insn))
6562 if (operands[2] == const1_rtx)
6563 return "inc{w}\t%0";
6566 gcc_assert (operands[2] == constm1_rtx);
6567 return "dec{w}\t%0";
6571 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6572 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6573 if (CONST_INT_P (operands[2])
6574 && (INTVAL (operands[2]) == 128
6575 || (INTVAL (operands[2]) < 0
6576 && INTVAL (operands[2]) != -128)))
6578 operands[2] = GEN_INT (-INTVAL (operands[2]));
6579 return "sub{w}\t{%2, %0|%0, %2}";
6581 return "add{w}\t{%2, %0|%0, %2}";
6585 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6586 (const_string "incdec")
6587 (const_string "alu")))
6588 (set_attr "mode" "HI")])
6590 (define_insn "*addhi_3"
6591 [(set (reg FLAGS_REG)
6592 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6593 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6594 (clobber (match_scratch:HI 0 "=r"))]
6595 "ix86_match_ccmode (insn, CCZmode)
6596 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6598 switch (get_attr_type (insn))
6601 if (operands[2] == const1_rtx)
6602 return "inc{w}\t%0";
6605 gcc_assert (operands[2] == constm1_rtx);
6606 return "dec{w}\t%0";
6610 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6611 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6612 if (CONST_INT_P (operands[2])
6613 && (INTVAL (operands[2]) == 128
6614 || (INTVAL (operands[2]) < 0
6615 && INTVAL (operands[2]) != -128)))
6617 operands[2] = GEN_INT (-INTVAL (operands[2]));
6618 return "sub{w}\t{%2, %0|%0, %2}";
6620 return "add{w}\t{%2, %0|%0, %2}";
6624 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6625 (const_string "incdec")
6626 (const_string "alu")))
6627 (set_attr "mode" "HI")])
6629 ; See comments above addsi_4 for details.
6630 (define_insn "*addhi_4"
6631 [(set (reg FLAGS_REG)
6632 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6633 (match_operand:HI 2 "const_int_operand" "n")))
6634 (clobber (match_scratch:HI 0 "=rm"))]
6635 "ix86_match_ccmode (insn, CCGCmode)
6636 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6638 switch (get_attr_type (insn))
6641 if (operands[2] == constm1_rtx)
6642 return "inc{w}\t%0";
6645 gcc_assert (operands[2] == const1_rtx);
6646 return "dec{w}\t%0";
6650 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6651 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6652 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6653 if ((INTVAL (operands[2]) == -128
6654 || (INTVAL (operands[2]) > 0
6655 && INTVAL (operands[2]) != 128)))
6656 return "sub{w}\t{%2, %0|%0, %2}";
6657 operands[2] = GEN_INT (-INTVAL (operands[2]));
6658 return "add{w}\t{%2, %0|%0, %2}";
6662 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6663 (const_string "incdec")
6664 (const_string "alu")))
6665 (set_attr "mode" "SI")])
6668 (define_insn "*addhi_5"
6669 [(set (reg FLAGS_REG)
6671 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6672 (match_operand:HI 2 "general_operand" "rmni"))
6674 (clobber (match_scratch:HI 0 "=r"))]
6675 "ix86_match_ccmode (insn, CCGOCmode)
6676 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6678 switch (get_attr_type (insn))
6681 if (operands[2] == const1_rtx)
6682 return "inc{w}\t%0";
6685 gcc_assert (operands[2] == constm1_rtx);
6686 return "dec{w}\t%0";
6690 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6691 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6692 if (CONST_INT_P (operands[2])
6693 && (INTVAL (operands[2]) == 128
6694 || (INTVAL (operands[2]) < 0
6695 && INTVAL (operands[2]) != -128)))
6697 operands[2] = GEN_INT (-INTVAL (operands[2]));
6698 return "sub{w}\t{%2, %0|%0, %2}";
6700 return "add{w}\t{%2, %0|%0, %2}";
6704 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6705 (const_string "incdec")
6706 (const_string "alu")))
6707 (set_attr "mode" "HI")])
6709 (define_expand "addqi3"
6710 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6711 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6712 (match_operand:QI 2 "general_operand" "")))
6713 (clobber (reg:CC FLAGS_REG))])]
6714 "TARGET_QIMODE_MATH"
6715 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6717 ;; %%% Potential partial reg stall on alternative 2. What to do?
6718 (define_insn "*addqi_1_lea"
6719 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6720 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6721 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6722 (clobber (reg:CC FLAGS_REG))]
6723 "!TARGET_PARTIAL_REG_STALL
6724 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6726 int widen = (which_alternative == 2);
6727 switch (get_attr_type (insn))
6732 if (operands[2] == const1_rtx)
6733 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6736 gcc_assert (operands[2] == constm1_rtx);
6737 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6741 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6742 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6743 if (CONST_INT_P (operands[2])
6744 && (INTVAL (operands[2]) == 128
6745 || (INTVAL (operands[2]) < 0
6746 && INTVAL (operands[2]) != -128)))
6748 operands[2] = GEN_INT (-INTVAL (operands[2]));
6750 return "sub{l}\t{%2, %k0|%k0, %2}";
6752 return "sub{b}\t{%2, %0|%0, %2}";
6755 return "add{l}\t{%k2, %k0|%k0, %k2}";
6757 return "add{b}\t{%2, %0|%0, %2}";
6761 (if_then_else (eq_attr "alternative" "3")
6762 (const_string "lea")
6763 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6764 (const_string "incdec")
6765 (const_string "alu"))))
6766 (set_attr "mode" "QI,QI,SI,SI")])
6768 (define_insn "*addqi_1"
6769 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6770 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6771 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6772 (clobber (reg:CC FLAGS_REG))]
6773 "TARGET_PARTIAL_REG_STALL
6774 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6776 int widen = (which_alternative == 2);
6777 switch (get_attr_type (insn))
6780 if (operands[2] == const1_rtx)
6781 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6784 gcc_assert (operands[2] == constm1_rtx);
6785 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6789 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6790 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6791 if (CONST_INT_P (operands[2])
6792 && (INTVAL (operands[2]) == 128
6793 || (INTVAL (operands[2]) < 0
6794 && INTVAL (operands[2]) != -128)))
6796 operands[2] = GEN_INT (-INTVAL (operands[2]));
6798 return "sub{l}\t{%2, %k0|%k0, %2}";
6800 return "sub{b}\t{%2, %0|%0, %2}";
6803 return "add{l}\t{%k2, %k0|%k0, %k2}";
6805 return "add{b}\t{%2, %0|%0, %2}";
6809 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6810 (const_string "incdec")
6811 (const_string "alu")))
6812 (set_attr "mode" "QI,QI,SI")])
6814 (define_insn "*addqi_1_slp"
6815 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6816 (plus:QI (match_dup 0)
6817 (match_operand:QI 1 "general_operand" "qn,qnm")))
6818 (clobber (reg:CC FLAGS_REG))]
6819 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6820 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6822 switch (get_attr_type (insn))
6825 if (operands[1] == const1_rtx)
6826 return "inc{b}\t%0";
6829 gcc_assert (operands[1] == constm1_rtx);
6830 return "dec{b}\t%0";
6834 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6835 if (CONST_INT_P (operands[1])
6836 && INTVAL (operands[1]) < 0)
6838 operands[1] = GEN_INT (-INTVAL (operands[1]));
6839 return "sub{b}\t{%1, %0|%0, %1}";
6841 return "add{b}\t{%1, %0|%0, %1}";
6845 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6846 (const_string "incdec")
6847 (const_string "alu1")))
6848 (set (attr "memory")
6849 (if_then_else (match_operand 1 "memory_operand" "")
6850 (const_string "load")
6851 (const_string "none")))
6852 (set_attr "mode" "QI")])
6854 (define_insn "*addqi_2"
6855 [(set (reg FLAGS_REG)
6857 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6858 (match_operand:QI 2 "general_operand" "qmni,qni"))
6860 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6861 (plus:QI (match_dup 1) (match_dup 2)))]
6862 "ix86_match_ccmode (insn, CCGOCmode)
6863 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6865 switch (get_attr_type (insn))
6868 if (operands[2] == const1_rtx)
6869 return "inc{b}\t%0";
6872 gcc_assert (operands[2] == constm1_rtx
6873 || (CONST_INT_P (operands[2])
6874 && INTVAL (operands[2]) == 255));
6875 return "dec{b}\t%0";
6879 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6880 if (CONST_INT_P (operands[2])
6881 && INTVAL (operands[2]) < 0)
6883 operands[2] = GEN_INT (-INTVAL (operands[2]));
6884 return "sub{b}\t{%2, %0|%0, %2}";
6886 return "add{b}\t{%2, %0|%0, %2}";
6890 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6891 (const_string "incdec")
6892 (const_string "alu")))
6893 (set_attr "mode" "QI")])
6895 (define_insn "*addqi_3"
6896 [(set (reg FLAGS_REG)
6897 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6898 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6899 (clobber (match_scratch:QI 0 "=q"))]
6900 "ix86_match_ccmode (insn, CCZmode)
6901 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6903 switch (get_attr_type (insn))
6906 if (operands[2] == const1_rtx)
6907 return "inc{b}\t%0";
6910 gcc_assert (operands[2] == constm1_rtx
6911 || (CONST_INT_P (operands[2])
6912 && INTVAL (operands[2]) == 255));
6913 return "dec{b}\t%0";
6917 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6918 if (CONST_INT_P (operands[2])
6919 && INTVAL (operands[2]) < 0)
6921 operands[2] = GEN_INT (-INTVAL (operands[2]));
6922 return "sub{b}\t{%2, %0|%0, %2}";
6924 return "add{b}\t{%2, %0|%0, %2}";
6928 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6929 (const_string "incdec")
6930 (const_string "alu")))
6931 (set_attr "mode" "QI")])
6933 ; See comments above addsi_4 for details.
6934 (define_insn "*addqi_4"
6935 [(set (reg FLAGS_REG)
6936 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6937 (match_operand:QI 2 "const_int_operand" "n")))
6938 (clobber (match_scratch:QI 0 "=qm"))]
6939 "ix86_match_ccmode (insn, CCGCmode)
6940 && (INTVAL (operands[2]) & 0xff) != 0x80"
6942 switch (get_attr_type (insn))
6945 if (operands[2] == constm1_rtx
6946 || (CONST_INT_P (operands[2])
6947 && INTVAL (operands[2]) == 255))
6948 return "inc{b}\t%0";
6951 gcc_assert (operands[2] == const1_rtx);
6952 return "dec{b}\t%0";
6956 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6957 if (INTVAL (operands[2]) < 0)
6959 operands[2] = GEN_INT (-INTVAL (operands[2]));
6960 return "add{b}\t{%2, %0|%0, %2}";
6962 return "sub{b}\t{%2, %0|%0, %2}";
6966 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6967 (const_string "incdec")
6968 (const_string "alu")))
6969 (set_attr "mode" "QI")])
6972 (define_insn "*addqi_5"
6973 [(set (reg FLAGS_REG)
6975 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6976 (match_operand:QI 2 "general_operand" "qmni"))
6978 (clobber (match_scratch:QI 0 "=q"))]
6979 "ix86_match_ccmode (insn, CCGOCmode)
6980 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6982 switch (get_attr_type (insn))
6985 if (operands[2] == const1_rtx)
6986 return "inc{b}\t%0";
6989 gcc_assert (operands[2] == constm1_rtx
6990 || (CONST_INT_P (operands[2])
6991 && INTVAL (operands[2]) == 255));
6992 return "dec{b}\t%0";
6996 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6997 if (CONST_INT_P (operands[2])
6998 && INTVAL (operands[2]) < 0)
7000 operands[2] = GEN_INT (-INTVAL (operands[2]));
7001 return "sub{b}\t{%2, %0|%0, %2}";
7003 return "add{b}\t{%2, %0|%0, %2}";
7007 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7008 (const_string "incdec")
7009 (const_string "alu")))
7010 (set_attr "mode" "QI")])
7013 (define_insn "addqi_ext_1"
7014 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7019 (match_operand 1 "ext_register_operand" "0")
7022 (match_operand:QI 2 "general_operand" "Qmn")))
7023 (clobber (reg:CC FLAGS_REG))]
7026 switch (get_attr_type (insn))
7029 if (operands[2] == const1_rtx)
7030 return "inc{b}\t%h0";
7033 gcc_assert (operands[2] == constm1_rtx
7034 || (CONST_INT_P (operands[2])
7035 && INTVAL (operands[2]) == 255));
7036 return "dec{b}\t%h0";
7040 return "add{b}\t{%2, %h0|%h0, %2}";
7044 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7045 (const_string "incdec")
7046 (const_string "alu")))
7047 (set_attr "mode" "QI")])
7049 (define_insn "*addqi_ext_1_rex64"
7050 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7055 (match_operand 1 "ext_register_operand" "0")
7058 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7059 (clobber (reg:CC FLAGS_REG))]
7062 switch (get_attr_type (insn))
7065 if (operands[2] == const1_rtx)
7066 return "inc{b}\t%h0";
7069 gcc_assert (operands[2] == constm1_rtx
7070 || (CONST_INT_P (operands[2])
7071 && INTVAL (operands[2]) == 255));
7072 return "dec{b}\t%h0";
7076 return "add{b}\t{%2, %h0|%h0, %2}";
7080 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7081 (const_string "incdec")
7082 (const_string "alu")))
7083 (set_attr "mode" "QI")])
7085 (define_insn "*addqi_ext_2"
7086 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7091 (match_operand 1 "ext_register_operand" "%0")
7095 (match_operand 2 "ext_register_operand" "Q")
7098 (clobber (reg:CC FLAGS_REG))]
7100 "add{b}\t{%h2, %h0|%h0, %h2}"
7101 [(set_attr "type" "alu")
7102 (set_attr "mode" "QI")])
7104 ;; The patterns that match these are at the end of this file.
7106 (define_expand "addxf3"
7107 [(set (match_operand:XF 0 "register_operand" "")
7108 (plus:XF (match_operand:XF 1 "register_operand" "")
7109 (match_operand:XF 2 "register_operand" "")))]
7113 (define_expand "add<mode>3"
7114 [(set (match_operand:MODEF 0 "register_operand" "")
7115 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7116 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7117 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7120 ;; Subtract instructions
7122 ;; %%% splits for subditi3
7124 (define_expand "subti3"
7125 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7126 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7127 (match_operand:TI 2 "x86_64_general_operand" "")))
7128 (clobber (reg:CC FLAGS_REG))])]
7130 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7132 (define_insn "*subti3_1"
7133 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7134 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7135 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7136 (clobber (reg:CC FLAGS_REG))]
7137 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7141 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7142 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7143 (match_operand:TI 2 "x86_64_general_operand" "")))
7144 (clobber (reg:CC FLAGS_REG))]
7145 "TARGET_64BIT && reload_completed"
7146 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7147 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7148 (parallel [(set (match_dup 3)
7149 (minus:DI (match_dup 4)
7150 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7152 (clobber (reg:CC FLAGS_REG))])]
7153 "split_ti (operands+0, 1, operands+0, operands+3);
7154 split_ti (operands+1, 1, operands+1, operands+4);
7155 split_ti (operands+2, 1, operands+2, operands+5);")
7157 ;; %%% splits for subsidi3
7159 (define_expand "subdi3"
7160 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7161 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7162 (match_operand:DI 2 "x86_64_general_operand" "")))
7163 (clobber (reg:CC FLAGS_REG))])]
7165 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7167 (define_insn "*subdi3_1"
7168 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7169 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7170 (match_operand:DI 2 "general_operand" "roiF,riF")))
7171 (clobber (reg:CC FLAGS_REG))]
7172 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7176 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7177 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7178 (match_operand:DI 2 "general_operand" "")))
7179 (clobber (reg:CC FLAGS_REG))]
7180 "!TARGET_64BIT && reload_completed"
7181 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7182 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7183 (parallel [(set (match_dup 3)
7184 (minus:SI (match_dup 4)
7185 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7187 (clobber (reg:CC FLAGS_REG))])]
7188 "split_di (operands+0, 1, operands+0, operands+3);
7189 split_di (operands+1, 1, operands+1, operands+4);
7190 split_di (operands+2, 1, operands+2, operands+5);")
7192 (define_insn "subdi3_carry_rex64"
7193 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7194 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7195 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7196 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7197 (clobber (reg:CC FLAGS_REG))]
7198 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7199 "sbb{q}\t{%2, %0|%0, %2}"
7200 [(set_attr "type" "alu")
7201 (set_attr "pent_pair" "pu")
7202 (set_attr "mode" "DI")])
7204 (define_insn "*subdi_1_rex64"
7205 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7206 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7207 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7208 (clobber (reg:CC FLAGS_REG))]
7209 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7210 "sub{q}\t{%2, %0|%0, %2}"
7211 [(set_attr "type" "alu")
7212 (set_attr "mode" "DI")])
7214 (define_insn "*subdi_2_rex64"
7215 [(set (reg FLAGS_REG)
7217 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7218 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7220 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7221 (minus:DI (match_dup 1) (match_dup 2)))]
7222 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7223 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7224 "sub{q}\t{%2, %0|%0, %2}"
7225 [(set_attr "type" "alu")
7226 (set_attr "mode" "DI")])
7228 (define_insn "*subdi_3_rex63"
7229 [(set (reg FLAGS_REG)
7230 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7231 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7232 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7233 (minus:DI (match_dup 1) (match_dup 2)))]
7234 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7235 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7236 "sub{q}\t{%2, %0|%0, %2}"
7237 [(set_attr "type" "alu")
7238 (set_attr "mode" "DI")])
7240 (define_insn "subqi3_carry"
7241 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7242 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7243 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7244 (match_operand:QI 2 "general_operand" "qi,qm"))))
7245 (clobber (reg:CC FLAGS_REG))]
7246 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7247 "sbb{b}\t{%2, %0|%0, %2}"
7248 [(set_attr "type" "alu")
7249 (set_attr "pent_pair" "pu")
7250 (set_attr "mode" "QI")])
7252 (define_insn "subhi3_carry"
7253 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7254 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7255 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7256 (match_operand:HI 2 "general_operand" "ri,rm"))))
7257 (clobber (reg:CC FLAGS_REG))]
7258 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7259 "sbb{w}\t{%2, %0|%0, %2}"
7260 [(set_attr "type" "alu")
7261 (set_attr "pent_pair" "pu")
7262 (set_attr "mode" "HI")])
7264 (define_insn "subsi3_carry"
7265 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7266 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7267 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7268 (match_operand:SI 2 "general_operand" "ri,rm"))))
7269 (clobber (reg:CC FLAGS_REG))]
7270 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7271 "sbb{l}\t{%2, %0|%0, %2}"
7272 [(set_attr "type" "alu")
7273 (set_attr "pent_pair" "pu")
7274 (set_attr "mode" "SI")])
7276 (define_insn "subsi3_carry_zext"
7277 [(set (match_operand:DI 0 "register_operand" "=r")
7279 (minus:SI (match_operand:SI 1 "register_operand" "0")
7280 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7281 (match_operand:SI 2 "general_operand" "g")))))
7282 (clobber (reg:CC FLAGS_REG))]
7283 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7284 "sbb{l}\t{%2, %k0|%k0, %2}"
7285 [(set_attr "type" "alu")
7286 (set_attr "pent_pair" "pu")
7287 (set_attr "mode" "SI")])
7289 (define_expand "subsi3"
7290 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7291 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7292 (match_operand:SI 2 "general_operand" "")))
7293 (clobber (reg:CC FLAGS_REG))])]
7295 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7297 (define_insn "*subsi_1"
7298 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7299 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7300 (match_operand:SI 2 "general_operand" "ri,rm")))
7301 (clobber (reg:CC FLAGS_REG))]
7302 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7303 "sub{l}\t{%2, %0|%0, %2}"
7304 [(set_attr "type" "alu")
7305 (set_attr "mode" "SI")])
7307 (define_insn "*subsi_1_zext"
7308 [(set (match_operand:DI 0 "register_operand" "=r")
7310 (minus:SI (match_operand:SI 1 "register_operand" "0")
7311 (match_operand:SI 2 "general_operand" "g"))))
7312 (clobber (reg:CC FLAGS_REG))]
7313 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7314 "sub{l}\t{%2, %k0|%k0, %2}"
7315 [(set_attr "type" "alu")
7316 (set_attr "mode" "SI")])
7318 (define_insn "*subsi_2"
7319 [(set (reg FLAGS_REG)
7321 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7322 (match_operand:SI 2 "general_operand" "ri,rm"))
7324 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7325 (minus:SI (match_dup 1) (match_dup 2)))]
7326 "ix86_match_ccmode (insn, CCGOCmode)
7327 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7328 "sub{l}\t{%2, %0|%0, %2}"
7329 [(set_attr "type" "alu")
7330 (set_attr "mode" "SI")])
7332 (define_insn "*subsi_2_zext"
7333 [(set (reg FLAGS_REG)
7335 (minus:SI (match_operand:SI 1 "register_operand" "0")
7336 (match_operand:SI 2 "general_operand" "g"))
7338 (set (match_operand:DI 0 "register_operand" "=r")
7340 (minus:SI (match_dup 1)
7342 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7343 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7344 "sub{l}\t{%2, %k0|%k0, %2}"
7345 [(set_attr "type" "alu")
7346 (set_attr "mode" "SI")])
7348 (define_insn "*subsi_3"
7349 [(set (reg FLAGS_REG)
7350 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7351 (match_operand:SI 2 "general_operand" "ri,rm")))
7352 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7353 (minus:SI (match_dup 1) (match_dup 2)))]
7354 "ix86_match_ccmode (insn, CCmode)
7355 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7356 "sub{l}\t{%2, %0|%0, %2}"
7357 [(set_attr "type" "alu")
7358 (set_attr "mode" "SI")])
7360 (define_insn "*subsi_3_zext"
7361 [(set (reg FLAGS_REG)
7362 (compare (match_operand:SI 1 "register_operand" "0")
7363 (match_operand:SI 2 "general_operand" "g")))
7364 (set (match_operand:DI 0 "register_operand" "=r")
7366 (minus:SI (match_dup 1)
7368 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7369 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7370 "sub{l}\t{%2, %1|%1, %2}"
7371 [(set_attr "type" "alu")
7372 (set_attr "mode" "DI")])
7374 (define_expand "subhi3"
7375 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7376 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7377 (match_operand:HI 2 "general_operand" "")))
7378 (clobber (reg:CC FLAGS_REG))])]
7379 "TARGET_HIMODE_MATH"
7380 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7382 (define_insn "*subhi_1"
7383 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7384 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7385 (match_operand:HI 2 "general_operand" "ri,rm")))
7386 (clobber (reg:CC FLAGS_REG))]
7387 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7388 "sub{w}\t{%2, %0|%0, %2}"
7389 [(set_attr "type" "alu")
7390 (set_attr "mode" "HI")])
7392 (define_insn "*subhi_2"
7393 [(set (reg FLAGS_REG)
7395 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7396 (match_operand:HI 2 "general_operand" "ri,rm"))
7398 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7399 (minus:HI (match_dup 1) (match_dup 2)))]
7400 "ix86_match_ccmode (insn, CCGOCmode)
7401 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7402 "sub{w}\t{%2, %0|%0, %2}"
7403 [(set_attr "type" "alu")
7404 (set_attr "mode" "HI")])
7406 (define_insn "*subhi_3"
7407 [(set (reg FLAGS_REG)
7408 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7409 (match_operand:HI 2 "general_operand" "ri,rm")))
7410 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7411 (minus:HI (match_dup 1) (match_dup 2)))]
7412 "ix86_match_ccmode (insn, CCmode)
7413 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7414 "sub{w}\t{%2, %0|%0, %2}"
7415 [(set_attr "type" "alu")
7416 (set_attr "mode" "HI")])
7418 (define_expand "subqi3"
7419 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7420 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7421 (match_operand:QI 2 "general_operand" "")))
7422 (clobber (reg:CC FLAGS_REG))])]
7423 "TARGET_QIMODE_MATH"
7424 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7426 (define_insn "*subqi_1"
7427 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7428 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7429 (match_operand:QI 2 "general_operand" "qn,qmn")))
7430 (clobber (reg:CC FLAGS_REG))]
7431 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7432 "sub{b}\t{%2, %0|%0, %2}"
7433 [(set_attr "type" "alu")
7434 (set_attr "mode" "QI")])
7436 (define_insn "*subqi_1_slp"
7437 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7438 (minus:QI (match_dup 0)
7439 (match_operand:QI 1 "general_operand" "qn,qmn")))
7440 (clobber (reg:CC FLAGS_REG))]
7441 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7442 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7443 "sub{b}\t{%1, %0|%0, %1}"
7444 [(set_attr "type" "alu1")
7445 (set_attr "mode" "QI")])
7447 (define_insn "*subqi_2"
7448 [(set (reg FLAGS_REG)
7450 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7451 (match_operand:QI 2 "general_operand" "qi,qm"))
7453 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7454 (minus:HI (match_dup 1) (match_dup 2)))]
7455 "ix86_match_ccmode (insn, CCGOCmode)
7456 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7457 "sub{b}\t{%2, %0|%0, %2}"
7458 [(set_attr "type" "alu")
7459 (set_attr "mode" "QI")])
7461 (define_insn "*subqi_3"
7462 [(set (reg FLAGS_REG)
7463 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7464 (match_operand:QI 2 "general_operand" "qi,qm")))
7465 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7466 (minus:HI (match_dup 1) (match_dup 2)))]
7467 "ix86_match_ccmode (insn, CCmode)
7468 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7469 "sub{b}\t{%2, %0|%0, %2}"
7470 [(set_attr "type" "alu")
7471 (set_attr "mode" "QI")])
7473 ;; The patterns that match these are at the end of this file.
7475 (define_expand "subxf3"
7476 [(set (match_operand:XF 0 "register_operand" "")
7477 (minus:XF (match_operand:XF 1 "register_operand" "")
7478 (match_operand:XF 2 "register_operand" "")))]
7482 (define_expand "sub<mode>3"
7483 [(set (match_operand:MODEF 0 "register_operand" "")
7484 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7485 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7486 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7489 ;; Multiply instructions
7491 (define_expand "muldi3"
7492 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7493 (mult:DI (match_operand:DI 1 "register_operand" "")
7494 (match_operand:DI 2 "x86_64_general_operand" "")))
7495 (clobber (reg:CC FLAGS_REG))])]
7500 ;; IMUL reg64, reg64, imm8 Direct
7501 ;; IMUL reg64, mem64, imm8 VectorPath
7502 ;; IMUL reg64, reg64, imm32 Direct
7503 ;; IMUL reg64, mem64, imm32 VectorPath
7504 ;; IMUL reg64, reg64 Direct
7505 ;; IMUL reg64, mem64 Direct
7507 (define_insn "*muldi3_1_rex64"
7508 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7509 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7510 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7511 (clobber (reg:CC FLAGS_REG))]
7513 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7515 imul{q}\t{%2, %1, %0|%0, %1, %2}
7516 imul{q}\t{%2, %1, %0|%0, %1, %2}
7517 imul{q}\t{%2, %0|%0, %2}"
7518 [(set_attr "type" "imul")
7519 (set_attr "prefix_0f" "0,0,1")
7520 (set (attr "athlon_decode")
7521 (cond [(eq_attr "cpu" "athlon")
7522 (const_string "vector")
7523 (eq_attr "alternative" "1")
7524 (const_string "vector")
7525 (and (eq_attr "alternative" "2")
7526 (match_operand 1 "memory_operand" ""))
7527 (const_string "vector")]
7528 (const_string "direct")))
7529 (set (attr "amdfam10_decode")
7530 (cond [(and (eq_attr "alternative" "0,1")
7531 (match_operand 1 "memory_operand" ""))
7532 (const_string "vector")]
7533 (const_string "direct")))
7534 (set_attr "mode" "DI")])
7536 (define_expand "mulsi3"
7537 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7538 (mult:SI (match_operand:SI 1 "register_operand" "")
7539 (match_operand:SI 2 "general_operand" "")))
7540 (clobber (reg:CC FLAGS_REG))])]
7545 ;; IMUL reg32, reg32, imm8 Direct
7546 ;; IMUL reg32, mem32, imm8 VectorPath
7547 ;; IMUL reg32, reg32, imm32 Direct
7548 ;; IMUL reg32, mem32, imm32 VectorPath
7549 ;; IMUL reg32, reg32 Direct
7550 ;; IMUL reg32, mem32 Direct
7552 (define_insn "*mulsi3_1"
7553 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7554 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7555 (match_operand:SI 2 "general_operand" "K,i,mr")))
7556 (clobber (reg:CC FLAGS_REG))]
7557 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7559 imul{l}\t{%2, %1, %0|%0, %1, %2}
7560 imul{l}\t{%2, %1, %0|%0, %1, %2}
7561 imul{l}\t{%2, %0|%0, %2}"
7562 [(set_attr "type" "imul")
7563 (set_attr "prefix_0f" "0,0,1")
7564 (set (attr "athlon_decode")
7565 (cond [(eq_attr "cpu" "athlon")
7566 (const_string "vector")
7567 (eq_attr "alternative" "1")
7568 (const_string "vector")
7569 (and (eq_attr "alternative" "2")
7570 (match_operand 1 "memory_operand" ""))
7571 (const_string "vector")]
7572 (const_string "direct")))
7573 (set (attr "amdfam10_decode")
7574 (cond [(and (eq_attr "alternative" "0,1")
7575 (match_operand 1 "memory_operand" ""))
7576 (const_string "vector")]
7577 (const_string "direct")))
7578 (set_attr "mode" "SI")])
7580 (define_insn "*mulsi3_1_zext"
7581 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7583 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7584 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7585 (clobber (reg:CC FLAGS_REG))]
7587 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7589 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7590 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7591 imul{l}\t{%2, %k0|%k0, %2}"
7592 [(set_attr "type" "imul")
7593 (set_attr "prefix_0f" "0,0,1")
7594 (set (attr "athlon_decode")
7595 (cond [(eq_attr "cpu" "athlon")
7596 (const_string "vector")
7597 (eq_attr "alternative" "1")
7598 (const_string "vector")
7599 (and (eq_attr "alternative" "2")
7600 (match_operand 1 "memory_operand" ""))
7601 (const_string "vector")]
7602 (const_string "direct")))
7603 (set (attr "amdfam10_decode")
7604 (cond [(and (eq_attr "alternative" "0,1")
7605 (match_operand 1 "memory_operand" ""))
7606 (const_string "vector")]
7607 (const_string "direct")))
7608 (set_attr "mode" "SI")])
7610 (define_expand "mulhi3"
7611 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7612 (mult:HI (match_operand:HI 1 "register_operand" "")
7613 (match_operand:HI 2 "general_operand" "")))
7614 (clobber (reg:CC FLAGS_REG))])]
7615 "TARGET_HIMODE_MATH"
7619 ;; IMUL reg16, reg16, imm8 VectorPath
7620 ;; IMUL reg16, mem16, imm8 VectorPath
7621 ;; IMUL reg16, reg16, imm16 VectorPath
7622 ;; IMUL reg16, mem16, imm16 VectorPath
7623 ;; IMUL reg16, reg16 Direct
7624 ;; IMUL reg16, mem16 Direct
7625 (define_insn "*mulhi3_1"
7626 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7627 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7628 (match_operand:HI 2 "general_operand" "K,i,mr")))
7629 (clobber (reg:CC FLAGS_REG))]
7630 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7632 imul{w}\t{%2, %1, %0|%0, %1, %2}
7633 imul{w}\t{%2, %1, %0|%0, %1, %2}
7634 imul{w}\t{%2, %0|%0, %2}"
7635 [(set_attr "type" "imul")
7636 (set_attr "prefix_0f" "0,0,1")
7637 (set (attr "athlon_decode")
7638 (cond [(eq_attr "cpu" "athlon")
7639 (const_string "vector")
7640 (eq_attr "alternative" "1,2")
7641 (const_string "vector")]
7642 (const_string "direct")))
7643 (set (attr "amdfam10_decode")
7644 (cond [(eq_attr "alternative" "0,1")
7645 (const_string "vector")]
7646 (const_string "direct")))
7647 (set_attr "mode" "HI")])
7649 (define_expand "mulqi3"
7650 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7651 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7652 (match_operand:QI 2 "register_operand" "")))
7653 (clobber (reg:CC FLAGS_REG))])]
7654 "TARGET_QIMODE_MATH"
7661 (define_insn "*mulqi3_1"
7662 [(set (match_operand:QI 0 "register_operand" "=a")
7663 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7664 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7665 (clobber (reg:CC FLAGS_REG))]
7667 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7669 [(set_attr "type" "imul")
7670 (set_attr "length_immediate" "0")
7671 (set (attr "athlon_decode")
7672 (if_then_else (eq_attr "cpu" "athlon")
7673 (const_string "vector")
7674 (const_string "direct")))
7675 (set_attr "amdfam10_decode" "direct")
7676 (set_attr "mode" "QI")])
7678 (define_expand "umulqihi3"
7679 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7680 (mult:HI (zero_extend:HI
7681 (match_operand:QI 1 "nonimmediate_operand" ""))
7683 (match_operand:QI 2 "register_operand" ""))))
7684 (clobber (reg:CC FLAGS_REG))])]
7685 "TARGET_QIMODE_MATH"
7688 (define_insn "*umulqihi3_1"
7689 [(set (match_operand:HI 0 "register_operand" "=a")
7690 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7691 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7692 (clobber (reg:CC FLAGS_REG))]
7694 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7696 [(set_attr "type" "imul")
7697 (set_attr "length_immediate" "0")
7698 (set (attr "athlon_decode")
7699 (if_then_else (eq_attr "cpu" "athlon")
7700 (const_string "vector")
7701 (const_string "direct")))
7702 (set_attr "amdfam10_decode" "direct")
7703 (set_attr "mode" "QI")])
7705 (define_expand "mulqihi3"
7706 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7707 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7708 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7709 (clobber (reg:CC FLAGS_REG))])]
7710 "TARGET_QIMODE_MATH"
7713 (define_insn "*mulqihi3_insn"
7714 [(set (match_operand:HI 0 "register_operand" "=a")
7715 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7716 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7717 (clobber (reg:CC FLAGS_REG))]
7719 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7721 [(set_attr "type" "imul")
7722 (set_attr "length_immediate" "0")
7723 (set (attr "athlon_decode")
7724 (if_then_else (eq_attr "cpu" "athlon")
7725 (const_string "vector")
7726 (const_string "direct")))
7727 (set_attr "amdfam10_decode" "direct")
7728 (set_attr "mode" "QI")])
7730 (define_expand "umulditi3"
7731 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7732 (mult:TI (zero_extend:TI
7733 (match_operand:DI 1 "nonimmediate_operand" ""))
7735 (match_operand:DI 2 "register_operand" ""))))
7736 (clobber (reg:CC FLAGS_REG))])]
7740 (define_insn "*umulditi3_insn"
7741 [(set (match_operand:TI 0 "register_operand" "=A")
7742 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7743 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7744 (clobber (reg:CC FLAGS_REG))]
7746 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7748 [(set_attr "type" "imul")
7749 (set_attr "length_immediate" "0")
7750 (set (attr "athlon_decode")
7751 (if_then_else (eq_attr "cpu" "athlon")
7752 (const_string "vector")
7753 (const_string "double")))
7754 (set_attr "amdfam10_decode" "double")
7755 (set_attr "mode" "DI")])
7757 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7758 (define_expand "umulsidi3"
7759 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7760 (mult:DI (zero_extend:DI
7761 (match_operand:SI 1 "nonimmediate_operand" ""))
7763 (match_operand:SI 2 "register_operand" ""))))
7764 (clobber (reg:CC FLAGS_REG))])]
7768 (define_insn "*umulsidi3_insn"
7769 [(set (match_operand:DI 0 "register_operand" "=A")
7770 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7771 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7772 (clobber (reg:CC FLAGS_REG))]
7774 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7776 [(set_attr "type" "imul")
7777 (set_attr "length_immediate" "0")
7778 (set (attr "athlon_decode")
7779 (if_then_else (eq_attr "cpu" "athlon")
7780 (const_string "vector")
7781 (const_string "double")))
7782 (set_attr "amdfam10_decode" "double")
7783 (set_attr "mode" "SI")])
7785 (define_expand "mulditi3"
7786 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7787 (mult:TI (sign_extend:TI
7788 (match_operand:DI 1 "nonimmediate_operand" ""))
7790 (match_operand:DI 2 "register_operand" ""))))
7791 (clobber (reg:CC FLAGS_REG))])]
7795 (define_insn "*mulditi3_insn"
7796 [(set (match_operand:TI 0 "register_operand" "=A")
7797 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7798 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7799 (clobber (reg:CC FLAGS_REG))]
7801 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7803 [(set_attr "type" "imul")
7804 (set_attr "length_immediate" "0")
7805 (set (attr "athlon_decode")
7806 (if_then_else (eq_attr "cpu" "athlon")
7807 (const_string "vector")
7808 (const_string "double")))
7809 (set_attr "amdfam10_decode" "double")
7810 (set_attr "mode" "DI")])
7812 (define_expand "mulsidi3"
7813 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7814 (mult:DI (sign_extend:DI
7815 (match_operand:SI 1 "nonimmediate_operand" ""))
7817 (match_operand:SI 2 "register_operand" ""))))
7818 (clobber (reg:CC FLAGS_REG))])]
7822 (define_insn "*mulsidi3_insn"
7823 [(set (match_operand:DI 0 "register_operand" "=A")
7824 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7825 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7826 (clobber (reg:CC FLAGS_REG))]
7828 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7830 [(set_attr "type" "imul")
7831 (set_attr "length_immediate" "0")
7832 (set (attr "athlon_decode")
7833 (if_then_else (eq_attr "cpu" "athlon")
7834 (const_string "vector")
7835 (const_string "double")))
7836 (set_attr "amdfam10_decode" "double")
7837 (set_attr "mode" "SI")])
7839 (define_expand "umuldi3_highpart"
7840 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7843 (mult:TI (zero_extend:TI
7844 (match_operand:DI 1 "nonimmediate_operand" ""))
7846 (match_operand:DI 2 "register_operand" "")))
7848 (clobber (match_scratch:DI 3 ""))
7849 (clobber (reg:CC FLAGS_REG))])]
7853 (define_insn "*umuldi3_highpart_rex64"
7854 [(set (match_operand:DI 0 "register_operand" "=d")
7857 (mult:TI (zero_extend:TI
7858 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7860 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7862 (clobber (match_scratch:DI 3 "=1"))
7863 (clobber (reg:CC FLAGS_REG))]
7865 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7867 [(set_attr "type" "imul")
7868 (set_attr "length_immediate" "0")
7869 (set (attr "athlon_decode")
7870 (if_then_else (eq_attr "cpu" "athlon")
7871 (const_string "vector")
7872 (const_string "double")))
7873 (set_attr "amdfam10_decode" "double")
7874 (set_attr "mode" "DI")])
7876 (define_expand "umulsi3_highpart"
7877 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7880 (mult:DI (zero_extend:DI
7881 (match_operand:SI 1 "nonimmediate_operand" ""))
7883 (match_operand:SI 2 "register_operand" "")))
7885 (clobber (match_scratch:SI 3 ""))
7886 (clobber (reg:CC FLAGS_REG))])]
7890 (define_insn "*umulsi3_highpart_insn"
7891 [(set (match_operand:SI 0 "register_operand" "=d")
7894 (mult:DI (zero_extend:DI
7895 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7897 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7899 (clobber (match_scratch:SI 3 "=1"))
7900 (clobber (reg:CC FLAGS_REG))]
7901 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7903 [(set_attr "type" "imul")
7904 (set_attr "length_immediate" "0")
7905 (set (attr "athlon_decode")
7906 (if_then_else (eq_attr "cpu" "athlon")
7907 (const_string "vector")
7908 (const_string "double")))
7909 (set_attr "amdfam10_decode" "double")
7910 (set_attr "mode" "SI")])
7912 (define_insn "*umulsi3_highpart_zext"
7913 [(set (match_operand:DI 0 "register_operand" "=d")
7914 (zero_extend:DI (truncate:SI
7916 (mult:DI (zero_extend:DI
7917 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7919 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7921 (clobber (match_scratch:SI 3 "=1"))
7922 (clobber (reg:CC FLAGS_REG))]
7924 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7926 [(set_attr "type" "imul")
7927 (set_attr "length_immediate" "0")
7928 (set (attr "athlon_decode")
7929 (if_then_else (eq_attr "cpu" "athlon")
7930 (const_string "vector")
7931 (const_string "double")))
7932 (set_attr "amdfam10_decode" "double")
7933 (set_attr "mode" "SI")])
7935 (define_expand "smuldi3_highpart"
7936 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7939 (mult:TI (sign_extend:TI
7940 (match_operand:DI 1 "nonimmediate_operand" ""))
7942 (match_operand:DI 2 "register_operand" "")))
7944 (clobber (match_scratch:DI 3 ""))
7945 (clobber (reg:CC FLAGS_REG))])]
7949 (define_insn "*smuldi3_highpart_rex64"
7950 [(set (match_operand:DI 0 "register_operand" "=d")
7953 (mult:TI (sign_extend:TI
7954 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7956 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7958 (clobber (match_scratch:DI 3 "=1"))
7959 (clobber (reg:CC FLAGS_REG))]
7961 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7963 [(set_attr "type" "imul")
7964 (set (attr "athlon_decode")
7965 (if_then_else (eq_attr "cpu" "athlon")
7966 (const_string "vector")
7967 (const_string "double")))
7968 (set_attr "amdfam10_decode" "double")
7969 (set_attr "mode" "DI")])
7971 (define_expand "smulsi3_highpart"
7972 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7975 (mult:DI (sign_extend:DI
7976 (match_operand:SI 1 "nonimmediate_operand" ""))
7978 (match_operand:SI 2 "register_operand" "")))
7980 (clobber (match_scratch:SI 3 ""))
7981 (clobber (reg:CC FLAGS_REG))])]
7985 (define_insn "*smulsi3_highpart_insn"
7986 [(set (match_operand:SI 0 "register_operand" "=d")
7989 (mult:DI (sign_extend:DI
7990 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7992 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7994 (clobber (match_scratch:SI 3 "=1"))
7995 (clobber (reg:CC FLAGS_REG))]
7996 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7998 [(set_attr "type" "imul")
7999 (set (attr "athlon_decode")
8000 (if_then_else (eq_attr "cpu" "athlon")
8001 (const_string "vector")
8002 (const_string "double")))
8003 (set_attr "amdfam10_decode" "double")
8004 (set_attr "mode" "SI")])
8006 (define_insn "*smulsi3_highpart_zext"
8007 [(set (match_operand:DI 0 "register_operand" "=d")
8008 (zero_extend:DI (truncate:SI
8010 (mult:DI (sign_extend:DI
8011 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8013 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8015 (clobber (match_scratch:SI 3 "=1"))
8016 (clobber (reg:CC FLAGS_REG))]
8018 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8020 [(set_attr "type" "imul")
8021 (set (attr "athlon_decode")
8022 (if_then_else (eq_attr "cpu" "athlon")
8023 (const_string "vector")
8024 (const_string "double")))
8025 (set_attr "amdfam10_decode" "double")
8026 (set_attr "mode" "SI")])
8028 ;; The patterns that match these are at the end of this file.
8030 (define_expand "mulxf3"
8031 [(set (match_operand:XF 0 "register_operand" "")
8032 (mult:XF (match_operand:XF 1 "register_operand" "")
8033 (match_operand:XF 2 "register_operand" "")))]
8037 (define_expand "mul<mode>3"
8038 [(set (match_operand:MODEF 0 "register_operand" "")
8039 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8040 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8041 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8044 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8047 ;; Divide instructions
8049 (define_insn "divqi3"
8050 [(set (match_operand:QI 0 "register_operand" "=a")
8051 (div:QI (match_operand:HI 1 "register_operand" "0")
8052 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8053 (clobber (reg:CC FLAGS_REG))]
8054 "TARGET_QIMODE_MATH"
8056 [(set_attr "type" "idiv")
8057 (set_attr "mode" "QI")])
8059 (define_insn "udivqi3"
8060 [(set (match_operand:QI 0 "register_operand" "=a")
8061 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8062 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8063 (clobber (reg:CC FLAGS_REG))]
8064 "TARGET_QIMODE_MATH"
8066 [(set_attr "type" "idiv")
8067 (set_attr "mode" "QI")])
8069 ;; The patterns that match these are at the end of this file.
8071 (define_expand "divxf3"
8072 [(set (match_operand:XF 0 "register_operand" "")
8073 (div:XF (match_operand:XF 1 "register_operand" "")
8074 (match_operand:XF 2 "register_operand" "")))]
8078 (define_expand "divdf3"
8079 [(set (match_operand:DF 0 "register_operand" "")
8080 (div:DF (match_operand:DF 1 "register_operand" "")
8081 (match_operand:DF 2 "nonimmediate_operand" "")))]
8082 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8085 (define_expand "divsf3"
8086 [(set (match_operand:SF 0 "register_operand" "")
8087 (div:SF (match_operand:SF 1 "register_operand" "")
8088 (match_operand:SF 2 "nonimmediate_operand" "")))]
8089 "TARGET_80387 || TARGET_SSE_MATH"
8091 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8092 && flag_finite_math_only && !flag_trapping_math
8093 && flag_unsafe_math_optimizations)
8095 ix86_emit_swdivsf (operands[0], operands[1],
8096 operands[2], SFmode);
8101 ;; Remainder instructions.
8103 (define_expand "divmoddi4"
8104 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8105 (div:DI (match_operand:DI 1 "register_operand" "")
8106 (match_operand:DI 2 "nonimmediate_operand" "")))
8107 (set (match_operand:DI 3 "register_operand" "")
8108 (mod:DI (match_dup 1) (match_dup 2)))
8109 (clobber (reg:CC FLAGS_REG))])]
8113 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8114 ;; Penalize eax case slightly because it results in worse scheduling
8116 (define_insn "*divmoddi4_nocltd_rex64"
8117 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8118 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8119 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8120 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8121 (mod:DI (match_dup 2) (match_dup 3)))
8122 (clobber (reg:CC FLAGS_REG))]
8123 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8125 [(set_attr "type" "multi")])
8127 (define_insn "*divmoddi4_cltd_rex64"
8128 [(set (match_operand:DI 0 "register_operand" "=a")
8129 (div:DI (match_operand:DI 2 "register_operand" "a")
8130 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8131 (set (match_operand:DI 1 "register_operand" "=&d")
8132 (mod:DI (match_dup 2) (match_dup 3)))
8133 (clobber (reg:CC FLAGS_REG))]
8134 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8136 [(set_attr "type" "multi")])
8138 (define_insn "*divmoddi_noext_rex64"
8139 [(set (match_operand:DI 0 "register_operand" "=a")
8140 (div:DI (match_operand:DI 1 "register_operand" "0")
8141 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8142 (set (match_operand:DI 3 "register_operand" "=d")
8143 (mod:DI (match_dup 1) (match_dup 2)))
8144 (use (match_operand:DI 4 "register_operand" "3"))
8145 (clobber (reg:CC FLAGS_REG))]
8148 [(set_attr "type" "idiv")
8149 (set_attr "mode" "DI")])
8152 [(set (match_operand:DI 0 "register_operand" "")
8153 (div:DI (match_operand:DI 1 "register_operand" "")
8154 (match_operand:DI 2 "nonimmediate_operand" "")))
8155 (set (match_operand:DI 3 "register_operand" "")
8156 (mod:DI (match_dup 1) (match_dup 2)))
8157 (clobber (reg:CC FLAGS_REG))]
8158 "TARGET_64BIT && reload_completed"
8159 [(parallel [(set (match_dup 3)
8160 (ashiftrt:DI (match_dup 4) (const_int 63)))
8161 (clobber (reg:CC FLAGS_REG))])
8162 (parallel [(set (match_dup 0)
8163 (div:DI (reg:DI 0) (match_dup 2)))
8165 (mod:DI (reg:DI 0) (match_dup 2)))
8167 (clobber (reg:CC FLAGS_REG))])]
8169 /* Avoid use of cltd in favor of a mov+shift. */
8170 if (!TARGET_USE_CLTD && !optimize_size)
8172 if (true_regnum (operands[1]))
8173 emit_move_insn (operands[0], operands[1]);
8175 emit_move_insn (operands[3], operands[1]);
8176 operands[4] = operands[3];
8180 gcc_assert (!true_regnum (operands[1]));
8181 operands[4] = operands[1];
8186 (define_expand "divmodsi4"
8187 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8188 (div:SI (match_operand:SI 1 "register_operand" "")
8189 (match_operand:SI 2 "nonimmediate_operand" "")))
8190 (set (match_operand:SI 3 "register_operand" "")
8191 (mod:SI (match_dup 1) (match_dup 2)))
8192 (clobber (reg:CC FLAGS_REG))])]
8196 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8197 ;; Penalize eax case slightly because it results in worse scheduling
8199 (define_insn "*divmodsi4_nocltd"
8200 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8201 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8202 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8203 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8204 (mod:SI (match_dup 2) (match_dup 3)))
8205 (clobber (reg:CC FLAGS_REG))]
8206 "!optimize_size && !TARGET_USE_CLTD"
8208 [(set_attr "type" "multi")])
8210 (define_insn "*divmodsi4_cltd"
8211 [(set (match_operand:SI 0 "register_operand" "=a")
8212 (div:SI (match_operand:SI 2 "register_operand" "a")
8213 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8214 (set (match_operand:SI 1 "register_operand" "=&d")
8215 (mod:SI (match_dup 2) (match_dup 3)))
8216 (clobber (reg:CC FLAGS_REG))]
8217 "optimize_size || TARGET_USE_CLTD"
8219 [(set_attr "type" "multi")])
8221 (define_insn "*divmodsi_noext"
8222 [(set (match_operand:SI 0 "register_operand" "=a")
8223 (div:SI (match_operand:SI 1 "register_operand" "0")
8224 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8225 (set (match_operand:SI 3 "register_operand" "=d")
8226 (mod:SI (match_dup 1) (match_dup 2)))
8227 (use (match_operand:SI 4 "register_operand" "3"))
8228 (clobber (reg:CC FLAGS_REG))]
8231 [(set_attr "type" "idiv")
8232 (set_attr "mode" "SI")])
8235 [(set (match_operand:SI 0 "register_operand" "")
8236 (div:SI (match_operand:SI 1 "register_operand" "")
8237 (match_operand:SI 2 "nonimmediate_operand" "")))
8238 (set (match_operand:SI 3 "register_operand" "")
8239 (mod:SI (match_dup 1) (match_dup 2)))
8240 (clobber (reg:CC FLAGS_REG))]
8242 [(parallel [(set (match_dup 3)
8243 (ashiftrt:SI (match_dup 4) (const_int 31)))
8244 (clobber (reg:CC FLAGS_REG))])
8245 (parallel [(set (match_dup 0)
8246 (div:SI (reg:SI 0) (match_dup 2)))
8248 (mod:SI (reg:SI 0) (match_dup 2)))
8250 (clobber (reg:CC FLAGS_REG))])]
8252 /* Avoid use of cltd in favor of a mov+shift. */
8253 if (!TARGET_USE_CLTD && !optimize_size)
8255 if (true_regnum (operands[1]))
8256 emit_move_insn (operands[0], operands[1]);
8258 emit_move_insn (operands[3], operands[1]);
8259 operands[4] = operands[3];
8263 gcc_assert (!true_regnum (operands[1]));
8264 operands[4] = operands[1];
8268 (define_insn "divmodhi4"
8269 [(set (match_operand:HI 0 "register_operand" "=a")
8270 (div:HI (match_operand:HI 1 "register_operand" "0")
8271 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8272 (set (match_operand:HI 3 "register_operand" "=&d")
8273 (mod:HI (match_dup 1) (match_dup 2)))
8274 (clobber (reg:CC FLAGS_REG))]
8275 "TARGET_HIMODE_MATH"
8277 [(set_attr "type" "multi")
8278 (set_attr "length_immediate" "0")
8279 (set_attr "mode" "SI")])
8281 (define_insn "udivmoddi4"
8282 [(set (match_operand:DI 0 "register_operand" "=a")
8283 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8284 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8285 (set (match_operand:DI 3 "register_operand" "=&d")
8286 (umod:DI (match_dup 1) (match_dup 2)))
8287 (clobber (reg:CC FLAGS_REG))]
8289 "xor{q}\t%3, %3\;div{q}\t%2"
8290 [(set_attr "type" "multi")
8291 (set_attr "length_immediate" "0")
8292 (set_attr "mode" "DI")])
8294 (define_insn "*udivmoddi4_noext"
8295 [(set (match_operand:DI 0 "register_operand" "=a")
8296 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8297 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8298 (set (match_operand:DI 3 "register_operand" "=d")
8299 (umod:DI (match_dup 1) (match_dup 2)))
8301 (clobber (reg:CC FLAGS_REG))]
8304 [(set_attr "type" "idiv")
8305 (set_attr "mode" "DI")])
8308 [(set (match_operand:DI 0 "register_operand" "")
8309 (udiv:DI (match_operand:DI 1 "register_operand" "")
8310 (match_operand:DI 2 "nonimmediate_operand" "")))
8311 (set (match_operand:DI 3 "register_operand" "")
8312 (umod:DI (match_dup 1) (match_dup 2)))
8313 (clobber (reg:CC FLAGS_REG))]
8314 "TARGET_64BIT && reload_completed"
8315 [(set (match_dup 3) (const_int 0))
8316 (parallel [(set (match_dup 0)
8317 (udiv:DI (match_dup 1) (match_dup 2)))
8319 (umod:DI (match_dup 1) (match_dup 2)))
8321 (clobber (reg:CC FLAGS_REG))])]
8324 (define_insn "udivmodsi4"
8325 [(set (match_operand:SI 0 "register_operand" "=a")
8326 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8327 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8328 (set (match_operand:SI 3 "register_operand" "=&d")
8329 (umod:SI (match_dup 1) (match_dup 2)))
8330 (clobber (reg:CC FLAGS_REG))]
8332 "xor{l}\t%3, %3\;div{l}\t%2"
8333 [(set_attr "type" "multi")
8334 (set_attr "length_immediate" "0")
8335 (set_attr "mode" "SI")])
8337 (define_insn "*udivmodsi4_noext"
8338 [(set (match_operand:SI 0 "register_operand" "=a")
8339 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8340 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8341 (set (match_operand:SI 3 "register_operand" "=d")
8342 (umod:SI (match_dup 1) (match_dup 2)))
8344 (clobber (reg:CC FLAGS_REG))]
8347 [(set_attr "type" "idiv")
8348 (set_attr "mode" "SI")])
8351 [(set (match_operand:SI 0 "register_operand" "")
8352 (udiv:SI (match_operand:SI 1 "register_operand" "")
8353 (match_operand:SI 2 "nonimmediate_operand" "")))
8354 (set (match_operand:SI 3 "register_operand" "")
8355 (umod:SI (match_dup 1) (match_dup 2)))
8356 (clobber (reg:CC FLAGS_REG))]
8358 [(set (match_dup 3) (const_int 0))
8359 (parallel [(set (match_dup 0)
8360 (udiv:SI (match_dup 1) (match_dup 2)))
8362 (umod:SI (match_dup 1) (match_dup 2)))
8364 (clobber (reg:CC FLAGS_REG))])]
8367 (define_expand "udivmodhi4"
8368 [(set (match_dup 4) (const_int 0))
8369 (parallel [(set (match_operand:HI 0 "register_operand" "")
8370 (udiv:HI (match_operand:HI 1 "register_operand" "")
8371 (match_operand:HI 2 "nonimmediate_operand" "")))
8372 (set (match_operand:HI 3 "register_operand" "")
8373 (umod:HI (match_dup 1) (match_dup 2)))
8375 (clobber (reg:CC FLAGS_REG))])]
8376 "TARGET_HIMODE_MATH"
8377 "operands[4] = gen_reg_rtx (HImode);")
8379 (define_insn "*udivmodhi_noext"
8380 [(set (match_operand:HI 0 "register_operand" "=a")
8381 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8382 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8383 (set (match_operand:HI 3 "register_operand" "=d")
8384 (umod:HI (match_dup 1) (match_dup 2)))
8385 (use (match_operand:HI 4 "register_operand" "3"))
8386 (clobber (reg:CC FLAGS_REG))]
8389 [(set_attr "type" "idiv")
8390 (set_attr "mode" "HI")])
8392 ;; We cannot use div/idiv for double division, because it causes
8393 ;; "division by zero" on the overflow and that's not what we expect
8394 ;; from truncate. Because true (non truncating) double division is
8395 ;; never generated, we can't create this insn anyway.
8398 ; [(set (match_operand:SI 0 "register_operand" "=a")
8400 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8402 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8403 ; (set (match_operand:SI 3 "register_operand" "=d")
8405 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8406 ; (clobber (reg:CC FLAGS_REG))]
8408 ; "div{l}\t{%2, %0|%0, %2}"
8409 ; [(set_attr "type" "idiv")])
8411 ;;- Logical AND instructions
8413 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8414 ;; Note that this excludes ah.
8416 (define_insn "*testdi_1_rex64"
8417 [(set (reg FLAGS_REG)
8419 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8420 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8422 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8423 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8425 test{l}\t{%k1, %k0|%k0, %k1}
8426 test{l}\t{%k1, %k0|%k0, %k1}
8427 test{q}\t{%1, %0|%0, %1}
8428 test{q}\t{%1, %0|%0, %1}
8429 test{q}\t{%1, %0|%0, %1}"
8430 [(set_attr "type" "test")
8431 (set_attr "modrm" "0,1,0,1,1")
8432 (set_attr "mode" "SI,SI,DI,DI,DI")
8433 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8435 (define_insn "testsi_1"
8436 [(set (reg FLAGS_REG)
8438 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8439 (match_operand:SI 1 "general_operand" "in,in,rin"))
8441 "ix86_match_ccmode (insn, CCNOmode)
8442 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8443 "test{l}\t{%1, %0|%0, %1}"
8444 [(set_attr "type" "test")
8445 (set_attr "modrm" "0,1,1")
8446 (set_attr "mode" "SI")
8447 (set_attr "pent_pair" "uv,np,uv")])
8449 (define_expand "testsi_ccno_1"
8450 [(set (reg:CCNO FLAGS_REG)
8452 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8453 (match_operand:SI 1 "nonmemory_operand" ""))
8458 (define_insn "*testhi_1"
8459 [(set (reg FLAGS_REG)
8460 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8461 (match_operand:HI 1 "general_operand" "n,n,rn"))
8463 "ix86_match_ccmode (insn, CCNOmode)
8464 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8465 "test{w}\t{%1, %0|%0, %1}"
8466 [(set_attr "type" "test")
8467 (set_attr "modrm" "0,1,1")
8468 (set_attr "mode" "HI")
8469 (set_attr "pent_pair" "uv,np,uv")])
8471 (define_expand "testqi_ccz_1"
8472 [(set (reg:CCZ FLAGS_REG)
8473 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8474 (match_operand:QI 1 "nonmemory_operand" ""))
8479 (define_insn "*testqi_1_maybe_si"
8480 [(set (reg FLAGS_REG)
8483 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8484 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8486 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8487 && ix86_match_ccmode (insn,
8488 CONST_INT_P (operands[1])
8489 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8491 if (which_alternative == 3)
8493 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8494 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8495 return "test{l}\t{%1, %k0|%k0, %1}";
8497 return "test{b}\t{%1, %0|%0, %1}";
8499 [(set_attr "type" "test")
8500 (set_attr "modrm" "0,1,1,1")
8501 (set_attr "mode" "QI,QI,QI,SI")
8502 (set_attr "pent_pair" "uv,np,uv,np")])
8504 (define_insn "*testqi_1"
8505 [(set (reg FLAGS_REG)
8508 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8509 (match_operand:QI 1 "general_operand" "n,n,qn"))
8511 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8512 && ix86_match_ccmode (insn, CCNOmode)"
8513 "test{b}\t{%1, %0|%0, %1}"
8514 [(set_attr "type" "test")
8515 (set_attr "modrm" "0,1,1")
8516 (set_attr "mode" "QI")
8517 (set_attr "pent_pair" "uv,np,uv")])
8519 (define_expand "testqi_ext_ccno_0"
8520 [(set (reg:CCNO FLAGS_REG)
8524 (match_operand 0 "ext_register_operand" "")
8527 (match_operand 1 "const_int_operand" ""))
8532 (define_insn "*testqi_ext_0"
8533 [(set (reg FLAGS_REG)
8537 (match_operand 0 "ext_register_operand" "Q")
8540 (match_operand 1 "const_int_operand" "n"))
8542 "ix86_match_ccmode (insn, CCNOmode)"
8543 "test{b}\t{%1, %h0|%h0, %1}"
8544 [(set_attr "type" "test")
8545 (set_attr "mode" "QI")
8546 (set_attr "length_immediate" "1")
8547 (set_attr "pent_pair" "np")])
8549 (define_insn "*testqi_ext_1"
8550 [(set (reg FLAGS_REG)
8554 (match_operand 0 "ext_register_operand" "Q")
8558 (match_operand:QI 1 "general_operand" "Qm")))
8560 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8561 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8562 "test{b}\t{%1, %h0|%h0, %1}"
8563 [(set_attr "type" "test")
8564 (set_attr "mode" "QI")])
8566 (define_insn "*testqi_ext_1_rex64"
8567 [(set (reg FLAGS_REG)
8571 (match_operand 0 "ext_register_operand" "Q")
8575 (match_operand:QI 1 "register_operand" "Q")))
8577 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8578 "test{b}\t{%1, %h0|%h0, %1}"
8579 [(set_attr "type" "test")
8580 (set_attr "mode" "QI")])
8582 (define_insn "*testqi_ext_2"
8583 [(set (reg FLAGS_REG)
8587 (match_operand 0 "ext_register_operand" "Q")
8591 (match_operand 1 "ext_register_operand" "Q")
8595 "ix86_match_ccmode (insn, CCNOmode)"
8596 "test{b}\t{%h1, %h0|%h0, %h1}"
8597 [(set_attr "type" "test")
8598 (set_attr "mode" "QI")])
8600 ;; Combine likes to form bit extractions for some tests. Humor it.
8601 (define_insn "*testqi_ext_3"
8602 [(set (reg FLAGS_REG)
8603 (compare (zero_extract:SI
8604 (match_operand 0 "nonimmediate_operand" "rm")
8605 (match_operand:SI 1 "const_int_operand" "")
8606 (match_operand:SI 2 "const_int_operand" ""))
8608 "ix86_match_ccmode (insn, CCNOmode)
8609 && INTVAL (operands[1]) > 0
8610 && INTVAL (operands[2]) >= 0
8611 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8612 && (GET_MODE (operands[0]) == SImode
8613 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8614 || GET_MODE (operands[0]) == HImode
8615 || GET_MODE (operands[0]) == QImode)"
8618 (define_insn "*testqi_ext_3_rex64"
8619 [(set (reg FLAGS_REG)
8620 (compare (zero_extract:DI
8621 (match_operand 0 "nonimmediate_operand" "rm")
8622 (match_operand:DI 1 "const_int_operand" "")
8623 (match_operand:DI 2 "const_int_operand" ""))
8626 && ix86_match_ccmode (insn, CCNOmode)
8627 && INTVAL (operands[1]) > 0
8628 && INTVAL (operands[2]) >= 0
8629 /* Ensure that resulting mask is zero or sign extended operand. */
8630 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8631 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8632 && INTVAL (operands[1]) > 32))
8633 && (GET_MODE (operands[0]) == SImode
8634 || GET_MODE (operands[0]) == DImode
8635 || GET_MODE (operands[0]) == HImode
8636 || GET_MODE (operands[0]) == QImode)"
8640 [(set (match_operand 0 "flags_reg_operand" "")
8641 (match_operator 1 "compare_operator"
8643 (match_operand 2 "nonimmediate_operand" "")
8644 (match_operand 3 "const_int_operand" "")
8645 (match_operand 4 "const_int_operand" ""))
8647 "ix86_match_ccmode (insn, CCNOmode)"
8648 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8650 rtx val = operands[2];
8651 HOST_WIDE_INT len = INTVAL (operands[3]);
8652 HOST_WIDE_INT pos = INTVAL (operands[4]);
8654 enum machine_mode mode, submode;
8656 mode = GET_MODE (val);
8659 /* ??? Combine likes to put non-volatile mem extractions in QImode
8660 no matter the size of the test. So find a mode that works. */
8661 if (! MEM_VOLATILE_P (val))
8663 mode = smallest_mode_for_size (pos + len, MODE_INT);
8664 val = adjust_address (val, mode, 0);
8667 else if (GET_CODE (val) == SUBREG
8668 && (submode = GET_MODE (SUBREG_REG (val)),
8669 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8670 && pos + len <= GET_MODE_BITSIZE (submode))
8672 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8674 val = SUBREG_REG (val);
8676 else if (mode == HImode && pos + len <= 8)
8678 /* Small HImode tests can be converted to QImode. */
8680 val = gen_lowpart (QImode, val);
8683 if (len == HOST_BITS_PER_WIDE_INT)
8686 mask = ((HOST_WIDE_INT)1 << len) - 1;
8689 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8692 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8693 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8694 ;; this is relatively important trick.
8695 ;; Do the conversion only post-reload to avoid limiting of the register class
8698 [(set (match_operand 0 "flags_reg_operand" "")
8699 (match_operator 1 "compare_operator"
8700 [(and (match_operand 2 "register_operand" "")
8701 (match_operand 3 "const_int_operand" ""))
8704 && QI_REG_P (operands[2])
8705 && GET_MODE (operands[2]) != QImode
8706 && ((ix86_match_ccmode (insn, CCZmode)
8707 && !(INTVAL (operands[3]) & ~(255 << 8)))
8708 || (ix86_match_ccmode (insn, CCNOmode)
8709 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8712 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8715 "operands[2] = gen_lowpart (SImode, operands[2]);
8716 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8719 [(set (match_operand 0 "flags_reg_operand" "")
8720 (match_operator 1 "compare_operator"
8721 [(and (match_operand 2 "nonimmediate_operand" "")
8722 (match_operand 3 "const_int_operand" ""))
8725 && GET_MODE (operands[2]) != QImode
8726 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8727 && ((ix86_match_ccmode (insn, CCZmode)
8728 && !(INTVAL (operands[3]) & ~255))
8729 || (ix86_match_ccmode (insn, CCNOmode)
8730 && !(INTVAL (operands[3]) & ~127)))"
8732 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8734 "operands[2] = gen_lowpart (QImode, operands[2]);
8735 operands[3] = gen_lowpart (QImode, operands[3]);")
8738 ;; %%% This used to optimize known byte-wide and operations to memory,
8739 ;; and sometimes to QImode registers. If this is considered useful,
8740 ;; it should be done with splitters.
8742 (define_expand "anddi3"
8743 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8744 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8745 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8746 (clobber (reg:CC FLAGS_REG))]
8748 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8750 (define_insn "*anddi_1_rex64"
8751 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8752 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8753 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8754 (clobber (reg:CC FLAGS_REG))]
8755 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8757 switch (get_attr_type (insn))
8761 enum machine_mode mode;
8763 gcc_assert (CONST_INT_P (operands[2]));
8764 if (INTVAL (operands[2]) == 0xff)
8768 gcc_assert (INTVAL (operands[2]) == 0xffff);
8772 operands[1] = gen_lowpart (mode, operands[1]);
8774 return "movz{bq|x}\t{%1,%0|%0, %1}";
8776 return "movz{wq|x}\t{%1,%0|%0, %1}";
8780 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8781 if (get_attr_mode (insn) == MODE_SI)
8782 return "and{l}\t{%k2, %k0|%k0, %k2}";
8784 return "and{q}\t{%2, %0|%0, %2}";
8787 [(set_attr "type" "alu,alu,alu,imovx")
8788 (set_attr "length_immediate" "*,*,*,0")
8789 (set_attr "mode" "SI,DI,DI,DI")])
8791 (define_insn "*anddi_2"
8792 [(set (reg FLAGS_REG)
8793 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8794 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8796 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8797 (and:DI (match_dup 1) (match_dup 2)))]
8798 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8799 && ix86_binary_operator_ok (AND, DImode, operands)"
8801 and{l}\t{%k2, %k0|%k0, %k2}
8802 and{q}\t{%2, %0|%0, %2}
8803 and{q}\t{%2, %0|%0, %2}"
8804 [(set_attr "type" "alu")
8805 (set_attr "mode" "SI,DI,DI")])
8807 (define_expand "andsi3"
8808 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8809 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8810 (match_operand:SI 2 "general_operand" "")))
8811 (clobber (reg:CC FLAGS_REG))]
8813 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8815 (define_insn "*andsi_1"
8816 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8817 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8818 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8819 (clobber (reg:CC FLAGS_REG))]
8820 "ix86_binary_operator_ok (AND, SImode, operands)"
8822 switch (get_attr_type (insn))
8826 enum machine_mode mode;
8828 gcc_assert (CONST_INT_P (operands[2]));
8829 if (INTVAL (operands[2]) == 0xff)
8833 gcc_assert (INTVAL (operands[2]) == 0xffff);
8837 operands[1] = gen_lowpart (mode, operands[1]);
8839 return "movz{bl|x}\t{%1,%0|%0, %1}";
8841 return "movz{wl|x}\t{%1,%0|%0, %1}";
8845 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8846 return "and{l}\t{%2, %0|%0, %2}";
8849 [(set_attr "type" "alu,alu,imovx")
8850 (set_attr "length_immediate" "*,*,0")
8851 (set_attr "mode" "SI")])
8854 [(set (match_operand 0 "register_operand" "")
8856 (const_int -65536)))
8857 (clobber (reg:CC FLAGS_REG))]
8858 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8859 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8860 "operands[1] = gen_lowpart (HImode, operands[0]);")
8863 [(set (match_operand 0 "ext_register_operand" "")
8866 (clobber (reg:CC FLAGS_REG))]
8867 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8868 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8869 "operands[1] = gen_lowpart (QImode, operands[0]);")
8872 [(set (match_operand 0 "ext_register_operand" "")
8874 (const_int -65281)))
8875 (clobber (reg:CC FLAGS_REG))]
8876 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8877 [(parallel [(set (zero_extract:SI (match_dup 0)
8881 (zero_extract:SI (match_dup 0)
8884 (zero_extract:SI (match_dup 0)
8887 (clobber (reg:CC FLAGS_REG))])]
8888 "operands[0] = gen_lowpart (SImode, operands[0]);")
8890 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8891 (define_insn "*andsi_1_zext"
8892 [(set (match_operand:DI 0 "register_operand" "=r")
8894 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8895 (match_operand:SI 2 "general_operand" "g"))))
8896 (clobber (reg:CC FLAGS_REG))]
8897 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8898 "and{l}\t{%2, %k0|%k0, %2}"
8899 [(set_attr "type" "alu")
8900 (set_attr "mode" "SI")])
8902 (define_insn "*andsi_2"
8903 [(set (reg FLAGS_REG)
8904 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8905 (match_operand:SI 2 "general_operand" "g,ri"))
8907 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8908 (and:SI (match_dup 1) (match_dup 2)))]
8909 "ix86_match_ccmode (insn, CCNOmode)
8910 && ix86_binary_operator_ok (AND, SImode, operands)"
8911 "and{l}\t{%2, %0|%0, %2}"
8912 [(set_attr "type" "alu")
8913 (set_attr "mode" "SI")])
8915 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8916 (define_insn "*andsi_2_zext"
8917 [(set (reg FLAGS_REG)
8918 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8919 (match_operand:SI 2 "general_operand" "g"))
8921 (set (match_operand:DI 0 "register_operand" "=r")
8922 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8923 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8924 && ix86_binary_operator_ok (AND, SImode, operands)"
8925 "and{l}\t{%2, %k0|%k0, %2}"
8926 [(set_attr "type" "alu")
8927 (set_attr "mode" "SI")])
8929 (define_expand "andhi3"
8930 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8931 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8932 (match_operand:HI 2 "general_operand" "")))
8933 (clobber (reg:CC FLAGS_REG))]
8934 "TARGET_HIMODE_MATH"
8935 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8937 (define_insn "*andhi_1"
8938 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8939 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8940 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8941 (clobber (reg:CC FLAGS_REG))]
8942 "ix86_binary_operator_ok (AND, HImode, operands)"
8944 switch (get_attr_type (insn))
8947 gcc_assert (CONST_INT_P (operands[2]));
8948 gcc_assert (INTVAL (operands[2]) == 0xff);
8949 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8952 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8954 return "and{w}\t{%2, %0|%0, %2}";
8957 [(set_attr "type" "alu,alu,imovx")
8958 (set_attr "length_immediate" "*,*,0")
8959 (set_attr "mode" "HI,HI,SI")])
8961 (define_insn "*andhi_2"
8962 [(set (reg FLAGS_REG)
8963 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8964 (match_operand:HI 2 "general_operand" "g,ri"))
8966 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8967 (and:HI (match_dup 1) (match_dup 2)))]
8968 "ix86_match_ccmode (insn, CCNOmode)
8969 && ix86_binary_operator_ok (AND, HImode, operands)"
8970 "and{w}\t{%2, %0|%0, %2}"
8971 [(set_attr "type" "alu")
8972 (set_attr "mode" "HI")])
8974 (define_expand "andqi3"
8975 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8976 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8977 (match_operand:QI 2 "general_operand" "")))
8978 (clobber (reg:CC FLAGS_REG))]
8979 "TARGET_QIMODE_MATH"
8980 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8982 ;; %%% Potential partial reg stall on alternative 2. What to do?
8983 (define_insn "*andqi_1"
8984 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8985 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8986 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8987 (clobber (reg:CC FLAGS_REG))]
8988 "ix86_binary_operator_ok (AND, QImode, operands)"
8990 and{b}\t{%2, %0|%0, %2}
8991 and{b}\t{%2, %0|%0, %2}
8992 and{l}\t{%k2, %k0|%k0, %k2}"
8993 [(set_attr "type" "alu")
8994 (set_attr "mode" "QI,QI,SI")])
8996 (define_insn "*andqi_1_slp"
8997 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8998 (and:QI (match_dup 0)
8999 (match_operand:QI 1 "general_operand" "qi,qmi")))
9000 (clobber (reg:CC FLAGS_REG))]
9001 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9002 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9003 "and{b}\t{%1, %0|%0, %1}"
9004 [(set_attr "type" "alu1")
9005 (set_attr "mode" "QI")])
9007 (define_insn "*andqi_2_maybe_si"
9008 [(set (reg FLAGS_REG)
9010 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9011 (match_operand:QI 2 "general_operand" "qim,qi,i"))
9013 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9014 (and:QI (match_dup 1) (match_dup 2)))]
9015 "ix86_binary_operator_ok (AND, QImode, operands)
9016 && ix86_match_ccmode (insn,
9017 CONST_INT_P (operands[2])
9018 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9020 if (which_alternative == 2)
9022 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9023 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9024 return "and{l}\t{%2, %k0|%k0, %2}";
9026 return "and{b}\t{%2, %0|%0, %2}";
9028 [(set_attr "type" "alu")
9029 (set_attr "mode" "QI,QI,SI")])
9031 (define_insn "*andqi_2"
9032 [(set (reg FLAGS_REG)
9034 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9035 (match_operand:QI 2 "general_operand" "qim,qi"))
9037 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9038 (and:QI (match_dup 1) (match_dup 2)))]
9039 "ix86_match_ccmode (insn, CCNOmode)
9040 && ix86_binary_operator_ok (AND, QImode, operands)"
9041 "and{b}\t{%2, %0|%0, %2}"
9042 [(set_attr "type" "alu")
9043 (set_attr "mode" "QI")])
9045 (define_insn "*andqi_2_slp"
9046 [(set (reg FLAGS_REG)
9048 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9049 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9051 (set (strict_low_part (match_dup 0))
9052 (and:QI (match_dup 0) (match_dup 1)))]
9053 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9054 && ix86_match_ccmode (insn, CCNOmode)
9055 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9056 "and{b}\t{%1, %0|%0, %1}"
9057 [(set_attr "type" "alu1")
9058 (set_attr "mode" "QI")])
9060 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9061 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9062 ;; for a QImode operand, which of course failed.
9064 (define_insn "andqi_ext_0"
9065 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9070 (match_operand 1 "ext_register_operand" "0")
9073 (match_operand 2 "const_int_operand" "n")))
9074 (clobber (reg:CC FLAGS_REG))]
9076 "and{b}\t{%2, %h0|%h0, %2}"
9077 [(set_attr "type" "alu")
9078 (set_attr "length_immediate" "1")
9079 (set_attr "mode" "QI")])
9081 ;; Generated by peephole translating test to and. This shows up
9082 ;; often in fp comparisons.
9084 (define_insn "*andqi_ext_0_cc"
9085 [(set (reg FLAGS_REG)
9089 (match_operand 1 "ext_register_operand" "0")
9092 (match_operand 2 "const_int_operand" "n"))
9094 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9103 "ix86_match_ccmode (insn, CCNOmode)"
9104 "and{b}\t{%2, %h0|%h0, %2}"
9105 [(set_attr "type" "alu")
9106 (set_attr "length_immediate" "1")
9107 (set_attr "mode" "QI")])
9109 (define_insn "*andqi_ext_1"
9110 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9115 (match_operand 1 "ext_register_operand" "0")
9119 (match_operand:QI 2 "general_operand" "Qm"))))
9120 (clobber (reg:CC FLAGS_REG))]
9122 "and{b}\t{%2, %h0|%h0, %2}"
9123 [(set_attr "type" "alu")
9124 (set_attr "length_immediate" "0")
9125 (set_attr "mode" "QI")])
9127 (define_insn "*andqi_ext_1_rex64"
9128 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9133 (match_operand 1 "ext_register_operand" "0")
9137 (match_operand 2 "ext_register_operand" "Q"))))
9138 (clobber (reg:CC FLAGS_REG))]
9140 "and{b}\t{%2, %h0|%h0, %2}"
9141 [(set_attr "type" "alu")
9142 (set_attr "length_immediate" "0")
9143 (set_attr "mode" "QI")])
9145 (define_insn "*andqi_ext_2"
9146 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9151 (match_operand 1 "ext_register_operand" "%0")
9155 (match_operand 2 "ext_register_operand" "Q")
9158 (clobber (reg:CC FLAGS_REG))]
9160 "and{b}\t{%h2, %h0|%h0, %h2}"
9161 [(set_attr "type" "alu")
9162 (set_attr "length_immediate" "0")
9163 (set_attr "mode" "QI")])
9165 ;; Convert wide AND instructions with immediate operand to shorter QImode
9166 ;; equivalents when possible.
9167 ;; Don't do the splitting with memory operands, since it introduces risk
9168 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9169 ;; for size, but that can (should?) be handled by generic code instead.
9171 [(set (match_operand 0 "register_operand" "")
9172 (and (match_operand 1 "register_operand" "")
9173 (match_operand 2 "const_int_operand" "")))
9174 (clobber (reg:CC FLAGS_REG))]
9176 && QI_REG_P (operands[0])
9177 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9178 && !(~INTVAL (operands[2]) & ~(255 << 8))
9179 && GET_MODE (operands[0]) != QImode"
9180 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9181 (and:SI (zero_extract:SI (match_dup 1)
9182 (const_int 8) (const_int 8))
9184 (clobber (reg:CC FLAGS_REG))])]
9185 "operands[0] = gen_lowpart (SImode, operands[0]);
9186 operands[1] = gen_lowpart (SImode, operands[1]);
9187 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9189 ;; Since AND can be encoded with sign extended immediate, this is only
9190 ;; profitable when 7th bit is not set.
9192 [(set (match_operand 0 "register_operand" "")
9193 (and (match_operand 1 "general_operand" "")
9194 (match_operand 2 "const_int_operand" "")))
9195 (clobber (reg:CC FLAGS_REG))]
9197 && ANY_QI_REG_P (operands[0])
9198 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9199 && !(~INTVAL (operands[2]) & ~255)
9200 && !(INTVAL (operands[2]) & 128)
9201 && GET_MODE (operands[0]) != QImode"
9202 [(parallel [(set (strict_low_part (match_dup 0))
9203 (and:QI (match_dup 1)
9205 (clobber (reg:CC FLAGS_REG))])]
9206 "operands[0] = gen_lowpart (QImode, operands[0]);
9207 operands[1] = gen_lowpart (QImode, operands[1]);
9208 operands[2] = gen_lowpart (QImode, operands[2]);")
9210 ;; Logical inclusive OR instructions
9212 ;; %%% This used to optimize known byte-wide and operations to memory.
9213 ;; If this is considered useful, it should be done with splitters.
9215 (define_expand "iordi3"
9216 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9217 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9218 (match_operand:DI 2 "x86_64_general_operand" "")))
9219 (clobber (reg:CC FLAGS_REG))]
9221 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9223 (define_insn "*iordi_1_rex64"
9224 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9225 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9226 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9227 (clobber (reg:CC FLAGS_REG))]
9229 && ix86_binary_operator_ok (IOR, DImode, operands)"
9230 "or{q}\t{%2, %0|%0, %2}"
9231 [(set_attr "type" "alu")
9232 (set_attr "mode" "DI")])
9234 (define_insn "*iordi_2_rex64"
9235 [(set (reg FLAGS_REG)
9236 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9237 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9239 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9240 (ior:DI (match_dup 1) (match_dup 2)))]
9242 && ix86_match_ccmode (insn, CCNOmode)
9243 && ix86_binary_operator_ok (IOR, DImode, operands)"
9244 "or{q}\t{%2, %0|%0, %2}"
9245 [(set_attr "type" "alu")
9246 (set_attr "mode" "DI")])
9248 (define_insn "*iordi_3_rex64"
9249 [(set (reg FLAGS_REG)
9250 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9251 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9253 (clobber (match_scratch:DI 0 "=r"))]
9255 && ix86_match_ccmode (insn, CCNOmode)
9256 && ix86_binary_operator_ok (IOR, DImode, operands)"
9257 "or{q}\t{%2, %0|%0, %2}"
9258 [(set_attr "type" "alu")
9259 (set_attr "mode" "DI")])
9262 (define_expand "iorsi3"
9263 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9264 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9265 (match_operand:SI 2 "general_operand" "")))
9266 (clobber (reg:CC FLAGS_REG))]
9268 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9270 (define_insn "*iorsi_1"
9271 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9272 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9273 (match_operand:SI 2 "general_operand" "ri,g")))
9274 (clobber (reg:CC FLAGS_REG))]
9275 "ix86_binary_operator_ok (IOR, SImode, operands)"
9276 "or{l}\t{%2, %0|%0, %2}"
9277 [(set_attr "type" "alu")
9278 (set_attr "mode" "SI")])
9280 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9281 (define_insn "*iorsi_1_zext"
9282 [(set (match_operand:DI 0 "register_operand" "=r")
9284 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9285 (match_operand:SI 2 "general_operand" "g"))))
9286 (clobber (reg:CC FLAGS_REG))]
9287 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9288 "or{l}\t{%2, %k0|%k0, %2}"
9289 [(set_attr "type" "alu")
9290 (set_attr "mode" "SI")])
9292 (define_insn "*iorsi_1_zext_imm"
9293 [(set (match_operand:DI 0 "register_operand" "=r")
9294 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9295 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9296 (clobber (reg:CC FLAGS_REG))]
9298 "or{l}\t{%2, %k0|%k0, %2}"
9299 [(set_attr "type" "alu")
9300 (set_attr "mode" "SI")])
9302 (define_insn "*iorsi_2"
9303 [(set (reg FLAGS_REG)
9304 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9305 (match_operand:SI 2 "general_operand" "g,ri"))
9307 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9308 (ior:SI (match_dup 1) (match_dup 2)))]
9309 "ix86_match_ccmode (insn, CCNOmode)
9310 && ix86_binary_operator_ok (IOR, SImode, operands)"
9311 "or{l}\t{%2, %0|%0, %2}"
9312 [(set_attr "type" "alu")
9313 (set_attr "mode" "SI")])
9315 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9316 ;; ??? Special case for immediate operand is missing - it is tricky.
9317 (define_insn "*iorsi_2_zext"
9318 [(set (reg FLAGS_REG)
9319 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9320 (match_operand:SI 2 "general_operand" "g"))
9322 (set (match_operand:DI 0 "register_operand" "=r")
9323 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9324 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9325 && ix86_binary_operator_ok (IOR, SImode, operands)"
9326 "or{l}\t{%2, %k0|%k0, %2}"
9327 [(set_attr "type" "alu")
9328 (set_attr "mode" "SI")])
9330 (define_insn "*iorsi_2_zext_imm"
9331 [(set (reg FLAGS_REG)
9332 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9333 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9335 (set (match_operand:DI 0 "register_operand" "=r")
9336 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9337 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9338 && ix86_binary_operator_ok (IOR, SImode, operands)"
9339 "or{l}\t{%2, %k0|%k0, %2}"
9340 [(set_attr "type" "alu")
9341 (set_attr "mode" "SI")])
9343 (define_insn "*iorsi_3"
9344 [(set (reg FLAGS_REG)
9345 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9346 (match_operand:SI 2 "general_operand" "g"))
9348 (clobber (match_scratch:SI 0 "=r"))]
9349 "ix86_match_ccmode (insn, CCNOmode)
9350 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9351 "or{l}\t{%2, %0|%0, %2}"
9352 [(set_attr "type" "alu")
9353 (set_attr "mode" "SI")])
9355 (define_expand "iorhi3"
9356 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9357 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9358 (match_operand:HI 2 "general_operand" "")))
9359 (clobber (reg:CC FLAGS_REG))]
9360 "TARGET_HIMODE_MATH"
9361 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9363 (define_insn "*iorhi_1"
9364 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9365 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9366 (match_operand:HI 2 "general_operand" "g,ri")))
9367 (clobber (reg:CC FLAGS_REG))]
9368 "ix86_binary_operator_ok (IOR, HImode, operands)"
9369 "or{w}\t{%2, %0|%0, %2}"
9370 [(set_attr "type" "alu")
9371 (set_attr "mode" "HI")])
9373 (define_insn "*iorhi_2"
9374 [(set (reg FLAGS_REG)
9375 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9376 (match_operand:HI 2 "general_operand" "g,ri"))
9378 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9379 (ior:HI (match_dup 1) (match_dup 2)))]
9380 "ix86_match_ccmode (insn, CCNOmode)
9381 && ix86_binary_operator_ok (IOR, HImode, operands)"
9382 "or{w}\t{%2, %0|%0, %2}"
9383 [(set_attr "type" "alu")
9384 (set_attr "mode" "HI")])
9386 (define_insn "*iorhi_3"
9387 [(set (reg FLAGS_REG)
9388 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9389 (match_operand:HI 2 "general_operand" "g"))
9391 (clobber (match_scratch:HI 0 "=r"))]
9392 "ix86_match_ccmode (insn, CCNOmode)
9393 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9394 "or{w}\t{%2, %0|%0, %2}"
9395 [(set_attr "type" "alu")
9396 (set_attr "mode" "HI")])
9398 (define_expand "iorqi3"
9399 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9400 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9401 (match_operand:QI 2 "general_operand" "")))
9402 (clobber (reg:CC FLAGS_REG))]
9403 "TARGET_QIMODE_MATH"
9404 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9406 ;; %%% Potential partial reg stall on alternative 2. What to do?
9407 (define_insn "*iorqi_1"
9408 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9409 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9410 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9411 (clobber (reg:CC FLAGS_REG))]
9412 "ix86_binary_operator_ok (IOR, QImode, operands)"
9414 or{b}\t{%2, %0|%0, %2}
9415 or{b}\t{%2, %0|%0, %2}
9416 or{l}\t{%k2, %k0|%k0, %k2}"
9417 [(set_attr "type" "alu")
9418 (set_attr "mode" "QI,QI,SI")])
9420 (define_insn "*iorqi_1_slp"
9421 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9422 (ior:QI (match_dup 0)
9423 (match_operand:QI 1 "general_operand" "qmi,qi")))
9424 (clobber (reg:CC FLAGS_REG))]
9425 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9426 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9427 "or{b}\t{%1, %0|%0, %1}"
9428 [(set_attr "type" "alu1")
9429 (set_attr "mode" "QI")])
9431 (define_insn "*iorqi_2"
9432 [(set (reg FLAGS_REG)
9433 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9434 (match_operand:QI 2 "general_operand" "qim,qi"))
9436 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9437 (ior:QI (match_dup 1) (match_dup 2)))]
9438 "ix86_match_ccmode (insn, CCNOmode)
9439 && ix86_binary_operator_ok (IOR, QImode, operands)"
9440 "or{b}\t{%2, %0|%0, %2}"
9441 [(set_attr "type" "alu")
9442 (set_attr "mode" "QI")])
9444 (define_insn "*iorqi_2_slp"
9445 [(set (reg FLAGS_REG)
9446 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9447 (match_operand:QI 1 "general_operand" "qim,qi"))
9449 (set (strict_low_part (match_dup 0))
9450 (ior:QI (match_dup 0) (match_dup 1)))]
9451 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9452 && ix86_match_ccmode (insn, CCNOmode)
9453 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9454 "or{b}\t{%1, %0|%0, %1}"
9455 [(set_attr "type" "alu1")
9456 (set_attr "mode" "QI")])
9458 (define_insn "*iorqi_3"
9459 [(set (reg FLAGS_REG)
9460 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9461 (match_operand:QI 2 "general_operand" "qim"))
9463 (clobber (match_scratch:QI 0 "=q"))]
9464 "ix86_match_ccmode (insn, CCNOmode)
9465 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9466 "or{b}\t{%2, %0|%0, %2}"
9467 [(set_attr "type" "alu")
9468 (set_attr "mode" "QI")])
9470 (define_insn "iorqi_ext_0"
9471 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9476 (match_operand 1 "ext_register_operand" "0")
9479 (match_operand 2 "const_int_operand" "n")))
9480 (clobber (reg:CC FLAGS_REG))]
9481 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9482 "or{b}\t{%2, %h0|%h0, %2}"
9483 [(set_attr "type" "alu")
9484 (set_attr "length_immediate" "1")
9485 (set_attr "mode" "QI")])
9487 (define_insn "*iorqi_ext_1"
9488 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9493 (match_operand 1 "ext_register_operand" "0")
9497 (match_operand:QI 2 "general_operand" "Qm"))))
9498 (clobber (reg:CC FLAGS_REG))]
9500 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9501 "or{b}\t{%2, %h0|%h0, %2}"
9502 [(set_attr "type" "alu")
9503 (set_attr "length_immediate" "0")
9504 (set_attr "mode" "QI")])
9506 (define_insn "*iorqi_ext_1_rex64"
9507 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9512 (match_operand 1 "ext_register_operand" "0")
9516 (match_operand 2 "ext_register_operand" "Q"))))
9517 (clobber (reg:CC FLAGS_REG))]
9519 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9520 "or{b}\t{%2, %h0|%h0, %2}"
9521 [(set_attr "type" "alu")
9522 (set_attr "length_immediate" "0")
9523 (set_attr "mode" "QI")])
9525 (define_insn "*iorqi_ext_2"
9526 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9530 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9533 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9536 (clobber (reg:CC FLAGS_REG))]
9537 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9538 "ior{b}\t{%h2, %h0|%h0, %h2}"
9539 [(set_attr "type" "alu")
9540 (set_attr "length_immediate" "0")
9541 (set_attr "mode" "QI")])
9544 [(set (match_operand 0 "register_operand" "")
9545 (ior (match_operand 1 "register_operand" "")
9546 (match_operand 2 "const_int_operand" "")))
9547 (clobber (reg:CC FLAGS_REG))]
9549 && QI_REG_P (operands[0])
9550 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9551 && !(INTVAL (operands[2]) & ~(255 << 8))
9552 && GET_MODE (operands[0]) != QImode"
9553 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9554 (ior:SI (zero_extract:SI (match_dup 1)
9555 (const_int 8) (const_int 8))
9557 (clobber (reg:CC FLAGS_REG))])]
9558 "operands[0] = gen_lowpart (SImode, operands[0]);
9559 operands[1] = gen_lowpart (SImode, operands[1]);
9560 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9562 ;; Since OR can be encoded with sign extended immediate, this is only
9563 ;; profitable when 7th bit is set.
9565 [(set (match_operand 0 "register_operand" "")
9566 (ior (match_operand 1 "general_operand" "")
9567 (match_operand 2 "const_int_operand" "")))
9568 (clobber (reg:CC FLAGS_REG))]
9570 && ANY_QI_REG_P (operands[0])
9571 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9572 && !(INTVAL (operands[2]) & ~255)
9573 && (INTVAL (operands[2]) & 128)
9574 && GET_MODE (operands[0]) != QImode"
9575 [(parallel [(set (strict_low_part (match_dup 0))
9576 (ior:QI (match_dup 1)
9578 (clobber (reg:CC FLAGS_REG))])]
9579 "operands[0] = gen_lowpart (QImode, operands[0]);
9580 operands[1] = gen_lowpart (QImode, operands[1]);
9581 operands[2] = gen_lowpart (QImode, operands[2]);")
9583 ;; Logical XOR instructions
9585 ;; %%% This used to optimize known byte-wide and operations to memory.
9586 ;; If this is considered useful, it should be done with splitters.
9588 (define_expand "xordi3"
9589 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9590 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9591 (match_operand:DI 2 "x86_64_general_operand" "")))
9592 (clobber (reg:CC FLAGS_REG))]
9594 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9596 (define_insn "*xordi_1_rex64"
9597 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9598 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9599 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9600 (clobber (reg:CC FLAGS_REG))]
9602 && ix86_binary_operator_ok (XOR, DImode, operands)"
9604 xor{q}\t{%2, %0|%0, %2}
9605 xor{q}\t{%2, %0|%0, %2}"
9606 [(set_attr "type" "alu")
9607 (set_attr "mode" "DI,DI")])
9609 (define_insn "*xordi_2_rex64"
9610 [(set (reg FLAGS_REG)
9611 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9612 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9614 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9615 (xor:DI (match_dup 1) (match_dup 2)))]
9617 && ix86_match_ccmode (insn, CCNOmode)
9618 && ix86_binary_operator_ok (XOR, DImode, operands)"
9620 xor{q}\t{%2, %0|%0, %2}
9621 xor{q}\t{%2, %0|%0, %2}"
9622 [(set_attr "type" "alu")
9623 (set_attr "mode" "DI,DI")])
9625 (define_insn "*xordi_3_rex64"
9626 [(set (reg FLAGS_REG)
9627 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9628 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9630 (clobber (match_scratch:DI 0 "=r"))]
9632 && ix86_match_ccmode (insn, CCNOmode)
9633 && ix86_binary_operator_ok (XOR, DImode, operands)"
9634 "xor{q}\t{%2, %0|%0, %2}"
9635 [(set_attr "type" "alu")
9636 (set_attr "mode" "DI")])
9638 (define_expand "xorsi3"
9639 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9640 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9641 (match_operand:SI 2 "general_operand" "")))
9642 (clobber (reg:CC FLAGS_REG))]
9644 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9646 (define_insn "*xorsi_1"
9647 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9648 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9649 (match_operand:SI 2 "general_operand" "ri,rm")))
9650 (clobber (reg:CC FLAGS_REG))]
9651 "ix86_binary_operator_ok (XOR, SImode, operands)"
9652 "xor{l}\t{%2, %0|%0, %2}"
9653 [(set_attr "type" "alu")
9654 (set_attr "mode" "SI")])
9656 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9657 ;; Add speccase for immediates
9658 (define_insn "*xorsi_1_zext"
9659 [(set (match_operand:DI 0 "register_operand" "=r")
9661 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9662 (match_operand:SI 2 "general_operand" "g"))))
9663 (clobber (reg:CC FLAGS_REG))]
9664 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9665 "xor{l}\t{%2, %k0|%k0, %2}"
9666 [(set_attr "type" "alu")
9667 (set_attr "mode" "SI")])
9669 (define_insn "*xorsi_1_zext_imm"
9670 [(set (match_operand:DI 0 "register_operand" "=r")
9671 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9672 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9673 (clobber (reg:CC FLAGS_REG))]
9674 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9675 "xor{l}\t{%2, %k0|%k0, %2}"
9676 [(set_attr "type" "alu")
9677 (set_attr "mode" "SI")])
9679 (define_insn "*xorsi_2"
9680 [(set (reg FLAGS_REG)
9681 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9682 (match_operand:SI 2 "general_operand" "g,ri"))
9684 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9685 (xor:SI (match_dup 1) (match_dup 2)))]
9686 "ix86_match_ccmode (insn, CCNOmode)
9687 && ix86_binary_operator_ok (XOR, SImode, operands)"
9688 "xor{l}\t{%2, %0|%0, %2}"
9689 [(set_attr "type" "alu")
9690 (set_attr "mode" "SI")])
9692 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9693 ;; ??? Special case for immediate operand is missing - it is tricky.
9694 (define_insn "*xorsi_2_zext"
9695 [(set (reg FLAGS_REG)
9696 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9697 (match_operand:SI 2 "general_operand" "g"))
9699 (set (match_operand:DI 0 "register_operand" "=r")
9700 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9701 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9702 && ix86_binary_operator_ok (XOR, SImode, operands)"
9703 "xor{l}\t{%2, %k0|%k0, %2}"
9704 [(set_attr "type" "alu")
9705 (set_attr "mode" "SI")])
9707 (define_insn "*xorsi_2_zext_imm"
9708 [(set (reg FLAGS_REG)
9709 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9710 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9712 (set (match_operand:DI 0 "register_operand" "=r")
9713 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9714 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9715 && ix86_binary_operator_ok (XOR, SImode, operands)"
9716 "xor{l}\t{%2, %k0|%k0, %2}"
9717 [(set_attr "type" "alu")
9718 (set_attr "mode" "SI")])
9720 (define_insn "*xorsi_3"
9721 [(set (reg FLAGS_REG)
9722 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9723 (match_operand:SI 2 "general_operand" "g"))
9725 (clobber (match_scratch:SI 0 "=r"))]
9726 "ix86_match_ccmode (insn, CCNOmode)
9727 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9728 "xor{l}\t{%2, %0|%0, %2}"
9729 [(set_attr "type" "alu")
9730 (set_attr "mode" "SI")])
9732 (define_expand "xorhi3"
9733 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9734 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9735 (match_operand:HI 2 "general_operand" "")))
9736 (clobber (reg:CC FLAGS_REG))]
9737 "TARGET_HIMODE_MATH"
9738 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9740 (define_insn "*xorhi_1"
9741 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9742 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9743 (match_operand:HI 2 "general_operand" "g,ri")))
9744 (clobber (reg:CC FLAGS_REG))]
9745 "ix86_binary_operator_ok (XOR, HImode, operands)"
9746 "xor{w}\t{%2, %0|%0, %2}"
9747 [(set_attr "type" "alu")
9748 (set_attr "mode" "HI")])
9750 (define_insn "*xorhi_2"
9751 [(set (reg FLAGS_REG)
9752 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9753 (match_operand:HI 2 "general_operand" "g,ri"))
9755 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9756 (xor:HI (match_dup 1) (match_dup 2)))]
9757 "ix86_match_ccmode (insn, CCNOmode)
9758 && ix86_binary_operator_ok (XOR, HImode, operands)"
9759 "xor{w}\t{%2, %0|%0, %2}"
9760 [(set_attr "type" "alu")
9761 (set_attr "mode" "HI")])
9763 (define_insn "*xorhi_3"
9764 [(set (reg FLAGS_REG)
9765 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9766 (match_operand:HI 2 "general_operand" "g"))
9768 (clobber (match_scratch:HI 0 "=r"))]
9769 "ix86_match_ccmode (insn, CCNOmode)
9770 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9771 "xor{w}\t{%2, %0|%0, %2}"
9772 [(set_attr "type" "alu")
9773 (set_attr "mode" "HI")])
9775 (define_expand "xorqi3"
9776 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9777 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9778 (match_operand:QI 2 "general_operand" "")))
9779 (clobber (reg:CC FLAGS_REG))]
9780 "TARGET_QIMODE_MATH"
9781 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9783 ;; %%% Potential partial reg stall on alternative 2. What to do?
9784 (define_insn "*xorqi_1"
9785 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9786 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9787 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9788 (clobber (reg:CC FLAGS_REG))]
9789 "ix86_binary_operator_ok (XOR, QImode, operands)"
9791 xor{b}\t{%2, %0|%0, %2}
9792 xor{b}\t{%2, %0|%0, %2}
9793 xor{l}\t{%k2, %k0|%k0, %k2}"
9794 [(set_attr "type" "alu")
9795 (set_attr "mode" "QI,QI,SI")])
9797 (define_insn "*xorqi_1_slp"
9798 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9799 (xor:QI (match_dup 0)
9800 (match_operand:QI 1 "general_operand" "qi,qmi")))
9801 (clobber (reg:CC FLAGS_REG))]
9802 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9803 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9804 "xor{b}\t{%1, %0|%0, %1}"
9805 [(set_attr "type" "alu1")
9806 (set_attr "mode" "QI")])
9808 (define_insn "xorqi_ext_0"
9809 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9814 (match_operand 1 "ext_register_operand" "0")
9817 (match_operand 2 "const_int_operand" "n")))
9818 (clobber (reg:CC FLAGS_REG))]
9819 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9820 "xor{b}\t{%2, %h0|%h0, %2}"
9821 [(set_attr "type" "alu")
9822 (set_attr "length_immediate" "1")
9823 (set_attr "mode" "QI")])
9825 (define_insn "*xorqi_ext_1"
9826 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9831 (match_operand 1 "ext_register_operand" "0")
9835 (match_operand:QI 2 "general_operand" "Qm"))))
9836 (clobber (reg:CC FLAGS_REG))]
9838 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9839 "xor{b}\t{%2, %h0|%h0, %2}"
9840 [(set_attr "type" "alu")
9841 (set_attr "length_immediate" "0")
9842 (set_attr "mode" "QI")])
9844 (define_insn "*xorqi_ext_1_rex64"
9845 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9850 (match_operand 1 "ext_register_operand" "0")
9854 (match_operand 2 "ext_register_operand" "Q"))))
9855 (clobber (reg:CC FLAGS_REG))]
9857 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9858 "xor{b}\t{%2, %h0|%h0, %2}"
9859 [(set_attr "type" "alu")
9860 (set_attr "length_immediate" "0")
9861 (set_attr "mode" "QI")])
9863 (define_insn "*xorqi_ext_2"
9864 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9868 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9871 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9874 (clobber (reg:CC FLAGS_REG))]
9875 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9876 "xor{b}\t{%h2, %h0|%h0, %h2}"
9877 [(set_attr "type" "alu")
9878 (set_attr "length_immediate" "0")
9879 (set_attr "mode" "QI")])
9881 (define_insn "*xorqi_cc_1"
9882 [(set (reg FLAGS_REG)
9884 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9885 (match_operand:QI 2 "general_operand" "qim,qi"))
9887 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9888 (xor:QI (match_dup 1) (match_dup 2)))]
9889 "ix86_match_ccmode (insn, CCNOmode)
9890 && ix86_binary_operator_ok (XOR, QImode, operands)"
9891 "xor{b}\t{%2, %0|%0, %2}"
9892 [(set_attr "type" "alu")
9893 (set_attr "mode" "QI")])
9895 (define_insn "*xorqi_2_slp"
9896 [(set (reg FLAGS_REG)
9897 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9898 (match_operand:QI 1 "general_operand" "qim,qi"))
9900 (set (strict_low_part (match_dup 0))
9901 (xor:QI (match_dup 0) (match_dup 1)))]
9902 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9903 && ix86_match_ccmode (insn, CCNOmode)
9904 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9905 "xor{b}\t{%1, %0|%0, %1}"
9906 [(set_attr "type" "alu1")
9907 (set_attr "mode" "QI")])
9909 (define_insn "*xorqi_cc_2"
9910 [(set (reg FLAGS_REG)
9912 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9913 (match_operand:QI 2 "general_operand" "qim"))
9915 (clobber (match_scratch:QI 0 "=q"))]
9916 "ix86_match_ccmode (insn, CCNOmode)
9917 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9918 "xor{b}\t{%2, %0|%0, %2}"
9919 [(set_attr "type" "alu")
9920 (set_attr "mode" "QI")])
9922 (define_insn "*xorqi_cc_ext_1"
9923 [(set (reg FLAGS_REG)
9927 (match_operand 1 "ext_register_operand" "0")
9930 (match_operand:QI 2 "general_operand" "qmn"))
9932 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9936 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9938 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9939 "xor{b}\t{%2, %h0|%h0, %2}"
9940 [(set_attr "type" "alu")
9941 (set_attr "mode" "QI")])
9943 (define_insn "*xorqi_cc_ext_1_rex64"
9944 [(set (reg FLAGS_REG)
9948 (match_operand 1 "ext_register_operand" "0")
9951 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9953 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9957 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9959 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9960 "xor{b}\t{%2, %h0|%h0, %2}"
9961 [(set_attr "type" "alu")
9962 (set_attr "mode" "QI")])
9964 (define_expand "xorqi_cc_ext_1"
9966 (set (reg:CCNO FLAGS_REG)
9970 (match_operand 1 "ext_register_operand" "")
9973 (match_operand:QI 2 "general_operand" ""))
9975 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9979 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9985 [(set (match_operand 0 "register_operand" "")
9986 (xor (match_operand 1 "register_operand" "")
9987 (match_operand 2 "const_int_operand" "")))
9988 (clobber (reg:CC FLAGS_REG))]
9990 && QI_REG_P (operands[0])
9991 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9992 && !(INTVAL (operands[2]) & ~(255 << 8))
9993 && GET_MODE (operands[0]) != QImode"
9994 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9995 (xor:SI (zero_extract:SI (match_dup 1)
9996 (const_int 8) (const_int 8))
9998 (clobber (reg:CC FLAGS_REG))])]
9999 "operands[0] = gen_lowpart (SImode, operands[0]);
10000 operands[1] = gen_lowpart (SImode, operands[1]);
10001 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10003 ;; Since XOR can be encoded with sign extended immediate, this is only
10004 ;; profitable when 7th bit is set.
10006 [(set (match_operand 0 "register_operand" "")
10007 (xor (match_operand 1 "general_operand" "")
10008 (match_operand 2 "const_int_operand" "")))
10009 (clobber (reg:CC FLAGS_REG))]
10011 && ANY_QI_REG_P (operands[0])
10012 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10013 && !(INTVAL (operands[2]) & ~255)
10014 && (INTVAL (operands[2]) & 128)
10015 && GET_MODE (operands[0]) != QImode"
10016 [(parallel [(set (strict_low_part (match_dup 0))
10017 (xor:QI (match_dup 1)
10019 (clobber (reg:CC FLAGS_REG))])]
10020 "operands[0] = gen_lowpart (QImode, operands[0]);
10021 operands[1] = gen_lowpart (QImode, operands[1]);
10022 operands[2] = gen_lowpart (QImode, operands[2]);")
10024 ;; Negation instructions
10026 (define_expand "negti2"
10027 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10028 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10029 (clobber (reg:CC FLAGS_REG))])]
10031 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10033 (define_insn "*negti2_1"
10034 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10035 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10036 (clobber (reg:CC FLAGS_REG))]
10038 && ix86_unary_operator_ok (NEG, TImode, operands)"
10042 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10043 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10044 (clobber (reg:CC FLAGS_REG))]
10045 "TARGET_64BIT && reload_completed"
10047 [(set (reg:CCZ FLAGS_REG)
10048 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10049 (set (match_dup 0) (neg:DI (match_dup 2)))])
10051 [(set (match_dup 1)
10052 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10055 (clobber (reg:CC FLAGS_REG))])
10057 [(set (match_dup 1)
10058 (neg:DI (match_dup 1)))
10059 (clobber (reg:CC FLAGS_REG))])]
10060 "split_ti (operands+1, 1, operands+2, operands+3);
10061 split_ti (operands+0, 1, operands+0, operands+1);")
10063 (define_expand "negdi2"
10064 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10065 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10066 (clobber (reg:CC FLAGS_REG))])]
10068 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10070 (define_insn "*negdi2_1"
10071 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10072 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10073 (clobber (reg:CC FLAGS_REG))]
10075 && ix86_unary_operator_ok (NEG, DImode, operands)"
10079 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10080 (neg:DI (match_operand:DI 1 "general_operand" "")))
10081 (clobber (reg:CC FLAGS_REG))]
10082 "!TARGET_64BIT && reload_completed"
10084 [(set (reg:CCZ FLAGS_REG)
10085 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10086 (set (match_dup 0) (neg:SI (match_dup 2)))])
10088 [(set (match_dup 1)
10089 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10092 (clobber (reg:CC FLAGS_REG))])
10094 [(set (match_dup 1)
10095 (neg:SI (match_dup 1)))
10096 (clobber (reg:CC FLAGS_REG))])]
10097 "split_di (operands+1, 1, operands+2, operands+3);
10098 split_di (operands+0, 1, operands+0, operands+1);")
10100 (define_insn "*negdi2_1_rex64"
10101 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10102 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10103 (clobber (reg:CC FLAGS_REG))]
10104 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10106 [(set_attr "type" "negnot")
10107 (set_attr "mode" "DI")])
10109 ;; The problem with neg is that it does not perform (compare x 0),
10110 ;; it really performs (compare 0 x), which leaves us with the zero
10111 ;; flag being the only useful item.
10113 (define_insn "*negdi2_cmpz_rex64"
10114 [(set (reg:CCZ FLAGS_REG)
10115 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10117 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10118 (neg:DI (match_dup 1)))]
10119 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10121 [(set_attr "type" "negnot")
10122 (set_attr "mode" "DI")])
10125 (define_expand "negsi2"
10126 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10127 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10128 (clobber (reg:CC FLAGS_REG))])]
10130 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10132 (define_insn "*negsi2_1"
10133 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10134 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10135 (clobber (reg:CC FLAGS_REG))]
10136 "ix86_unary_operator_ok (NEG, SImode, operands)"
10138 [(set_attr "type" "negnot")
10139 (set_attr "mode" "SI")])
10141 ;; Combine is quite creative about this pattern.
10142 (define_insn "*negsi2_1_zext"
10143 [(set (match_operand:DI 0 "register_operand" "=r")
10144 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10147 (clobber (reg:CC FLAGS_REG))]
10148 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10150 [(set_attr "type" "negnot")
10151 (set_attr "mode" "SI")])
10153 ;; The problem with neg is that it does not perform (compare x 0),
10154 ;; it really performs (compare 0 x), which leaves us with the zero
10155 ;; flag being the only useful item.
10157 (define_insn "*negsi2_cmpz"
10158 [(set (reg:CCZ FLAGS_REG)
10159 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10161 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10162 (neg:SI (match_dup 1)))]
10163 "ix86_unary_operator_ok (NEG, SImode, operands)"
10165 [(set_attr "type" "negnot")
10166 (set_attr "mode" "SI")])
10168 (define_insn "*negsi2_cmpz_zext"
10169 [(set (reg:CCZ FLAGS_REG)
10170 (compare:CCZ (lshiftrt:DI
10172 (match_operand:DI 1 "register_operand" "0")
10176 (set (match_operand:DI 0 "register_operand" "=r")
10177 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10180 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10182 [(set_attr "type" "negnot")
10183 (set_attr "mode" "SI")])
10185 (define_expand "neghi2"
10186 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10187 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10188 (clobber (reg:CC FLAGS_REG))])]
10189 "TARGET_HIMODE_MATH"
10190 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10192 (define_insn "*neghi2_1"
10193 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10194 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10195 (clobber (reg:CC FLAGS_REG))]
10196 "ix86_unary_operator_ok (NEG, HImode, operands)"
10198 [(set_attr "type" "negnot")
10199 (set_attr "mode" "HI")])
10201 (define_insn "*neghi2_cmpz"
10202 [(set (reg:CCZ FLAGS_REG)
10203 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10205 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10206 (neg:HI (match_dup 1)))]
10207 "ix86_unary_operator_ok (NEG, HImode, operands)"
10209 [(set_attr "type" "negnot")
10210 (set_attr "mode" "HI")])
10212 (define_expand "negqi2"
10213 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10214 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10215 (clobber (reg:CC FLAGS_REG))])]
10216 "TARGET_QIMODE_MATH"
10217 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10219 (define_insn "*negqi2_1"
10220 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10221 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10222 (clobber (reg:CC FLAGS_REG))]
10223 "ix86_unary_operator_ok (NEG, QImode, operands)"
10225 [(set_attr "type" "negnot")
10226 (set_attr "mode" "QI")])
10228 (define_insn "*negqi2_cmpz"
10229 [(set (reg:CCZ FLAGS_REG)
10230 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10232 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10233 (neg:QI (match_dup 1)))]
10234 "ix86_unary_operator_ok (NEG, QImode, operands)"
10236 [(set_attr "type" "negnot")
10237 (set_attr "mode" "QI")])
10239 ;; Changing of sign for FP values is doable using integer unit too.
10241 (define_expand "neg<mode>2"
10242 [(set (match_operand:X87MODEF 0 "register_operand" "")
10243 (neg: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 (NEG, <MODE>mode, operands); DONE;")
10247 (define_expand "abs<mode>2"
10248 [(set (match_operand:X87MODEF 0 "register_operand" "")
10249 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10250 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10251 "ix86_expand_fp_absneg_operator (ABS, <MODE>mode, operands); DONE;")
10253 (define_insn "*absneg<mode>2_mixed"
10254 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10255 (match_operator:MODEF 3 "absneg_operator"
10256 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10257 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10258 (clobber (reg:CC FLAGS_REG))]
10259 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10262 (define_insn "*absneg<mode>2_sse"
10263 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10264 (match_operator:MODEF 3 "absneg_operator"
10265 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10266 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10267 (clobber (reg:CC FLAGS_REG))]
10268 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10271 (define_insn "*absneg<mode>2_i387"
10272 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10273 (match_operator:X87MODEF 3 "absneg_operator"
10274 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10275 (use (match_operand 2 "" ""))
10276 (clobber (reg:CC FLAGS_REG))]
10277 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10280 (define_expand "negtf2"
10281 [(set (match_operand:TF 0 "register_operand" "")
10282 (neg:TF (match_operand:TF 1 "register_operand" "")))]
10284 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10286 (define_expand "abstf2"
10287 [(set (match_operand:TF 0 "register_operand" "")
10288 (abs:TF (match_operand:TF 1 "register_operand" "")))]
10290 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10292 (define_insn "*absnegtf2_sse"
10293 [(set (match_operand:TF 0 "register_operand" "=x,x")
10294 (match_operator:TF 3 "absneg_operator"
10295 [(match_operand:TF 1 "register_operand" "0,x")]))
10296 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10297 (clobber (reg:CC FLAGS_REG))]
10301 ;; Splitters for fp abs and neg.
10304 [(set (match_operand 0 "fp_register_operand" "")
10305 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10306 (use (match_operand 2 "" ""))
10307 (clobber (reg:CC FLAGS_REG))]
10309 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10312 [(set (match_operand 0 "register_operand" "")
10313 (match_operator 3 "absneg_operator"
10314 [(match_operand 1 "register_operand" "")]))
10315 (use (match_operand 2 "nonimmediate_operand" ""))
10316 (clobber (reg:CC FLAGS_REG))]
10317 "reload_completed && SSE_REG_P (operands[0])"
10318 [(set (match_dup 0) (match_dup 3))]
10320 enum machine_mode mode = GET_MODE (operands[0]);
10321 enum machine_mode vmode = GET_MODE (operands[2]);
10324 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10325 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10326 if (operands_match_p (operands[0], operands[2]))
10329 operands[1] = operands[2];
10332 if (GET_CODE (operands[3]) == ABS)
10333 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10335 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10340 [(set (match_operand:SF 0 "register_operand" "")
10341 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10342 (use (match_operand:V4SF 2 "" ""))
10343 (clobber (reg:CC FLAGS_REG))]
10345 [(parallel [(set (match_dup 0) (match_dup 1))
10346 (clobber (reg:CC FLAGS_REG))])]
10349 operands[0] = gen_lowpart (SImode, operands[0]);
10350 if (GET_CODE (operands[1]) == ABS)
10352 tmp = gen_int_mode (0x7fffffff, SImode);
10353 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10357 tmp = gen_int_mode (0x80000000, SImode);
10358 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10364 [(set (match_operand:DF 0 "register_operand" "")
10365 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10366 (use (match_operand 2 "" ""))
10367 (clobber (reg:CC FLAGS_REG))]
10369 [(parallel [(set (match_dup 0) (match_dup 1))
10370 (clobber (reg:CC FLAGS_REG))])]
10375 tmp = gen_lowpart (DImode, operands[0]);
10376 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10379 if (GET_CODE (operands[1]) == ABS)
10382 tmp = gen_rtx_NOT (DImode, tmp);
10386 operands[0] = gen_highpart (SImode, operands[0]);
10387 if (GET_CODE (operands[1]) == ABS)
10389 tmp = gen_int_mode (0x7fffffff, SImode);
10390 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10394 tmp = gen_int_mode (0x80000000, SImode);
10395 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10402 [(set (match_operand:XF 0 "register_operand" "")
10403 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10404 (use (match_operand 2 "" ""))
10405 (clobber (reg:CC FLAGS_REG))]
10407 [(parallel [(set (match_dup 0) (match_dup 1))
10408 (clobber (reg:CC FLAGS_REG))])]
10411 operands[0] = gen_rtx_REG (SImode,
10412 true_regnum (operands[0])
10413 + (TARGET_64BIT ? 1 : 2));
10414 if (GET_CODE (operands[1]) == ABS)
10416 tmp = GEN_INT (0x7fff);
10417 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10421 tmp = GEN_INT (0x8000);
10422 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10427 ;; Conditionalize these after reload. If they match before reload, we
10428 ;; lose the clobber and ability to use integer instructions.
10430 (define_insn "*neg<mode>2_1"
10431 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10432 (neg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10434 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10436 [(set_attr "type" "fsgn")
10437 (set_attr "mode" "<MODE>")])
10439 (define_insn "*abs<mode>2_1"
10440 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10441 (abs:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10443 && (reload_completed || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10445 [(set_attr "type" "fsgn")
10446 (set_attr "mode" "<MODE>")])
10448 (define_insn "*negextendsfdf2"
10449 [(set (match_operand:DF 0 "register_operand" "=f")
10450 (neg:DF (float_extend:DF
10451 (match_operand:SF 1 "register_operand" "0"))))]
10452 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10454 [(set_attr "type" "fsgn")
10455 (set_attr "mode" "DF")])
10457 (define_insn "*negextenddfxf2"
10458 [(set (match_operand:XF 0 "register_operand" "=f")
10459 (neg:XF (float_extend:XF
10460 (match_operand:DF 1 "register_operand" "0"))))]
10463 [(set_attr "type" "fsgn")
10464 (set_attr "mode" "XF")])
10466 (define_insn "*negextendsfxf2"
10467 [(set (match_operand:XF 0 "register_operand" "=f")
10468 (neg:XF (float_extend:XF
10469 (match_operand:SF 1 "register_operand" "0"))))]
10472 [(set_attr "type" "fsgn")
10473 (set_attr "mode" "XF")])
10475 (define_insn "*absextendsfdf2"
10476 [(set (match_operand:DF 0 "register_operand" "=f")
10477 (abs:DF (float_extend:DF
10478 (match_operand:SF 1 "register_operand" "0"))))]
10479 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10481 [(set_attr "type" "fsgn")
10482 (set_attr "mode" "DF")])
10484 (define_insn "*absextenddfxf2"
10485 [(set (match_operand:XF 0 "register_operand" "=f")
10486 (abs:XF (float_extend:XF
10487 (match_operand:DF 1 "register_operand" "0"))))]
10490 [(set_attr "type" "fsgn")
10491 (set_attr "mode" "XF")])
10493 (define_insn "*absextendsfxf2"
10494 [(set (match_operand:XF 0 "register_operand" "=f")
10495 (abs:XF (float_extend:XF
10496 (match_operand:SF 1 "register_operand" "0"))))]
10499 [(set_attr "type" "fsgn")
10500 (set_attr "mode" "XF")])
10502 ;; Copysign instructions
10504 (define_mode_iterator CSGNMODE [SF DF TF])
10505 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10507 (define_expand "copysign<mode>3"
10508 [(match_operand:CSGNMODE 0 "register_operand" "")
10509 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10510 (match_operand:CSGNMODE 2 "register_operand" "")]
10511 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10512 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10514 ix86_expand_copysign (operands);
10518 (define_insn_and_split "copysign<mode>3_const"
10519 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10521 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10522 (match_operand:CSGNMODE 2 "register_operand" "0")
10523 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10525 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10526 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10528 "&& reload_completed"
10531 ix86_split_copysign_const (operands);
10535 (define_insn "copysign<mode>3_var"
10536 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10538 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10539 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10540 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10541 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10543 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10544 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10545 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10549 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10551 [(match_operand:CSGNMODE 2 "register_operand" "")
10552 (match_operand:CSGNMODE 3 "register_operand" "")
10553 (match_operand:<CSGNVMODE> 4 "" "")
10554 (match_operand:<CSGNVMODE> 5 "" "")]
10556 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10557 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10558 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10559 && reload_completed"
10562 ix86_split_copysign_var (operands);
10566 ;; One complement instructions
10568 (define_expand "one_cmpldi2"
10569 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10570 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10572 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10574 (define_insn "*one_cmpldi2_1_rex64"
10575 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10576 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10577 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10579 [(set_attr "type" "negnot")
10580 (set_attr "mode" "DI")])
10582 (define_insn "*one_cmpldi2_2_rex64"
10583 [(set (reg FLAGS_REG)
10584 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10586 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10587 (not:DI (match_dup 1)))]
10588 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10589 && ix86_unary_operator_ok (NOT, DImode, operands)"
10591 [(set_attr "type" "alu1")
10592 (set_attr "mode" "DI")])
10595 [(set (match_operand 0 "flags_reg_operand" "")
10596 (match_operator 2 "compare_operator"
10597 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10599 (set (match_operand:DI 1 "nonimmediate_operand" "")
10600 (not:DI (match_dup 3)))]
10601 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10602 [(parallel [(set (match_dup 0)
10604 [(xor:DI (match_dup 3) (const_int -1))
10607 (xor:DI (match_dup 3) (const_int -1)))])]
10610 (define_expand "one_cmplsi2"
10611 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10612 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10614 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10616 (define_insn "*one_cmplsi2_1"
10617 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10618 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10619 "ix86_unary_operator_ok (NOT, SImode, operands)"
10621 [(set_attr "type" "negnot")
10622 (set_attr "mode" "SI")])
10624 ;; ??? Currently never generated - xor is used instead.
10625 (define_insn "*one_cmplsi2_1_zext"
10626 [(set (match_operand:DI 0 "register_operand" "=r")
10627 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10628 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10630 [(set_attr "type" "negnot")
10631 (set_attr "mode" "SI")])
10633 (define_insn "*one_cmplsi2_2"
10634 [(set (reg FLAGS_REG)
10635 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10637 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10638 (not:SI (match_dup 1)))]
10639 "ix86_match_ccmode (insn, CCNOmode)
10640 && ix86_unary_operator_ok (NOT, SImode, operands)"
10642 [(set_attr "type" "alu1")
10643 (set_attr "mode" "SI")])
10646 [(set (match_operand 0 "flags_reg_operand" "")
10647 (match_operator 2 "compare_operator"
10648 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10650 (set (match_operand:SI 1 "nonimmediate_operand" "")
10651 (not:SI (match_dup 3)))]
10652 "ix86_match_ccmode (insn, CCNOmode)"
10653 [(parallel [(set (match_dup 0)
10654 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10657 (xor:SI (match_dup 3) (const_int -1)))])]
10660 ;; ??? Currently never generated - xor is used instead.
10661 (define_insn "*one_cmplsi2_2_zext"
10662 [(set (reg FLAGS_REG)
10663 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10665 (set (match_operand:DI 0 "register_operand" "=r")
10666 (zero_extend:DI (not:SI (match_dup 1))))]
10667 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10668 && ix86_unary_operator_ok (NOT, SImode, operands)"
10670 [(set_attr "type" "alu1")
10671 (set_attr "mode" "SI")])
10674 [(set (match_operand 0 "flags_reg_operand" "")
10675 (match_operator 2 "compare_operator"
10676 [(not:SI (match_operand:SI 3 "register_operand" ""))
10678 (set (match_operand:DI 1 "register_operand" "")
10679 (zero_extend:DI (not:SI (match_dup 3))))]
10680 "ix86_match_ccmode (insn, CCNOmode)"
10681 [(parallel [(set (match_dup 0)
10682 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10685 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10688 (define_expand "one_cmplhi2"
10689 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10690 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10691 "TARGET_HIMODE_MATH"
10692 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10694 (define_insn "*one_cmplhi2_1"
10695 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10696 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10697 "ix86_unary_operator_ok (NOT, HImode, operands)"
10699 [(set_attr "type" "negnot")
10700 (set_attr "mode" "HI")])
10702 (define_insn "*one_cmplhi2_2"
10703 [(set (reg FLAGS_REG)
10704 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10706 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10707 (not:HI (match_dup 1)))]
10708 "ix86_match_ccmode (insn, CCNOmode)
10709 && ix86_unary_operator_ok (NEG, HImode, operands)"
10711 [(set_attr "type" "alu1")
10712 (set_attr "mode" "HI")])
10715 [(set (match_operand 0 "flags_reg_operand" "")
10716 (match_operator 2 "compare_operator"
10717 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10719 (set (match_operand:HI 1 "nonimmediate_operand" "")
10720 (not:HI (match_dup 3)))]
10721 "ix86_match_ccmode (insn, CCNOmode)"
10722 [(parallel [(set (match_dup 0)
10723 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10726 (xor:HI (match_dup 3) (const_int -1)))])]
10729 ;; %%% Potential partial reg stall on alternative 1. What to do?
10730 (define_expand "one_cmplqi2"
10731 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10732 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10733 "TARGET_QIMODE_MATH"
10734 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10736 (define_insn "*one_cmplqi2_1"
10737 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10738 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10739 "ix86_unary_operator_ok (NOT, QImode, operands)"
10743 [(set_attr "type" "negnot")
10744 (set_attr "mode" "QI,SI")])
10746 (define_insn "*one_cmplqi2_2"
10747 [(set (reg FLAGS_REG)
10748 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10750 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10751 (not:QI (match_dup 1)))]
10752 "ix86_match_ccmode (insn, CCNOmode)
10753 && ix86_unary_operator_ok (NOT, QImode, operands)"
10755 [(set_attr "type" "alu1")
10756 (set_attr "mode" "QI")])
10759 [(set (match_operand 0 "flags_reg_operand" "")
10760 (match_operator 2 "compare_operator"
10761 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10763 (set (match_operand:QI 1 "nonimmediate_operand" "")
10764 (not:QI (match_dup 3)))]
10765 "ix86_match_ccmode (insn, CCNOmode)"
10766 [(parallel [(set (match_dup 0)
10767 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10770 (xor:QI (match_dup 3) (const_int -1)))])]
10773 ;; Arithmetic shift instructions
10775 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10776 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10777 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10778 ;; from the assembler input.
10780 ;; This instruction shifts the target reg/mem as usual, but instead of
10781 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10782 ;; is a left shift double, bits are taken from the high order bits of
10783 ;; reg, else if the insn is a shift right double, bits are taken from the
10784 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10785 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10787 ;; Since sh[lr]d does not change the `reg' operand, that is done
10788 ;; separately, making all shifts emit pairs of shift double and normal
10789 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10790 ;; support a 63 bit shift, each shift where the count is in a reg expands
10791 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10793 ;; If the shift count is a constant, we need never emit more than one
10794 ;; shift pair, instead using moves and sign extension for counts greater
10797 (define_expand "ashlti3"
10798 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10799 (ashift:TI (match_operand:TI 1 "register_operand" "")
10800 (match_operand:QI 2 "nonmemory_operand" "")))
10801 (clobber (reg:CC FLAGS_REG))])]
10804 if (! immediate_operand (operands[2], QImode))
10806 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10809 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10813 (define_insn "ashlti3_1"
10814 [(set (match_operand:TI 0 "register_operand" "=r")
10815 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10816 (match_operand:QI 2 "register_operand" "c")))
10817 (clobber (match_scratch:DI 3 "=&r"))
10818 (clobber (reg:CC FLAGS_REG))]
10821 [(set_attr "type" "multi")])
10823 ;; This pattern must be defined before *ashlti3_2 to prevent
10824 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10826 (define_insn "sse2_ashlti3"
10827 [(set (match_operand:TI 0 "register_operand" "=x")
10828 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10829 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10832 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10833 return "pslldq\t{%2, %0|%0, %2}";
10835 [(set_attr "type" "sseishft")
10836 (set_attr "prefix_data16" "1")
10837 (set_attr "mode" "TI")])
10839 (define_insn "*ashlti3_2"
10840 [(set (match_operand:TI 0 "register_operand" "=r")
10841 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10842 (match_operand:QI 2 "immediate_operand" "O")))
10843 (clobber (reg:CC FLAGS_REG))]
10846 [(set_attr "type" "multi")])
10849 [(set (match_operand:TI 0 "register_operand" "")
10850 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10851 (match_operand:QI 2 "register_operand" "")))
10852 (clobber (match_scratch:DI 3 ""))
10853 (clobber (reg:CC FLAGS_REG))]
10854 "TARGET_64BIT && reload_completed"
10856 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10859 [(set (match_operand:TI 0 "register_operand" "")
10860 (ashift:TI (match_operand:TI 1 "register_operand" "")
10861 (match_operand:QI 2 "immediate_operand" "")))
10862 (clobber (reg:CC FLAGS_REG))]
10863 "TARGET_64BIT && reload_completed"
10865 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10867 (define_insn "x86_64_shld"
10868 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10869 (ior:DI (ashift:DI (match_dup 0)
10870 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10871 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10872 (minus:QI (const_int 64) (match_dup 2)))))
10873 (clobber (reg:CC FLAGS_REG))]
10876 shld{q}\t{%2, %1, %0|%0, %1, %2}
10877 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10878 [(set_attr "type" "ishift")
10879 (set_attr "prefix_0f" "1")
10880 (set_attr "mode" "DI")
10881 (set_attr "athlon_decode" "vector")
10882 (set_attr "amdfam10_decode" "vector")])
10884 (define_expand "x86_64_shift_adj"
10885 [(set (reg:CCZ FLAGS_REG)
10886 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10889 (set (match_operand:DI 0 "register_operand" "")
10890 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10891 (match_operand:DI 1 "register_operand" "")
10894 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10895 (match_operand:DI 3 "register_operand" "r")
10900 (define_expand "ashldi3"
10901 [(set (match_operand:DI 0 "shiftdi_operand" "")
10902 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10903 (match_operand:QI 2 "nonmemory_operand" "")))]
10905 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10907 (define_insn "*ashldi3_1_rex64"
10908 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10909 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10910 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10911 (clobber (reg:CC FLAGS_REG))]
10912 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10914 switch (get_attr_type (insn))
10917 gcc_assert (operands[2] == const1_rtx);
10918 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10919 return "add{q}\t%0, %0";
10922 gcc_assert (CONST_INT_P (operands[2]));
10923 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10924 operands[1] = gen_rtx_MULT (DImode, operands[1],
10925 GEN_INT (1 << INTVAL (operands[2])));
10926 return "lea{q}\t{%a1, %0|%0, %a1}";
10929 if (REG_P (operands[2]))
10930 return "sal{q}\t{%b2, %0|%0, %b2}";
10931 else if (operands[2] == const1_rtx
10932 && (TARGET_SHIFT1 || optimize_size))
10933 return "sal{q}\t%0";
10935 return "sal{q}\t{%2, %0|%0, %2}";
10938 [(set (attr "type")
10939 (cond [(eq_attr "alternative" "1")
10940 (const_string "lea")
10941 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10943 (match_operand 0 "register_operand" ""))
10944 (match_operand 2 "const1_operand" ""))
10945 (const_string "alu")
10947 (const_string "ishift")))
10948 (set_attr "mode" "DI")])
10950 ;; Convert lea to the lea pattern to avoid flags dependency.
10952 [(set (match_operand:DI 0 "register_operand" "")
10953 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10954 (match_operand:QI 2 "immediate_operand" "")))
10955 (clobber (reg:CC FLAGS_REG))]
10956 "TARGET_64BIT && reload_completed
10957 && true_regnum (operands[0]) != true_regnum (operands[1])"
10958 [(set (match_dup 0)
10959 (mult:DI (match_dup 1)
10961 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10963 ;; This pattern can't accept a variable shift count, since shifts by
10964 ;; zero don't affect the flags. We assume that shifts by constant
10965 ;; zero are optimized away.
10966 (define_insn "*ashldi3_cmp_rex64"
10967 [(set (reg FLAGS_REG)
10969 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10970 (match_operand:QI 2 "immediate_operand" "e"))
10972 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10973 (ashift:DI (match_dup 1) (match_dup 2)))]
10976 || !TARGET_PARTIAL_FLAG_REG_STALL
10977 || (operands[2] == const1_rtx
10979 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10980 && ix86_match_ccmode (insn, CCGOCmode)
10981 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10983 switch (get_attr_type (insn))
10986 gcc_assert (operands[2] == const1_rtx);
10987 return "add{q}\t%0, %0";
10990 if (REG_P (operands[2]))
10991 return "sal{q}\t{%b2, %0|%0, %b2}";
10992 else if (operands[2] == const1_rtx
10993 && (TARGET_SHIFT1 || optimize_size))
10994 return "sal{q}\t%0";
10996 return "sal{q}\t{%2, %0|%0, %2}";
10999 [(set (attr "type")
11000 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11002 (match_operand 0 "register_operand" ""))
11003 (match_operand 2 "const1_operand" ""))
11004 (const_string "alu")
11006 (const_string "ishift")))
11007 (set_attr "mode" "DI")])
11009 (define_insn "*ashldi3_cconly_rex64"
11010 [(set (reg FLAGS_REG)
11012 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11013 (match_operand:QI 2 "immediate_operand" "e"))
11015 (clobber (match_scratch:DI 0 "=r"))]
11018 || !TARGET_PARTIAL_FLAG_REG_STALL
11019 || (operands[2] == const1_rtx
11021 || TARGET_DOUBLE_WITH_ADD)))
11022 && ix86_match_ccmode (insn, CCGOCmode)
11023 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11025 switch (get_attr_type (insn))
11028 gcc_assert (operands[2] == const1_rtx);
11029 return "add{q}\t%0, %0";
11032 if (REG_P (operands[2]))
11033 return "sal{q}\t{%b2, %0|%0, %b2}";
11034 else if (operands[2] == const1_rtx
11035 && (TARGET_SHIFT1 || optimize_size))
11036 return "sal{q}\t%0";
11038 return "sal{q}\t{%2, %0|%0, %2}";
11041 [(set (attr "type")
11042 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11044 (match_operand 0 "register_operand" ""))
11045 (match_operand 2 "const1_operand" ""))
11046 (const_string "alu")
11048 (const_string "ishift")))
11049 (set_attr "mode" "DI")])
11051 (define_insn "*ashldi3_1"
11052 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11053 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11054 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11055 (clobber (reg:CC FLAGS_REG))]
11058 [(set_attr "type" "multi")])
11060 ;; By default we don't ask for a scratch register, because when DImode
11061 ;; values are manipulated, registers are already at a premium. But if
11062 ;; we have one handy, we won't turn it away.
11064 [(match_scratch:SI 3 "r")
11065 (parallel [(set (match_operand:DI 0 "register_operand" "")
11066 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11067 (match_operand:QI 2 "nonmemory_operand" "")))
11068 (clobber (reg:CC FLAGS_REG))])
11070 "!TARGET_64BIT && TARGET_CMOVE"
11072 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11075 [(set (match_operand:DI 0 "register_operand" "")
11076 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11077 (match_operand:QI 2 "nonmemory_operand" "")))
11078 (clobber (reg:CC FLAGS_REG))]
11079 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11080 ? epilogue_completed : reload_completed)"
11082 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11084 (define_insn "x86_shld_1"
11085 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11086 (ior:SI (ashift:SI (match_dup 0)
11087 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11088 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11089 (minus:QI (const_int 32) (match_dup 2)))))
11090 (clobber (reg:CC FLAGS_REG))]
11093 shld{l}\t{%2, %1, %0|%0, %1, %2}
11094 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11095 [(set_attr "type" "ishift")
11096 (set_attr "prefix_0f" "1")
11097 (set_attr "mode" "SI")
11098 (set_attr "pent_pair" "np")
11099 (set_attr "athlon_decode" "vector")
11100 (set_attr "amdfam10_decode" "vector")])
11102 (define_expand "x86_shift_adj_1"
11103 [(set (reg:CCZ FLAGS_REG)
11104 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11107 (set (match_operand:SI 0 "register_operand" "")
11108 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11109 (match_operand:SI 1 "register_operand" "")
11112 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11113 (match_operand:SI 3 "register_operand" "r")
11118 (define_expand "x86_shift_adj_2"
11119 [(use (match_operand:SI 0 "register_operand" ""))
11120 (use (match_operand:SI 1 "register_operand" ""))
11121 (use (match_operand:QI 2 "register_operand" ""))]
11124 rtx label = gen_label_rtx ();
11127 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11129 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11130 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11131 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11132 gen_rtx_LABEL_REF (VOIDmode, label),
11134 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11135 JUMP_LABEL (tmp) = label;
11137 emit_move_insn (operands[0], operands[1]);
11138 ix86_expand_clear (operands[1]);
11140 emit_label (label);
11141 LABEL_NUSES (label) = 1;
11146 (define_expand "ashlsi3"
11147 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11148 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11149 (match_operand:QI 2 "nonmemory_operand" "")))
11150 (clobber (reg:CC FLAGS_REG))]
11152 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11154 (define_insn "*ashlsi3_1"
11155 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11156 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11157 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11158 (clobber (reg:CC FLAGS_REG))]
11159 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11161 switch (get_attr_type (insn))
11164 gcc_assert (operands[2] == const1_rtx);
11165 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11166 return "add{l}\t%0, %0";
11172 if (REG_P (operands[2]))
11173 return "sal{l}\t{%b2, %0|%0, %b2}";
11174 else if (operands[2] == const1_rtx
11175 && (TARGET_SHIFT1 || optimize_size))
11176 return "sal{l}\t%0";
11178 return "sal{l}\t{%2, %0|%0, %2}";
11181 [(set (attr "type")
11182 (cond [(eq_attr "alternative" "1")
11183 (const_string "lea")
11184 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11186 (match_operand 0 "register_operand" ""))
11187 (match_operand 2 "const1_operand" ""))
11188 (const_string "alu")
11190 (const_string "ishift")))
11191 (set_attr "mode" "SI")])
11193 ;; Convert lea to the lea pattern to avoid flags dependency.
11195 [(set (match_operand 0 "register_operand" "")
11196 (ashift (match_operand 1 "index_register_operand" "")
11197 (match_operand:QI 2 "const_int_operand" "")))
11198 (clobber (reg:CC FLAGS_REG))]
11200 && true_regnum (operands[0]) != true_regnum (operands[1])
11201 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11205 enum machine_mode mode = GET_MODE (operands[0]);
11207 if (GET_MODE_SIZE (mode) < 4)
11208 operands[0] = gen_lowpart (SImode, operands[0]);
11210 operands[1] = gen_lowpart (Pmode, operands[1]);
11211 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11213 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11214 if (Pmode != SImode)
11215 pat = gen_rtx_SUBREG (SImode, pat, 0);
11216 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11220 ;; Rare case of shifting RSP is handled by generating move and shift
11222 [(set (match_operand 0 "register_operand" "")
11223 (ashift (match_operand 1 "register_operand" "")
11224 (match_operand:QI 2 "const_int_operand" "")))
11225 (clobber (reg:CC FLAGS_REG))]
11227 && true_regnum (operands[0]) != true_regnum (operands[1])"
11231 emit_move_insn (operands[0], operands[1]);
11232 pat = gen_rtx_SET (VOIDmode, operands[0],
11233 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11234 operands[0], operands[2]));
11235 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11236 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11240 (define_insn "*ashlsi3_1_zext"
11241 [(set (match_operand:DI 0 "register_operand" "=r,r")
11242 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11243 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11244 (clobber (reg:CC FLAGS_REG))]
11245 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11247 switch (get_attr_type (insn))
11250 gcc_assert (operands[2] == const1_rtx);
11251 return "add{l}\t%k0, %k0";
11257 if (REG_P (operands[2]))
11258 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11259 else if (operands[2] == const1_rtx
11260 && (TARGET_SHIFT1 || optimize_size))
11261 return "sal{l}\t%k0";
11263 return "sal{l}\t{%2, %k0|%k0, %2}";
11266 [(set (attr "type")
11267 (cond [(eq_attr "alternative" "1")
11268 (const_string "lea")
11269 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11271 (match_operand 2 "const1_operand" ""))
11272 (const_string "alu")
11274 (const_string "ishift")))
11275 (set_attr "mode" "SI")])
11277 ;; Convert lea to the lea pattern to avoid flags dependency.
11279 [(set (match_operand:DI 0 "register_operand" "")
11280 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11281 (match_operand:QI 2 "const_int_operand" ""))))
11282 (clobber (reg:CC FLAGS_REG))]
11283 "TARGET_64BIT && reload_completed
11284 && true_regnum (operands[0]) != true_regnum (operands[1])"
11285 [(set (match_dup 0) (zero_extend:DI
11286 (subreg:SI (mult:SI (match_dup 1)
11287 (match_dup 2)) 0)))]
11289 operands[1] = gen_lowpart (Pmode, operands[1]);
11290 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11293 ;; This pattern can't accept a variable shift count, since shifts by
11294 ;; zero don't affect the flags. We assume that shifts by constant
11295 ;; zero are optimized away.
11296 (define_insn "*ashlsi3_cmp"
11297 [(set (reg FLAGS_REG)
11299 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11300 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11302 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11303 (ashift:SI (match_dup 1) (match_dup 2)))]
11305 || !TARGET_PARTIAL_FLAG_REG_STALL
11306 || (operands[2] == const1_rtx
11308 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11309 && ix86_match_ccmode (insn, CCGOCmode)
11310 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11312 switch (get_attr_type (insn))
11315 gcc_assert (operands[2] == const1_rtx);
11316 return "add{l}\t%0, %0";
11319 if (REG_P (operands[2]))
11320 return "sal{l}\t{%b2, %0|%0, %b2}";
11321 else if (operands[2] == const1_rtx
11322 && (TARGET_SHIFT1 || optimize_size))
11323 return "sal{l}\t%0";
11325 return "sal{l}\t{%2, %0|%0, %2}";
11328 [(set (attr "type")
11329 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11331 (match_operand 0 "register_operand" ""))
11332 (match_operand 2 "const1_operand" ""))
11333 (const_string "alu")
11335 (const_string "ishift")))
11336 (set_attr "mode" "SI")])
11338 (define_insn "*ashlsi3_cconly"
11339 [(set (reg FLAGS_REG)
11341 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11342 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11344 (clobber (match_scratch:SI 0 "=r"))]
11346 || !TARGET_PARTIAL_FLAG_REG_STALL
11347 || (operands[2] == const1_rtx
11349 || TARGET_DOUBLE_WITH_ADD)))
11350 && ix86_match_ccmode (insn, CCGOCmode)
11351 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11353 switch (get_attr_type (insn))
11356 gcc_assert (operands[2] == const1_rtx);
11357 return "add{l}\t%0, %0";
11360 if (REG_P (operands[2]))
11361 return "sal{l}\t{%b2, %0|%0, %b2}";
11362 else if (operands[2] == const1_rtx
11363 && (TARGET_SHIFT1 || optimize_size))
11364 return "sal{l}\t%0";
11366 return "sal{l}\t{%2, %0|%0, %2}";
11369 [(set (attr "type")
11370 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11372 (match_operand 0 "register_operand" ""))
11373 (match_operand 2 "const1_operand" ""))
11374 (const_string "alu")
11376 (const_string "ishift")))
11377 (set_attr "mode" "SI")])
11379 (define_insn "*ashlsi3_cmp_zext"
11380 [(set (reg FLAGS_REG)
11382 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11383 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11385 (set (match_operand:DI 0 "register_operand" "=r")
11386 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11389 || !TARGET_PARTIAL_FLAG_REG_STALL
11390 || (operands[2] == const1_rtx
11392 || TARGET_DOUBLE_WITH_ADD)))
11393 && ix86_match_ccmode (insn, CCGOCmode)
11394 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11396 switch (get_attr_type (insn))
11399 gcc_assert (operands[2] == const1_rtx);
11400 return "add{l}\t%k0, %k0";
11403 if (REG_P (operands[2]))
11404 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11405 else if (operands[2] == const1_rtx
11406 && (TARGET_SHIFT1 || optimize_size))
11407 return "sal{l}\t%k0";
11409 return "sal{l}\t{%2, %k0|%k0, %2}";
11412 [(set (attr "type")
11413 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11415 (match_operand 2 "const1_operand" ""))
11416 (const_string "alu")
11418 (const_string "ishift")))
11419 (set_attr "mode" "SI")])
11421 (define_expand "ashlhi3"
11422 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11423 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11424 (match_operand:QI 2 "nonmemory_operand" "")))
11425 (clobber (reg:CC FLAGS_REG))]
11426 "TARGET_HIMODE_MATH"
11427 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11429 (define_insn "*ashlhi3_1_lea"
11430 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11431 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11432 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11433 (clobber (reg:CC FLAGS_REG))]
11434 "!TARGET_PARTIAL_REG_STALL
11435 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11437 switch (get_attr_type (insn))
11442 gcc_assert (operands[2] == const1_rtx);
11443 return "add{w}\t%0, %0";
11446 if (REG_P (operands[2]))
11447 return "sal{w}\t{%b2, %0|%0, %b2}";
11448 else if (operands[2] == const1_rtx
11449 && (TARGET_SHIFT1 || optimize_size))
11450 return "sal{w}\t%0";
11452 return "sal{w}\t{%2, %0|%0, %2}";
11455 [(set (attr "type")
11456 (cond [(eq_attr "alternative" "1")
11457 (const_string "lea")
11458 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11460 (match_operand 0 "register_operand" ""))
11461 (match_operand 2 "const1_operand" ""))
11462 (const_string "alu")
11464 (const_string "ishift")))
11465 (set_attr "mode" "HI,SI")])
11467 (define_insn "*ashlhi3_1"
11468 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11469 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11470 (match_operand:QI 2 "nonmemory_operand" "cI")))
11471 (clobber (reg:CC FLAGS_REG))]
11472 "TARGET_PARTIAL_REG_STALL
11473 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11475 switch (get_attr_type (insn))
11478 gcc_assert (operands[2] == const1_rtx);
11479 return "add{w}\t%0, %0";
11482 if (REG_P (operands[2]))
11483 return "sal{w}\t{%b2, %0|%0, %b2}";
11484 else if (operands[2] == const1_rtx
11485 && (TARGET_SHIFT1 || optimize_size))
11486 return "sal{w}\t%0";
11488 return "sal{w}\t{%2, %0|%0, %2}";
11491 [(set (attr "type")
11492 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11494 (match_operand 0 "register_operand" ""))
11495 (match_operand 2 "const1_operand" ""))
11496 (const_string "alu")
11498 (const_string "ishift")))
11499 (set_attr "mode" "HI")])
11501 ;; This pattern can't accept a variable shift count, since shifts by
11502 ;; zero don't affect the flags. We assume that shifts by constant
11503 ;; zero are optimized away.
11504 (define_insn "*ashlhi3_cmp"
11505 [(set (reg FLAGS_REG)
11507 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11508 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11510 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11511 (ashift:HI (match_dup 1) (match_dup 2)))]
11513 || !TARGET_PARTIAL_FLAG_REG_STALL
11514 || (operands[2] == const1_rtx
11516 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11517 && ix86_match_ccmode (insn, CCGOCmode)
11518 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11520 switch (get_attr_type (insn))
11523 gcc_assert (operands[2] == const1_rtx);
11524 return "add{w}\t%0, %0";
11527 if (REG_P (operands[2]))
11528 return "sal{w}\t{%b2, %0|%0, %b2}";
11529 else if (operands[2] == const1_rtx
11530 && (TARGET_SHIFT1 || optimize_size))
11531 return "sal{w}\t%0";
11533 return "sal{w}\t{%2, %0|%0, %2}";
11536 [(set (attr "type")
11537 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11539 (match_operand 0 "register_operand" ""))
11540 (match_operand 2 "const1_operand" ""))
11541 (const_string "alu")
11543 (const_string "ishift")))
11544 (set_attr "mode" "HI")])
11546 (define_insn "*ashlhi3_cconly"
11547 [(set (reg FLAGS_REG)
11549 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11550 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11552 (clobber (match_scratch:HI 0 "=r"))]
11554 || !TARGET_PARTIAL_FLAG_REG_STALL
11555 || (operands[2] == const1_rtx
11557 || TARGET_DOUBLE_WITH_ADD)))
11558 && ix86_match_ccmode (insn, CCGOCmode)
11559 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11561 switch (get_attr_type (insn))
11564 gcc_assert (operands[2] == const1_rtx);
11565 return "add{w}\t%0, %0";
11568 if (REG_P (operands[2]))
11569 return "sal{w}\t{%b2, %0|%0, %b2}";
11570 else if (operands[2] == const1_rtx
11571 && (TARGET_SHIFT1 || optimize_size))
11572 return "sal{w}\t%0";
11574 return "sal{w}\t{%2, %0|%0, %2}";
11577 [(set (attr "type")
11578 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11580 (match_operand 0 "register_operand" ""))
11581 (match_operand 2 "const1_operand" ""))
11582 (const_string "alu")
11584 (const_string "ishift")))
11585 (set_attr "mode" "HI")])
11587 (define_expand "ashlqi3"
11588 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11589 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11590 (match_operand:QI 2 "nonmemory_operand" "")))
11591 (clobber (reg:CC FLAGS_REG))]
11592 "TARGET_QIMODE_MATH"
11593 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11595 ;; %%% Potential partial reg stall on alternative 2. What to do?
11597 (define_insn "*ashlqi3_1_lea"
11598 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11599 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11600 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11601 (clobber (reg:CC FLAGS_REG))]
11602 "!TARGET_PARTIAL_REG_STALL
11603 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11605 switch (get_attr_type (insn))
11610 gcc_assert (operands[2] == const1_rtx);
11611 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11612 return "add{l}\t%k0, %k0";
11614 return "add{b}\t%0, %0";
11617 if (REG_P (operands[2]))
11619 if (get_attr_mode (insn) == MODE_SI)
11620 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11622 return "sal{b}\t{%b2, %0|%0, %b2}";
11624 else if (operands[2] == const1_rtx
11625 && (TARGET_SHIFT1 || optimize_size))
11627 if (get_attr_mode (insn) == MODE_SI)
11628 return "sal{l}\t%0";
11630 return "sal{b}\t%0";
11634 if (get_attr_mode (insn) == MODE_SI)
11635 return "sal{l}\t{%2, %k0|%k0, %2}";
11637 return "sal{b}\t{%2, %0|%0, %2}";
11641 [(set (attr "type")
11642 (cond [(eq_attr "alternative" "2")
11643 (const_string "lea")
11644 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11646 (match_operand 0 "register_operand" ""))
11647 (match_operand 2 "const1_operand" ""))
11648 (const_string "alu")
11650 (const_string "ishift")))
11651 (set_attr "mode" "QI,SI,SI")])
11653 (define_insn "*ashlqi3_1"
11654 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11655 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11656 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11657 (clobber (reg:CC FLAGS_REG))]
11658 "TARGET_PARTIAL_REG_STALL
11659 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11661 switch (get_attr_type (insn))
11664 gcc_assert (operands[2] == const1_rtx);
11665 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11666 return "add{l}\t%k0, %k0";
11668 return "add{b}\t%0, %0";
11671 if (REG_P (operands[2]))
11673 if (get_attr_mode (insn) == MODE_SI)
11674 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11676 return "sal{b}\t{%b2, %0|%0, %b2}";
11678 else if (operands[2] == const1_rtx
11679 && (TARGET_SHIFT1 || optimize_size))
11681 if (get_attr_mode (insn) == MODE_SI)
11682 return "sal{l}\t%0";
11684 return "sal{b}\t%0";
11688 if (get_attr_mode (insn) == MODE_SI)
11689 return "sal{l}\t{%2, %k0|%k0, %2}";
11691 return "sal{b}\t{%2, %0|%0, %2}";
11695 [(set (attr "type")
11696 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11698 (match_operand 0 "register_operand" ""))
11699 (match_operand 2 "const1_operand" ""))
11700 (const_string "alu")
11702 (const_string "ishift")))
11703 (set_attr "mode" "QI,SI")])
11705 ;; This pattern can't accept a variable shift count, since shifts by
11706 ;; zero don't affect the flags. We assume that shifts by constant
11707 ;; zero are optimized away.
11708 (define_insn "*ashlqi3_cmp"
11709 [(set (reg FLAGS_REG)
11711 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11712 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11714 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11715 (ashift:QI (match_dup 1) (match_dup 2)))]
11717 || !TARGET_PARTIAL_FLAG_REG_STALL
11718 || (operands[2] == const1_rtx
11720 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11721 && ix86_match_ccmode (insn, CCGOCmode)
11722 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11724 switch (get_attr_type (insn))
11727 gcc_assert (operands[2] == const1_rtx);
11728 return "add{b}\t%0, %0";
11731 if (REG_P (operands[2]))
11732 return "sal{b}\t{%b2, %0|%0, %b2}";
11733 else if (operands[2] == const1_rtx
11734 && (TARGET_SHIFT1 || optimize_size))
11735 return "sal{b}\t%0";
11737 return "sal{b}\t{%2, %0|%0, %2}";
11740 [(set (attr "type")
11741 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11743 (match_operand 0 "register_operand" ""))
11744 (match_operand 2 "const1_operand" ""))
11745 (const_string "alu")
11747 (const_string "ishift")))
11748 (set_attr "mode" "QI")])
11750 (define_insn "*ashlqi3_cconly"
11751 [(set (reg FLAGS_REG)
11753 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11754 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11756 (clobber (match_scratch:QI 0 "=q"))]
11758 || !TARGET_PARTIAL_FLAG_REG_STALL
11759 || (operands[2] == const1_rtx
11761 || TARGET_DOUBLE_WITH_ADD)))
11762 && ix86_match_ccmode (insn, CCGOCmode)
11763 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11765 switch (get_attr_type (insn))
11768 gcc_assert (operands[2] == const1_rtx);
11769 return "add{b}\t%0, %0";
11772 if (REG_P (operands[2]))
11773 return "sal{b}\t{%b2, %0|%0, %b2}";
11774 else if (operands[2] == const1_rtx
11775 && (TARGET_SHIFT1 || optimize_size))
11776 return "sal{b}\t%0";
11778 return "sal{b}\t{%2, %0|%0, %2}";
11781 [(set (attr "type")
11782 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11784 (match_operand 0 "register_operand" ""))
11785 (match_operand 2 "const1_operand" ""))
11786 (const_string "alu")
11788 (const_string "ishift")))
11789 (set_attr "mode" "QI")])
11791 ;; See comment above `ashldi3' about how this works.
11793 (define_expand "ashrti3"
11794 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11795 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11796 (match_operand:QI 2 "nonmemory_operand" "")))
11797 (clobber (reg:CC FLAGS_REG))])]
11800 if (! immediate_operand (operands[2], QImode))
11802 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11805 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11809 (define_insn "ashrti3_1"
11810 [(set (match_operand:TI 0 "register_operand" "=r")
11811 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11812 (match_operand:QI 2 "register_operand" "c")))
11813 (clobber (match_scratch:DI 3 "=&r"))
11814 (clobber (reg:CC FLAGS_REG))]
11817 [(set_attr "type" "multi")])
11819 (define_insn "*ashrti3_2"
11820 [(set (match_operand:TI 0 "register_operand" "=r")
11821 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11822 (match_operand:QI 2 "immediate_operand" "O")))
11823 (clobber (reg:CC FLAGS_REG))]
11826 [(set_attr "type" "multi")])
11829 [(set (match_operand:TI 0 "register_operand" "")
11830 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11831 (match_operand:QI 2 "register_operand" "")))
11832 (clobber (match_scratch:DI 3 ""))
11833 (clobber (reg:CC FLAGS_REG))]
11834 "TARGET_64BIT && reload_completed"
11836 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11839 [(set (match_operand:TI 0 "register_operand" "")
11840 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11841 (match_operand:QI 2 "immediate_operand" "")))
11842 (clobber (reg:CC FLAGS_REG))]
11843 "TARGET_64BIT && reload_completed"
11845 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11847 (define_insn "x86_64_shrd"
11848 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11849 (ior:DI (ashiftrt:DI (match_dup 0)
11850 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11851 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11852 (minus:QI (const_int 64) (match_dup 2)))))
11853 (clobber (reg:CC FLAGS_REG))]
11856 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11857 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11858 [(set_attr "type" "ishift")
11859 (set_attr "prefix_0f" "1")
11860 (set_attr "mode" "DI")
11861 (set_attr "athlon_decode" "vector")
11862 (set_attr "amdfam10_decode" "vector")])
11864 (define_expand "ashrdi3"
11865 [(set (match_operand:DI 0 "shiftdi_operand" "")
11866 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11867 (match_operand:QI 2 "nonmemory_operand" "")))]
11869 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11871 (define_insn "*ashrdi3_63_rex64"
11872 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11873 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11874 (match_operand:DI 2 "const_int_operand" "i,i")))
11875 (clobber (reg:CC FLAGS_REG))]
11876 "TARGET_64BIT && INTVAL (operands[2]) == 63
11877 && (TARGET_USE_CLTD || optimize_size)
11878 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11881 sar{q}\t{%2, %0|%0, %2}"
11882 [(set_attr "type" "imovx,ishift")
11883 (set_attr "prefix_0f" "0,*")
11884 (set_attr "length_immediate" "0,*")
11885 (set_attr "modrm" "0,1")
11886 (set_attr "mode" "DI")])
11888 (define_insn "*ashrdi3_1_one_bit_rex64"
11889 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11890 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11891 (match_operand:QI 2 "const1_operand" "")))
11892 (clobber (reg:CC FLAGS_REG))]
11894 && (TARGET_SHIFT1 || optimize_size)
11895 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11897 [(set_attr "type" "ishift")
11898 (set (attr "length")
11899 (if_then_else (match_operand:DI 0 "register_operand" "")
11901 (const_string "*")))])
11903 (define_insn "*ashrdi3_1_rex64"
11904 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11905 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11906 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11907 (clobber (reg:CC FLAGS_REG))]
11908 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11910 sar{q}\t{%2, %0|%0, %2}
11911 sar{q}\t{%b2, %0|%0, %b2}"
11912 [(set_attr "type" "ishift")
11913 (set_attr "mode" "DI")])
11915 ;; This pattern can't accept a variable shift count, since shifts by
11916 ;; zero don't affect the flags. We assume that shifts by constant
11917 ;; zero are optimized away.
11918 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11919 [(set (reg FLAGS_REG)
11921 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11922 (match_operand:QI 2 "const1_operand" ""))
11924 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11925 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11927 && (TARGET_SHIFT1 || optimize_size)
11928 && ix86_match_ccmode (insn, CCGOCmode)
11929 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11931 [(set_attr "type" "ishift")
11932 (set (attr "length")
11933 (if_then_else (match_operand:DI 0 "register_operand" "")
11935 (const_string "*")))])
11937 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11938 [(set (reg FLAGS_REG)
11940 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11941 (match_operand:QI 2 "const1_operand" ""))
11943 (clobber (match_scratch:DI 0 "=r"))]
11945 && (TARGET_SHIFT1 || optimize_size)
11946 && ix86_match_ccmode (insn, CCGOCmode)
11947 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11949 [(set_attr "type" "ishift")
11950 (set_attr "length" "2")])
11952 ;; This pattern can't accept a variable shift count, since shifts by
11953 ;; zero don't affect the flags. We assume that shifts by constant
11954 ;; zero are optimized away.
11955 (define_insn "*ashrdi3_cmp_rex64"
11956 [(set (reg FLAGS_REG)
11958 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11959 (match_operand:QI 2 "const_int_operand" "n"))
11961 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11962 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11964 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11965 && ix86_match_ccmode (insn, CCGOCmode)
11966 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11967 "sar{q}\t{%2, %0|%0, %2}"
11968 [(set_attr "type" "ishift")
11969 (set_attr "mode" "DI")])
11971 (define_insn "*ashrdi3_cconly_rex64"
11972 [(set (reg FLAGS_REG)
11974 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11975 (match_operand:QI 2 "const_int_operand" "n"))
11977 (clobber (match_scratch:DI 0 "=r"))]
11979 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11980 && ix86_match_ccmode (insn, CCGOCmode)
11981 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11982 "sar{q}\t{%2, %0|%0, %2}"
11983 [(set_attr "type" "ishift")
11984 (set_attr "mode" "DI")])
11986 (define_insn "*ashrdi3_1"
11987 [(set (match_operand:DI 0 "register_operand" "=r")
11988 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11989 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11990 (clobber (reg:CC FLAGS_REG))]
11993 [(set_attr "type" "multi")])
11995 ;; By default we don't ask for a scratch register, because when DImode
11996 ;; values are manipulated, registers are already at a premium. But if
11997 ;; we have one handy, we won't turn it away.
11999 [(match_scratch:SI 3 "r")
12000 (parallel [(set (match_operand:DI 0 "register_operand" "")
12001 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12002 (match_operand:QI 2 "nonmemory_operand" "")))
12003 (clobber (reg:CC FLAGS_REG))])
12005 "!TARGET_64BIT && TARGET_CMOVE"
12007 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12010 [(set (match_operand:DI 0 "register_operand" "")
12011 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12012 (match_operand:QI 2 "nonmemory_operand" "")))
12013 (clobber (reg:CC FLAGS_REG))]
12014 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12015 ? epilogue_completed : reload_completed)"
12017 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12019 (define_insn "x86_shrd_1"
12020 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12021 (ior:SI (ashiftrt:SI (match_dup 0)
12022 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12023 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12024 (minus:QI (const_int 32) (match_dup 2)))))
12025 (clobber (reg:CC FLAGS_REG))]
12028 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12029 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12030 [(set_attr "type" "ishift")
12031 (set_attr "prefix_0f" "1")
12032 (set_attr "pent_pair" "np")
12033 (set_attr "mode" "SI")])
12035 (define_expand "x86_shift_adj_3"
12036 [(use (match_operand:SI 0 "register_operand" ""))
12037 (use (match_operand:SI 1 "register_operand" ""))
12038 (use (match_operand:QI 2 "register_operand" ""))]
12041 rtx label = gen_label_rtx ();
12044 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12046 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12047 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12048 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12049 gen_rtx_LABEL_REF (VOIDmode, label),
12051 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12052 JUMP_LABEL (tmp) = label;
12054 emit_move_insn (operands[0], operands[1]);
12055 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12057 emit_label (label);
12058 LABEL_NUSES (label) = 1;
12063 (define_insn "ashrsi3_31"
12064 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12065 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12066 (match_operand:SI 2 "const_int_operand" "i,i")))
12067 (clobber (reg:CC FLAGS_REG))]
12068 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12069 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12072 sar{l}\t{%2, %0|%0, %2}"
12073 [(set_attr "type" "imovx,ishift")
12074 (set_attr "prefix_0f" "0,*")
12075 (set_attr "length_immediate" "0,*")
12076 (set_attr "modrm" "0,1")
12077 (set_attr "mode" "SI")])
12079 (define_insn "*ashrsi3_31_zext"
12080 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12081 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12082 (match_operand:SI 2 "const_int_operand" "i,i"))))
12083 (clobber (reg:CC FLAGS_REG))]
12084 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12085 && INTVAL (operands[2]) == 31
12086 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12089 sar{l}\t{%2, %k0|%k0, %2}"
12090 [(set_attr "type" "imovx,ishift")
12091 (set_attr "prefix_0f" "0,*")
12092 (set_attr "length_immediate" "0,*")
12093 (set_attr "modrm" "0,1")
12094 (set_attr "mode" "SI")])
12096 (define_expand "ashrsi3"
12097 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12098 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12099 (match_operand:QI 2 "nonmemory_operand" "")))
12100 (clobber (reg:CC FLAGS_REG))]
12102 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12104 (define_insn "*ashrsi3_1_one_bit"
12105 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12106 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12107 (match_operand:QI 2 "const1_operand" "")))
12108 (clobber (reg:CC FLAGS_REG))]
12109 "(TARGET_SHIFT1 || optimize_size)
12110 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12112 [(set_attr "type" "ishift")
12113 (set (attr "length")
12114 (if_then_else (match_operand:SI 0 "register_operand" "")
12116 (const_string "*")))])
12118 (define_insn "*ashrsi3_1_one_bit_zext"
12119 [(set (match_operand:DI 0 "register_operand" "=r")
12120 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12121 (match_operand:QI 2 "const1_operand" ""))))
12122 (clobber (reg:CC FLAGS_REG))]
12124 && (TARGET_SHIFT1 || optimize_size)
12125 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12127 [(set_attr "type" "ishift")
12128 (set_attr "length" "2")])
12130 (define_insn "*ashrsi3_1"
12131 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12132 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12133 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12134 (clobber (reg:CC FLAGS_REG))]
12135 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12137 sar{l}\t{%2, %0|%0, %2}
12138 sar{l}\t{%b2, %0|%0, %b2}"
12139 [(set_attr "type" "ishift")
12140 (set_attr "mode" "SI")])
12142 (define_insn "*ashrsi3_1_zext"
12143 [(set (match_operand:DI 0 "register_operand" "=r,r")
12144 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12145 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12146 (clobber (reg:CC FLAGS_REG))]
12147 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12149 sar{l}\t{%2, %k0|%k0, %2}
12150 sar{l}\t{%b2, %k0|%k0, %b2}"
12151 [(set_attr "type" "ishift")
12152 (set_attr "mode" "SI")])
12154 ;; This pattern can't accept a variable shift count, since shifts by
12155 ;; zero don't affect the flags. We assume that shifts by constant
12156 ;; zero are optimized away.
12157 (define_insn "*ashrsi3_one_bit_cmp"
12158 [(set (reg FLAGS_REG)
12160 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12161 (match_operand:QI 2 "const1_operand" ""))
12163 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12164 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12165 "(TARGET_SHIFT1 || optimize_size)
12166 && ix86_match_ccmode (insn, CCGOCmode)
12167 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12169 [(set_attr "type" "ishift")
12170 (set (attr "length")
12171 (if_then_else (match_operand:SI 0 "register_operand" "")
12173 (const_string "*")))])
12175 (define_insn "*ashrsi3_one_bit_cconly"
12176 [(set (reg FLAGS_REG)
12178 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12179 (match_operand:QI 2 "const1_operand" ""))
12181 (clobber (match_scratch:SI 0 "=r"))]
12182 "(TARGET_SHIFT1 || optimize_size)
12183 && ix86_match_ccmode (insn, CCGOCmode)
12184 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12186 [(set_attr "type" "ishift")
12187 (set_attr "length" "2")])
12189 (define_insn "*ashrsi3_one_bit_cmp_zext"
12190 [(set (reg FLAGS_REG)
12192 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12193 (match_operand:QI 2 "const1_operand" ""))
12195 (set (match_operand:DI 0 "register_operand" "=r")
12196 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12198 && (TARGET_SHIFT1 || optimize_size)
12199 && ix86_match_ccmode (insn, CCmode)
12200 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12202 [(set_attr "type" "ishift")
12203 (set_attr "length" "2")])
12205 ;; This pattern can't accept a variable shift count, since shifts by
12206 ;; zero don't affect the flags. We assume that shifts by constant
12207 ;; zero are optimized away.
12208 (define_insn "*ashrsi3_cmp"
12209 [(set (reg FLAGS_REG)
12211 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12212 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12214 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12215 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12216 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12217 && ix86_match_ccmode (insn, CCGOCmode)
12218 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12219 "sar{l}\t{%2, %0|%0, %2}"
12220 [(set_attr "type" "ishift")
12221 (set_attr "mode" "SI")])
12223 (define_insn "*ashrsi3_cconly"
12224 [(set (reg FLAGS_REG)
12226 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12227 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12229 (clobber (match_scratch:SI 0 "=r"))]
12230 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12231 && ix86_match_ccmode (insn, CCGOCmode)
12232 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12233 "sar{l}\t{%2, %0|%0, %2}"
12234 [(set_attr "type" "ishift")
12235 (set_attr "mode" "SI")])
12237 (define_insn "*ashrsi3_cmp_zext"
12238 [(set (reg FLAGS_REG)
12240 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12241 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12243 (set (match_operand:DI 0 "register_operand" "=r")
12244 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12246 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12247 && ix86_match_ccmode (insn, CCGOCmode)
12248 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12249 "sar{l}\t{%2, %k0|%k0, %2}"
12250 [(set_attr "type" "ishift")
12251 (set_attr "mode" "SI")])
12253 (define_expand "ashrhi3"
12254 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12255 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12256 (match_operand:QI 2 "nonmemory_operand" "")))
12257 (clobber (reg:CC FLAGS_REG))]
12258 "TARGET_HIMODE_MATH"
12259 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12261 (define_insn "*ashrhi3_1_one_bit"
12262 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12263 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12264 (match_operand:QI 2 "const1_operand" "")))
12265 (clobber (reg:CC FLAGS_REG))]
12266 "(TARGET_SHIFT1 || optimize_size)
12267 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12269 [(set_attr "type" "ishift")
12270 (set (attr "length")
12271 (if_then_else (match_operand 0 "register_operand" "")
12273 (const_string "*")))])
12275 (define_insn "*ashrhi3_1"
12276 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12277 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12278 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12279 (clobber (reg:CC FLAGS_REG))]
12280 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12282 sar{w}\t{%2, %0|%0, %2}
12283 sar{w}\t{%b2, %0|%0, %b2}"
12284 [(set_attr "type" "ishift")
12285 (set_attr "mode" "HI")])
12287 ;; This pattern can't accept a variable shift count, since shifts by
12288 ;; zero don't affect the flags. We assume that shifts by constant
12289 ;; zero are optimized away.
12290 (define_insn "*ashrhi3_one_bit_cmp"
12291 [(set (reg FLAGS_REG)
12293 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12294 (match_operand:QI 2 "const1_operand" ""))
12296 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12297 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12298 "(TARGET_SHIFT1 || optimize_size)
12299 && ix86_match_ccmode (insn, CCGOCmode)
12300 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12302 [(set_attr "type" "ishift")
12303 (set (attr "length")
12304 (if_then_else (match_operand 0 "register_operand" "")
12306 (const_string "*")))])
12308 (define_insn "*ashrhi3_one_bit_cconly"
12309 [(set (reg FLAGS_REG)
12311 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12312 (match_operand:QI 2 "const1_operand" ""))
12314 (clobber (match_scratch:HI 0 "=r"))]
12315 "(TARGET_SHIFT1 || optimize_size)
12316 && ix86_match_ccmode (insn, CCGOCmode)
12317 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12319 [(set_attr "type" "ishift")
12320 (set_attr "length" "2")])
12322 ;; This pattern can't accept a variable shift count, since shifts by
12323 ;; zero don't affect the flags. We assume that shifts by constant
12324 ;; zero are optimized away.
12325 (define_insn "*ashrhi3_cmp"
12326 [(set (reg FLAGS_REG)
12328 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12329 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12331 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12332 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12333 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12334 && ix86_match_ccmode (insn, CCGOCmode)
12335 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12336 "sar{w}\t{%2, %0|%0, %2}"
12337 [(set_attr "type" "ishift")
12338 (set_attr "mode" "HI")])
12340 (define_insn "*ashrhi3_cconly"
12341 [(set (reg FLAGS_REG)
12343 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12344 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12346 (clobber (match_scratch:HI 0 "=r"))]
12347 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12348 && ix86_match_ccmode (insn, CCGOCmode)
12349 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12350 "sar{w}\t{%2, %0|%0, %2}"
12351 [(set_attr "type" "ishift")
12352 (set_attr "mode" "HI")])
12354 (define_expand "ashrqi3"
12355 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12356 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12357 (match_operand:QI 2 "nonmemory_operand" "")))
12358 (clobber (reg:CC FLAGS_REG))]
12359 "TARGET_QIMODE_MATH"
12360 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12362 (define_insn "*ashrqi3_1_one_bit"
12363 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12364 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12365 (match_operand:QI 2 "const1_operand" "")))
12366 (clobber (reg:CC FLAGS_REG))]
12367 "(TARGET_SHIFT1 || optimize_size)
12368 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12370 [(set_attr "type" "ishift")
12371 (set (attr "length")
12372 (if_then_else (match_operand 0 "register_operand" "")
12374 (const_string "*")))])
12376 (define_insn "*ashrqi3_1_one_bit_slp"
12377 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12378 (ashiftrt:QI (match_dup 0)
12379 (match_operand:QI 1 "const1_operand" "")))
12380 (clobber (reg:CC FLAGS_REG))]
12381 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12382 && (TARGET_SHIFT1 || optimize_size)
12383 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12385 [(set_attr "type" "ishift1")
12386 (set (attr "length")
12387 (if_then_else (match_operand 0 "register_operand" "")
12389 (const_string "*")))])
12391 (define_insn "*ashrqi3_1"
12392 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12393 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12394 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12395 (clobber (reg:CC FLAGS_REG))]
12396 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12398 sar{b}\t{%2, %0|%0, %2}
12399 sar{b}\t{%b2, %0|%0, %b2}"
12400 [(set_attr "type" "ishift")
12401 (set_attr "mode" "QI")])
12403 (define_insn "*ashrqi3_1_slp"
12404 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12405 (ashiftrt:QI (match_dup 0)
12406 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12407 (clobber (reg:CC FLAGS_REG))]
12408 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12409 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12411 sar{b}\t{%1, %0|%0, %1}
12412 sar{b}\t{%b1, %0|%0, %b1}"
12413 [(set_attr "type" "ishift1")
12414 (set_attr "mode" "QI")])
12416 ;; This pattern can't accept a variable shift count, since shifts by
12417 ;; zero don't affect the flags. We assume that shifts by constant
12418 ;; zero are optimized away.
12419 (define_insn "*ashrqi3_one_bit_cmp"
12420 [(set (reg FLAGS_REG)
12422 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12423 (match_operand:QI 2 "const1_operand" "I"))
12425 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12426 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12427 "(TARGET_SHIFT1 || optimize_size)
12428 && ix86_match_ccmode (insn, CCGOCmode)
12429 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12431 [(set_attr "type" "ishift")
12432 (set (attr "length")
12433 (if_then_else (match_operand 0 "register_operand" "")
12435 (const_string "*")))])
12437 (define_insn "*ashrqi3_one_bit_cconly"
12438 [(set (reg FLAGS_REG)
12440 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12441 (match_operand:QI 2 "const1_operand" "I"))
12443 (clobber (match_scratch:QI 0 "=q"))]
12444 "(TARGET_SHIFT1 || optimize_size)
12445 && ix86_match_ccmode (insn, CCGOCmode)
12446 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12448 [(set_attr "type" "ishift")
12449 (set_attr "length" "2")])
12451 ;; This pattern can't accept a variable shift count, since shifts by
12452 ;; zero don't affect the flags. We assume that shifts by constant
12453 ;; zero are optimized away.
12454 (define_insn "*ashrqi3_cmp"
12455 [(set (reg FLAGS_REG)
12457 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12458 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12460 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12461 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12462 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12463 && ix86_match_ccmode (insn, CCGOCmode)
12464 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12465 "sar{b}\t{%2, %0|%0, %2}"
12466 [(set_attr "type" "ishift")
12467 (set_attr "mode" "QI")])
12469 (define_insn "*ashrqi3_cconly"
12470 [(set (reg FLAGS_REG)
12472 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12473 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12475 (clobber (match_scratch:QI 0 "=q"))]
12476 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12477 && ix86_match_ccmode (insn, CCGOCmode)
12478 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12479 "sar{b}\t{%2, %0|%0, %2}"
12480 [(set_attr "type" "ishift")
12481 (set_attr "mode" "QI")])
12484 ;; Logical shift instructions
12486 ;; See comment above `ashldi3' about how this works.
12488 (define_expand "lshrti3"
12489 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12490 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12491 (match_operand:QI 2 "nonmemory_operand" "")))
12492 (clobber (reg:CC FLAGS_REG))])]
12495 if (! immediate_operand (operands[2], QImode))
12497 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12500 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12504 (define_insn "lshrti3_1"
12505 [(set (match_operand:TI 0 "register_operand" "=r")
12506 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12507 (match_operand:QI 2 "register_operand" "c")))
12508 (clobber (match_scratch:DI 3 "=&r"))
12509 (clobber (reg:CC FLAGS_REG))]
12512 [(set_attr "type" "multi")])
12514 ;; This pattern must be defined before *lshrti3_2 to prevent
12515 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12517 (define_insn "sse2_lshrti3"
12518 [(set (match_operand:TI 0 "register_operand" "=x")
12519 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12520 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12523 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12524 return "psrldq\t{%2, %0|%0, %2}";
12526 [(set_attr "type" "sseishft")
12527 (set_attr "prefix_data16" "1")
12528 (set_attr "mode" "TI")])
12530 (define_insn "*lshrti3_2"
12531 [(set (match_operand:TI 0 "register_operand" "=r")
12532 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12533 (match_operand:QI 2 "immediate_operand" "O")))
12534 (clobber (reg:CC FLAGS_REG))]
12537 [(set_attr "type" "multi")])
12540 [(set (match_operand:TI 0 "register_operand" "")
12541 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12542 (match_operand:QI 2 "register_operand" "")))
12543 (clobber (match_scratch:DI 3 ""))
12544 (clobber (reg:CC FLAGS_REG))]
12545 "TARGET_64BIT && reload_completed"
12547 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12550 [(set (match_operand:TI 0 "register_operand" "")
12551 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12552 (match_operand:QI 2 "immediate_operand" "")))
12553 (clobber (reg:CC FLAGS_REG))]
12554 "TARGET_64BIT && reload_completed"
12556 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12558 (define_expand "lshrdi3"
12559 [(set (match_operand:DI 0 "shiftdi_operand" "")
12560 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12561 (match_operand:QI 2 "nonmemory_operand" "")))]
12563 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12565 (define_insn "*lshrdi3_1_one_bit_rex64"
12566 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12567 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12568 (match_operand:QI 2 "const1_operand" "")))
12569 (clobber (reg:CC FLAGS_REG))]
12571 && (TARGET_SHIFT1 || optimize_size)
12572 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12574 [(set_attr "type" "ishift")
12575 (set (attr "length")
12576 (if_then_else (match_operand:DI 0 "register_operand" "")
12578 (const_string "*")))])
12580 (define_insn "*lshrdi3_1_rex64"
12581 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12582 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12583 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12584 (clobber (reg:CC FLAGS_REG))]
12585 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12587 shr{q}\t{%2, %0|%0, %2}
12588 shr{q}\t{%b2, %0|%0, %b2}"
12589 [(set_attr "type" "ishift")
12590 (set_attr "mode" "DI")])
12592 ;; This pattern can't accept a variable shift count, since shifts by
12593 ;; zero don't affect the flags. We assume that shifts by constant
12594 ;; zero are optimized away.
12595 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12596 [(set (reg FLAGS_REG)
12598 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12599 (match_operand:QI 2 "const1_operand" ""))
12601 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12602 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12604 && (TARGET_SHIFT1 || optimize_size)
12605 && ix86_match_ccmode (insn, CCGOCmode)
12606 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12608 [(set_attr "type" "ishift")
12609 (set (attr "length")
12610 (if_then_else (match_operand:DI 0 "register_operand" "")
12612 (const_string "*")))])
12614 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12615 [(set (reg FLAGS_REG)
12617 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12618 (match_operand:QI 2 "const1_operand" ""))
12620 (clobber (match_scratch:DI 0 "=r"))]
12622 && (TARGET_SHIFT1 || optimize_size)
12623 && ix86_match_ccmode (insn, CCGOCmode)
12624 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12626 [(set_attr "type" "ishift")
12627 (set_attr "length" "2")])
12629 ;; This pattern can't accept a variable shift count, since shifts by
12630 ;; zero don't affect the flags. We assume that shifts by constant
12631 ;; zero are optimized away.
12632 (define_insn "*lshrdi3_cmp_rex64"
12633 [(set (reg FLAGS_REG)
12635 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12636 (match_operand:QI 2 "const_int_operand" "e"))
12638 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12639 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12641 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12642 && ix86_match_ccmode (insn, CCGOCmode)
12643 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12644 "shr{q}\t{%2, %0|%0, %2}"
12645 [(set_attr "type" "ishift")
12646 (set_attr "mode" "DI")])
12648 (define_insn "*lshrdi3_cconly_rex64"
12649 [(set (reg FLAGS_REG)
12651 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12652 (match_operand:QI 2 "const_int_operand" "e"))
12654 (clobber (match_scratch:DI 0 "=r"))]
12656 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12657 && ix86_match_ccmode (insn, CCGOCmode)
12658 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12659 "shr{q}\t{%2, %0|%0, %2}"
12660 [(set_attr "type" "ishift")
12661 (set_attr "mode" "DI")])
12663 (define_insn "*lshrdi3_1"
12664 [(set (match_operand:DI 0 "register_operand" "=r")
12665 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12666 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12667 (clobber (reg:CC FLAGS_REG))]
12670 [(set_attr "type" "multi")])
12672 ;; By default we don't ask for a scratch register, because when DImode
12673 ;; values are manipulated, registers are already at a premium. But if
12674 ;; we have one handy, we won't turn it away.
12676 [(match_scratch:SI 3 "r")
12677 (parallel [(set (match_operand:DI 0 "register_operand" "")
12678 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12679 (match_operand:QI 2 "nonmemory_operand" "")))
12680 (clobber (reg:CC FLAGS_REG))])
12682 "!TARGET_64BIT && TARGET_CMOVE"
12684 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12687 [(set (match_operand:DI 0 "register_operand" "")
12688 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12689 (match_operand:QI 2 "nonmemory_operand" "")))
12690 (clobber (reg:CC FLAGS_REG))]
12691 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12692 ? epilogue_completed : reload_completed)"
12694 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12696 (define_expand "lshrsi3"
12697 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12698 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12699 (match_operand:QI 2 "nonmemory_operand" "")))
12700 (clobber (reg:CC FLAGS_REG))]
12702 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12704 (define_insn "*lshrsi3_1_one_bit"
12705 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12706 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12707 (match_operand:QI 2 "const1_operand" "")))
12708 (clobber (reg:CC FLAGS_REG))]
12709 "(TARGET_SHIFT1 || optimize_size)
12710 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12712 [(set_attr "type" "ishift")
12713 (set (attr "length")
12714 (if_then_else (match_operand:SI 0 "register_operand" "")
12716 (const_string "*")))])
12718 (define_insn "*lshrsi3_1_one_bit_zext"
12719 [(set (match_operand:DI 0 "register_operand" "=r")
12720 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12721 (match_operand:QI 2 "const1_operand" "")))
12722 (clobber (reg:CC FLAGS_REG))]
12724 && (TARGET_SHIFT1 || optimize_size)
12725 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12727 [(set_attr "type" "ishift")
12728 (set_attr "length" "2")])
12730 (define_insn "*lshrsi3_1"
12731 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12732 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12733 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12734 (clobber (reg:CC FLAGS_REG))]
12735 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12737 shr{l}\t{%2, %0|%0, %2}
12738 shr{l}\t{%b2, %0|%0, %b2}"
12739 [(set_attr "type" "ishift")
12740 (set_attr "mode" "SI")])
12742 (define_insn "*lshrsi3_1_zext"
12743 [(set (match_operand:DI 0 "register_operand" "=r,r")
12745 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12746 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12747 (clobber (reg:CC FLAGS_REG))]
12748 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12750 shr{l}\t{%2, %k0|%k0, %2}
12751 shr{l}\t{%b2, %k0|%k0, %b2}"
12752 [(set_attr "type" "ishift")
12753 (set_attr "mode" "SI")])
12755 ;; This pattern can't accept a variable shift count, since shifts by
12756 ;; zero don't affect the flags. We assume that shifts by constant
12757 ;; zero are optimized away.
12758 (define_insn "*lshrsi3_one_bit_cmp"
12759 [(set (reg FLAGS_REG)
12761 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12762 (match_operand:QI 2 "const1_operand" ""))
12764 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12765 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12766 "(TARGET_SHIFT1 || optimize_size)
12767 && ix86_match_ccmode (insn, CCGOCmode)
12768 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12770 [(set_attr "type" "ishift")
12771 (set (attr "length")
12772 (if_then_else (match_operand:SI 0 "register_operand" "")
12774 (const_string "*")))])
12776 (define_insn "*lshrsi3_one_bit_cconly"
12777 [(set (reg FLAGS_REG)
12779 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12780 (match_operand:QI 2 "const1_operand" ""))
12782 (clobber (match_scratch:SI 0 "=r"))]
12783 "(TARGET_SHIFT1 || optimize_size)
12784 && ix86_match_ccmode (insn, CCGOCmode)
12785 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12787 [(set_attr "type" "ishift")
12788 (set_attr "length" "2")])
12790 (define_insn "*lshrsi3_cmp_one_bit_zext"
12791 [(set (reg FLAGS_REG)
12793 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12794 (match_operand:QI 2 "const1_operand" ""))
12796 (set (match_operand:DI 0 "register_operand" "=r")
12797 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12799 && (TARGET_SHIFT1 || optimize_size)
12800 && ix86_match_ccmode (insn, CCGOCmode)
12801 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12803 [(set_attr "type" "ishift")
12804 (set_attr "length" "2")])
12806 ;; This pattern can't accept a variable shift count, since shifts by
12807 ;; zero don't affect the flags. We assume that shifts by constant
12808 ;; zero are optimized away.
12809 (define_insn "*lshrsi3_cmp"
12810 [(set (reg FLAGS_REG)
12812 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12813 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12815 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12816 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12817 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12818 && ix86_match_ccmode (insn, CCGOCmode)
12819 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12820 "shr{l}\t{%2, %0|%0, %2}"
12821 [(set_attr "type" "ishift")
12822 (set_attr "mode" "SI")])
12824 (define_insn "*lshrsi3_cconly"
12825 [(set (reg FLAGS_REG)
12827 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12828 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12830 (clobber (match_scratch:SI 0 "=r"))]
12831 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12832 && ix86_match_ccmode (insn, CCGOCmode)
12833 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12834 "shr{l}\t{%2, %0|%0, %2}"
12835 [(set_attr "type" "ishift")
12836 (set_attr "mode" "SI")])
12838 (define_insn "*lshrsi3_cmp_zext"
12839 [(set (reg FLAGS_REG)
12841 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12842 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12844 (set (match_operand:DI 0 "register_operand" "=r")
12845 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12847 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12848 && ix86_match_ccmode (insn, CCGOCmode)
12849 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12850 "shr{l}\t{%2, %k0|%k0, %2}"
12851 [(set_attr "type" "ishift")
12852 (set_attr "mode" "SI")])
12854 (define_expand "lshrhi3"
12855 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12856 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12857 (match_operand:QI 2 "nonmemory_operand" "")))
12858 (clobber (reg:CC FLAGS_REG))]
12859 "TARGET_HIMODE_MATH"
12860 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12862 (define_insn "*lshrhi3_1_one_bit"
12863 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12864 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12865 (match_operand:QI 2 "const1_operand" "")))
12866 (clobber (reg:CC FLAGS_REG))]
12867 "(TARGET_SHIFT1 || optimize_size)
12868 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12870 [(set_attr "type" "ishift")
12871 (set (attr "length")
12872 (if_then_else (match_operand 0 "register_operand" "")
12874 (const_string "*")))])
12876 (define_insn "*lshrhi3_1"
12877 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12878 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12879 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12880 (clobber (reg:CC FLAGS_REG))]
12881 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12883 shr{w}\t{%2, %0|%0, %2}
12884 shr{w}\t{%b2, %0|%0, %b2}"
12885 [(set_attr "type" "ishift")
12886 (set_attr "mode" "HI")])
12888 ;; This pattern can't accept a variable shift count, since shifts by
12889 ;; zero don't affect the flags. We assume that shifts by constant
12890 ;; zero are optimized away.
12891 (define_insn "*lshrhi3_one_bit_cmp"
12892 [(set (reg FLAGS_REG)
12894 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12895 (match_operand:QI 2 "const1_operand" ""))
12897 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12898 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12899 "(TARGET_SHIFT1 || optimize_size)
12900 && ix86_match_ccmode (insn, CCGOCmode)
12901 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12903 [(set_attr "type" "ishift")
12904 (set (attr "length")
12905 (if_then_else (match_operand:SI 0 "register_operand" "")
12907 (const_string "*")))])
12909 (define_insn "*lshrhi3_one_bit_cconly"
12910 [(set (reg FLAGS_REG)
12912 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12913 (match_operand:QI 2 "const1_operand" ""))
12915 (clobber (match_scratch:HI 0 "=r"))]
12916 "(TARGET_SHIFT1 || optimize_size)
12917 && ix86_match_ccmode (insn, CCGOCmode)
12918 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12920 [(set_attr "type" "ishift")
12921 (set_attr "length" "2")])
12923 ;; This pattern can't accept a variable shift count, since shifts by
12924 ;; zero don't affect the flags. We assume that shifts by constant
12925 ;; zero are optimized away.
12926 (define_insn "*lshrhi3_cmp"
12927 [(set (reg FLAGS_REG)
12929 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12930 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12932 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12933 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12934 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12935 && ix86_match_ccmode (insn, CCGOCmode)
12936 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12937 "shr{w}\t{%2, %0|%0, %2}"
12938 [(set_attr "type" "ishift")
12939 (set_attr "mode" "HI")])
12941 (define_insn "*lshrhi3_cconly"
12942 [(set (reg FLAGS_REG)
12944 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12945 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12947 (clobber (match_scratch:HI 0 "=r"))]
12948 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12949 && ix86_match_ccmode (insn, CCGOCmode)
12950 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12951 "shr{w}\t{%2, %0|%0, %2}"
12952 [(set_attr "type" "ishift")
12953 (set_attr "mode" "HI")])
12955 (define_expand "lshrqi3"
12956 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12957 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12958 (match_operand:QI 2 "nonmemory_operand" "")))
12959 (clobber (reg:CC FLAGS_REG))]
12960 "TARGET_QIMODE_MATH"
12961 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12963 (define_insn "*lshrqi3_1_one_bit"
12964 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12965 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12966 (match_operand:QI 2 "const1_operand" "")))
12967 (clobber (reg:CC FLAGS_REG))]
12968 "(TARGET_SHIFT1 || optimize_size)
12969 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12971 [(set_attr "type" "ishift")
12972 (set (attr "length")
12973 (if_then_else (match_operand 0 "register_operand" "")
12975 (const_string "*")))])
12977 (define_insn "*lshrqi3_1_one_bit_slp"
12978 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12979 (lshiftrt:QI (match_dup 0)
12980 (match_operand:QI 1 "const1_operand" "")))
12981 (clobber (reg:CC FLAGS_REG))]
12982 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12983 && (TARGET_SHIFT1 || optimize_size)"
12985 [(set_attr "type" "ishift1")
12986 (set (attr "length")
12987 (if_then_else (match_operand 0 "register_operand" "")
12989 (const_string "*")))])
12991 (define_insn "*lshrqi3_1"
12992 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12993 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12994 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12995 (clobber (reg:CC FLAGS_REG))]
12996 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12998 shr{b}\t{%2, %0|%0, %2}
12999 shr{b}\t{%b2, %0|%0, %b2}"
13000 [(set_attr "type" "ishift")
13001 (set_attr "mode" "QI")])
13003 (define_insn "*lshrqi3_1_slp"
13004 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13005 (lshiftrt:QI (match_dup 0)
13006 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13007 (clobber (reg:CC FLAGS_REG))]
13008 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13009 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13011 shr{b}\t{%1, %0|%0, %1}
13012 shr{b}\t{%b1, %0|%0, %b1}"
13013 [(set_attr "type" "ishift1")
13014 (set_attr "mode" "QI")])
13016 ;; This pattern can't accept a variable shift count, since shifts by
13017 ;; zero don't affect the flags. We assume that shifts by constant
13018 ;; zero are optimized away.
13019 (define_insn "*lshrqi2_one_bit_cmp"
13020 [(set (reg FLAGS_REG)
13022 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13023 (match_operand:QI 2 "const1_operand" ""))
13025 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13026 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13027 "(TARGET_SHIFT1 || optimize_size)
13028 && ix86_match_ccmode (insn, CCGOCmode)
13029 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13031 [(set_attr "type" "ishift")
13032 (set (attr "length")
13033 (if_then_else (match_operand:SI 0 "register_operand" "")
13035 (const_string "*")))])
13037 (define_insn "*lshrqi2_one_bit_cconly"
13038 [(set (reg FLAGS_REG)
13040 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13041 (match_operand:QI 2 "const1_operand" ""))
13043 (clobber (match_scratch:QI 0 "=q"))]
13044 "(TARGET_SHIFT1 || optimize_size)
13045 && ix86_match_ccmode (insn, CCGOCmode)
13046 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13048 [(set_attr "type" "ishift")
13049 (set_attr "length" "2")])
13051 ;; This pattern can't accept a variable shift count, since shifts by
13052 ;; zero don't affect the flags. We assume that shifts by constant
13053 ;; zero are optimized away.
13054 (define_insn "*lshrqi2_cmp"
13055 [(set (reg FLAGS_REG)
13057 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13058 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13060 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13061 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13062 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13063 && ix86_match_ccmode (insn, CCGOCmode)
13064 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13065 "shr{b}\t{%2, %0|%0, %2}"
13066 [(set_attr "type" "ishift")
13067 (set_attr "mode" "QI")])
13069 (define_insn "*lshrqi2_cconly"
13070 [(set (reg FLAGS_REG)
13072 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13073 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13075 (clobber (match_scratch:QI 0 "=q"))]
13076 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13077 && ix86_match_ccmode (insn, CCGOCmode)
13078 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13079 "shr{b}\t{%2, %0|%0, %2}"
13080 [(set_attr "type" "ishift")
13081 (set_attr "mode" "QI")])
13083 ;; Rotate instructions
13085 (define_expand "rotldi3"
13086 [(set (match_operand:DI 0 "shiftdi_operand" "")
13087 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13088 (match_operand:QI 2 "nonmemory_operand" "")))
13089 (clobber (reg:CC FLAGS_REG))]
13094 ix86_expand_binary_operator (ROTATE, DImode, operands);
13097 if (!const_1_to_31_operand (operands[2], VOIDmode))
13099 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13103 ;; Implement rotation using two double-precision shift instructions
13104 ;; and a scratch register.
13105 (define_insn_and_split "ix86_rotldi3"
13106 [(set (match_operand:DI 0 "register_operand" "=r")
13107 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13108 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13109 (clobber (reg:CC FLAGS_REG))
13110 (clobber (match_scratch:SI 3 "=&r"))]
13113 "&& reload_completed"
13114 [(set (match_dup 3) (match_dup 4))
13116 [(set (match_dup 4)
13117 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13118 (lshiftrt:SI (match_dup 5)
13119 (minus:QI (const_int 32) (match_dup 2)))))
13120 (clobber (reg:CC FLAGS_REG))])
13122 [(set (match_dup 5)
13123 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13124 (lshiftrt:SI (match_dup 3)
13125 (minus:QI (const_int 32) (match_dup 2)))))
13126 (clobber (reg:CC FLAGS_REG))])]
13127 "split_di (operands, 1, operands + 4, operands + 5);")
13129 (define_insn "*rotlsi3_1_one_bit_rex64"
13130 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13131 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13132 (match_operand:QI 2 "const1_operand" "")))
13133 (clobber (reg:CC FLAGS_REG))]
13135 && (TARGET_SHIFT1 || optimize_size)
13136 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13138 [(set_attr "type" "rotate")
13139 (set (attr "length")
13140 (if_then_else (match_operand:DI 0 "register_operand" "")
13142 (const_string "*")))])
13144 (define_insn "*rotldi3_1_rex64"
13145 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13146 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13147 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13148 (clobber (reg:CC FLAGS_REG))]
13149 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13151 rol{q}\t{%2, %0|%0, %2}
13152 rol{q}\t{%b2, %0|%0, %b2}"
13153 [(set_attr "type" "rotate")
13154 (set_attr "mode" "DI")])
13156 (define_expand "rotlsi3"
13157 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13158 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13159 (match_operand:QI 2 "nonmemory_operand" "")))
13160 (clobber (reg:CC FLAGS_REG))]
13162 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13164 (define_insn "*rotlsi3_1_one_bit"
13165 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13166 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13167 (match_operand:QI 2 "const1_operand" "")))
13168 (clobber (reg:CC FLAGS_REG))]
13169 "(TARGET_SHIFT1 || optimize_size)
13170 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13172 [(set_attr "type" "rotate")
13173 (set (attr "length")
13174 (if_then_else (match_operand:SI 0 "register_operand" "")
13176 (const_string "*")))])
13178 (define_insn "*rotlsi3_1_one_bit_zext"
13179 [(set (match_operand:DI 0 "register_operand" "=r")
13181 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13182 (match_operand:QI 2 "const1_operand" ""))))
13183 (clobber (reg:CC FLAGS_REG))]
13185 && (TARGET_SHIFT1 || optimize_size)
13186 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13188 [(set_attr "type" "rotate")
13189 (set_attr "length" "2")])
13191 (define_insn "*rotlsi3_1"
13192 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13193 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13194 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13195 (clobber (reg:CC FLAGS_REG))]
13196 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13198 rol{l}\t{%2, %0|%0, %2}
13199 rol{l}\t{%b2, %0|%0, %b2}"
13200 [(set_attr "type" "rotate")
13201 (set_attr "mode" "SI")])
13203 (define_insn "*rotlsi3_1_zext"
13204 [(set (match_operand:DI 0 "register_operand" "=r,r")
13206 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13207 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13208 (clobber (reg:CC FLAGS_REG))]
13209 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13211 rol{l}\t{%2, %k0|%k0, %2}
13212 rol{l}\t{%b2, %k0|%k0, %b2}"
13213 [(set_attr "type" "rotate")
13214 (set_attr "mode" "SI")])
13216 (define_expand "rotlhi3"
13217 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13218 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13219 (match_operand:QI 2 "nonmemory_operand" "")))
13220 (clobber (reg:CC FLAGS_REG))]
13221 "TARGET_HIMODE_MATH"
13222 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13224 (define_insn "*rotlhi3_1_one_bit"
13225 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13226 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13227 (match_operand:QI 2 "const1_operand" "")))
13228 (clobber (reg:CC FLAGS_REG))]
13229 "(TARGET_SHIFT1 || optimize_size)
13230 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13232 [(set_attr "type" "rotate")
13233 (set (attr "length")
13234 (if_then_else (match_operand 0 "register_operand" "")
13236 (const_string "*")))])
13238 (define_insn "*rotlhi3_1"
13239 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13240 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13241 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13242 (clobber (reg:CC FLAGS_REG))]
13243 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13245 rol{w}\t{%2, %0|%0, %2}
13246 rol{w}\t{%b2, %0|%0, %b2}"
13247 [(set_attr "type" "rotate")
13248 (set_attr "mode" "HI")])
13251 [(set (match_operand:HI 0 "register_operand" "")
13252 (rotate:HI (match_dup 0) (const_int 8)))
13253 (clobber (reg:CC FLAGS_REG))]
13255 [(parallel [(set (strict_low_part (match_dup 0))
13256 (bswap:HI (match_dup 0)))
13257 (clobber (reg:CC FLAGS_REG))])]
13260 (define_expand "rotlqi3"
13261 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13262 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13263 (match_operand:QI 2 "nonmemory_operand" "")))
13264 (clobber (reg:CC FLAGS_REG))]
13265 "TARGET_QIMODE_MATH"
13266 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13268 (define_insn "*rotlqi3_1_one_bit_slp"
13269 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13270 (rotate:QI (match_dup 0)
13271 (match_operand:QI 1 "const1_operand" "")))
13272 (clobber (reg:CC FLAGS_REG))]
13273 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13274 && (TARGET_SHIFT1 || optimize_size)"
13276 [(set_attr "type" "rotate1")
13277 (set (attr "length")
13278 (if_then_else (match_operand 0 "register_operand" "")
13280 (const_string "*")))])
13282 (define_insn "*rotlqi3_1_one_bit"
13283 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13284 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13285 (match_operand:QI 2 "const1_operand" "")))
13286 (clobber (reg:CC FLAGS_REG))]
13287 "(TARGET_SHIFT1 || optimize_size)
13288 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13290 [(set_attr "type" "rotate")
13291 (set (attr "length")
13292 (if_then_else (match_operand 0 "register_operand" "")
13294 (const_string "*")))])
13296 (define_insn "*rotlqi3_1_slp"
13297 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13298 (rotate:QI (match_dup 0)
13299 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13300 (clobber (reg:CC FLAGS_REG))]
13301 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13302 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13304 rol{b}\t{%1, %0|%0, %1}
13305 rol{b}\t{%b1, %0|%0, %b1}"
13306 [(set_attr "type" "rotate1")
13307 (set_attr "mode" "QI")])
13309 (define_insn "*rotlqi3_1"
13310 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13311 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13312 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13313 (clobber (reg:CC FLAGS_REG))]
13314 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13316 rol{b}\t{%2, %0|%0, %2}
13317 rol{b}\t{%b2, %0|%0, %b2}"
13318 [(set_attr "type" "rotate")
13319 (set_attr "mode" "QI")])
13321 (define_expand "rotrdi3"
13322 [(set (match_operand:DI 0 "shiftdi_operand" "")
13323 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13324 (match_operand:QI 2 "nonmemory_operand" "")))
13325 (clobber (reg:CC FLAGS_REG))]
13330 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13333 if (!const_1_to_31_operand (operands[2], VOIDmode))
13335 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13339 ;; Implement rotation using two double-precision shift instructions
13340 ;; and a scratch register.
13341 (define_insn_and_split "ix86_rotrdi3"
13342 [(set (match_operand:DI 0 "register_operand" "=r")
13343 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13344 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13345 (clobber (reg:CC FLAGS_REG))
13346 (clobber (match_scratch:SI 3 "=&r"))]
13349 "&& reload_completed"
13350 [(set (match_dup 3) (match_dup 4))
13352 [(set (match_dup 4)
13353 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13354 (ashift:SI (match_dup 5)
13355 (minus:QI (const_int 32) (match_dup 2)))))
13356 (clobber (reg:CC FLAGS_REG))])
13358 [(set (match_dup 5)
13359 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13360 (ashift:SI (match_dup 3)
13361 (minus:QI (const_int 32) (match_dup 2)))))
13362 (clobber (reg:CC FLAGS_REG))])]
13363 "split_di (operands, 1, operands + 4, operands + 5);")
13365 (define_insn "*rotrdi3_1_one_bit_rex64"
13366 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13367 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13368 (match_operand:QI 2 "const1_operand" "")))
13369 (clobber (reg:CC FLAGS_REG))]
13371 && (TARGET_SHIFT1 || optimize_size)
13372 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13374 [(set_attr "type" "rotate")
13375 (set (attr "length")
13376 (if_then_else (match_operand:DI 0 "register_operand" "")
13378 (const_string "*")))])
13380 (define_insn "*rotrdi3_1_rex64"
13381 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13382 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13383 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13384 (clobber (reg:CC FLAGS_REG))]
13385 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13387 ror{q}\t{%2, %0|%0, %2}
13388 ror{q}\t{%b2, %0|%0, %b2}"
13389 [(set_attr "type" "rotate")
13390 (set_attr "mode" "DI")])
13392 (define_expand "rotrsi3"
13393 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13394 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13395 (match_operand:QI 2 "nonmemory_operand" "")))
13396 (clobber (reg:CC FLAGS_REG))]
13398 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13400 (define_insn "*rotrsi3_1_one_bit"
13401 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13402 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13403 (match_operand:QI 2 "const1_operand" "")))
13404 (clobber (reg:CC FLAGS_REG))]
13405 "(TARGET_SHIFT1 || optimize_size)
13406 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13408 [(set_attr "type" "rotate")
13409 (set (attr "length")
13410 (if_then_else (match_operand:SI 0 "register_operand" "")
13412 (const_string "*")))])
13414 (define_insn "*rotrsi3_1_one_bit_zext"
13415 [(set (match_operand:DI 0 "register_operand" "=r")
13417 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13418 (match_operand:QI 2 "const1_operand" ""))))
13419 (clobber (reg:CC FLAGS_REG))]
13421 && (TARGET_SHIFT1 || optimize_size)
13422 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13424 [(set_attr "type" "rotate")
13425 (set (attr "length")
13426 (if_then_else (match_operand:SI 0 "register_operand" "")
13428 (const_string "*")))])
13430 (define_insn "*rotrsi3_1"
13431 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13432 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13433 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13434 (clobber (reg:CC FLAGS_REG))]
13435 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13437 ror{l}\t{%2, %0|%0, %2}
13438 ror{l}\t{%b2, %0|%0, %b2}"
13439 [(set_attr "type" "rotate")
13440 (set_attr "mode" "SI")])
13442 (define_insn "*rotrsi3_1_zext"
13443 [(set (match_operand:DI 0 "register_operand" "=r,r")
13445 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13446 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13447 (clobber (reg:CC FLAGS_REG))]
13448 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13450 ror{l}\t{%2, %k0|%k0, %2}
13451 ror{l}\t{%b2, %k0|%k0, %b2}"
13452 [(set_attr "type" "rotate")
13453 (set_attr "mode" "SI")])
13455 (define_expand "rotrhi3"
13456 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13457 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13458 (match_operand:QI 2 "nonmemory_operand" "")))
13459 (clobber (reg:CC FLAGS_REG))]
13460 "TARGET_HIMODE_MATH"
13461 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13463 (define_insn "*rotrhi3_one_bit"
13464 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13465 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13466 (match_operand:QI 2 "const1_operand" "")))
13467 (clobber (reg:CC FLAGS_REG))]
13468 "(TARGET_SHIFT1 || optimize_size)
13469 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13471 [(set_attr "type" "rotate")
13472 (set (attr "length")
13473 (if_then_else (match_operand 0 "register_operand" "")
13475 (const_string "*")))])
13477 (define_insn "*rotrhi3_1"
13478 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13479 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13480 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13481 (clobber (reg:CC FLAGS_REG))]
13482 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13484 ror{w}\t{%2, %0|%0, %2}
13485 ror{w}\t{%b2, %0|%0, %b2}"
13486 [(set_attr "type" "rotate")
13487 (set_attr "mode" "HI")])
13490 [(set (match_operand:HI 0 "register_operand" "")
13491 (rotatert:HI (match_dup 0) (const_int 8)))
13492 (clobber (reg:CC FLAGS_REG))]
13494 [(parallel [(set (strict_low_part (match_dup 0))
13495 (bswap:HI (match_dup 0)))
13496 (clobber (reg:CC FLAGS_REG))])]
13499 (define_expand "rotrqi3"
13500 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13501 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13502 (match_operand:QI 2 "nonmemory_operand" "")))
13503 (clobber (reg:CC FLAGS_REG))]
13504 "TARGET_QIMODE_MATH"
13505 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13507 (define_insn "*rotrqi3_1_one_bit"
13508 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13509 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13510 (match_operand:QI 2 "const1_operand" "")))
13511 (clobber (reg:CC FLAGS_REG))]
13512 "(TARGET_SHIFT1 || optimize_size)
13513 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13515 [(set_attr "type" "rotate")
13516 (set (attr "length")
13517 (if_then_else (match_operand 0 "register_operand" "")
13519 (const_string "*")))])
13521 (define_insn "*rotrqi3_1_one_bit_slp"
13522 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13523 (rotatert:QI (match_dup 0)
13524 (match_operand:QI 1 "const1_operand" "")))
13525 (clobber (reg:CC FLAGS_REG))]
13526 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13527 && (TARGET_SHIFT1 || optimize_size)"
13529 [(set_attr "type" "rotate1")
13530 (set (attr "length")
13531 (if_then_else (match_operand 0 "register_operand" "")
13533 (const_string "*")))])
13535 (define_insn "*rotrqi3_1"
13536 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13537 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13538 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13539 (clobber (reg:CC FLAGS_REG))]
13540 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13542 ror{b}\t{%2, %0|%0, %2}
13543 ror{b}\t{%b2, %0|%0, %b2}"
13544 [(set_attr "type" "rotate")
13545 (set_attr "mode" "QI")])
13547 (define_insn "*rotrqi3_1_slp"
13548 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13549 (rotatert:QI (match_dup 0)
13550 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13551 (clobber (reg:CC FLAGS_REG))]
13552 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13553 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13555 ror{b}\t{%1, %0|%0, %1}
13556 ror{b}\t{%b1, %0|%0, %b1}"
13557 [(set_attr "type" "rotate1")
13558 (set_attr "mode" "QI")])
13560 ;; Bit set / bit test instructions
13562 (define_expand "extv"
13563 [(set (match_operand:SI 0 "register_operand" "")
13564 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13565 (match_operand:SI 2 "const8_operand" "")
13566 (match_operand:SI 3 "const8_operand" "")))]
13569 /* Handle extractions from %ah et al. */
13570 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13573 /* From mips.md: extract_bit_field doesn't verify that our source
13574 matches the predicate, so check it again here. */
13575 if (! ext_register_operand (operands[1], VOIDmode))
13579 (define_expand "extzv"
13580 [(set (match_operand:SI 0 "register_operand" "")
13581 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13582 (match_operand:SI 2 "const8_operand" "")
13583 (match_operand:SI 3 "const8_operand" "")))]
13586 /* Handle extractions from %ah et al. */
13587 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13590 /* From mips.md: extract_bit_field doesn't verify that our source
13591 matches the predicate, so check it again here. */
13592 if (! ext_register_operand (operands[1], VOIDmode))
13596 (define_expand "insv"
13597 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13598 (match_operand 1 "const8_operand" "")
13599 (match_operand 2 "const8_operand" ""))
13600 (match_operand 3 "register_operand" ""))]
13603 /* Handle insertions to %ah et al. */
13604 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13607 /* From mips.md: insert_bit_field doesn't verify that our source
13608 matches the predicate, so check it again here. */
13609 if (! ext_register_operand (operands[0], VOIDmode))
13613 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13615 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13620 ;; %%% bts, btr, btc, bt.
13621 ;; In general these instructions are *slow* when applied to memory,
13622 ;; since they enforce atomic operation. When applied to registers,
13623 ;; it depends on the cpu implementation. They're never faster than
13624 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13625 ;; no point. But in 64-bit, we can't hold the relevant immediates
13626 ;; within the instruction itself, so operating on bits in the high
13627 ;; 32-bits of a register becomes easier.
13629 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13630 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13631 ;; negdf respectively, so they can never be disabled entirely.
13633 (define_insn "*btsq"
13634 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13636 (match_operand:DI 1 "const_0_to_63_operand" ""))
13638 (clobber (reg:CC FLAGS_REG))]
13639 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13641 [(set_attr "type" "alu1")])
13643 (define_insn "*btrq"
13644 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13646 (match_operand:DI 1 "const_0_to_63_operand" ""))
13648 (clobber (reg:CC FLAGS_REG))]
13649 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13651 [(set_attr "type" "alu1")])
13653 (define_insn "*btcq"
13654 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13656 (match_operand:DI 1 "const_0_to_63_operand" ""))
13657 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13658 (clobber (reg:CC FLAGS_REG))]
13659 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13661 [(set_attr "type" "alu1")])
13663 ;; Allow Nocona to avoid these instructions if a register is available.
13666 [(match_scratch:DI 2 "r")
13667 (parallel [(set (zero_extract:DI
13668 (match_operand:DI 0 "register_operand" "")
13670 (match_operand:DI 1 "const_0_to_63_operand" ""))
13672 (clobber (reg:CC FLAGS_REG))])]
13673 "TARGET_64BIT && !TARGET_USE_BT"
13676 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13679 if (HOST_BITS_PER_WIDE_INT >= 64)
13680 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13681 else if (i < HOST_BITS_PER_WIDE_INT)
13682 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13684 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13686 op1 = immed_double_const (lo, hi, DImode);
13689 emit_move_insn (operands[2], op1);
13693 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13698 [(match_scratch:DI 2 "r")
13699 (parallel [(set (zero_extract:DI
13700 (match_operand:DI 0 "register_operand" "")
13702 (match_operand:DI 1 "const_0_to_63_operand" ""))
13704 (clobber (reg:CC FLAGS_REG))])]
13705 "TARGET_64BIT && !TARGET_USE_BT"
13708 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13711 if (HOST_BITS_PER_WIDE_INT >= 64)
13712 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13713 else if (i < HOST_BITS_PER_WIDE_INT)
13714 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13716 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13718 op1 = immed_double_const (~lo, ~hi, DImode);
13721 emit_move_insn (operands[2], op1);
13725 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13730 [(match_scratch:DI 2 "r")
13731 (parallel [(set (zero_extract:DI
13732 (match_operand:DI 0 "register_operand" "")
13734 (match_operand:DI 1 "const_0_to_63_operand" ""))
13735 (not:DI (zero_extract:DI
13736 (match_dup 0) (const_int 1) (match_dup 1))))
13737 (clobber (reg:CC FLAGS_REG))])]
13738 "TARGET_64BIT && !TARGET_USE_BT"
13741 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13744 if (HOST_BITS_PER_WIDE_INT >= 64)
13745 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13746 else if (i < HOST_BITS_PER_WIDE_INT)
13747 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13749 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13751 op1 = immed_double_const (lo, hi, DImode);
13754 emit_move_insn (operands[2], op1);
13758 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13762 ;; Store-flag instructions.
13764 ;; For all sCOND expanders, also expand the compare or test insn that
13765 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13767 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13768 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13769 ;; way, which can later delete the movzx if only QImode is needed.
13771 (define_expand "seq"
13772 [(set (match_operand:QI 0 "register_operand" "")
13773 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13775 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13777 (define_expand "sne"
13778 [(set (match_operand:QI 0 "register_operand" "")
13779 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13781 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13783 (define_expand "sgt"
13784 [(set (match_operand:QI 0 "register_operand" "")
13785 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13787 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13789 (define_expand "sgtu"
13790 [(set (match_operand:QI 0 "register_operand" "")
13791 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13793 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13795 (define_expand "slt"
13796 [(set (match_operand:QI 0 "register_operand" "")
13797 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13799 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13801 (define_expand "sltu"
13802 [(set (match_operand:QI 0 "register_operand" "")
13803 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13805 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13807 (define_expand "sge"
13808 [(set (match_operand:QI 0 "register_operand" "")
13809 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13811 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13813 (define_expand "sgeu"
13814 [(set (match_operand:QI 0 "register_operand" "")
13815 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13817 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13819 (define_expand "sle"
13820 [(set (match_operand:QI 0 "register_operand" "")
13821 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13823 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13825 (define_expand "sleu"
13826 [(set (match_operand:QI 0 "register_operand" "")
13827 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13829 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13831 (define_expand "sunordered"
13832 [(set (match_operand:QI 0 "register_operand" "")
13833 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13834 "TARGET_80387 || TARGET_SSE"
13835 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13837 (define_expand "sordered"
13838 [(set (match_operand:QI 0 "register_operand" "")
13839 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13841 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13843 (define_expand "suneq"
13844 [(set (match_operand:QI 0 "register_operand" "")
13845 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13846 "TARGET_80387 || TARGET_SSE"
13847 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13849 (define_expand "sunge"
13850 [(set (match_operand:QI 0 "register_operand" "")
13851 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13852 "TARGET_80387 || TARGET_SSE"
13853 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13855 (define_expand "sungt"
13856 [(set (match_operand:QI 0 "register_operand" "")
13857 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13858 "TARGET_80387 || TARGET_SSE"
13859 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13861 (define_expand "sunle"
13862 [(set (match_operand:QI 0 "register_operand" "")
13863 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13864 "TARGET_80387 || TARGET_SSE"
13865 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13867 (define_expand "sunlt"
13868 [(set (match_operand:QI 0 "register_operand" "")
13869 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13870 "TARGET_80387 || TARGET_SSE"
13871 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13873 (define_expand "sltgt"
13874 [(set (match_operand:QI 0 "register_operand" "")
13875 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13876 "TARGET_80387 || TARGET_SSE"
13877 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13879 (define_insn "*setcc_1"
13880 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13881 (match_operator:QI 1 "ix86_comparison_operator"
13882 [(reg FLAGS_REG) (const_int 0)]))]
13885 [(set_attr "type" "setcc")
13886 (set_attr "mode" "QI")])
13888 (define_insn "*setcc_2"
13889 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13890 (match_operator:QI 1 "ix86_comparison_operator"
13891 [(reg FLAGS_REG) (const_int 0)]))]
13894 [(set_attr "type" "setcc")
13895 (set_attr "mode" "QI")])
13897 ;; In general it is not safe to assume too much about CCmode registers,
13898 ;; so simplify-rtx stops when it sees a second one. Under certain
13899 ;; conditions this is safe on x86, so help combine not create
13906 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13907 (ne:QI (match_operator 1 "ix86_comparison_operator"
13908 [(reg FLAGS_REG) (const_int 0)])
13911 [(set (match_dup 0) (match_dup 1))]
13913 PUT_MODE (operands[1], QImode);
13917 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13918 (ne:QI (match_operator 1 "ix86_comparison_operator"
13919 [(reg FLAGS_REG) (const_int 0)])
13922 [(set (match_dup 0) (match_dup 1))]
13924 PUT_MODE (operands[1], QImode);
13928 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13929 (eq:QI (match_operator 1 "ix86_comparison_operator"
13930 [(reg FLAGS_REG) (const_int 0)])
13933 [(set (match_dup 0) (match_dup 1))]
13935 rtx new_op1 = copy_rtx (operands[1]);
13936 operands[1] = new_op1;
13937 PUT_MODE (new_op1, QImode);
13938 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13939 GET_MODE (XEXP (new_op1, 0))));
13941 /* Make sure that (a) the CCmode we have for the flags is strong
13942 enough for the reversed compare or (b) we have a valid FP compare. */
13943 if (! ix86_comparison_operator (new_op1, VOIDmode))
13948 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13949 (eq:QI (match_operator 1 "ix86_comparison_operator"
13950 [(reg FLAGS_REG) (const_int 0)])
13953 [(set (match_dup 0) (match_dup 1))]
13955 rtx new_op1 = copy_rtx (operands[1]);
13956 operands[1] = new_op1;
13957 PUT_MODE (new_op1, QImode);
13958 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13959 GET_MODE (XEXP (new_op1, 0))));
13961 /* Make sure that (a) the CCmode we have for the flags is strong
13962 enough for the reversed compare or (b) we have a valid FP compare. */
13963 if (! ix86_comparison_operator (new_op1, VOIDmode))
13967 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13968 ;; subsequent logical operations are used to imitate conditional moves.
13969 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13972 (define_insn "*sse_setccsf"
13973 [(set (match_operand:SF 0 "register_operand" "=x")
13974 (match_operator:SF 1 "sse_comparison_operator"
13975 [(match_operand:SF 2 "register_operand" "0")
13976 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13977 "TARGET_SSE && !TARGET_SSE5"
13978 "cmp%D1ss\t{%3, %0|%0, %3}"
13979 [(set_attr "type" "ssecmp")
13980 (set_attr "mode" "SF")])
13982 (define_insn "*sse_setccdf"
13983 [(set (match_operand:DF 0 "register_operand" "=x")
13984 (match_operator:DF 1 "sse_comparison_operator"
13985 [(match_operand:DF 2 "register_operand" "0")
13986 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13987 "TARGET_SSE2 && !TARGET_SSE5"
13988 "cmp%D1sd\t{%3, %0|%0, %3}"
13989 [(set_attr "type" "ssecmp")
13990 (set_attr "mode" "DF")])
13992 (define_insn "*sse5_setcc<mode>"
13993 [(set (match_operand:MODEF 0 "register_operand" "=x")
13994 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13995 [(match_operand:MODEF 2 "register_operand" "x")
13996 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13998 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13999 [(set_attr "type" "sse4arg")
14000 (set_attr "mode" "<MODE>")])
14003 ;; Basic conditional jump instructions.
14004 ;; We ignore the overflow flag for signed branch instructions.
14006 ;; For all bCOND expanders, also expand the compare or test insn that
14007 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14009 (define_expand "beq"
14011 (if_then_else (match_dup 1)
14012 (label_ref (match_operand 0 "" ""))
14015 "ix86_expand_branch (EQ, operands[0]); DONE;")
14017 (define_expand "bne"
14019 (if_then_else (match_dup 1)
14020 (label_ref (match_operand 0 "" ""))
14023 "ix86_expand_branch (NE, operands[0]); DONE;")
14025 (define_expand "bgt"
14027 (if_then_else (match_dup 1)
14028 (label_ref (match_operand 0 "" ""))
14031 "ix86_expand_branch (GT, operands[0]); DONE;")
14033 (define_expand "bgtu"
14035 (if_then_else (match_dup 1)
14036 (label_ref (match_operand 0 "" ""))
14039 "ix86_expand_branch (GTU, operands[0]); DONE;")
14041 (define_expand "blt"
14043 (if_then_else (match_dup 1)
14044 (label_ref (match_operand 0 "" ""))
14047 "ix86_expand_branch (LT, operands[0]); DONE;")
14049 (define_expand "bltu"
14051 (if_then_else (match_dup 1)
14052 (label_ref (match_operand 0 "" ""))
14055 "ix86_expand_branch (LTU, operands[0]); DONE;")
14057 (define_expand "bge"
14059 (if_then_else (match_dup 1)
14060 (label_ref (match_operand 0 "" ""))
14063 "ix86_expand_branch (GE, operands[0]); DONE;")
14065 (define_expand "bgeu"
14067 (if_then_else (match_dup 1)
14068 (label_ref (match_operand 0 "" ""))
14071 "ix86_expand_branch (GEU, operands[0]); DONE;")
14073 (define_expand "ble"
14075 (if_then_else (match_dup 1)
14076 (label_ref (match_operand 0 "" ""))
14079 "ix86_expand_branch (LE, operands[0]); DONE;")
14081 (define_expand "bleu"
14083 (if_then_else (match_dup 1)
14084 (label_ref (match_operand 0 "" ""))
14087 "ix86_expand_branch (LEU, operands[0]); DONE;")
14089 (define_expand "bunordered"
14091 (if_then_else (match_dup 1)
14092 (label_ref (match_operand 0 "" ""))
14094 "TARGET_80387 || TARGET_SSE_MATH"
14095 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
14097 (define_expand "bordered"
14099 (if_then_else (match_dup 1)
14100 (label_ref (match_operand 0 "" ""))
14102 "TARGET_80387 || TARGET_SSE_MATH"
14103 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
14105 (define_expand "buneq"
14107 (if_then_else (match_dup 1)
14108 (label_ref (match_operand 0 "" ""))
14110 "TARGET_80387 || TARGET_SSE_MATH"
14111 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
14113 (define_expand "bunge"
14115 (if_then_else (match_dup 1)
14116 (label_ref (match_operand 0 "" ""))
14118 "TARGET_80387 || TARGET_SSE_MATH"
14119 "ix86_expand_branch (UNGE, operands[0]); DONE;")
14121 (define_expand "bungt"
14123 (if_then_else (match_dup 1)
14124 (label_ref (match_operand 0 "" ""))
14126 "TARGET_80387 || TARGET_SSE_MATH"
14127 "ix86_expand_branch (UNGT, operands[0]); DONE;")
14129 (define_expand "bunle"
14131 (if_then_else (match_dup 1)
14132 (label_ref (match_operand 0 "" ""))
14134 "TARGET_80387 || TARGET_SSE_MATH"
14135 "ix86_expand_branch (UNLE, operands[0]); DONE;")
14137 (define_expand "bunlt"
14139 (if_then_else (match_dup 1)
14140 (label_ref (match_operand 0 "" ""))
14142 "TARGET_80387 || TARGET_SSE_MATH"
14143 "ix86_expand_branch (UNLT, operands[0]); DONE;")
14145 (define_expand "bltgt"
14147 (if_then_else (match_dup 1)
14148 (label_ref (match_operand 0 "" ""))
14150 "TARGET_80387 || TARGET_SSE_MATH"
14151 "ix86_expand_branch (LTGT, operands[0]); DONE;")
14153 (define_insn "*jcc_1"
14155 (if_then_else (match_operator 1 "ix86_comparison_operator"
14156 [(reg FLAGS_REG) (const_int 0)])
14157 (label_ref (match_operand 0 "" ""))
14161 [(set_attr "type" "ibr")
14162 (set_attr "modrm" "0")
14163 (set (attr "length")
14164 (if_then_else (and (ge (minus (match_dup 0) (pc))
14166 (lt (minus (match_dup 0) (pc))
14171 (define_insn "*jcc_2"
14173 (if_then_else (match_operator 1 "ix86_comparison_operator"
14174 [(reg FLAGS_REG) (const_int 0)])
14176 (label_ref (match_operand 0 "" ""))))]
14179 [(set_attr "type" "ibr")
14180 (set_attr "modrm" "0")
14181 (set (attr "length")
14182 (if_then_else (and (ge (minus (match_dup 0) (pc))
14184 (lt (minus (match_dup 0) (pc))
14189 ;; In general it is not safe to assume too much about CCmode registers,
14190 ;; so simplify-rtx stops when it sees a second one. Under certain
14191 ;; conditions this is safe on x86, so help combine not create
14199 (if_then_else (ne (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 PUT_MODE (operands[0], VOIDmode);
14215 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14216 [(reg FLAGS_REG) (const_int 0)])
14218 (label_ref (match_operand 1 "" ""))
14222 (if_then_else (match_dup 0)
14223 (label_ref (match_dup 1))
14226 rtx new_op0 = copy_rtx (operands[0]);
14227 operands[0] = new_op0;
14228 PUT_MODE (new_op0, VOIDmode);
14229 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14230 GET_MODE (XEXP (new_op0, 0))));
14232 /* Make sure that (a) the CCmode we have for the flags is strong
14233 enough for the reversed compare or (b) we have a valid FP compare. */
14234 if (! ix86_comparison_operator (new_op0, VOIDmode))
14238 ;; Define combination compare-and-branch fp compare instructions to use
14239 ;; during early optimization. Splitting the operation apart early makes
14240 ;; for bad code when we want to reverse the operation.
14242 (define_insn "*fp_jcc_1_mixed"
14244 (if_then_else (match_operator 0 "comparison_operator"
14245 [(match_operand 1 "register_operand" "f,x")
14246 (match_operand 2 "nonimmediate_operand" "f,xm")])
14247 (label_ref (match_operand 3 "" ""))
14249 (clobber (reg:CCFP FPSR_REG))
14250 (clobber (reg:CCFP FLAGS_REG))]
14251 "TARGET_MIX_SSE_I387
14252 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14253 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14254 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14257 (define_insn "*fp_jcc_1_sse"
14259 (if_then_else (match_operator 0 "comparison_operator"
14260 [(match_operand 1 "register_operand" "x")
14261 (match_operand 2 "nonimmediate_operand" "xm")])
14262 (label_ref (match_operand 3 "" ""))
14264 (clobber (reg:CCFP FPSR_REG))
14265 (clobber (reg:CCFP FLAGS_REG))]
14267 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14268 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14269 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14272 (define_insn "*fp_jcc_1_387"
14274 (if_then_else (match_operator 0 "comparison_operator"
14275 [(match_operand 1 "register_operand" "f")
14276 (match_operand 2 "register_operand" "f")])
14277 (label_ref (match_operand 3 "" ""))
14279 (clobber (reg:CCFP FPSR_REG))
14280 (clobber (reg:CCFP FLAGS_REG))]
14281 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14283 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14284 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14287 (define_insn "*fp_jcc_2_mixed"
14289 (if_then_else (match_operator 0 "comparison_operator"
14290 [(match_operand 1 "register_operand" "f,x")
14291 (match_operand 2 "nonimmediate_operand" "f,xm")])
14293 (label_ref (match_operand 3 "" ""))))
14294 (clobber (reg:CCFP FPSR_REG))
14295 (clobber (reg:CCFP FLAGS_REG))]
14296 "TARGET_MIX_SSE_I387
14297 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14298 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14299 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14302 (define_insn "*fp_jcc_2_sse"
14304 (if_then_else (match_operator 0 "comparison_operator"
14305 [(match_operand 1 "register_operand" "x")
14306 (match_operand 2 "nonimmediate_operand" "xm")])
14308 (label_ref (match_operand 3 "" ""))))
14309 (clobber (reg:CCFP FPSR_REG))
14310 (clobber (reg:CCFP FLAGS_REG))]
14312 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14313 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14314 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14317 (define_insn "*fp_jcc_2_387"
14319 (if_then_else (match_operator 0 "comparison_operator"
14320 [(match_operand 1 "register_operand" "f")
14321 (match_operand 2 "register_operand" "f")])
14323 (label_ref (match_operand 3 "" ""))))
14324 (clobber (reg:CCFP FPSR_REG))
14325 (clobber (reg:CCFP FLAGS_REG))]
14326 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14328 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14329 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14332 (define_insn "*fp_jcc_3_387"
14334 (if_then_else (match_operator 0 "comparison_operator"
14335 [(match_operand 1 "register_operand" "f")
14336 (match_operand 2 "nonimmediate_operand" "fm")])
14337 (label_ref (match_operand 3 "" ""))
14339 (clobber (reg:CCFP FPSR_REG))
14340 (clobber (reg:CCFP FLAGS_REG))
14341 (clobber (match_scratch:HI 4 "=a"))]
14343 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14344 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14345 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14346 && SELECT_CC_MODE (GET_CODE (operands[0]),
14347 operands[1], operands[2]) == CCFPmode
14348 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14351 (define_insn "*fp_jcc_4_387"
14353 (if_then_else (match_operator 0 "comparison_operator"
14354 [(match_operand 1 "register_operand" "f")
14355 (match_operand 2 "nonimmediate_operand" "fm")])
14357 (label_ref (match_operand 3 "" ""))))
14358 (clobber (reg:CCFP FPSR_REG))
14359 (clobber (reg:CCFP FLAGS_REG))
14360 (clobber (match_scratch:HI 4 "=a"))]
14362 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14363 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14364 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14365 && SELECT_CC_MODE (GET_CODE (operands[0]),
14366 operands[1], operands[2]) == CCFPmode
14367 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14370 (define_insn "*fp_jcc_5_387"
14372 (if_then_else (match_operator 0 "comparison_operator"
14373 [(match_operand 1 "register_operand" "f")
14374 (match_operand 2 "register_operand" "f")])
14375 (label_ref (match_operand 3 "" ""))
14377 (clobber (reg:CCFP FPSR_REG))
14378 (clobber (reg:CCFP FLAGS_REG))
14379 (clobber (match_scratch:HI 4 "=a"))]
14380 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14381 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14382 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14385 (define_insn "*fp_jcc_6_387"
14387 (if_then_else (match_operator 0 "comparison_operator"
14388 [(match_operand 1 "register_operand" "f")
14389 (match_operand 2 "register_operand" "f")])
14391 (label_ref (match_operand 3 "" ""))))
14392 (clobber (reg:CCFP FPSR_REG))
14393 (clobber (reg:CCFP FLAGS_REG))
14394 (clobber (match_scratch:HI 4 "=a"))]
14395 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14396 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14397 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14400 (define_insn "*fp_jcc_7_387"
14402 (if_then_else (match_operator 0 "comparison_operator"
14403 [(match_operand 1 "register_operand" "f")
14404 (match_operand 2 "const0_operand" "X")])
14405 (label_ref (match_operand 3 "" ""))
14407 (clobber (reg:CCFP FPSR_REG))
14408 (clobber (reg:CCFP FLAGS_REG))
14409 (clobber (match_scratch:HI 4 "=a"))]
14410 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14411 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14412 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14413 && SELECT_CC_MODE (GET_CODE (operands[0]),
14414 operands[1], operands[2]) == CCFPmode
14415 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14418 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14419 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14420 ;; with a precedence over other operators and is always put in the first
14421 ;; place. Swap condition and operands to match ficom instruction.
14423 (define_insn "*fp_jcc_8<mode>_387"
14425 (if_then_else (match_operator 0 "comparison_operator"
14426 [(match_operator 1 "float_operator"
14427 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14428 (match_operand 3 "register_operand" "f,f")])
14429 (label_ref (match_operand 4 "" ""))
14431 (clobber (reg:CCFP FPSR_REG))
14432 (clobber (reg:CCFP FLAGS_REG))
14433 (clobber (match_scratch:HI 5 "=a,a"))]
14434 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14435 && TARGET_USE_<MODE>MODE_FIOP
14436 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14437 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14438 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14439 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14444 (if_then_else (match_operator 0 "comparison_operator"
14445 [(match_operand 1 "register_operand" "")
14446 (match_operand 2 "nonimmediate_operand" "")])
14447 (match_operand 3 "" "")
14448 (match_operand 4 "" "")))
14449 (clobber (reg:CCFP FPSR_REG))
14450 (clobber (reg:CCFP FLAGS_REG))]
14454 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14455 operands[3], operands[4], NULL_RTX, NULL_RTX);
14461 (if_then_else (match_operator 0 "comparison_operator"
14462 [(match_operand 1 "register_operand" "")
14463 (match_operand 2 "general_operand" "")])
14464 (match_operand 3 "" "")
14465 (match_operand 4 "" "")))
14466 (clobber (reg:CCFP FPSR_REG))
14467 (clobber (reg:CCFP FLAGS_REG))
14468 (clobber (match_scratch:HI 5 "=a"))]
14472 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14473 operands[3], operands[4], operands[5], NULL_RTX);
14479 (if_then_else (match_operator 0 "comparison_operator"
14480 [(match_operator 1 "float_operator"
14481 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14482 (match_operand 3 "register_operand" "")])
14483 (match_operand 4 "" "")
14484 (match_operand 5 "" "")))
14485 (clobber (reg:CCFP FPSR_REG))
14486 (clobber (reg:CCFP FLAGS_REG))
14487 (clobber (match_scratch:HI 6 "=a"))]
14491 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14492 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14493 operands[3], operands[7],
14494 operands[4], operands[5], operands[6], NULL_RTX);
14498 ;; %%% Kill this when reload knows how to do it.
14501 (if_then_else (match_operator 0 "comparison_operator"
14502 [(match_operator 1 "float_operator"
14503 [(match_operand:X87MODEI12 2 "register_operand" "")])
14504 (match_operand 3 "register_operand" "")])
14505 (match_operand 4 "" "")
14506 (match_operand 5 "" "")))
14507 (clobber (reg:CCFP FPSR_REG))
14508 (clobber (reg:CCFP FLAGS_REG))
14509 (clobber (match_scratch:HI 6 "=a"))]
14513 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14514 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14515 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14516 operands[3], operands[7],
14517 operands[4], operands[5], operands[6], operands[2]);
14521 ;; Unconditional and other jump instructions
14523 (define_insn "jump"
14525 (label_ref (match_operand 0 "" "")))]
14528 [(set_attr "type" "ibr")
14529 (set (attr "length")
14530 (if_then_else (and (ge (minus (match_dup 0) (pc))
14532 (lt (minus (match_dup 0) (pc))
14536 (set_attr "modrm" "0")])
14538 (define_expand "indirect_jump"
14539 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14543 (define_insn "*indirect_jump"
14544 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14547 [(set_attr "type" "ibr")
14548 (set_attr "length_immediate" "0")])
14550 (define_insn "*indirect_jump_rtx64"
14551 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14554 [(set_attr "type" "ibr")
14555 (set_attr "length_immediate" "0")])
14557 (define_expand "tablejump"
14558 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14559 (use (label_ref (match_operand 1 "" "")))])]
14562 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14563 relative. Convert the relative address to an absolute address. */
14567 enum rtx_code code;
14569 /* We can't use @GOTOFF for text labels on VxWorks;
14570 see gotoff_operand. */
14571 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14575 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14577 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14581 op1 = pic_offset_table_rtx;
14586 op0 = pic_offset_table_rtx;
14590 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14595 (define_insn "*tablejump_1"
14596 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14597 (use (label_ref (match_operand 1 "" "")))]
14600 [(set_attr "type" "ibr")
14601 (set_attr "length_immediate" "0")])
14603 (define_insn "*tablejump_1_rtx64"
14604 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14605 (use (label_ref (match_operand 1 "" "")))]
14608 [(set_attr "type" "ibr")
14609 (set_attr "length_immediate" "0")])
14611 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14614 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14615 (set (match_operand:QI 1 "register_operand" "")
14616 (match_operator:QI 2 "ix86_comparison_operator"
14617 [(reg FLAGS_REG) (const_int 0)]))
14618 (set (match_operand 3 "q_regs_operand" "")
14619 (zero_extend (match_dup 1)))]
14620 "(peep2_reg_dead_p (3, operands[1])
14621 || operands_match_p (operands[1], operands[3]))
14622 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14623 [(set (match_dup 4) (match_dup 0))
14624 (set (strict_low_part (match_dup 5))
14627 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14628 operands[5] = gen_lowpart (QImode, operands[3]);
14629 ix86_expand_clear (operands[3]);
14632 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14635 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14636 (set (match_operand:QI 1 "register_operand" "")
14637 (match_operator:QI 2 "ix86_comparison_operator"
14638 [(reg FLAGS_REG) (const_int 0)]))
14639 (parallel [(set (match_operand 3 "q_regs_operand" "")
14640 (zero_extend (match_dup 1)))
14641 (clobber (reg:CC FLAGS_REG))])]
14642 "(peep2_reg_dead_p (3, operands[1])
14643 || operands_match_p (operands[1], operands[3]))
14644 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14645 [(set (match_dup 4) (match_dup 0))
14646 (set (strict_low_part (match_dup 5))
14649 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14650 operands[5] = gen_lowpart (QImode, operands[3]);
14651 ix86_expand_clear (operands[3]);
14654 ;; Call instructions.
14656 ;; The predicates normally associated with named expanders are not properly
14657 ;; checked for calls. This is a bug in the generic code, but it isn't that
14658 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14660 ;; Call subroutine returning no value.
14662 (define_expand "call_pop"
14663 [(parallel [(call (match_operand:QI 0 "" "")
14664 (match_operand:SI 1 "" ""))
14665 (set (reg:SI SP_REG)
14666 (plus:SI (reg:SI SP_REG)
14667 (match_operand:SI 3 "" "")))])]
14670 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14674 (define_insn "*call_pop_0"
14675 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14676 (match_operand:SI 1 "" ""))
14677 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14678 (match_operand:SI 2 "immediate_operand" "")))]
14681 if (SIBLING_CALL_P (insn))
14684 return "call\t%P0";
14686 [(set_attr "type" "call")])
14688 (define_insn "*call_pop_1"
14689 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14690 (match_operand:SI 1 "" ""))
14691 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14692 (match_operand:SI 2 "immediate_operand" "i")))]
14695 if (constant_call_address_operand (operands[0], Pmode))
14697 if (SIBLING_CALL_P (insn))
14700 return "call\t%P0";
14702 if (SIBLING_CALL_P (insn))
14705 return "call\t%A0";
14707 [(set_attr "type" "call")])
14709 (define_expand "call"
14710 [(call (match_operand:QI 0 "" "")
14711 (match_operand 1 "" ""))
14712 (use (match_operand 2 "" ""))]
14715 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14719 (define_expand "sibcall"
14720 [(call (match_operand:QI 0 "" "")
14721 (match_operand 1 "" ""))
14722 (use (match_operand 2 "" ""))]
14725 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14729 (define_insn "*call_0"
14730 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14731 (match_operand 1 "" ""))]
14734 if (SIBLING_CALL_P (insn))
14737 return "call\t%P0";
14739 [(set_attr "type" "call")])
14741 (define_insn "*call_1"
14742 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14743 (match_operand 1 "" ""))]
14744 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14746 if (constant_call_address_operand (operands[0], Pmode))
14747 return "call\t%P0";
14748 return "call\t%A0";
14750 [(set_attr "type" "call")])
14752 (define_insn "*sibcall_1"
14753 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14754 (match_operand 1 "" ""))]
14755 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14757 if (constant_call_address_operand (operands[0], Pmode))
14761 [(set_attr "type" "call")])
14763 (define_insn "*call_1_rex64"
14764 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14765 (match_operand 1 "" ""))]
14766 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14767 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14769 if (constant_call_address_operand (operands[0], Pmode))
14770 return "call\t%P0";
14771 return "call\t%A0";
14773 [(set_attr "type" "call")])
14775 (define_insn "*call_1_rex64_large"
14776 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14777 (match_operand 1 "" ""))]
14778 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14780 [(set_attr "type" "call")])
14782 (define_insn "*sibcall_1_rex64"
14783 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14784 (match_operand 1 "" ""))]
14785 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14787 [(set_attr "type" "call")])
14789 (define_insn "*sibcall_1_rex64_v"
14790 [(call (mem:QI (reg:DI R11_REG))
14791 (match_operand 0 "" ""))]
14792 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14794 [(set_attr "type" "call")])
14797 ;; Call subroutine, returning value in operand 0
14799 (define_expand "call_value_pop"
14800 [(parallel [(set (match_operand 0 "" "")
14801 (call (match_operand:QI 1 "" "")
14802 (match_operand:SI 2 "" "")))
14803 (set (reg:SI SP_REG)
14804 (plus:SI (reg:SI SP_REG)
14805 (match_operand:SI 4 "" "")))])]
14808 ix86_expand_call (operands[0], operands[1], operands[2],
14809 operands[3], operands[4], 0);
14813 (define_expand "call_value"
14814 [(set (match_operand 0 "" "")
14815 (call (match_operand:QI 1 "" "")
14816 (match_operand:SI 2 "" "")))
14817 (use (match_operand:SI 3 "" ""))]
14818 ;; Operand 2 not used on the i386.
14821 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14825 (define_expand "sibcall_value"
14826 [(set (match_operand 0 "" "")
14827 (call (match_operand:QI 1 "" "")
14828 (match_operand:SI 2 "" "")))
14829 (use (match_operand:SI 3 "" ""))]
14830 ;; Operand 2 not used on the i386.
14833 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14837 ;; Call subroutine returning any type.
14839 (define_expand "untyped_call"
14840 [(parallel [(call (match_operand 0 "" "")
14842 (match_operand 1 "" "")
14843 (match_operand 2 "" "")])]
14848 /* In order to give reg-stack an easier job in validating two
14849 coprocessor registers as containing a possible return value,
14850 simply pretend the untyped call returns a complex long double
14853 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14854 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14855 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14858 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14860 rtx set = XVECEXP (operands[2], 0, i);
14861 emit_move_insn (SET_DEST (set), SET_SRC (set));
14864 /* The optimizer does not know that the call sets the function value
14865 registers we stored in the result block. We avoid problems by
14866 claiming that all hard registers are used and clobbered at this
14868 emit_insn (gen_blockage ());
14873 ;; Prologue and epilogue instructions
14875 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14876 ;; all of memory. This blocks insns from being moved across this point.
14878 (define_insn "blockage"
14879 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14882 [(set_attr "length" "0")])
14884 ;; As USE insns aren't meaningful after reload, this is used instead
14885 ;; to prevent deleting instructions setting registers for PIC code
14886 (define_insn "prologue_use"
14887 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14890 [(set_attr "length" "0")])
14892 ;; Insn emitted into the body of a function to return from a function.
14893 ;; This is only done if the function's epilogue is known to be simple.
14894 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14896 (define_expand "return"
14898 "ix86_can_use_return_insn_p ()"
14900 if (current_function_pops_args)
14902 rtx popc = GEN_INT (current_function_pops_args);
14903 emit_jump_insn (gen_return_pop_internal (popc));
14908 (define_insn "return_internal"
14912 [(set_attr "length" "1")
14913 (set_attr "length_immediate" "0")
14914 (set_attr "modrm" "0")])
14916 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14917 ;; instruction Athlon and K8 have.
14919 (define_insn "return_internal_long"
14921 (unspec [(const_int 0)] UNSPEC_REP)]
14924 [(set_attr "length" "1")
14925 (set_attr "length_immediate" "0")
14926 (set_attr "prefix_rep" "1")
14927 (set_attr "modrm" "0")])
14929 (define_insn "return_pop_internal"
14931 (use (match_operand:SI 0 "const_int_operand" ""))]
14934 [(set_attr "length" "3")
14935 (set_attr "length_immediate" "2")
14936 (set_attr "modrm" "0")])
14938 (define_insn "return_indirect_internal"
14940 (use (match_operand:SI 0 "register_operand" "r"))]
14943 [(set_attr "type" "ibr")
14944 (set_attr "length_immediate" "0")])
14950 [(set_attr "length" "1")
14951 (set_attr "length_immediate" "0")
14952 (set_attr "modrm" "0")])
14954 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14955 ;; branch prediction penalty for the third jump in a 16-byte
14958 (define_insn "align"
14959 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14962 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14963 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14965 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14966 The align insn is used to avoid 3 jump instructions in the row to improve
14967 branch prediction and the benefits hardly outweigh the cost of extra 8
14968 nops on the average inserted by full alignment pseudo operation. */
14972 [(set_attr "length" "16")])
14974 (define_expand "prologue"
14977 "ix86_expand_prologue (); DONE;")
14979 (define_insn "set_got"
14980 [(set (match_operand:SI 0 "register_operand" "=r")
14981 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14982 (clobber (reg:CC FLAGS_REG))]
14984 { return output_set_got (operands[0], NULL_RTX); }
14985 [(set_attr "type" "multi")
14986 (set_attr "length" "12")])
14988 (define_insn "set_got_labelled"
14989 [(set (match_operand:SI 0 "register_operand" "=r")
14990 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14992 (clobber (reg:CC FLAGS_REG))]
14994 { return output_set_got (operands[0], operands[1]); }
14995 [(set_attr "type" "multi")
14996 (set_attr "length" "12")])
14998 (define_insn "set_got_rex64"
14999 [(set (match_operand:DI 0 "register_operand" "=r")
15000 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15002 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15003 [(set_attr "type" "lea")
15004 (set_attr "length" "6")])
15006 (define_insn "set_rip_rex64"
15007 [(set (match_operand:DI 0 "register_operand" "=r")
15008 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15010 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15011 [(set_attr "type" "lea")
15012 (set_attr "length" "6")])
15014 (define_insn "set_got_offset_rex64"
15015 [(set (match_operand:DI 0 "register_operand" "=r")
15016 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15018 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15019 [(set_attr "type" "imov")
15020 (set_attr "length" "11")])
15022 (define_expand "epilogue"
15025 "ix86_expand_epilogue (1); DONE;")
15027 (define_expand "sibcall_epilogue"
15030 "ix86_expand_epilogue (0); DONE;")
15032 (define_expand "eh_return"
15033 [(use (match_operand 0 "register_operand" ""))]
15036 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15038 /* Tricky bit: we write the address of the handler to which we will
15039 be returning into someone else's stack frame, one word below the
15040 stack address we wish to restore. */
15041 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15042 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15043 tmp = gen_rtx_MEM (Pmode, tmp);
15044 emit_move_insn (tmp, ra);
15046 if (Pmode == SImode)
15047 emit_jump_insn (gen_eh_return_si (sa));
15049 emit_jump_insn (gen_eh_return_di (sa));
15054 (define_insn_and_split "eh_return_si"
15056 (unspec [(match_operand:SI 0 "register_operand" "c")]
15057 UNSPEC_EH_RETURN))]
15062 "ix86_expand_epilogue (2); DONE;")
15064 (define_insn_and_split "eh_return_di"
15066 (unspec [(match_operand:DI 0 "register_operand" "c")]
15067 UNSPEC_EH_RETURN))]
15072 "ix86_expand_epilogue (2); DONE;")
15074 (define_insn "leave"
15075 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15076 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15077 (clobber (mem:BLK (scratch)))]
15080 [(set_attr "type" "leave")])
15082 (define_insn "leave_rex64"
15083 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15084 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15085 (clobber (mem:BLK (scratch)))]
15088 [(set_attr "type" "leave")])
15090 (define_expand "ffssi2"
15092 [(set (match_operand:SI 0 "register_operand" "")
15093 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15094 (clobber (match_scratch:SI 2 ""))
15095 (clobber (reg:CC FLAGS_REG))])]
15100 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15105 (define_expand "ffs_cmove"
15106 [(set (match_dup 2) (const_int -1))
15107 (parallel [(set (reg:CCZ FLAGS_REG)
15108 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15110 (set (match_operand:SI 0 "nonimmediate_operand" "")
15111 (ctz:SI (match_dup 1)))])
15112 (set (match_dup 0) (if_then_else:SI
15113 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15116 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15117 (clobber (reg:CC FLAGS_REG))])]
15119 "operands[2] = gen_reg_rtx (SImode);")
15121 (define_insn_and_split "*ffs_no_cmove"
15122 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15123 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15124 (clobber (match_scratch:SI 2 "=&q"))
15125 (clobber (reg:CC FLAGS_REG))]
15128 "&& reload_completed"
15129 [(parallel [(set (reg:CCZ FLAGS_REG)
15130 (compare:CCZ (match_dup 1) (const_int 0)))
15131 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15132 (set (strict_low_part (match_dup 3))
15133 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15134 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15135 (clobber (reg:CC FLAGS_REG))])
15136 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15137 (clobber (reg:CC FLAGS_REG))])
15138 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15139 (clobber (reg:CC FLAGS_REG))])]
15141 operands[3] = gen_lowpart (QImode, operands[2]);
15142 ix86_expand_clear (operands[2]);
15145 (define_insn "*ffssi_1"
15146 [(set (reg:CCZ FLAGS_REG)
15147 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15149 (set (match_operand:SI 0 "register_operand" "=r")
15150 (ctz:SI (match_dup 1)))]
15152 "bsf{l}\t{%1, %0|%0, %1}"
15153 [(set_attr "prefix_0f" "1")])
15155 (define_expand "ffsdi2"
15156 [(set (match_dup 2) (const_int -1))
15157 (parallel [(set (reg:CCZ FLAGS_REG)
15158 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15160 (set (match_operand:DI 0 "nonimmediate_operand" "")
15161 (ctz:DI (match_dup 1)))])
15162 (set (match_dup 0) (if_then_else:DI
15163 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15166 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15167 (clobber (reg:CC FLAGS_REG))])]
15169 "operands[2] = gen_reg_rtx (DImode);")
15171 (define_insn "*ffsdi_1"
15172 [(set (reg:CCZ FLAGS_REG)
15173 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15175 (set (match_operand:DI 0 "register_operand" "=r")
15176 (ctz:DI (match_dup 1)))]
15178 "bsf{q}\t{%1, %0|%0, %1}"
15179 [(set_attr "prefix_0f" "1")])
15181 (define_insn "ctzsi2"
15182 [(set (match_operand:SI 0 "register_operand" "=r")
15183 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15184 (clobber (reg:CC FLAGS_REG))]
15186 "bsf{l}\t{%1, %0|%0, %1}"
15187 [(set_attr "prefix_0f" "1")])
15189 (define_insn "ctzdi2"
15190 [(set (match_operand:DI 0 "register_operand" "=r")
15191 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15192 (clobber (reg:CC FLAGS_REG))]
15194 "bsf{q}\t{%1, %0|%0, %1}"
15195 [(set_attr "prefix_0f" "1")])
15197 (define_expand "clzsi2"
15199 [(set (match_operand:SI 0 "register_operand" "")
15200 (minus:SI (const_int 31)
15201 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15202 (clobber (reg:CC FLAGS_REG))])
15204 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15205 (clobber (reg:CC FLAGS_REG))])]
15210 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15215 (define_insn "clzsi2_abm"
15216 [(set (match_operand:SI 0 "register_operand" "=r")
15217 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15218 (clobber (reg:CC FLAGS_REG))]
15220 "lzcnt{l}\t{%1, %0|%0, %1}"
15221 [(set_attr "prefix_rep" "1")
15222 (set_attr "type" "bitmanip")
15223 (set_attr "mode" "SI")])
15225 (define_insn "*bsr"
15226 [(set (match_operand:SI 0 "register_operand" "=r")
15227 (minus:SI (const_int 31)
15228 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15229 (clobber (reg:CC FLAGS_REG))]
15231 "bsr{l}\t{%1, %0|%0, %1}"
15232 [(set_attr "prefix_0f" "1")
15233 (set_attr "mode" "SI")])
15235 (define_insn "popcountsi2"
15236 [(set (match_operand:SI 0 "register_operand" "=r")
15237 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15238 (clobber (reg:CC FLAGS_REG))]
15240 "popcnt{l}\t{%1, %0|%0, %1}"
15241 [(set_attr "prefix_rep" "1")
15242 (set_attr "type" "bitmanip")
15243 (set_attr "mode" "SI")])
15245 (define_insn "*popcountsi2_cmp"
15246 [(set (reg FLAGS_REG)
15248 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15250 (set (match_operand:SI 0 "register_operand" "=r")
15251 (popcount:SI (match_dup 1)))]
15252 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15253 "popcnt{l}\t{%1, %0|%0, %1}"
15254 [(set_attr "prefix_rep" "1")
15255 (set_attr "type" "bitmanip")
15256 (set_attr "mode" "SI")])
15258 (define_insn "*popcountsi2_cmp_zext"
15259 [(set (reg FLAGS_REG)
15261 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15263 (set (match_operand:DI 0 "register_operand" "=r")
15264 (zero_extend:DI(popcount:SI (match_dup 1))))]
15265 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15266 "popcnt{l}\t{%1, %0|%0, %1}"
15267 [(set_attr "prefix_rep" "1")
15268 (set_attr "type" "bitmanip")
15269 (set_attr "mode" "SI")])
15271 (define_expand "bswapsi2"
15272 [(set (match_operand:SI 0 "register_operand" "")
15273 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15278 rtx x = operands[0];
15280 emit_move_insn (x, operands[1]);
15281 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15282 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15283 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15288 (define_insn "*bswapsi_1"
15289 [(set (match_operand:SI 0 "register_operand" "=r")
15290 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15293 [(set_attr "prefix_0f" "1")
15294 (set_attr "length" "2")])
15296 (define_insn "*bswaphi_lowpart_1"
15297 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15298 (bswap:HI (match_dup 0)))
15299 (clobber (reg:CC FLAGS_REG))]
15300 "TARGET_USE_XCHGB || optimize_size"
15302 xchg{b}\t{%h0, %b0|%b0, %h0}
15303 rol{w}\t{$8, %0|%0, 8}"
15304 [(set_attr "length" "2,4")
15305 (set_attr "mode" "QI,HI")])
15307 (define_insn "bswaphi_lowpart"
15308 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15309 (bswap:HI (match_dup 0)))
15310 (clobber (reg:CC FLAGS_REG))]
15312 "rol{w}\t{$8, %0|%0, 8}"
15313 [(set_attr "length" "4")
15314 (set_attr "mode" "HI")])
15316 (define_insn "bswapdi2"
15317 [(set (match_operand:DI 0 "register_operand" "=r")
15318 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15321 [(set_attr "prefix_0f" "1")
15322 (set_attr "length" "3")])
15324 (define_expand "clzdi2"
15326 [(set (match_operand:DI 0 "register_operand" "")
15327 (minus:DI (const_int 63)
15328 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15329 (clobber (reg:CC FLAGS_REG))])
15331 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15332 (clobber (reg:CC FLAGS_REG))])]
15337 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15342 (define_insn "clzdi2_abm"
15343 [(set (match_operand:DI 0 "register_operand" "=r")
15344 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15345 (clobber (reg:CC FLAGS_REG))]
15346 "TARGET_64BIT && TARGET_ABM"
15347 "lzcnt{q}\t{%1, %0|%0, %1}"
15348 [(set_attr "prefix_rep" "1")
15349 (set_attr "type" "bitmanip")
15350 (set_attr "mode" "DI")])
15352 (define_insn "*bsr_rex64"
15353 [(set (match_operand:DI 0 "register_operand" "=r")
15354 (minus:DI (const_int 63)
15355 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15356 (clobber (reg:CC FLAGS_REG))]
15358 "bsr{q}\t{%1, %0|%0, %1}"
15359 [(set_attr "prefix_0f" "1")
15360 (set_attr "mode" "DI")])
15362 (define_insn "popcountdi2"
15363 [(set (match_operand:DI 0 "register_operand" "=r")
15364 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15365 (clobber (reg:CC FLAGS_REG))]
15366 "TARGET_64BIT && TARGET_POPCNT"
15367 "popcnt{q}\t{%1, %0|%0, %1}"
15368 [(set_attr "prefix_rep" "1")
15369 (set_attr "type" "bitmanip")
15370 (set_attr "mode" "DI")])
15372 (define_insn "*popcountdi2_cmp"
15373 [(set (reg FLAGS_REG)
15375 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15377 (set (match_operand:DI 0 "register_operand" "=r")
15378 (popcount:DI (match_dup 1)))]
15379 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15380 "popcnt{q}\t{%1, %0|%0, %1}"
15381 [(set_attr "prefix_rep" "1")
15382 (set_attr "type" "bitmanip")
15383 (set_attr "mode" "DI")])
15385 (define_expand "clzhi2"
15387 [(set (match_operand:HI 0 "register_operand" "")
15388 (minus:HI (const_int 15)
15389 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15390 (clobber (reg:CC FLAGS_REG))])
15392 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15393 (clobber (reg:CC FLAGS_REG))])]
15398 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15403 (define_insn "clzhi2_abm"
15404 [(set (match_operand:HI 0 "register_operand" "=r")
15405 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15406 (clobber (reg:CC FLAGS_REG))]
15408 "lzcnt{w}\t{%1, %0|%0, %1}"
15409 [(set_attr "prefix_rep" "1")
15410 (set_attr "type" "bitmanip")
15411 (set_attr "mode" "HI")])
15413 (define_insn "*bsrhi"
15414 [(set (match_operand:HI 0 "register_operand" "=r")
15415 (minus:HI (const_int 15)
15416 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15417 (clobber (reg:CC FLAGS_REG))]
15419 "bsr{w}\t{%1, %0|%0, %1}"
15420 [(set_attr "prefix_0f" "1")
15421 (set_attr "mode" "HI")])
15423 (define_insn "popcounthi2"
15424 [(set (match_operand:HI 0 "register_operand" "=r")
15425 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15426 (clobber (reg:CC FLAGS_REG))]
15428 "popcnt{w}\t{%1, %0|%0, %1}"
15429 [(set_attr "prefix_rep" "1")
15430 (set_attr "type" "bitmanip")
15431 (set_attr "mode" "HI")])
15433 (define_insn "*popcounthi2_cmp"
15434 [(set (reg FLAGS_REG)
15436 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15438 (set (match_operand:HI 0 "register_operand" "=r")
15439 (popcount:HI (match_dup 1)))]
15440 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15441 "popcnt{w}\t{%1, %0|%0, %1}"
15442 [(set_attr "prefix_rep" "1")
15443 (set_attr "type" "bitmanip")
15444 (set_attr "mode" "HI")])
15446 (define_expand "paritydi2"
15447 [(set (match_operand:DI 0 "register_operand" "")
15448 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15451 rtx scratch = gen_reg_rtx (QImode);
15454 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15455 NULL_RTX, operands[1]));
15457 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15458 gen_rtx_REG (CCmode, FLAGS_REG),
15460 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15463 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15466 rtx tmp = gen_reg_rtx (SImode);
15468 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15469 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15474 (define_insn_and_split "paritydi2_cmp"
15475 [(set (reg:CC FLAGS_REG)
15476 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15477 (clobber (match_scratch:DI 0 "=r,X"))
15478 (clobber (match_scratch:SI 1 "=r,r"))
15479 (clobber (match_scratch:HI 2 "=Q,Q"))]
15482 "&& reload_completed"
15484 [(set (match_dup 1)
15485 (xor:SI (match_dup 1) (match_dup 4)))
15486 (clobber (reg:CC FLAGS_REG))])
15488 [(set (reg:CC FLAGS_REG)
15489 (parity:CC (match_dup 1)))
15490 (clobber (match_dup 1))
15491 (clobber (match_dup 2))])]
15493 operands[4] = gen_lowpart (SImode, operands[3]);
15495 if (MEM_P (operands[3]))
15496 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15497 else if (! TARGET_64BIT)
15498 operands[1] = gen_highpart (SImode, operands[3]);
15501 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15502 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15506 (define_expand "paritysi2"
15507 [(set (match_operand:SI 0 "register_operand" "")
15508 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15511 rtx scratch = gen_reg_rtx (QImode);
15514 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15516 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15517 gen_rtx_REG (CCmode, FLAGS_REG),
15519 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15521 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15525 (define_insn_and_split "paritysi2_cmp"
15526 [(set (reg:CC FLAGS_REG)
15527 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15528 (clobber (match_scratch:SI 0 "=r,X"))
15529 (clobber (match_scratch:HI 1 "=Q,Q"))]
15532 "&& reload_completed"
15534 [(set (match_dup 1)
15535 (xor:HI (match_dup 1) (match_dup 3)))
15536 (clobber (reg:CC FLAGS_REG))])
15538 [(set (reg:CC FLAGS_REG)
15539 (parity:CC (match_dup 1)))
15540 (clobber (match_dup 1))])]
15542 operands[3] = gen_lowpart (HImode, operands[2]);
15544 if (MEM_P (operands[2]))
15545 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15548 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15549 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15553 (define_insn "*parityhi2_cmp"
15554 [(set (reg:CC FLAGS_REG)
15555 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15556 (clobber (match_scratch:HI 0 "=Q"))]
15558 "xor{b}\t{%h0, %b0|%b0, %h0}"
15559 [(set_attr "length" "2")
15560 (set_attr "mode" "HI")])
15562 (define_insn "*parityqi2_cmp"
15563 [(set (reg:CC FLAGS_REG)
15564 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15567 [(set_attr "length" "2")
15568 (set_attr "mode" "QI")])
15570 ;; Thread-local storage patterns for ELF.
15572 ;; Note that these code sequences must appear exactly as shown
15573 ;; in order to allow linker relaxation.
15575 (define_insn "*tls_global_dynamic_32_gnu"
15576 [(set (match_operand:SI 0 "register_operand" "=a")
15577 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15578 (match_operand:SI 2 "tls_symbolic_operand" "")
15579 (match_operand:SI 3 "call_insn_operand" "")]
15581 (clobber (match_scratch:SI 4 "=d"))
15582 (clobber (match_scratch:SI 5 "=c"))
15583 (clobber (reg:CC FLAGS_REG))]
15584 "!TARGET_64BIT && TARGET_GNU_TLS"
15585 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15586 [(set_attr "type" "multi")
15587 (set_attr "length" "12")])
15589 (define_insn "*tls_global_dynamic_32_sun"
15590 [(set (match_operand:SI 0 "register_operand" "=a")
15591 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15592 (match_operand:SI 2 "tls_symbolic_operand" "")
15593 (match_operand:SI 3 "call_insn_operand" "")]
15595 (clobber (match_scratch:SI 4 "=d"))
15596 (clobber (match_scratch:SI 5 "=c"))
15597 (clobber (reg:CC FLAGS_REG))]
15598 "!TARGET_64BIT && TARGET_SUN_TLS"
15599 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15600 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15601 [(set_attr "type" "multi")
15602 (set_attr "length" "14")])
15604 (define_expand "tls_global_dynamic_32"
15605 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15608 (match_operand:SI 1 "tls_symbolic_operand" "")
15611 (clobber (match_scratch:SI 4 ""))
15612 (clobber (match_scratch:SI 5 ""))
15613 (clobber (reg:CC FLAGS_REG))])]
15617 operands[2] = pic_offset_table_rtx;
15620 operands[2] = gen_reg_rtx (Pmode);
15621 emit_insn (gen_set_got (operands[2]));
15623 if (TARGET_GNU2_TLS)
15625 emit_insn (gen_tls_dynamic_gnu2_32
15626 (operands[0], operands[1], operands[2]));
15629 operands[3] = ix86_tls_get_addr ();
15632 (define_insn "*tls_global_dynamic_64"
15633 [(set (match_operand:DI 0 "register_operand" "=a")
15634 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15635 (match_operand:DI 3 "" "")))
15636 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15639 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15640 [(set_attr "type" "multi")
15641 (set_attr "length" "16")])
15643 (define_expand "tls_global_dynamic_64"
15644 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15645 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15646 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15650 if (TARGET_GNU2_TLS)
15652 emit_insn (gen_tls_dynamic_gnu2_64
15653 (operands[0], operands[1]));
15656 operands[2] = ix86_tls_get_addr ();
15659 (define_insn "*tls_local_dynamic_base_32_gnu"
15660 [(set (match_operand:SI 0 "register_operand" "=a")
15661 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15662 (match_operand:SI 2 "call_insn_operand" "")]
15663 UNSPEC_TLS_LD_BASE))
15664 (clobber (match_scratch:SI 3 "=d"))
15665 (clobber (match_scratch:SI 4 "=c"))
15666 (clobber (reg:CC FLAGS_REG))]
15667 "!TARGET_64BIT && TARGET_GNU_TLS"
15668 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15669 [(set_attr "type" "multi")
15670 (set_attr "length" "11")])
15672 (define_insn "*tls_local_dynamic_base_32_sun"
15673 [(set (match_operand:SI 0 "register_operand" "=a")
15674 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15675 (match_operand:SI 2 "call_insn_operand" "")]
15676 UNSPEC_TLS_LD_BASE))
15677 (clobber (match_scratch:SI 3 "=d"))
15678 (clobber (match_scratch:SI 4 "=c"))
15679 (clobber (reg:CC FLAGS_REG))]
15680 "!TARGET_64BIT && TARGET_SUN_TLS"
15681 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15682 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15683 [(set_attr "type" "multi")
15684 (set_attr "length" "13")])
15686 (define_expand "tls_local_dynamic_base_32"
15687 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15688 (unspec:SI [(match_dup 1) (match_dup 2)]
15689 UNSPEC_TLS_LD_BASE))
15690 (clobber (match_scratch:SI 3 ""))
15691 (clobber (match_scratch:SI 4 ""))
15692 (clobber (reg:CC FLAGS_REG))])]
15696 operands[1] = pic_offset_table_rtx;
15699 operands[1] = gen_reg_rtx (Pmode);
15700 emit_insn (gen_set_got (operands[1]));
15702 if (TARGET_GNU2_TLS)
15704 emit_insn (gen_tls_dynamic_gnu2_32
15705 (operands[0], ix86_tls_module_base (), operands[1]));
15708 operands[2] = ix86_tls_get_addr ();
15711 (define_insn "*tls_local_dynamic_base_64"
15712 [(set (match_operand:DI 0 "register_operand" "=a")
15713 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15714 (match_operand:DI 2 "" "")))
15715 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15717 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15718 [(set_attr "type" "multi")
15719 (set_attr "length" "12")])
15721 (define_expand "tls_local_dynamic_base_64"
15722 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15723 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15724 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15727 if (TARGET_GNU2_TLS)
15729 emit_insn (gen_tls_dynamic_gnu2_64
15730 (operands[0], ix86_tls_module_base ()));
15733 operands[1] = ix86_tls_get_addr ();
15736 ;; Local dynamic of a single variable is a lose. Show combine how
15737 ;; to convert that back to global dynamic.
15739 (define_insn_and_split "*tls_local_dynamic_32_once"
15740 [(set (match_operand:SI 0 "register_operand" "=a")
15741 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15742 (match_operand:SI 2 "call_insn_operand" "")]
15743 UNSPEC_TLS_LD_BASE)
15744 (const:SI (unspec:SI
15745 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15747 (clobber (match_scratch:SI 4 "=d"))
15748 (clobber (match_scratch:SI 5 "=c"))
15749 (clobber (reg:CC FLAGS_REG))]
15753 [(parallel [(set (match_dup 0)
15754 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15756 (clobber (match_dup 4))
15757 (clobber (match_dup 5))
15758 (clobber (reg:CC FLAGS_REG))])]
15761 ;; Load and add the thread base pointer from %gs:0.
15763 (define_insn "*load_tp_si"
15764 [(set (match_operand:SI 0 "register_operand" "=r")
15765 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15767 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15768 [(set_attr "type" "imov")
15769 (set_attr "modrm" "0")
15770 (set_attr "length" "7")
15771 (set_attr "memory" "load")
15772 (set_attr "imm_disp" "false")])
15774 (define_insn "*add_tp_si"
15775 [(set (match_operand:SI 0 "register_operand" "=r")
15776 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15777 (match_operand:SI 1 "register_operand" "0")))
15778 (clobber (reg:CC FLAGS_REG))]
15780 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15781 [(set_attr "type" "alu")
15782 (set_attr "modrm" "0")
15783 (set_attr "length" "7")
15784 (set_attr "memory" "load")
15785 (set_attr "imm_disp" "false")])
15787 (define_insn "*load_tp_di"
15788 [(set (match_operand:DI 0 "register_operand" "=r")
15789 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15791 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15792 [(set_attr "type" "imov")
15793 (set_attr "modrm" "0")
15794 (set_attr "length" "7")
15795 (set_attr "memory" "load")
15796 (set_attr "imm_disp" "false")])
15798 (define_insn "*add_tp_di"
15799 [(set (match_operand:DI 0 "register_operand" "=r")
15800 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15801 (match_operand:DI 1 "register_operand" "0")))
15802 (clobber (reg:CC FLAGS_REG))]
15804 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15805 [(set_attr "type" "alu")
15806 (set_attr "modrm" "0")
15807 (set_attr "length" "7")
15808 (set_attr "memory" "load")
15809 (set_attr "imm_disp" "false")])
15811 ;; GNU2 TLS patterns can be split.
15813 (define_expand "tls_dynamic_gnu2_32"
15814 [(set (match_dup 3)
15815 (plus:SI (match_operand:SI 2 "register_operand" "")
15817 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15820 [(set (match_operand:SI 0 "register_operand" "")
15821 (unspec:SI [(match_dup 1) (match_dup 3)
15822 (match_dup 2) (reg:SI SP_REG)]
15824 (clobber (reg:CC FLAGS_REG))])]
15825 "!TARGET_64BIT && TARGET_GNU2_TLS"
15827 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15828 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15831 (define_insn "*tls_dynamic_lea_32"
15832 [(set (match_operand:SI 0 "register_operand" "=r")
15833 (plus:SI (match_operand:SI 1 "register_operand" "b")
15835 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15836 UNSPEC_TLSDESC))))]
15837 "!TARGET_64BIT && TARGET_GNU2_TLS"
15838 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15839 [(set_attr "type" "lea")
15840 (set_attr "mode" "SI")
15841 (set_attr "length" "6")
15842 (set_attr "length_address" "4")])
15844 (define_insn "*tls_dynamic_call_32"
15845 [(set (match_operand:SI 0 "register_operand" "=a")
15846 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15847 (match_operand:SI 2 "register_operand" "0")
15848 ;; we have to make sure %ebx still points to the GOT
15849 (match_operand:SI 3 "register_operand" "b")
15852 (clobber (reg:CC FLAGS_REG))]
15853 "!TARGET_64BIT && TARGET_GNU2_TLS"
15854 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15855 [(set_attr "type" "call")
15856 (set_attr "length" "2")
15857 (set_attr "length_address" "0")])
15859 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15860 [(set (match_operand:SI 0 "register_operand" "=&a")
15862 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15863 (match_operand:SI 4 "" "")
15864 (match_operand:SI 2 "register_operand" "b")
15867 (const:SI (unspec:SI
15868 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15870 (clobber (reg:CC FLAGS_REG))]
15871 "!TARGET_64BIT && TARGET_GNU2_TLS"
15874 [(set (match_dup 0) (match_dup 5))]
15876 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15877 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15880 (define_expand "tls_dynamic_gnu2_64"
15881 [(set (match_dup 2)
15882 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15885 [(set (match_operand:DI 0 "register_operand" "")
15886 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15888 (clobber (reg:CC FLAGS_REG))])]
15889 "TARGET_64BIT && TARGET_GNU2_TLS"
15891 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15892 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15895 (define_insn "*tls_dynamic_lea_64"
15896 [(set (match_operand:DI 0 "register_operand" "=r")
15897 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15899 "TARGET_64BIT && TARGET_GNU2_TLS"
15900 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15901 [(set_attr "type" "lea")
15902 (set_attr "mode" "DI")
15903 (set_attr "length" "7")
15904 (set_attr "length_address" "4")])
15906 (define_insn "*tls_dynamic_call_64"
15907 [(set (match_operand:DI 0 "register_operand" "=a")
15908 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15909 (match_operand:DI 2 "register_operand" "0")
15912 (clobber (reg:CC FLAGS_REG))]
15913 "TARGET_64BIT && TARGET_GNU2_TLS"
15914 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15915 [(set_attr "type" "call")
15916 (set_attr "length" "2")
15917 (set_attr "length_address" "0")])
15919 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15920 [(set (match_operand:DI 0 "register_operand" "=&a")
15922 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15923 (match_operand:DI 3 "" "")
15926 (const:DI (unspec:DI
15927 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15929 (clobber (reg:CC FLAGS_REG))]
15930 "TARGET_64BIT && TARGET_GNU2_TLS"
15933 [(set (match_dup 0) (match_dup 4))]
15935 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15936 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15941 ;; These patterns match the binary 387 instructions for addM3, subM3,
15942 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15943 ;; SFmode. The first is the normal insn, the second the same insn but
15944 ;; with one operand a conversion, and the third the same insn but with
15945 ;; the other operand a conversion. The conversion may be SFmode or
15946 ;; SImode if the target mode DFmode, but only SImode if the target mode
15949 ;; Gcc is slightly more smart about handling normal two address instructions
15950 ;; so use special patterns for add and mull.
15952 (define_insn "*fop_sf_comm_mixed"
15953 [(set (match_operand:SF 0 "register_operand" "=f,x")
15954 (match_operator:SF 3 "binary_fp_operator"
15955 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15956 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15957 "TARGET_MIX_SSE_I387
15958 && COMMUTATIVE_ARITH_P (operands[3])
15959 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15960 "* return output_387_binary_op (insn, operands);"
15961 [(set (attr "type")
15962 (if_then_else (eq_attr "alternative" "1")
15963 (if_then_else (match_operand:SF 3 "mult_operator" "")
15964 (const_string "ssemul")
15965 (const_string "sseadd"))
15966 (if_then_else (match_operand:SF 3 "mult_operator" "")
15967 (const_string "fmul")
15968 (const_string "fop"))))
15969 (set_attr "mode" "SF")])
15971 (define_insn "*fop_sf_comm_sse"
15972 [(set (match_operand:SF 0 "register_operand" "=x")
15973 (match_operator:SF 3 "binary_fp_operator"
15974 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15975 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15977 && COMMUTATIVE_ARITH_P (operands[3])
15978 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15979 "* return output_387_binary_op (insn, operands);"
15980 [(set (attr "type")
15981 (if_then_else (match_operand:SF 3 "mult_operator" "")
15982 (const_string "ssemul")
15983 (const_string "sseadd")))
15984 (set_attr "mode" "SF")])
15986 (define_insn "*fop_sf_comm_i387"
15987 [(set (match_operand:SF 0 "register_operand" "=f")
15988 (match_operator:SF 3 "binary_fp_operator"
15989 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15990 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15992 && COMMUTATIVE_ARITH_P (operands[3])
15993 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15994 "* return output_387_binary_op (insn, operands);"
15995 [(set (attr "type")
15996 (if_then_else (match_operand:SF 3 "mult_operator" "")
15997 (const_string "fmul")
15998 (const_string "fop")))
15999 (set_attr "mode" "SF")])
16001 (define_insn "*fop_sf_1_mixed"
16002 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
16003 (match_operator:SF 3 "binary_fp_operator"
16004 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
16005 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
16006 "TARGET_MIX_SSE_I387
16007 && !COMMUTATIVE_ARITH_P (operands[3])
16008 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16009 "* return output_387_binary_op (insn, operands);"
16010 [(set (attr "type")
16011 (cond [(and (eq_attr "alternative" "2")
16012 (match_operand:SF 3 "mult_operator" ""))
16013 (const_string "ssemul")
16014 (and (eq_attr "alternative" "2")
16015 (match_operand:SF 3 "div_operator" ""))
16016 (const_string "ssediv")
16017 (eq_attr "alternative" "2")
16018 (const_string "sseadd")
16019 (match_operand:SF 3 "mult_operator" "")
16020 (const_string "fmul")
16021 (match_operand:SF 3 "div_operator" "")
16022 (const_string "fdiv")
16024 (const_string "fop")))
16025 (set_attr "mode" "SF")])
16027 (define_insn "*rcpsf2_sse"
16028 [(set (match_operand:SF 0 "register_operand" "=x")
16029 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16032 "rcpss\t{%1, %0|%0, %1}"
16033 [(set_attr "type" "sse")
16034 (set_attr "mode" "SF")])
16036 (define_insn "*fop_sf_1_sse"
16037 [(set (match_operand:SF 0 "register_operand" "=x")
16038 (match_operator:SF 3 "binary_fp_operator"
16039 [(match_operand:SF 1 "register_operand" "0")
16040 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16042 && !COMMUTATIVE_ARITH_P (operands[3])"
16043 "* return output_387_binary_op (insn, operands);"
16044 [(set (attr "type")
16045 (cond [(match_operand:SF 3 "mult_operator" "")
16046 (const_string "ssemul")
16047 (match_operand:SF 3 "div_operator" "")
16048 (const_string "ssediv")
16050 (const_string "sseadd")))
16051 (set_attr "mode" "SF")])
16053 ;; This pattern is not fully shadowed by the pattern above.
16054 (define_insn "*fop_sf_1_i387"
16055 [(set (match_operand:SF 0 "register_operand" "=f,f")
16056 (match_operator:SF 3 "binary_fp_operator"
16057 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
16058 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
16059 "TARGET_80387 && !TARGET_SSE_MATH
16060 && !COMMUTATIVE_ARITH_P (operands[3])
16061 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16062 "* return output_387_binary_op (insn, operands);"
16063 [(set (attr "type")
16064 (cond [(match_operand:SF 3 "mult_operator" "")
16065 (const_string "fmul")
16066 (match_operand:SF 3 "div_operator" "")
16067 (const_string "fdiv")
16069 (const_string "fop")))
16070 (set_attr "mode" "SF")])
16072 ;; ??? Add SSE splitters for these!
16073 (define_insn "*fop_sf_2<mode>_i387"
16074 [(set (match_operand:SF 0 "register_operand" "=f,f")
16075 (match_operator:SF 3 "binary_fp_operator"
16076 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16077 (match_operand:SF 2 "register_operand" "0,0")]))]
16078 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16079 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16080 [(set (attr "type")
16081 (cond [(match_operand:SF 3 "mult_operator" "")
16082 (const_string "fmul")
16083 (match_operand:SF 3 "div_operator" "")
16084 (const_string "fdiv")
16086 (const_string "fop")))
16087 (set_attr "fp_int_src" "true")
16088 (set_attr "mode" "<MODE>")])
16090 (define_insn "*fop_sf_3<mode>_i387"
16091 [(set (match_operand:SF 0 "register_operand" "=f,f")
16092 (match_operator:SF 3 "binary_fp_operator"
16093 [(match_operand:SF 1 "register_operand" "0,0")
16094 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16095 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16096 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16097 [(set (attr "type")
16098 (cond [(match_operand:SF 3 "mult_operator" "")
16099 (const_string "fmul")
16100 (match_operand:SF 3 "div_operator" "")
16101 (const_string "fdiv")
16103 (const_string "fop")))
16104 (set_attr "fp_int_src" "true")
16105 (set_attr "mode" "<MODE>")])
16107 (define_insn "*fop_df_comm_mixed"
16108 [(set (match_operand:DF 0 "register_operand" "=f,x")
16109 (match_operator:DF 3 "binary_fp_operator"
16110 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16111 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16112 "TARGET_SSE2 && TARGET_MIX_SSE_I387
16113 && COMMUTATIVE_ARITH_P (operands[3])
16114 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16115 "* return output_387_binary_op (insn, operands);"
16116 [(set (attr "type")
16117 (if_then_else (eq_attr "alternative" "1")
16118 (if_then_else (match_operand:DF 3 "mult_operator" "")
16119 (const_string "ssemul")
16120 (const_string "sseadd"))
16121 (if_then_else (match_operand:DF 3 "mult_operator" "")
16122 (const_string "fmul")
16123 (const_string "fop"))))
16124 (set_attr "mode" "DF")])
16126 (define_insn "*fop_df_comm_sse"
16127 [(set (match_operand:DF 0 "register_operand" "=x")
16128 (match_operator:DF 3 "binary_fp_operator"
16129 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16130 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16131 "TARGET_SSE2 && TARGET_SSE_MATH
16132 && COMMUTATIVE_ARITH_P (operands[3])
16133 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16134 "* return output_387_binary_op (insn, operands);"
16135 [(set (attr "type")
16136 (if_then_else (match_operand:DF 3 "mult_operator" "")
16137 (const_string "ssemul")
16138 (const_string "sseadd")))
16139 (set_attr "mode" "DF")])
16141 (define_insn "*fop_df_comm_i387"
16142 [(set (match_operand:DF 0 "register_operand" "=f")
16143 (match_operator:DF 3 "binary_fp_operator"
16144 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16145 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16147 && COMMUTATIVE_ARITH_P (operands[3])
16148 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16149 "* return output_387_binary_op (insn, operands);"
16150 [(set (attr "type")
16151 (if_then_else (match_operand:DF 3 "mult_operator" "")
16152 (const_string "fmul")
16153 (const_string "fop")))
16154 (set_attr "mode" "DF")])
16156 (define_insn "*fop_df_1_mixed"
16157 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16158 (match_operator:DF 3 "binary_fp_operator"
16159 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16160 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16161 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16162 && !COMMUTATIVE_ARITH_P (operands[3])
16163 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16164 "* return output_387_binary_op (insn, operands);"
16165 [(set (attr "type")
16166 (cond [(and (eq_attr "alternative" "2")
16167 (match_operand:DF 3 "mult_operator" ""))
16168 (const_string "ssemul")
16169 (and (eq_attr "alternative" "2")
16170 (match_operand:DF 3 "div_operator" ""))
16171 (const_string "ssediv")
16172 (eq_attr "alternative" "2")
16173 (const_string "sseadd")
16174 (match_operand:DF 3 "mult_operator" "")
16175 (const_string "fmul")
16176 (match_operand:DF 3 "div_operator" "")
16177 (const_string "fdiv")
16179 (const_string "fop")))
16180 (set_attr "mode" "DF")])
16182 (define_insn "*fop_df_1_sse"
16183 [(set (match_operand:DF 0 "register_operand" "=x")
16184 (match_operator:DF 3 "binary_fp_operator"
16185 [(match_operand:DF 1 "register_operand" "0")
16186 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16187 "TARGET_SSE2 && TARGET_SSE_MATH
16188 && !COMMUTATIVE_ARITH_P (operands[3])"
16189 "* return output_387_binary_op (insn, operands);"
16190 [(set_attr "mode" "DF")
16192 (cond [(match_operand:DF 3 "mult_operator" "")
16193 (const_string "ssemul")
16194 (match_operand:DF 3 "div_operator" "")
16195 (const_string "ssediv")
16197 (const_string "sseadd")))])
16199 ;; This pattern is not fully shadowed by the pattern above.
16200 (define_insn "*fop_df_1_i387"
16201 [(set (match_operand:DF 0 "register_operand" "=f,f")
16202 (match_operator:DF 3 "binary_fp_operator"
16203 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16204 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16205 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16206 && !COMMUTATIVE_ARITH_P (operands[3])
16207 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16208 "* return output_387_binary_op (insn, operands);"
16209 [(set (attr "type")
16210 (cond [(match_operand:DF 3 "mult_operator" "")
16211 (const_string "fmul")
16212 (match_operand:DF 3 "div_operator" "")
16213 (const_string "fdiv")
16215 (const_string "fop")))
16216 (set_attr "mode" "DF")])
16218 ;; ??? Add SSE splitters for these!
16219 (define_insn "*fop_df_2<mode>_i387"
16220 [(set (match_operand:DF 0 "register_operand" "=f,f")
16221 (match_operator:DF 3 "binary_fp_operator"
16222 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16223 (match_operand:DF 2 "register_operand" "0,0")]))]
16224 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16225 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16226 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16227 [(set (attr "type")
16228 (cond [(match_operand:DF 3 "mult_operator" "")
16229 (const_string "fmul")
16230 (match_operand:DF 3 "div_operator" "")
16231 (const_string "fdiv")
16233 (const_string "fop")))
16234 (set_attr "fp_int_src" "true")
16235 (set_attr "mode" "<MODE>")])
16237 (define_insn "*fop_df_3<mode>_i387"
16238 [(set (match_operand:DF 0 "register_operand" "=f,f")
16239 (match_operator:DF 3 "binary_fp_operator"
16240 [(match_operand:DF 1 "register_operand" "0,0")
16241 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16242 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16243 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16244 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16245 [(set (attr "type")
16246 (cond [(match_operand:DF 3 "mult_operator" "")
16247 (const_string "fmul")
16248 (match_operand:DF 3 "div_operator" "")
16249 (const_string "fdiv")
16251 (const_string "fop")))
16252 (set_attr "fp_int_src" "true")
16253 (set_attr "mode" "<MODE>")])
16255 (define_insn "*fop_df_4_i387"
16256 [(set (match_operand:DF 0 "register_operand" "=f,f")
16257 (match_operator:DF 3 "binary_fp_operator"
16258 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16259 (match_operand:DF 2 "register_operand" "0,f")]))]
16260 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16261 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16262 "* return output_387_binary_op (insn, operands);"
16263 [(set (attr "type")
16264 (cond [(match_operand:DF 3 "mult_operator" "")
16265 (const_string "fmul")
16266 (match_operand:DF 3 "div_operator" "")
16267 (const_string "fdiv")
16269 (const_string "fop")))
16270 (set_attr "mode" "SF")])
16272 (define_insn "*fop_df_5_i387"
16273 [(set (match_operand:DF 0 "register_operand" "=f,f")
16274 (match_operator:DF 3 "binary_fp_operator"
16275 [(match_operand:DF 1 "register_operand" "0,f")
16277 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16278 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16279 "* return output_387_binary_op (insn, operands);"
16280 [(set (attr "type")
16281 (cond [(match_operand:DF 3 "mult_operator" "")
16282 (const_string "fmul")
16283 (match_operand:DF 3 "div_operator" "")
16284 (const_string "fdiv")
16286 (const_string "fop")))
16287 (set_attr "mode" "SF")])
16289 (define_insn "*fop_df_6_i387"
16290 [(set (match_operand:DF 0 "register_operand" "=f,f")
16291 (match_operator:DF 3 "binary_fp_operator"
16293 (match_operand:SF 1 "register_operand" "0,f"))
16295 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16296 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16297 "* return output_387_binary_op (insn, operands);"
16298 [(set (attr "type")
16299 (cond [(match_operand:DF 3 "mult_operator" "")
16300 (const_string "fmul")
16301 (match_operand:DF 3 "div_operator" "")
16302 (const_string "fdiv")
16304 (const_string "fop")))
16305 (set_attr "mode" "SF")])
16307 (define_insn "*fop_xf_comm_i387"
16308 [(set (match_operand:XF 0 "register_operand" "=f")
16309 (match_operator:XF 3 "binary_fp_operator"
16310 [(match_operand:XF 1 "register_operand" "%0")
16311 (match_operand:XF 2 "register_operand" "f")]))]
16313 && COMMUTATIVE_ARITH_P (operands[3])"
16314 "* return output_387_binary_op (insn, operands);"
16315 [(set (attr "type")
16316 (if_then_else (match_operand:XF 3 "mult_operator" "")
16317 (const_string "fmul")
16318 (const_string "fop")))
16319 (set_attr "mode" "XF")])
16321 (define_insn "*fop_xf_1_i387"
16322 [(set (match_operand:XF 0 "register_operand" "=f,f")
16323 (match_operator:XF 3 "binary_fp_operator"
16324 [(match_operand:XF 1 "register_operand" "0,f")
16325 (match_operand:XF 2 "register_operand" "f,0")]))]
16327 && !COMMUTATIVE_ARITH_P (operands[3])"
16328 "* return 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 "mode" "XF")])
16338 (define_insn "*fop_xf_2<mode>_i387"
16339 [(set (match_operand:XF 0 "register_operand" "=f,f")
16340 (match_operator:XF 3 "binary_fp_operator"
16341 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16342 (match_operand:XF 2 "register_operand" "0,0")]))]
16343 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16344 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16345 [(set (attr "type")
16346 (cond [(match_operand:XF 3 "mult_operator" "")
16347 (const_string "fmul")
16348 (match_operand:XF 3 "div_operator" "")
16349 (const_string "fdiv")
16351 (const_string "fop")))
16352 (set_attr "fp_int_src" "true")
16353 (set_attr "mode" "<MODE>")])
16355 (define_insn "*fop_xf_3<mode>_i387"
16356 [(set (match_operand:XF 0 "register_operand" "=f,f")
16357 (match_operator:XF 3 "binary_fp_operator"
16358 [(match_operand:XF 1 "register_operand" "0,0")
16359 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16360 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16361 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16362 [(set (attr "type")
16363 (cond [(match_operand:XF 3 "mult_operator" "")
16364 (const_string "fmul")
16365 (match_operand:XF 3 "div_operator" "")
16366 (const_string "fdiv")
16368 (const_string "fop")))
16369 (set_attr "fp_int_src" "true")
16370 (set_attr "mode" "<MODE>")])
16372 (define_insn "*fop_xf_4_i387"
16373 [(set (match_operand:XF 0 "register_operand" "=f,f")
16374 (match_operator:XF 3 "binary_fp_operator"
16376 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16377 (match_operand:XF 2 "register_operand" "0,f")]))]
16379 "* return output_387_binary_op (insn, operands);"
16380 [(set (attr "type")
16381 (cond [(match_operand:XF 3 "mult_operator" "")
16382 (const_string "fmul")
16383 (match_operand:XF 3 "div_operator" "")
16384 (const_string "fdiv")
16386 (const_string "fop")))
16387 (set_attr "mode" "SF")])
16389 (define_insn "*fop_xf_5_i387"
16390 [(set (match_operand:XF 0 "register_operand" "=f,f")
16391 (match_operator:XF 3 "binary_fp_operator"
16392 [(match_operand:XF 1 "register_operand" "0,f")
16394 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16396 "* return output_387_binary_op (insn, operands);"
16397 [(set (attr "type")
16398 (cond [(match_operand:XF 3 "mult_operator" "")
16399 (const_string "fmul")
16400 (match_operand:XF 3 "div_operator" "")
16401 (const_string "fdiv")
16403 (const_string "fop")))
16404 (set_attr "mode" "SF")])
16406 (define_insn "*fop_xf_6_i387"
16407 [(set (match_operand:XF 0 "register_operand" "=f,f")
16408 (match_operator:XF 3 "binary_fp_operator"
16410 (match_operand:MODEF 1 "register_operand" "0,f"))
16412 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16414 "* return output_387_binary_op (insn, operands);"
16415 [(set (attr "type")
16416 (cond [(match_operand:XF 3 "mult_operator" "")
16417 (const_string "fmul")
16418 (match_operand:XF 3 "div_operator" "")
16419 (const_string "fdiv")
16421 (const_string "fop")))
16422 (set_attr "mode" "SF")])
16425 [(set (match_operand 0 "register_operand" "")
16426 (match_operator 3 "binary_fp_operator"
16427 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16428 (match_operand 2 "register_operand" "")]))]
16430 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16433 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16434 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16435 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16436 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16437 GET_MODE (operands[3]),
16440 ix86_free_from_memory (GET_MODE (operands[1]));
16445 [(set (match_operand 0 "register_operand" "")
16446 (match_operator 3 "binary_fp_operator"
16447 [(match_operand 1 "register_operand" "")
16448 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16450 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16453 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16454 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16455 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16456 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16457 GET_MODE (operands[3]),
16460 ix86_free_from_memory (GET_MODE (operands[2]));
16464 ;; FPU special functions.
16466 ;; This pattern implements a no-op XFmode truncation for
16467 ;; all fancy i386 XFmode math functions.
16469 (define_insn "truncxf<mode>2_i387_noop_unspec"
16470 [(set (match_operand:MODEF 0 "register_operand" "=f")
16471 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16472 UNSPEC_TRUNC_NOOP))]
16473 "TARGET_USE_FANCY_MATH_387"
16474 "* return output_387_reg_move (insn, operands);"
16475 [(set_attr "type" "fmov")
16476 (set_attr "mode" "<MODE>")])
16478 (define_insn "sqrtxf2"
16479 [(set (match_operand:XF 0 "register_operand" "=f")
16480 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16481 "TARGET_USE_FANCY_MATH_387"
16483 [(set_attr "type" "fpspc")
16484 (set_attr "mode" "XF")
16485 (set_attr "athlon_decode" "direct")
16486 (set_attr "amdfam10_decode" "direct")])
16488 (define_insn "sqrt_extend<mode>xf2_i387"
16489 [(set (match_operand:XF 0 "register_operand" "=f")
16492 (match_operand:MODEF 1 "register_operand" "0"))))]
16493 "TARGET_USE_FANCY_MATH_387"
16495 [(set_attr "type" "fpspc")
16496 (set_attr "mode" "XF")
16497 (set_attr "athlon_decode" "direct")
16498 (set_attr "amdfam10_decode" "direct")])
16500 (define_insn "*rsqrtsf2_sse"
16501 [(set (match_operand:SF 0 "register_operand" "=x")
16502 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16505 "rsqrtss\t{%1, %0|%0, %1}"
16506 [(set_attr "type" "sse")
16507 (set_attr "mode" "SF")])
16509 (define_expand "rsqrtsf2"
16510 [(set (match_operand:SF 0 "register_operand" "")
16511 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16515 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16519 (define_insn "*sqrt<mode>2_sse"
16520 [(set (match_operand:MODEF 0 "register_operand" "=x")
16522 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16523 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16524 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16525 [(set_attr "type" "sse")
16526 (set_attr "mode" "<MODE>")
16527 (set_attr "athlon_decode" "*")
16528 (set_attr "amdfam10_decode" "*")])
16530 (define_expand "sqrt<mode>2"
16531 [(set (match_operand:MODEF 0 "register_operand" "")
16533 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16534 "TARGET_USE_FANCY_MATH_387
16535 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16537 if (<MODE>mode == SFmode
16538 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16539 && flag_finite_math_only && !flag_trapping_math
16540 && flag_unsafe_math_optimizations)
16542 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16546 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16548 rtx op0 = gen_reg_rtx (XFmode);
16549 rtx op1 = force_reg (<MODE>mode, operands[1]);
16551 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16552 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16557 (define_insn "fpremxf4_i387"
16558 [(set (match_operand:XF 0 "register_operand" "=f")
16559 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16560 (match_operand:XF 3 "register_operand" "1")]
16562 (set (match_operand:XF 1 "register_operand" "=u")
16563 (unspec:XF [(match_dup 2) (match_dup 3)]
16565 (set (reg:CCFP FPSR_REG)
16566 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16568 "TARGET_USE_FANCY_MATH_387"
16570 [(set_attr "type" "fpspc")
16571 (set_attr "mode" "XF")])
16573 (define_expand "fmodxf3"
16574 [(use (match_operand:XF 0 "register_operand" ""))
16575 (use (match_operand:XF 1 "register_operand" ""))
16576 (use (match_operand:XF 2 "register_operand" ""))]
16577 "TARGET_USE_FANCY_MATH_387"
16579 rtx label = gen_label_rtx ();
16583 if (rtx_equal_p (operands[1], operands[2]))
16585 op2 = gen_reg_rtx (XFmode);
16586 emit_move_insn (op2, operands[2]);
16591 emit_label (label);
16592 emit_insn (gen_fpremxf4_i387 (operands[1], op2, operands[1], op2));
16593 ix86_emit_fp_unordered_jump (label);
16594 LABEL_NUSES (label) = 1;
16596 emit_move_insn (operands[0], operands[1]);
16600 (define_expand "fmod<mode>3"
16601 [(use (match_operand:MODEF 0 "register_operand" ""))
16602 (use (match_operand:MODEF 1 "general_operand" ""))
16603 (use (match_operand:MODEF 2 "general_operand" ""))]
16604 "TARGET_USE_FANCY_MATH_387"
16606 rtx label = gen_label_rtx ();
16608 rtx op1 = gen_reg_rtx (XFmode);
16609 rtx op2 = gen_reg_rtx (XFmode);
16611 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16612 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16614 emit_label (label);
16615 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16616 ix86_emit_fp_unordered_jump (label);
16617 LABEL_NUSES (label) = 1;
16619 /* Truncate the result properly for strict SSE math. */
16620 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16621 && !TARGET_MIX_SSE_I387)
16622 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16624 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16629 (define_insn "fprem1xf4_i387"
16630 [(set (match_operand:XF 0 "register_operand" "=f")
16631 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16632 (match_operand:XF 3 "register_operand" "1")]
16634 (set (match_operand:XF 1 "register_operand" "=u")
16635 (unspec:XF [(match_dup 2) (match_dup 3)]
16637 (set (reg:CCFP FPSR_REG)
16638 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16640 "TARGET_USE_FANCY_MATH_387"
16642 [(set_attr "type" "fpspc")
16643 (set_attr "mode" "XF")])
16645 (define_expand "remainderxf3"
16646 [(use (match_operand:XF 0 "register_operand" ""))
16647 (use (match_operand:XF 1 "register_operand" ""))
16648 (use (match_operand:XF 2 "register_operand" ""))]
16649 "TARGET_USE_FANCY_MATH_387"
16651 rtx label = gen_label_rtx ();
16655 if (rtx_equal_p (operands[1], operands[2]))
16657 op2 = gen_reg_rtx (XFmode);
16658 emit_move_insn (op2, operands[2]);
16663 emit_label (label);
16664 emit_insn (gen_fprem1xf4_i387 (operands[1], op2, operands[1], op2));
16665 ix86_emit_fp_unordered_jump (label);
16666 LABEL_NUSES (label) = 1;
16668 emit_move_insn (operands[0], operands[1]);
16672 (define_expand "remainder<mode>3"
16673 [(use (match_operand:MODEF 0 "register_operand" ""))
16674 (use (match_operand:MODEF 1 "general_operand" ""))
16675 (use (match_operand:MODEF 2 "general_operand" ""))]
16676 "TARGET_USE_FANCY_MATH_387"
16678 rtx label = gen_label_rtx ();
16680 rtx op1 = gen_reg_rtx (XFmode);
16681 rtx op2 = gen_reg_rtx (XFmode);
16683 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16684 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16686 emit_label (label);
16688 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16689 ix86_emit_fp_unordered_jump (label);
16690 LABEL_NUSES (label) = 1;
16692 /* Truncate the result properly for strict SSE math. */
16693 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16694 && !TARGET_MIX_SSE_I387)
16695 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16697 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16702 (define_insn "*sinxf2_i387"
16703 [(set (match_operand:XF 0 "register_operand" "=f")
16704 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16705 "TARGET_USE_FANCY_MATH_387
16706 && flag_unsafe_math_optimizations"
16708 [(set_attr "type" "fpspc")
16709 (set_attr "mode" "XF")])
16711 (define_insn "*sin_extend<mode>xf2_i387"
16712 [(set (match_operand:XF 0 "register_operand" "=f")
16713 (unspec:XF [(float_extend:XF
16714 (match_operand:MODEF 1 "register_operand" "0"))]
16716 "TARGET_USE_FANCY_MATH_387
16717 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16718 || TARGET_MIX_SSE_I387)
16719 && flag_unsafe_math_optimizations"
16721 [(set_attr "type" "fpspc")
16722 (set_attr "mode" "XF")])
16724 (define_insn "*cosxf2_i387"
16725 [(set (match_operand:XF 0 "register_operand" "=f")
16726 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16727 "TARGET_USE_FANCY_MATH_387
16728 && flag_unsafe_math_optimizations"
16730 [(set_attr "type" "fpspc")
16731 (set_attr "mode" "XF")])
16733 (define_insn "*cos_extend<mode>xf2_i387"
16734 [(set (match_operand:XF 0 "register_operand" "=f")
16735 (unspec:XF [(float_extend:XF
16736 (match_operand:MODEF 1 "register_operand" "0"))]
16738 "TARGET_USE_FANCY_MATH_387
16739 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16740 || TARGET_MIX_SSE_I387)
16741 && flag_unsafe_math_optimizations"
16743 [(set_attr "type" "fpspc")
16744 (set_attr "mode" "XF")])
16746 ;; When sincos pattern is defined, sin and cos builtin functions will be
16747 ;; expanded to sincos pattern with one of its outputs left unused.
16748 ;; CSE pass will figure out if two sincos patterns can be combined,
16749 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16750 ;; depending on the unused output.
16752 (define_insn "sincosxf3"
16753 [(set (match_operand:XF 0 "register_operand" "=f")
16754 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16755 UNSPEC_SINCOS_COS))
16756 (set (match_operand:XF 1 "register_operand" "=u")
16757 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16758 "TARGET_USE_FANCY_MATH_387
16759 && flag_unsafe_math_optimizations"
16761 [(set_attr "type" "fpspc")
16762 (set_attr "mode" "XF")])
16765 [(set (match_operand:XF 0 "register_operand" "")
16766 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16767 UNSPEC_SINCOS_COS))
16768 (set (match_operand:XF 1 "register_operand" "")
16769 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16770 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16771 && !(reload_completed || reload_in_progress)"
16772 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16776 [(set (match_operand:XF 0 "register_operand" "")
16777 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16778 UNSPEC_SINCOS_COS))
16779 (set (match_operand:XF 1 "register_operand" "")
16780 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16781 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16782 && !(reload_completed || reload_in_progress)"
16783 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16786 (define_insn "sincos_extend<mode>xf3_i387"
16787 [(set (match_operand:XF 0 "register_operand" "=f")
16788 (unspec:XF [(float_extend:XF
16789 (match_operand:MODEF 2 "register_operand" "0"))]
16790 UNSPEC_SINCOS_COS))
16791 (set (match_operand:XF 1 "register_operand" "=u")
16792 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16793 "TARGET_USE_FANCY_MATH_387
16794 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16795 || TARGET_MIX_SSE_I387)
16796 && flag_unsafe_math_optimizations"
16798 [(set_attr "type" "fpspc")
16799 (set_attr "mode" "XF")])
16802 [(set (match_operand:XF 0 "register_operand" "")
16803 (unspec:XF [(float_extend:XF
16804 (match_operand:MODEF 2 "register_operand" ""))]
16805 UNSPEC_SINCOS_COS))
16806 (set (match_operand:XF 1 "register_operand" "")
16807 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16808 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16809 && !(reload_completed || reload_in_progress)"
16810 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16814 [(set (match_operand:XF 0 "register_operand" "")
16815 (unspec:XF [(float_extend:XF
16816 (match_operand:MODEF 2 "register_operand" ""))]
16817 UNSPEC_SINCOS_COS))
16818 (set (match_operand:XF 1 "register_operand" "")
16819 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16820 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16821 && !(reload_completed || reload_in_progress)"
16822 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16825 (define_expand "sincos<mode>3"
16826 [(use (match_operand:MODEF 0 "register_operand" ""))
16827 (use (match_operand:MODEF 1 "register_operand" ""))
16828 (use (match_operand:MODEF 2 "register_operand" ""))]
16829 "TARGET_USE_FANCY_MATH_387
16830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16831 || TARGET_MIX_SSE_I387)
16832 && flag_unsafe_math_optimizations"
16834 rtx op0 = gen_reg_rtx (XFmode);
16835 rtx op1 = gen_reg_rtx (XFmode);
16837 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16838 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16839 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16843 (define_insn "fptanxf4_i387"
16844 [(set (match_operand:XF 0 "register_operand" "=f")
16845 (match_operand:XF 3 "const_double_operand" "F"))
16846 (set (match_operand:XF 1 "register_operand" "=u")
16847 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16849 "TARGET_USE_FANCY_MATH_387
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_insn "fptan_extend<mode>xf4_i387"
16857 [(set (match_operand:MODEF 0 "register_operand" "=f")
16858 (match_operand:MODEF 3 "const_double_operand" "F"))
16859 (set (match_operand:XF 1 "register_operand" "=u")
16860 (unspec:XF [(float_extend:XF
16861 (match_operand:MODEF 2 "register_operand" "0"))]
16863 "TARGET_USE_FANCY_MATH_387
16864 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16865 || TARGET_MIX_SSE_I387)
16866 && flag_unsafe_math_optimizations
16867 && standard_80387_constant_p (operands[3]) == 2"
16869 [(set_attr "type" "fpspc")
16870 (set_attr "mode" "XF")])
16872 (define_expand "tanxf2"
16873 [(use (match_operand:XF 0 "register_operand" ""))
16874 (use (match_operand:XF 1 "register_operand" ""))]
16875 "TARGET_USE_FANCY_MATH_387
16876 && flag_unsafe_math_optimizations"
16878 rtx one = gen_reg_rtx (XFmode);
16879 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16881 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16885 (define_expand "tan<mode>2"
16886 [(use (match_operand:MODEF 0 "register_operand" ""))
16887 (use (match_operand:MODEF 1 "register_operand" ""))]
16888 "TARGET_USE_FANCY_MATH_387
16889 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16890 || TARGET_MIX_SSE_I387)
16891 && flag_unsafe_math_optimizations"
16893 rtx op0 = gen_reg_rtx (XFmode);
16895 rtx one = gen_reg_rtx (<MODE>mode);
16896 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16898 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16899 operands[1], op2));
16900 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16904 (define_insn "*fpatanxf3_i387"
16905 [(set (match_operand:XF 0 "register_operand" "=f")
16906 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16907 (match_operand:XF 2 "register_operand" "u")]
16909 (clobber (match_scratch:XF 3 "=2"))]
16910 "TARGET_USE_FANCY_MATH_387
16911 && flag_unsafe_math_optimizations"
16913 [(set_attr "type" "fpspc")
16914 (set_attr "mode" "XF")])
16916 (define_insn "fpatan_extend<mode>xf3_i387"
16917 [(set (match_operand:XF 0 "register_operand" "=f")
16918 (unspec:XF [(float_extend:XF
16919 (match_operand:MODEF 1 "register_operand" "0"))
16921 (match_operand:MODEF 2 "register_operand" "u"))]
16923 (clobber (match_scratch:XF 3 "=2"))]
16924 "TARGET_USE_FANCY_MATH_387
16925 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16926 || TARGET_MIX_SSE_I387)
16927 && flag_unsafe_math_optimizations"
16929 [(set_attr "type" "fpspc")
16930 (set_attr "mode" "XF")])
16932 (define_expand "atan2xf3"
16933 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16934 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16935 (match_operand:XF 1 "register_operand" "")]
16937 (clobber (match_scratch:XF 3 ""))])]
16938 "TARGET_USE_FANCY_MATH_387
16939 && flag_unsafe_math_optimizations"
16942 (define_expand "atan2<mode>3"
16943 [(use (match_operand:MODEF 0 "register_operand" ""))
16944 (use (match_operand:MODEF 1 "register_operand" ""))
16945 (use (match_operand:MODEF 2 "register_operand" ""))]
16946 "TARGET_USE_FANCY_MATH_387
16947 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16948 || TARGET_MIX_SSE_I387)
16949 && flag_unsafe_math_optimizations"
16951 rtx op0 = gen_reg_rtx (XFmode);
16953 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16954 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16958 (define_expand "atanxf2"
16959 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16960 (unspec:XF [(match_dup 2)
16961 (match_operand:XF 1 "register_operand" "")]
16963 (clobber (match_scratch:XF 3 ""))])]
16964 "TARGET_USE_FANCY_MATH_387
16965 && flag_unsafe_math_optimizations"
16967 operands[2] = gen_reg_rtx (XFmode);
16968 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16971 (define_expand "atan<mode>2"
16972 [(use (match_operand:MODEF 0 "register_operand" ""))
16973 (use (match_operand:MODEF 1 "register_operand" ""))]
16974 "TARGET_USE_FANCY_MATH_387
16975 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16976 || TARGET_MIX_SSE_I387)
16977 && flag_unsafe_math_optimizations"
16979 rtx op0 = gen_reg_rtx (XFmode);
16981 rtx op2 = gen_reg_rtx (<MODE>mode);
16982 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16984 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16985 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16989 (define_expand "asinxf2"
16990 [(set (match_dup 2)
16991 (mult:XF (match_operand:XF 1 "register_operand" "")
16993 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16994 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16995 (parallel [(set (match_operand:XF 0 "register_operand" "")
16996 (unspec:XF [(match_dup 5) (match_dup 1)]
16998 (clobber (match_scratch:XF 6 ""))])]
16999 "TARGET_USE_FANCY_MATH_387
17000 && flag_unsafe_math_optimizations && !optimize_size"
17004 for (i = 2; i < 6; i++)
17005 operands[i] = gen_reg_rtx (XFmode);
17007 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17010 (define_expand "asin<mode>2"
17011 [(use (match_operand:MODEF 0 "register_operand" ""))
17012 (use (match_operand:MODEF 1 "general_operand" ""))]
17013 "TARGET_USE_FANCY_MATH_387
17014 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17015 || TARGET_MIX_SSE_I387)
17016 && flag_unsafe_math_optimizations && !optimize_size"
17018 rtx op0 = gen_reg_rtx (XFmode);
17019 rtx op1 = gen_reg_rtx (XFmode);
17021 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17022 emit_insn (gen_asinxf2 (op0, op1));
17023 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17027 (define_expand "acosxf2"
17028 [(set (match_dup 2)
17029 (mult:XF (match_operand:XF 1 "register_operand" "")
17031 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17032 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17033 (parallel [(set (match_operand:XF 0 "register_operand" "")
17034 (unspec:XF [(match_dup 1) (match_dup 5)]
17036 (clobber (match_scratch:XF 6 ""))])]
17037 "TARGET_USE_FANCY_MATH_387
17038 && flag_unsafe_math_optimizations && !optimize_size"
17042 for (i = 2; i < 6; i++)
17043 operands[i] = gen_reg_rtx (XFmode);
17045 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17048 (define_expand "acos<mode>2"
17049 [(use (match_operand:MODEF 0 "register_operand" ""))
17050 (use (match_operand:MODEF 1 "general_operand" ""))]
17051 "TARGET_USE_FANCY_MATH_387
17052 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17053 || TARGET_MIX_SSE_I387)
17054 && flag_unsafe_math_optimizations && !optimize_size"
17056 rtx op0 = gen_reg_rtx (XFmode);
17057 rtx op1 = gen_reg_rtx (XFmode);
17059 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17060 emit_insn (gen_acosxf2 (op0, op1));
17061 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17065 (define_insn "fyl2xxf3_i387"
17066 [(set (match_operand:XF 0 "register_operand" "=f")
17067 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17068 (match_operand:XF 2 "register_operand" "u")]
17070 (clobber (match_scratch:XF 3 "=2"))]
17071 "TARGET_USE_FANCY_MATH_387
17072 && flag_unsafe_math_optimizations"
17074 [(set_attr "type" "fpspc")
17075 (set_attr "mode" "XF")])
17077 (define_insn "fyl2x_extend<mode>xf3_i387"
17078 [(set (match_operand:XF 0 "register_operand" "=f")
17079 (unspec:XF [(float_extend:XF
17080 (match_operand:MODEF 1 "register_operand" "0"))
17081 (match_operand:XF 2 "register_operand" "u")]
17083 (clobber (match_scratch:XF 3 "=2"))]
17084 "TARGET_USE_FANCY_MATH_387
17085 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17086 || TARGET_MIX_SSE_I387)
17087 && flag_unsafe_math_optimizations"
17089 [(set_attr "type" "fpspc")
17090 (set_attr "mode" "XF")])
17092 (define_expand "logxf2"
17093 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17094 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17095 (match_dup 2)] UNSPEC_FYL2X))
17096 (clobber (match_scratch:XF 3 ""))])]
17097 "TARGET_USE_FANCY_MATH_387
17098 && flag_unsafe_math_optimizations"
17100 operands[2] = gen_reg_rtx (XFmode);
17101 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17104 (define_expand "log<mode>2"
17105 [(use (match_operand:MODEF 0 "register_operand" ""))
17106 (use (match_operand:MODEF 1 "register_operand" ""))]
17107 "TARGET_USE_FANCY_MATH_387
17108 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17109 || TARGET_MIX_SSE_I387)
17110 && flag_unsafe_math_optimizations"
17112 rtx op0 = gen_reg_rtx (XFmode);
17114 rtx op2 = gen_reg_rtx (XFmode);
17115 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17117 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17118 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17122 (define_expand "log10xf2"
17123 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17124 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17125 (match_dup 2)] UNSPEC_FYL2X))
17126 (clobber (match_scratch:XF 3 ""))])]
17127 "TARGET_USE_FANCY_MATH_387
17128 && flag_unsafe_math_optimizations"
17130 operands[2] = gen_reg_rtx (XFmode);
17131 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17134 (define_expand "log10<mode>2"
17135 [(use (match_operand:MODEF 0 "register_operand" ""))
17136 (use (match_operand:MODEF 1 "register_operand" ""))]
17137 "TARGET_USE_FANCY_MATH_387
17138 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17139 || TARGET_MIX_SSE_I387)
17140 && flag_unsafe_math_optimizations"
17142 rtx op0 = gen_reg_rtx (XFmode);
17144 rtx op2 = gen_reg_rtx (XFmode);
17145 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17147 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17148 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17152 (define_expand "log2xf2"
17153 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17154 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17155 (match_dup 2)] UNSPEC_FYL2X))
17156 (clobber (match_scratch:XF 3 ""))])]
17157 "TARGET_USE_FANCY_MATH_387
17158 && flag_unsafe_math_optimizations"
17160 operands[2] = gen_reg_rtx (XFmode);
17161 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17164 (define_expand "log2<mode>2"
17165 [(use (match_operand:MODEF 0 "register_operand" ""))
17166 (use (match_operand:MODEF 1 "register_operand" ""))]
17167 "TARGET_USE_FANCY_MATH_387
17168 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17169 || TARGET_MIX_SSE_I387)
17170 && flag_unsafe_math_optimizations"
17172 rtx op0 = gen_reg_rtx (XFmode);
17174 rtx op2 = gen_reg_rtx (XFmode);
17175 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17177 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17178 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17182 (define_insn "fyl2xp1xf3_i387"
17183 [(set (match_operand:XF 0 "register_operand" "=f")
17184 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17185 (match_operand:XF 2 "register_operand" "u")]
17187 (clobber (match_scratch:XF 3 "=2"))]
17188 "TARGET_USE_FANCY_MATH_387
17189 && flag_unsafe_math_optimizations"
17191 [(set_attr "type" "fpspc")
17192 (set_attr "mode" "XF")])
17194 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17195 [(set (match_operand:XF 0 "register_operand" "=f")
17196 (unspec:XF [(float_extend:XF
17197 (match_operand:MODEF 1 "register_operand" "0"))
17198 (match_operand:XF 2 "register_operand" "u")]
17200 (clobber (match_scratch:XF 3 "=2"))]
17201 "TARGET_USE_FANCY_MATH_387
17202 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17203 || TARGET_MIX_SSE_I387)
17204 && flag_unsafe_math_optimizations"
17206 [(set_attr "type" "fpspc")
17207 (set_attr "mode" "XF")])
17209 (define_expand "log1pxf2"
17210 [(use (match_operand:XF 0 "register_operand" ""))
17211 (use (match_operand:XF 1 "register_operand" ""))]
17212 "TARGET_USE_FANCY_MATH_387
17213 && flag_unsafe_math_optimizations && !optimize_size"
17215 ix86_emit_i387_log1p (operands[0], operands[1]);
17219 (define_expand "log1p<mode>2"
17220 [(use (match_operand:MODEF 0 "register_operand" ""))
17221 (use (match_operand:MODEF 1 "register_operand" ""))]
17222 "TARGET_USE_FANCY_MATH_387
17223 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17224 || TARGET_MIX_SSE_I387)
17225 && flag_unsafe_math_optimizations && !optimize_size"
17227 rtx op0 = gen_reg_rtx (XFmode);
17229 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17231 ix86_emit_i387_log1p (op0, operands[1]);
17232 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17236 (define_insn "fxtractxf3_i387"
17237 [(set (match_operand:XF 0 "register_operand" "=f")
17238 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17239 UNSPEC_XTRACT_FRACT))
17240 (set (match_operand:XF 1 "register_operand" "=u")
17241 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17242 "TARGET_USE_FANCY_MATH_387
17243 && flag_unsafe_math_optimizations"
17245 [(set_attr "type" "fpspc")
17246 (set_attr "mode" "XF")])
17248 (define_insn "fxtract_extend<mode>xf3_i387"
17249 [(set (match_operand:XF 0 "register_operand" "=f")
17250 (unspec:XF [(float_extend:XF
17251 (match_operand:MODEF 2 "register_operand" "0"))]
17252 UNSPEC_XTRACT_FRACT))
17253 (set (match_operand:XF 1 "register_operand" "=u")
17254 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17255 "TARGET_USE_FANCY_MATH_387
17256 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17257 || TARGET_MIX_SSE_I387)
17258 && flag_unsafe_math_optimizations"
17260 [(set_attr "type" "fpspc")
17261 (set_attr "mode" "XF")])
17263 (define_expand "logbxf2"
17264 [(parallel [(set (match_dup 2)
17265 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17266 UNSPEC_XTRACT_FRACT))
17267 (set (match_operand:XF 0 "register_operand" "")
17268 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17269 "TARGET_USE_FANCY_MATH_387
17270 && flag_unsafe_math_optimizations"
17272 operands[2] = gen_reg_rtx (XFmode);
17275 (define_expand "logb<mode>2"
17276 [(use (match_operand:MODEF 0 "register_operand" ""))
17277 (use (match_operand:MODEF 1 "register_operand" ""))]
17278 "TARGET_USE_FANCY_MATH_387
17279 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17280 || TARGET_MIX_SSE_I387)
17281 && flag_unsafe_math_optimizations"
17283 rtx op0 = gen_reg_rtx (XFmode);
17284 rtx op1 = gen_reg_rtx (XFmode);
17286 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17287 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17291 (define_expand "ilogbxf2"
17292 [(use (match_operand:SI 0 "register_operand" ""))
17293 (use (match_operand:XF 1 "register_operand" ""))]
17294 "TARGET_USE_FANCY_MATH_387
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_fxtractxf3_i387 (op0, op1, operands[1]));
17301 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17305 (define_expand "ilogb<mode>2"
17306 [(use (match_operand:SI 0 "register_operand" ""))
17307 (use (match_operand:MODEF 1 "register_operand" ""))]
17308 "TARGET_USE_FANCY_MATH_387
17309 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17310 || TARGET_MIX_SSE_I387)
17311 && flag_unsafe_math_optimizations && !optimize_size"
17313 rtx op0 = gen_reg_rtx (XFmode);
17314 rtx op1 = gen_reg_rtx (XFmode);
17316 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17317 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17321 (define_insn "*f2xm1xf2_i387"
17322 [(set (match_operand:XF 0 "register_operand" "=f")
17323 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17325 "TARGET_USE_FANCY_MATH_387
17326 && flag_unsafe_math_optimizations"
17328 [(set_attr "type" "fpspc")
17329 (set_attr "mode" "XF")])
17331 (define_insn "*fscalexf4_i387"
17332 [(set (match_operand:XF 0 "register_operand" "=f")
17333 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17334 (match_operand:XF 3 "register_operand" "1")]
17335 UNSPEC_FSCALE_FRACT))
17336 (set (match_operand:XF 1 "register_operand" "=u")
17337 (unspec:XF [(match_dup 2) (match_dup 3)]
17338 UNSPEC_FSCALE_EXP))]
17339 "TARGET_USE_FANCY_MATH_387
17340 && flag_unsafe_math_optimizations"
17342 [(set_attr "type" "fpspc")
17343 (set_attr "mode" "XF")])
17345 (define_expand "expNcorexf3"
17346 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17347 (match_operand:XF 2 "register_operand" "")))
17348 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17349 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17350 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17351 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17352 (parallel [(set (match_operand:XF 0 "register_operand" "")
17353 (unspec:XF [(match_dup 8) (match_dup 4)]
17354 UNSPEC_FSCALE_FRACT))
17356 (unspec:XF [(match_dup 8) (match_dup 4)]
17357 UNSPEC_FSCALE_EXP))])]
17358 "TARGET_USE_FANCY_MATH_387
17359 && flag_unsafe_math_optimizations && !optimize_size"
17363 for (i = 3; i < 10; i++)
17364 operands[i] = gen_reg_rtx (XFmode);
17366 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17369 (define_expand "expxf2"
17370 [(use (match_operand:XF 0 "register_operand" ""))
17371 (use (match_operand:XF 1 "register_operand" ""))]
17372 "TARGET_USE_FANCY_MATH_387
17373 && flag_unsafe_math_optimizations && !optimize_size"
17375 rtx op2 = gen_reg_rtx (XFmode);
17376 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17378 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17382 (define_expand "exp<mode>2"
17383 [(use (match_operand:MODEF 0 "register_operand" ""))
17384 (use (match_operand:MODEF 1 "general_operand" ""))]
17385 "TARGET_USE_FANCY_MATH_387
17386 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17387 || TARGET_MIX_SSE_I387)
17388 && flag_unsafe_math_optimizations && !optimize_size"
17390 rtx op0 = gen_reg_rtx (XFmode);
17391 rtx op1 = gen_reg_rtx (XFmode);
17393 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17394 emit_insn (gen_expxf2 (op0, op1));
17395 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17399 (define_expand "exp10xf2"
17400 [(use (match_operand:XF 0 "register_operand" ""))
17401 (use (match_operand:XF 1 "register_operand" ""))]
17402 "TARGET_USE_FANCY_MATH_387
17403 && flag_unsafe_math_optimizations && !optimize_size"
17405 rtx op2 = gen_reg_rtx (XFmode);
17406 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17408 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17412 (define_expand "exp10<mode>2"
17413 [(use (match_operand:MODEF 0 "register_operand" ""))
17414 (use (match_operand:MODEF 1 "general_operand" ""))]
17415 "TARGET_USE_FANCY_MATH_387
17416 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17417 || TARGET_MIX_SSE_I387)
17418 && flag_unsafe_math_optimizations && !optimize_size"
17420 rtx op0 = gen_reg_rtx (XFmode);
17421 rtx op1 = gen_reg_rtx (XFmode);
17423 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17424 emit_insn (gen_exp10xf2 (op0, op1));
17425 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17429 (define_expand "exp2xf2"
17430 [(use (match_operand:XF 0 "register_operand" ""))
17431 (use (match_operand:XF 1 "register_operand" ""))]
17432 "TARGET_USE_FANCY_MATH_387
17433 && flag_unsafe_math_optimizations && !optimize_size"
17435 rtx op2 = gen_reg_rtx (XFmode);
17436 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17438 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17442 (define_expand "exp2<mode>2"
17443 [(use (match_operand:MODEF 0 "register_operand" ""))
17444 (use (match_operand:MODEF 1 "general_operand" ""))]
17445 "TARGET_USE_FANCY_MATH_387
17446 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17447 || TARGET_MIX_SSE_I387)
17448 && flag_unsafe_math_optimizations && !optimize_size"
17450 rtx op0 = gen_reg_rtx (XFmode);
17451 rtx op1 = gen_reg_rtx (XFmode);
17453 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17454 emit_insn (gen_exp2xf2 (op0, op1));
17455 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17459 (define_expand "expm1xf2"
17460 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17462 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17463 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17464 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17465 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17466 (parallel [(set (match_dup 7)
17467 (unspec:XF [(match_dup 6) (match_dup 4)]
17468 UNSPEC_FSCALE_FRACT))
17470 (unspec:XF [(match_dup 6) (match_dup 4)]
17471 UNSPEC_FSCALE_EXP))])
17472 (parallel [(set (match_dup 10)
17473 (unspec:XF [(match_dup 9) (match_dup 8)]
17474 UNSPEC_FSCALE_FRACT))
17475 (set (match_dup 11)
17476 (unspec:XF [(match_dup 9) (match_dup 8)]
17477 UNSPEC_FSCALE_EXP))])
17478 (set (match_dup 12) (minus:XF (match_dup 10)
17479 (float_extend:XF (match_dup 13))))
17480 (set (match_operand:XF 0 "register_operand" "")
17481 (plus:XF (match_dup 12) (match_dup 7)))]
17482 "TARGET_USE_FANCY_MATH_387
17483 && flag_unsafe_math_optimizations && !optimize_size"
17487 for (i = 2; i < 13; i++)
17488 operands[i] = gen_reg_rtx (XFmode);
17491 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17493 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17496 (define_expand "expm1<mode>2"
17497 [(use (match_operand:MODEF 0 "register_operand" ""))
17498 (use (match_operand:MODEF 1 "general_operand" ""))]
17499 "TARGET_USE_FANCY_MATH_387
17500 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17501 || TARGET_MIX_SSE_I387)
17502 && flag_unsafe_math_optimizations && !optimize_size"
17504 rtx op0 = gen_reg_rtx (XFmode);
17505 rtx op1 = gen_reg_rtx (XFmode);
17507 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17508 emit_insn (gen_expm1xf2 (op0, op1));
17509 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17513 (define_expand "ldexpxf3"
17514 [(set (match_dup 3)
17515 (float:XF (match_operand:SI 2 "register_operand" "")))
17516 (parallel [(set (match_operand:XF 0 " register_operand" "")
17517 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17519 UNSPEC_FSCALE_FRACT))
17521 (unspec:XF [(match_dup 1) (match_dup 3)]
17522 UNSPEC_FSCALE_EXP))])]
17523 "TARGET_USE_FANCY_MATH_387
17524 && flag_unsafe_math_optimizations && !optimize_size"
17526 operands[3] = gen_reg_rtx (XFmode);
17527 operands[4] = gen_reg_rtx (XFmode);
17530 (define_expand "ldexp<mode>3"
17531 [(use (match_operand:MODEF 0 "register_operand" ""))
17532 (use (match_operand:MODEF 1 "general_operand" ""))
17533 (use (match_operand:SI 2 "register_operand" ""))]
17534 "TARGET_USE_FANCY_MATH_387
17535 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17536 || TARGET_MIX_SSE_I387)
17537 && flag_unsafe_math_optimizations && !optimize_size"
17539 rtx op0 = gen_reg_rtx (XFmode);
17540 rtx op1 = gen_reg_rtx (XFmode);
17542 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17543 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17544 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17548 (define_expand "scalbxf3"
17549 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17550 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17551 (match_operand:XF 2 "register_operand" "")]
17552 UNSPEC_FSCALE_FRACT))
17554 (unspec:XF [(match_dup 1) (match_dup 2)]
17555 UNSPEC_FSCALE_EXP))])]
17556 "TARGET_USE_FANCY_MATH_387
17557 && flag_unsafe_math_optimizations && !optimize_size"
17559 operands[3] = gen_reg_rtx (XFmode);
17562 (define_expand "scalb<mode>3"
17563 [(use (match_operand:MODEF 0 "register_operand" ""))
17564 (use (match_operand:MODEF 1 "general_operand" ""))
17565 (use (match_operand:MODEF 2 "register_operand" ""))]
17566 "TARGET_USE_FANCY_MATH_387
17567 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17568 || TARGET_MIX_SSE_I387)
17569 && flag_unsafe_math_optimizations && !optimize_size"
17571 rtx op0 = gen_reg_rtx (XFmode);
17572 rtx op1 = gen_reg_rtx (XFmode);
17573 rtx op2 = gen_reg_rtx (XFmode);
17575 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17576 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17577 emit_insn (gen_scalbxf3 (op0, op1, op2));
17578 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17583 (define_insn "sse4_1_round<mode>2"
17584 [(set (match_operand:MODEF 0 "register_operand" "=x")
17585 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17586 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17589 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17590 [(set_attr "type" "ssecvt")
17591 (set_attr "prefix_extra" "1")
17592 (set_attr "mode" "<MODE>")])
17594 (define_insn "rintxf2"
17595 [(set (match_operand:XF 0 "register_operand" "=f")
17596 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17598 "TARGET_USE_FANCY_MATH_387
17599 && flag_unsafe_math_optimizations"
17601 [(set_attr "type" "fpspc")
17602 (set_attr "mode" "XF")])
17604 (define_expand "rint<mode>2"
17605 [(use (match_operand:MODEF 0 "register_operand" ""))
17606 (use (match_operand:MODEF 1 "register_operand" ""))]
17607 "(TARGET_USE_FANCY_MATH_387
17608 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17609 || TARGET_MIX_SSE_I387)
17610 && flag_unsafe_math_optimizations)
17611 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17612 && !flag_trapping_math
17613 && (TARGET_ROUND || !optimize_size))"
17615 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17616 && !flag_trapping_math
17617 && (TARGET_ROUND || !optimize_size))
17620 emit_insn (gen_sse4_1_round<mode>2
17621 (operands[0], operands[1], GEN_INT (0x04)));
17623 ix86_expand_rint (operand0, operand1);
17627 rtx op0 = gen_reg_rtx (XFmode);
17628 rtx op1 = gen_reg_rtx (XFmode);
17630 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17631 emit_insn (gen_rintxf2 (op0, op1));
17633 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17638 (define_expand "round<mode>2"
17639 [(match_operand:MODEF 0 "register_operand" "")
17640 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17641 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17642 && !flag_trapping_math && !flag_rounding_math
17645 if (TARGET_64BIT || (<MODE>mode != DFmode))
17646 ix86_expand_round (operand0, operand1);
17648 ix86_expand_rounddf_32 (operand0, operand1);
17652 (define_insn_and_split "*fistdi2_1"
17653 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17654 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17656 "TARGET_USE_FANCY_MATH_387
17657 && !(reload_completed || reload_in_progress)"
17662 if (memory_operand (operands[0], VOIDmode))
17663 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17666 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17667 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17672 [(set_attr "type" "fpspc")
17673 (set_attr "mode" "DI")])
17675 (define_insn "fistdi2"
17676 [(set (match_operand:DI 0 "memory_operand" "=m")
17677 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17679 (clobber (match_scratch:XF 2 "=&1f"))]
17680 "TARGET_USE_FANCY_MATH_387"
17681 "* return output_fix_trunc (insn, operands, 0);"
17682 [(set_attr "type" "fpspc")
17683 (set_attr "mode" "DI")])
17685 (define_insn "fistdi2_with_temp"
17686 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17687 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17689 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17690 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17691 "TARGET_USE_FANCY_MATH_387"
17693 [(set_attr "type" "fpspc")
17694 (set_attr "mode" "DI")])
17697 [(set (match_operand:DI 0 "register_operand" "")
17698 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17700 (clobber (match_operand:DI 2 "memory_operand" ""))
17701 (clobber (match_scratch 3 ""))]
17703 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17704 (clobber (match_dup 3))])
17705 (set (match_dup 0) (match_dup 2))]
17709 [(set (match_operand:DI 0 "memory_operand" "")
17710 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17712 (clobber (match_operand:DI 2 "memory_operand" ""))
17713 (clobber (match_scratch 3 ""))]
17715 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17716 (clobber (match_dup 3))])]
17719 (define_insn_and_split "*fist<mode>2_1"
17720 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17721 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17723 "TARGET_USE_FANCY_MATH_387
17724 && !(reload_completed || reload_in_progress)"
17729 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17730 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17734 [(set_attr "type" "fpspc")
17735 (set_attr "mode" "<MODE>")])
17737 (define_insn "fist<mode>2"
17738 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17739 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17741 "TARGET_USE_FANCY_MATH_387"
17742 "* return output_fix_trunc (insn, operands, 0);"
17743 [(set_attr "type" "fpspc")
17744 (set_attr "mode" "<MODE>")])
17746 (define_insn "fist<mode>2_with_temp"
17747 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17748 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17750 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17751 "TARGET_USE_FANCY_MATH_387"
17753 [(set_attr "type" "fpspc")
17754 (set_attr "mode" "<MODE>")])
17757 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17758 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17760 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17762 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17763 (set (match_dup 0) (match_dup 2))]
17767 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17768 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17770 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17772 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17775 (define_expand "lrintxf<mode>2"
17776 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17777 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17779 "TARGET_USE_FANCY_MATH_387"
17782 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17783 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17784 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17785 UNSPEC_FIX_NOTRUNC))]
17786 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17787 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17790 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17791 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17792 (match_operand:MODEF 1 "register_operand" "")]
17793 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17794 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17795 && !flag_trapping_math && !flag_rounding_math
17798 ix86_expand_lround (operand0, operand1);
17802 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17803 (define_insn_and_split "frndintxf2_floor"
17804 [(set (match_operand:XF 0 "register_operand" "")
17805 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17806 UNSPEC_FRNDINT_FLOOR))
17807 (clobber (reg:CC FLAGS_REG))]
17808 "TARGET_USE_FANCY_MATH_387
17809 && flag_unsafe_math_optimizations
17810 && !(reload_completed || reload_in_progress)"
17815 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17817 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17818 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17820 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17821 operands[2], operands[3]));
17824 [(set_attr "type" "frndint")
17825 (set_attr "i387_cw" "floor")
17826 (set_attr "mode" "XF")])
17828 (define_insn "frndintxf2_floor_i387"
17829 [(set (match_operand:XF 0 "register_operand" "=f")
17830 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17831 UNSPEC_FRNDINT_FLOOR))
17832 (use (match_operand:HI 2 "memory_operand" "m"))
17833 (use (match_operand:HI 3 "memory_operand" "m"))]
17834 "TARGET_USE_FANCY_MATH_387
17835 && flag_unsafe_math_optimizations"
17836 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17837 [(set_attr "type" "frndint")
17838 (set_attr "i387_cw" "floor")
17839 (set_attr "mode" "XF")])
17841 (define_expand "floorxf2"
17842 [(use (match_operand:XF 0 "register_operand" ""))
17843 (use (match_operand:XF 1 "register_operand" ""))]
17844 "TARGET_USE_FANCY_MATH_387
17845 && flag_unsafe_math_optimizations && !optimize_size"
17847 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17851 (define_expand "floor<mode>2"
17852 [(use (match_operand:MODEF 0 "register_operand" ""))
17853 (use (match_operand:MODEF 1 "register_operand" ""))]
17854 "(TARGET_USE_FANCY_MATH_387
17855 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17856 || TARGET_MIX_SSE_I387)
17857 && flag_unsafe_math_optimizations && !optimize_size)
17858 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17859 && !flag_trapping_math
17860 && (TARGET_ROUND || !optimize_size))"
17862 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17863 && !flag_trapping_math
17864 && (TARGET_ROUND || !optimize_size))
17867 emit_insn (gen_sse4_1_round<mode>2
17868 (operands[0], operands[1], GEN_INT (0x01)));
17869 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17870 ix86_expand_floorceil (operand0, operand1, true);
17872 ix86_expand_floorceildf_32 (operand0, operand1, true);
17876 rtx op0 = gen_reg_rtx (XFmode);
17877 rtx op1 = gen_reg_rtx (XFmode);
17879 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17880 emit_insn (gen_frndintxf2_floor (op0, op1));
17882 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17887 (define_insn_and_split "*fist<mode>2_floor_1"
17888 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17889 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17890 UNSPEC_FIST_FLOOR))
17891 (clobber (reg:CC FLAGS_REG))]
17892 "TARGET_USE_FANCY_MATH_387
17893 && flag_unsafe_math_optimizations
17894 && !(reload_completed || reload_in_progress)"
17899 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17901 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17902 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17903 if (memory_operand (operands[0], VOIDmode))
17904 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17905 operands[2], operands[3]));
17908 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17909 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17910 operands[2], operands[3],
17915 [(set_attr "type" "fistp")
17916 (set_attr "i387_cw" "floor")
17917 (set_attr "mode" "<MODE>")])
17919 (define_insn "fistdi2_floor"
17920 [(set (match_operand:DI 0 "memory_operand" "=m")
17921 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17922 UNSPEC_FIST_FLOOR))
17923 (use (match_operand:HI 2 "memory_operand" "m"))
17924 (use (match_operand:HI 3 "memory_operand" "m"))
17925 (clobber (match_scratch:XF 4 "=&1f"))]
17926 "TARGET_USE_FANCY_MATH_387
17927 && flag_unsafe_math_optimizations"
17928 "* return output_fix_trunc (insn, operands, 0);"
17929 [(set_attr "type" "fistp")
17930 (set_attr "i387_cw" "floor")
17931 (set_attr "mode" "DI")])
17933 (define_insn "fistdi2_floor_with_temp"
17934 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17935 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17936 UNSPEC_FIST_FLOOR))
17937 (use (match_operand:HI 2 "memory_operand" "m,m"))
17938 (use (match_operand:HI 3 "memory_operand" "m,m"))
17939 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17940 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17941 "TARGET_USE_FANCY_MATH_387
17942 && flag_unsafe_math_optimizations"
17944 [(set_attr "type" "fistp")
17945 (set_attr "i387_cw" "floor")
17946 (set_attr "mode" "DI")])
17949 [(set (match_operand:DI 0 "register_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 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17958 (use (match_dup 2))
17959 (use (match_dup 3))
17960 (clobber (match_dup 5))])
17961 (set (match_dup 0) (match_dup 4))]
17965 [(set (match_operand:DI 0 "memory_operand" "")
17966 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17967 UNSPEC_FIST_FLOOR))
17968 (use (match_operand:HI 2 "memory_operand" ""))
17969 (use (match_operand:HI 3 "memory_operand" ""))
17970 (clobber (match_operand:DI 4 "memory_operand" ""))
17971 (clobber (match_scratch 5 ""))]
17973 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17974 (use (match_dup 2))
17975 (use (match_dup 3))
17976 (clobber (match_dup 5))])]
17979 (define_insn "fist<mode>2_floor"
17980 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17981 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17982 UNSPEC_FIST_FLOOR))
17983 (use (match_operand:HI 2 "memory_operand" "m"))
17984 (use (match_operand:HI 3 "memory_operand" "m"))]
17985 "TARGET_USE_FANCY_MATH_387
17986 && flag_unsafe_math_optimizations"
17987 "* return output_fix_trunc (insn, operands, 0);"
17988 [(set_attr "type" "fistp")
17989 (set_attr "i387_cw" "floor")
17990 (set_attr "mode" "<MODE>")])
17992 (define_insn "fist<mode>2_floor_with_temp"
17993 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17994 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17995 UNSPEC_FIST_FLOOR))
17996 (use (match_operand:HI 2 "memory_operand" "m,m"))
17997 (use (match_operand:HI 3 "memory_operand" "m,m"))
17998 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17999 "TARGET_USE_FANCY_MATH_387
18000 && flag_unsafe_math_optimizations"
18002 [(set_attr "type" "fistp")
18003 (set_attr "i387_cw" "floor")
18004 (set_attr "mode" "<MODE>")])
18007 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18008 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18009 UNSPEC_FIST_FLOOR))
18010 (use (match_operand:HI 2 "memory_operand" ""))
18011 (use (match_operand:HI 3 "memory_operand" ""))
18012 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18014 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18015 UNSPEC_FIST_FLOOR))
18016 (use (match_dup 2))
18017 (use (match_dup 3))])
18018 (set (match_dup 0) (match_dup 4))]
18022 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18023 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18024 UNSPEC_FIST_FLOOR))
18025 (use (match_operand:HI 2 "memory_operand" ""))
18026 (use (match_operand:HI 3 "memory_operand" ""))
18027 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18029 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18030 UNSPEC_FIST_FLOOR))
18031 (use (match_dup 2))
18032 (use (match_dup 3))])]
18035 (define_expand "lfloorxf<mode>2"
18036 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18037 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18038 UNSPEC_FIST_FLOOR))
18039 (clobber (reg:CC FLAGS_REG))])]
18040 "TARGET_USE_FANCY_MATH_387
18041 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18042 && flag_unsafe_math_optimizations"
18045 (define_expand "lfloor<mode>di2"
18046 [(match_operand:DI 0 "nonimmediate_operand" "")
18047 (match_operand:MODEF 1 "register_operand" "")]
18048 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18049 && !flag_trapping_math
18052 ix86_expand_lfloorceil (operand0, operand1, true);
18056 (define_expand "lfloor<mode>si2"
18057 [(match_operand:SI 0 "nonimmediate_operand" "")
18058 (match_operand:MODEF 1 "register_operand" "")]
18059 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18060 && !flag_trapping_math
18061 && (!optimize_size || !TARGET_64BIT)"
18063 ix86_expand_lfloorceil (operand0, operand1, true);
18067 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18068 (define_insn_and_split "frndintxf2_ceil"
18069 [(set (match_operand:XF 0 "register_operand" "")
18070 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18071 UNSPEC_FRNDINT_CEIL))
18072 (clobber (reg:CC FLAGS_REG))]
18073 "TARGET_USE_FANCY_MATH_387
18074 && flag_unsafe_math_optimizations
18075 && !(reload_completed || reload_in_progress)"
18080 ix86_optimize_mode_switching[I387_CEIL] = 1;
18082 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18083 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18085 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18086 operands[2], operands[3]));
18089 [(set_attr "type" "frndint")
18090 (set_attr "i387_cw" "ceil")
18091 (set_attr "mode" "XF")])
18093 (define_insn "frndintxf2_ceil_i387"
18094 [(set (match_operand:XF 0 "register_operand" "=f")
18095 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18096 UNSPEC_FRNDINT_CEIL))
18097 (use (match_operand:HI 2 "memory_operand" "m"))
18098 (use (match_operand:HI 3 "memory_operand" "m"))]
18099 "TARGET_USE_FANCY_MATH_387
18100 && flag_unsafe_math_optimizations"
18101 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18102 [(set_attr "type" "frndint")
18103 (set_attr "i387_cw" "ceil")
18104 (set_attr "mode" "XF")])
18106 (define_expand "ceilxf2"
18107 [(use (match_operand:XF 0 "register_operand" ""))
18108 (use (match_operand:XF 1 "register_operand" ""))]
18109 "TARGET_USE_FANCY_MATH_387
18110 && flag_unsafe_math_optimizations && !optimize_size"
18112 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18116 (define_expand "ceil<mode>2"
18117 [(use (match_operand:MODEF 0 "register_operand" ""))
18118 (use (match_operand:MODEF 1 "register_operand" ""))]
18119 "(TARGET_USE_FANCY_MATH_387
18120 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18121 || TARGET_MIX_SSE_I387)
18122 && flag_unsafe_math_optimizations && !optimize_size)
18123 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18124 && !flag_trapping_math
18125 && (TARGET_ROUND || !optimize_size))"
18127 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18128 && !flag_trapping_math
18129 && (TARGET_ROUND || !optimize_size))
18132 emit_insn (gen_sse4_1_round<mode>2
18133 (operands[0], operands[1], GEN_INT (0x02)));
18134 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18135 ix86_expand_floorceil (operand0, operand1, false);
18137 ix86_expand_floorceildf_32 (operand0, operand1, false);
18141 rtx op0 = gen_reg_rtx (XFmode);
18142 rtx op1 = gen_reg_rtx (XFmode);
18144 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18145 emit_insn (gen_frndintxf2_ceil (op0, op1));
18147 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18152 (define_insn_and_split "*fist<mode>2_ceil_1"
18153 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18154 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18156 (clobber (reg:CC FLAGS_REG))]
18157 "TARGET_USE_FANCY_MATH_387
18158 && flag_unsafe_math_optimizations
18159 && !(reload_completed || reload_in_progress)"
18164 ix86_optimize_mode_switching[I387_CEIL] = 1;
18166 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18167 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18168 if (memory_operand (operands[0], VOIDmode))
18169 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18170 operands[2], operands[3]));
18173 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18174 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18175 operands[2], operands[3],
18180 [(set_attr "type" "fistp")
18181 (set_attr "i387_cw" "ceil")
18182 (set_attr "mode" "<MODE>")])
18184 (define_insn "fistdi2_ceil"
18185 [(set (match_operand:DI 0 "memory_operand" "=m")
18186 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18188 (use (match_operand:HI 2 "memory_operand" "m"))
18189 (use (match_operand:HI 3 "memory_operand" "m"))
18190 (clobber (match_scratch:XF 4 "=&1f"))]
18191 "TARGET_USE_FANCY_MATH_387
18192 && flag_unsafe_math_optimizations"
18193 "* return output_fix_trunc (insn, operands, 0);"
18194 [(set_attr "type" "fistp")
18195 (set_attr "i387_cw" "ceil")
18196 (set_attr "mode" "DI")])
18198 (define_insn "fistdi2_ceil_with_temp"
18199 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18200 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18202 (use (match_operand:HI 2 "memory_operand" "m,m"))
18203 (use (match_operand:HI 3 "memory_operand" "m,m"))
18204 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18205 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18206 "TARGET_USE_FANCY_MATH_387
18207 && flag_unsafe_math_optimizations"
18209 [(set_attr "type" "fistp")
18210 (set_attr "i387_cw" "ceil")
18211 (set_attr "mode" "DI")])
18214 [(set (match_operand:DI 0 "register_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 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18223 (use (match_dup 2))
18224 (use (match_dup 3))
18225 (clobber (match_dup 5))])
18226 (set (match_dup 0) (match_dup 4))]
18230 [(set (match_operand:DI 0 "memory_operand" "")
18231 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18233 (use (match_operand:HI 2 "memory_operand" ""))
18234 (use (match_operand:HI 3 "memory_operand" ""))
18235 (clobber (match_operand:DI 4 "memory_operand" ""))
18236 (clobber (match_scratch 5 ""))]
18238 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18239 (use (match_dup 2))
18240 (use (match_dup 3))
18241 (clobber (match_dup 5))])]
18244 (define_insn "fist<mode>2_ceil"
18245 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18246 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18248 (use (match_operand:HI 2 "memory_operand" "m"))
18249 (use (match_operand:HI 3 "memory_operand" "m"))]
18250 "TARGET_USE_FANCY_MATH_387
18251 && flag_unsafe_math_optimizations"
18252 "* return output_fix_trunc (insn, operands, 0);"
18253 [(set_attr "type" "fistp")
18254 (set_attr "i387_cw" "ceil")
18255 (set_attr "mode" "<MODE>")])
18257 (define_insn "fist<mode>2_ceil_with_temp"
18258 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18259 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18261 (use (match_operand:HI 2 "memory_operand" "m,m"))
18262 (use (match_operand:HI 3 "memory_operand" "m,m"))
18263 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18264 "TARGET_USE_FANCY_MATH_387
18265 && flag_unsafe_math_optimizations"
18267 [(set_attr "type" "fistp")
18268 (set_attr "i387_cw" "ceil")
18269 (set_attr "mode" "<MODE>")])
18272 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18273 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18275 (use (match_operand:HI 2 "memory_operand" ""))
18276 (use (match_operand:HI 3 "memory_operand" ""))
18277 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18279 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18281 (use (match_dup 2))
18282 (use (match_dup 3))])
18283 (set (match_dup 0) (match_dup 4))]
18287 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18288 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18290 (use (match_operand:HI 2 "memory_operand" ""))
18291 (use (match_operand:HI 3 "memory_operand" ""))
18292 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18294 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18296 (use (match_dup 2))
18297 (use (match_dup 3))])]
18300 (define_expand "lceilxf<mode>2"
18301 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18302 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18304 (clobber (reg:CC FLAGS_REG))])]
18305 "TARGET_USE_FANCY_MATH_387
18306 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18307 && flag_unsafe_math_optimizations"
18310 (define_expand "lceil<mode>di2"
18311 [(match_operand:DI 0 "nonimmediate_operand" "")
18312 (match_operand:MODEF 1 "register_operand" "")]
18313 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18314 && !flag_trapping_math"
18316 ix86_expand_lfloorceil (operand0, operand1, false);
18320 (define_expand "lceil<mode>si2"
18321 [(match_operand:SI 0 "nonimmediate_operand" "")
18322 (match_operand:MODEF 1 "register_operand" "")]
18323 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18324 && !flag_trapping_math"
18326 ix86_expand_lfloorceil (operand0, operand1, false);
18330 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18331 (define_insn_and_split "frndintxf2_trunc"
18332 [(set (match_operand:XF 0 "register_operand" "")
18333 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18334 UNSPEC_FRNDINT_TRUNC))
18335 (clobber (reg:CC FLAGS_REG))]
18336 "TARGET_USE_FANCY_MATH_387
18337 && flag_unsafe_math_optimizations
18338 && !(reload_completed || reload_in_progress)"
18343 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18345 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18346 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18348 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18349 operands[2], operands[3]));
18352 [(set_attr "type" "frndint")
18353 (set_attr "i387_cw" "trunc")
18354 (set_attr "mode" "XF")])
18356 (define_insn "frndintxf2_trunc_i387"
18357 [(set (match_operand:XF 0 "register_operand" "=f")
18358 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18359 UNSPEC_FRNDINT_TRUNC))
18360 (use (match_operand:HI 2 "memory_operand" "m"))
18361 (use (match_operand:HI 3 "memory_operand" "m"))]
18362 "TARGET_USE_FANCY_MATH_387
18363 && flag_unsafe_math_optimizations"
18364 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18365 [(set_attr "type" "frndint")
18366 (set_attr "i387_cw" "trunc")
18367 (set_attr "mode" "XF")])
18369 (define_expand "btruncxf2"
18370 [(use (match_operand:XF 0 "register_operand" ""))
18371 (use (match_operand:XF 1 "register_operand" ""))]
18372 "TARGET_USE_FANCY_MATH_387
18373 && flag_unsafe_math_optimizations && !optimize_size"
18375 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18379 (define_expand "btrunc<mode>2"
18380 [(use (match_operand:MODEF 0 "register_operand" ""))
18381 (use (match_operand:MODEF 1 "register_operand" ""))]
18382 "(TARGET_USE_FANCY_MATH_387
18383 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18384 || TARGET_MIX_SSE_I387)
18385 && flag_unsafe_math_optimizations && !optimize_size)
18386 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18387 && !flag_trapping_math
18388 && (TARGET_ROUND || !optimize_size))"
18390 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18391 && !flag_trapping_math
18392 && (TARGET_ROUND || !optimize_size))
18395 emit_insn (gen_sse4_1_round<mode>2
18396 (operands[0], operands[1], GEN_INT (0x03)));
18397 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18398 ix86_expand_trunc (operand0, operand1);
18400 ix86_expand_truncdf_32 (operand0, operand1);
18404 rtx op0 = gen_reg_rtx (XFmode);
18405 rtx op1 = gen_reg_rtx (XFmode);
18407 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18408 emit_insn (gen_frndintxf2_trunc (op0, op1));
18410 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18415 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18416 (define_insn_and_split "frndintxf2_mask_pm"
18417 [(set (match_operand:XF 0 "register_operand" "")
18418 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18419 UNSPEC_FRNDINT_MASK_PM))
18420 (clobber (reg:CC FLAGS_REG))]
18421 "TARGET_USE_FANCY_MATH_387
18422 && flag_unsafe_math_optimizations
18423 && !(reload_completed || reload_in_progress)"
18428 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18430 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18431 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18433 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18434 operands[2], operands[3]));
18437 [(set_attr "type" "frndint")
18438 (set_attr "i387_cw" "mask_pm")
18439 (set_attr "mode" "XF")])
18441 (define_insn "frndintxf2_mask_pm_i387"
18442 [(set (match_operand:XF 0 "register_operand" "=f")
18443 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18444 UNSPEC_FRNDINT_MASK_PM))
18445 (use (match_operand:HI 2 "memory_operand" "m"))
18446 (use (match_operand:HI 3 "memory_operand" "m"))]
18447 "TARGET_USE_FANCY_MATH_387
18448 && flag_unsafe_math_optimizations"
18449 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18450 [(set_attr "type" "frndint")
18451 (set_attr "i387_cw" "mask_pm")
18452 (set_attr "mode" "XF")])
18454 (define_expand "nearbyintxf2"
18455 [(use (match_operand:XF 0 "register_operand" ""))
18456 (use (match_operand:XF 1 "register_operand" ""))]
18457 "TARGET_USE_FANCY_MATH_387
18458 && flag_unsafe_math_optimizations"
18460 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18465 (define_expand "nearbyint<mode>2"
18466 [(use (match_operand:MODEF 0 "register_operand" ""))
18467 (use (match_operand:MODEF 1 "register_operand" ""))]
18468 "TARGET_USE_FANCY_MATH_387
18469 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18470 || TARGET_MIX_SSE_I387)
18471 && flag_unsafe_math_optimizations"
18473 rtx op0 = gen_reg_rtx (XFmode);
18474 rtx op1 = gen_reg_rtx (XFmode);
18476 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18477 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18479 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18483 (define_insn "fxam<mode>2_i387"
18484 [(set (match_operand:HI 0 "register_operand" "=a")
18486 [(match_operand:X87MODEF 1 "register_operand" "f")]
18488 "TARGET_USE_FANCY_MATH_387"
18489 "fxam\n\tfnstsw\t%0"
18490 [(set_attr "type" "multi")
18491 (set_attr "unit" "i387")
18492 (set_attr "mode" "<MODE>")])
18494 (define_expand "isinf<mode>2"
18495 [(use (match_operand:SI 0 "register_operand" ""))
18496 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18497 "TARGET_USE_FANCY_MATH_387
18498 && TARGET_C99_FUNCTIONS
18499 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18501 rtx mask = GEN_INT (0x45);
18502 rtx val = GEN_INT (0x05);
18506 rtx scratch = gen_reg_rtx (HImode);
18507 rtx res = gen_reg_rtx (QImode);
18509 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18510 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18511 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18512 cond = gen_rtx_fmt_ee (EQ, QImode,
18513 gen_rtx_REG (CCmode, FLAGS_REG),
18515 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18516 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18520 (define_expand "signbit<mode>2"
18521 [(use (match_operand:SI 0 "register_operand" ""))
18522 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18523 "TARGET_USE_FANCY_MATH_387
18524 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18526 rtx mask = GEN_INT (0x0200);
18528 rtx scratch = gen_reg_rtx (HImode);
18530 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18531 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18535 ;; Block operation instructions
18537 (define_expand "movmemsi"
18538 [(use (match_operand:BLK 0 "memory_operand" ""))
18539 (use (match_operand:BLK 1 "memory_operand" ""))
18540 (use (match_operand:SI 2 "nonmemory_operand" ""))
18541 (use (match_operand:SI 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 (define_expand "movmemdi"
18554 [(use (match_operand:BLK 0 "memory_operand" ""))
18555 (use (match_operand:BLK 1 "memory_operand" ""))
18556 (use (match_operand:DI 2 "nonmemory_operand" ""))
18557 (use (match_operand:DI 3 "const_int_operand" ""))
18558 (use (match_operand:SI 4 "const_int_operand" ""))
18559 (use (match_operand:SI 5 "const_int_operand" ""))]
18562 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18563 operands[4], operands[5]))
18569 ;; Most CPUs don't like single string operations
18570 ;; Handle this case here to simplify previous expander.
18572 (define_expand "strmov"
18573 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18574 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18575 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18576 (clobber (reg:CC FLAGS_REG))])
18577 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18578 (clobber (reg:CC FLAGS_REG))])]
18581 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18583 /* If .md ever supports :P for Pmode, these can be directly
18584 in the pattern above. */
18585 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18586 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18588 /* Can't use this if the user has appropriated esi or edi. */
18589 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18590 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18592 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18593 operands[2], operands[3],
18594 operands[5], operands[6]));
18598 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18601 (define_expand "strmov_singleop"
18602 [(parallel [(set (match_operand 1 "memory_operand" "")
18603 (match_operand 3 "memory_operand" ""))
18604 (set (match_operand 0 "register_operand" "")
18605 (match_operand 4 "" ""))
18606 (set (match_operand 2 "register_operand" "")
18607 (match_operand 5 "" ""))])]
18608 "TARGET_SINGLE_STRINGOP || optimize_size"
18611 (define_insn "*strmovdi_rex_1"
18612 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18613 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18614 (set (match_operand:DI 0 "register_operand" "=D")
18615 (plus:DI (match_dup 2)
18617 (set (match_operand:DI 1 "register_operand" "=S")
18618 (plus:DI (match_dup 3)
18620 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18622 [(set_attr "type" "str")
18623 (set_attr "mode" "DI")
18624 (set_attr "memory" "both")])
18626 (define_insn "*strmovsi_1"
18627 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18628 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18629 (set (match_operand:SI 0 "register_operand" "=D")
18630 (plus:SI (match_dup 2)
18632 (set (match_operand:SI 1 "register_operand" "=S")
18633 (plus:SI (match_dup 3)
18635 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18637 [(set_attr "type" "str")
18638 (set_attr "mode" "SI")
18639 (set_attr "memory" "both")])
18641 (define_insn "*strmovsi_rex_1"
18642 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18643 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18644 (set (match_operand:DI 0 "register_operand" "=D")
18645 (plus:DI (match_dup 2)
18647 (set (match_operand:DI 1 "register_operand" "=S")
18648 (plus:DI (match_dup 3)
18650 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18652 [(set_attr "type" "str")
18653 (set_attr "mode" "SI")
18654 (set_attr "memory" "both")])
18656 (define_insn "*strmovhi_1"
18657 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18658 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18659 (set (match_operand:SI 0 "register_operand" "=D")
18660 (plus:SI (match_dup 2)
18662 (set (match_operand:SI 1 "register_operand" "=S")
18663 (plus:SI (match_dup 3)
18665 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18667 [(set_attr "type" "str")
18668 (set_attr "memory" "both")
18669 (set_attr "mode" "HI")])
18671 (define_insn "*strmovhi_rex_1"
18672 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18673 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18674 (set (match_operand:DI 0 "register_operand" "=D")
18675 (plus:DI (match_dup 2)
18677 (set (match_operand:DI 1 "register_operand" "=S")
18678 (plus:DI (match_dup 3)
18680 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18682 [(set_attr "type" "str")
18683 (set_attr "memory" "both")
18684 (set_attr "mode" "HI")])
18686 (define_insn "*strmovqi_1"
18687 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18688 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18689 (set (match_operand:SI 0 "register_operand" "=D")
18690 (plus:SI (match_dup 2)
18692 (set (match_operand:SI 1 "register_operand" "=S")
18693 (plus:SI (match_dup 3)
18695 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18697 [(set_attr "type" "str")
18698 (set_attr "memory" "both")
18699 (set_attr "mode" "QI")])
18701 (define_insn "*strmovqi_rex_1"
18702 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18703 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18704 (set (match_operand:DI 0 "register_operand" "=D")
18705 (plus:DI (match_dup 2)
18707 (set (match_operand:DI 1 "register_operand" "=S")
18708 (plus:DI (match_dup 3)
18710 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18712 [(set_attr "type" "str")
18713 (set_attr "memory" "both")
18714 (set_attr "mode" "QI")])
18716 (define_expand "rep_mov"
18717 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18718 (set (match_operand 0 "register_operand" "")
18719 (match_operand 5 "" ""))
18720 (set (match_operand 2 "register_operand" "")
18721 (match_operand 6 "" ""))
18722 (set (match_operand 1 "memory_operand" "")
18723 (match_operand 3 "memory_operand" ""))
18724 (use (match_dup 4))])]
18728 (define_insn "*rep_movdi_rex64"
18729 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18730 (set (match_operand:DI 0 "register_operand" "=D")
18731 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18733 (match_operand:DI 3 "register_operand" "0")))
18734 (set (match_operand:DI 1 "register_operand" "=S")
18735 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18736 (match_operand:DI 4 "register_operand" "1")))
18737 (set (mem:BLK (match_dup 3))
18738 (mem:BLK (match_dup 4)))
18739 (use (match_dup 5))]
18742 [(set_attr "type" "str")
18743 (set_attr "prefix_rep" "1")
18744 (set_attr "memory" "both")
18745 (set_attr "mode" "DI")])
18747 (define_insn "*rep_movsi"
18748 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18749 (set (match_operand:SI 0 "register_operand" "=D")
18750 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18752 (match_operand:SI 3 "register_operand" "0")))
18753 (set (match_operand:SI 1 "register_operand" "=S")
18754 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18755 (match_operand:SI 4 "register_operand" "1")))
18756 (set (mem:BLK (match_dup 3))
18757 (mem:BLK (match_dup 4)))
18758 (use (match_dup 5))]
18761 [(set_attr "type" "str")
18762 (set_attr "prefix_rep" "1")
18763 (set_attr "memory" "both")
18764 (set_attr "mode" "SI")])
18766 (define_insn "*rep_movsi_rex64"
18767 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18768 (set (match_operand:DI 0 "register_operand" "=D")
18769 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18771 (match_operand:DI 3 "register_operand" "0")))
18772 (set (match_operand:DI 1 "register_operand" "=S")
18773 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18774 (match_operand:DI 4 "register_operand" "1")))
18775 (set (mem:BLK (match_dup 3))
18776 (mem:BLK (match_dup 4)))
18777 (use (match_dup 5))]
18780 [(set_attr "type" "str")
18781 (set_attr "prefix_rep" "1")
18782 (set_attr "memory" "both")
18783 (set_attr "mode" "SI")])
18785 (define_insn "*rep_movqi"
18786 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18787 (set (match_operand:SI 0 "register_operand" "=D")
18788 (plus:SI (match_operand:SI 3 "register_operand" "0")
18789 (match_operand:SI 5 "register_operand" "2")))
18790 (set (match_operand:SI 1 "register_operand" "=S")
18791 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18792 (set (mem:BLK (match_dup 3))
18793 (mem:BLK (match_dup 4)))
18794 (use (match_dup 5))]
18797 [(set_attr "type" "str")
18798 (set_attr "prefix_rep" "1")
18799 (set_attr "memory" "both")
18800 (set_attr "mode" "SI")])
18802 (define_insn "*rep_movqi_rex64"
18803 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18804 (set (match_operand:DI 0 "register_operand" "=D")
18805 (plus:DI (match_operand:DI 3 "register_operand" "0")
18806 (match_operand:DI 5 "register_operand" "2")))
18807 (set (match_operand:DI 1 "register_operand" "=S")
18808 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18809 (set (mem:BLK (match_dup 3))
18810 (mem:BLK (match_dup 4)))
18811 (use (match_dup 5))]
18814 [(set_attr "type" "str")
18815 (set_attr "prefix_rep" "1")
18816 (set_attr "memory" "both")
18817 (set_attr "mode" "SI")])
18819 (define_expand "setmemsi"
18820 [(use (match_operand:BLK 0 "memory_operand" ""))
18821 (use (match_operand:SI 1 "nonmemory_operand" ""))
18822 (use (match_operand 2 "const_int_operand" ""))
18823 (use (match_operand 3 "const_int_operand" ""))
18824 (use (match_operand:SI 4 "const_int_operand" ""))
18825 (use (match_operand:SI 5 "const_int_operand" ""))]
18828 if (ix86_expand_setmem (operands[0], operands[1],
18829 operands[2], operands[3],
18830 operands[4], operands[5]))
18836 (define_expand "setmemdi"
18837 [(use (match_operand:BLK 0 "memory_operand" ""))
18838 (use (match_operand:DI 1 "nonmemory_operand" ""))
18839 (use (match_operand 2 "const_int_operand" ""))
18840 (use (match_operand 3 "const_int_operand" ""))
18841 (use (match_operand 4 "const_int_operand" ""))
18842 (use (match_operand 5 "const_int_operand" ""))]
18845 if (ix86_expand_setmem (operands[0], operands[1],
18846 operands[2], operands[3],
18847 operands[4], operands[5]))
18853 ;; Most CPUs don't like single string operations
18854 ;; Handle this case here to simplify previous expander.
18856 (define_expand "strset"
18857 [(set (match_operand 1 "memory_operand" "")
18858 (match_operand 2 "register_operand" ""))
18859 (parallel [(set (match_operand 0 "register_operand" "")
18861 (clobber (reg:CC FLAGS_REG))])]
18864 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18865 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18867 /* If .md ever supports :P for Pmode, this can be directly
18868 in the pattern above. */
18869 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18870 GEN_INT (GET_MODE_SIZE (GET_MODE
18872 if (TARGET_SINGLE_STRINGOP || optimize_size)
18874 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18880 (define_expand "strset_singleop"
18881 [(parallel [(set (match_operand 1 "memory_operand" "")
18882 (match_operand 2 "register_operand" ""))
18883 (set (match_operand 0 "register_operand" "")
18884 (match_operand 3 "" ""))])]
18885 "TARGET_SINGLE_STRINGOP || optimize_size"
18888 (define_insn "*strsetdi_rex_1"
18889 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18890 (match_operand:DI 2 "register_operand" "a"))
18891 (set (match_operand:DI 0 "register_operand" "=D")
18892 (plus:DI (match_dup 1)
18894 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18896 [(set_attr "type" "str")
18897 (set_attr "memory" "store")
18898 (set_attr "mode" "DI")])
18900 (define_insn "*strsetsi_1"
18901 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18902 (match_operand:SI 2 "register_operand" "a"))
18903 (set (match_operand:SI 0 "register_operand" "=D")
18904 (plus:SI (match_dup 1)
18906 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18908 [(set_attr "type" "str")
18909 (set_attr "memory" "store")
18910 (set_attr "mode" "SI")])
18912 (define_insn "*strsetsi_rex_1"
18913 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18914 (match_operand:SI 2 "register_operand" "a"))
18915 (set (match_operand:DI 0 "register_operand" "=D")
18916 (plus:DI (match_dup 1)
18918 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18920 [(set_attr "type" "str")
18921 (set_attr "memory" "store")
18922 (set_attr "mode" "SI")])
18924 (define_insn "*strsethi_1"
18925 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18926 (match_operand:HI 2 "register_operand" "a"))
18927 (set (match_operand:SI 0 "register_operand" "=D")
18928 (plus:SI (match_dup 1)
18930 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18932 [(set_attr "type" "str")
18933 (set_attr "memory" "store")
18934 (set_attr "mode" "HI")])
18936 (define_insn "*strsethi_rex_1"
18937 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18938 (match_operand:HI 2 "register_operand" "a"))
18939 (set (match_operand:DI 0 "register_operand" "=D")
18940 (plus:DI (match_dup 1)
18942 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18944 [(set_attr "type" "str")
18945 (set_attr "memory" "store")
18946 (set_attr "mode" "HI")])
18948 (define_insn "*strsetqi_1"
18949 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18950 (match_operand:QI 2 "register_operand" "a"))
18951 (set (match_operand:SI 0 "register_operand" "=D")
18952 (plus:SI (match_dup 1)
18954 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18956 [(set_attr "type" "str")
18957 (set_attr "memory" "store")
18958 (set_attr "mode" "QI")])
18960 (define_insn "*strsetqi_rex_1"
18961 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18962 (match_operand:QI 2 "register_operand" "a"))
18963 (set (match_operand:DI 0 "register_operand" "=D")
18964 (plus:DI (match_dup 1)
18966 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18968 [(set_attr "type" "str")
18969 (set_attr "memory" "store")
18970 (set_attr "mode" "QI")])
18972 (define_expand "rep_stos"
18973 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18974 (set (match_operand 0 "register_operand" "")
18975 (match_operand 4 "" ""))
18976 (set (match_operand 2 "memory_operand" "") (const_int 0))
18977 (use (match_operand 3 "register_operand" ""))
18978 (use (match_dup 1))])]
18982 (define_insn "*rep_stosdi_rex64"
18983 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18984 (set (match_operand:DI 0 "register_operand" "=D")
18985 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18987 (match_operand:DI 3 "register_operand" "0")))
18988 (set (mem:BLK (match_dup 3))
18990 (use (match_operand:DI 2 "register_operand" "a"))
18991 (use (match_dup 4))]
18994 [(set_attr "type" "str")
18995 (set_attr "prefix_rep" "1")
18996 (set_attr "memory" "store")
18997 (set_attr "mode" "DI")])
18999 (define_insn "*rep_stossi"
19000 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19001 (set (match_operand:SI 0 "register_operand" "=D")
19002 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19004 (match_operand:SI 3 "register_operand" "0")))
19005 (set (mem:BLK (match_dup 3))
19007 (use (match_operand:SI 2 "register_operand" "a"))
19008 (use (match_dup 4))]
19011 [(set_attr "type" "str")
19012 (set_attr "prefix_rep" "1")
19013 (set_attr "memory" "store")
19014 (set_attr "mode" "SI")])
19016 (define_insn "*rep_stossi_rex64"
19017 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19018 (set (match_operand:DI 0 "register_operand" "=D")
19019 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19021 (match_operand:DI 3 "register_operand" "0")))
19022 (set (mem:BLK (match_dup 3))
19024 (use (match_operand:SI 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" "SI")])
19033 (define_insn "*rep_stosqi"
19034 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19035 (set (match_operand:SI 0 "register_operand" "=D")
19036 (plus:SI (match_operand:SI 3 "register_operand" "0")
19037 (match_operand:SI 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_insn "*rep_stosqi_rex64"
19050 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19051 (set (match_operand:DI 0 "register_operand" "=D")
19052 (plus:DI (match_operand:DI 3 "register_operand" "0")
19053 (match_operand:DI 4 "register_operand" "1")))
19054 (set (mem:BLK (match_dup 3))
19056 (use (match_operand:QI 2 "register_operand" "a"))
19057 (use (match_dup 4))]
19060 [(set_attr "type" "str")
19061 (set_attr "prefix_rep" "1")
19062 (set_attr "memory" "store")
19063 (set_attr "mode" "QI")])
19065 (define_expand "cmpstrnsi"
19066 [(set (match_operand:SI 0 "register_operand" "")
19067 (compare:SI (match_operand:BLK 1 "general_operand" "")
19068 (match_operand:BLK 2 "general_operand" "")))
19069 (use (match_operand 3 "general_operand" ""))
19070 (use (match_operand 4 "immediate_operand" ""))]
19071 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
19073 rtx addr1, addr2, out, outlow, count, countreg, align;
19075 /* Can't use this if the user has appropriated esi or edi. */
19076 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19081 out = gen_reg_rtx (SImode);
19083 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19084 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19085 if (addr1 != XEXP (operands[1], 0))
19086 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19087 if (addr2 != XEXP (operands[2], 0))
19088 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19090 count = operands[3];
19091 countreg = ix86_zero_extend_to_Pmode (count);
19093 /* %%% Iff we are testing strict equality, we can use known alignment
19094 to good advantage. This may be possible with combine, particularly
19095 once cc0 is dead. */
19096 align = operands[4];
19098 if (CONST_INT_P (count))
19100 if (INTVAL (count) == 0)
19102 emit_move_insn (operands[0], const0_rtx);
19105 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19106 operands[1], operands[2]));
19111 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19113 emit_insn (gen_cmpsi_1 (countreg, countreg));
19114 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19115 operands[1], operands[2]));
19118 outlow = gen_lowpart (QImode, out);
19119 emit_insn (gen_cmpintqi (outlow));
19120 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19122 if (operands[0] != out)
19123 emit_move_insn (operands[0], out);
19128 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19130 (define_expand "cmpintqi"
19131 [(set (match_dup 1)
19132 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19134 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19135 (parallel [(set (match_operand:QI 0 "register_operand" "")
19136 (minus:QI (match_dup 1)
19138 (clobber (reg:CC FLAGS_REG))])]
19140 "operands[1] = gen_reg_rtx (QImode);
19141 operands[2] = gen_reg_rtx (QImode);")
19143 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19144 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19146 (define_expand "cmpstrnqi_nz_1"
19147 [(parallel [(set (reg:CC FLAGS_REG)
19148 (compare:CC (match_operand 4 "memory_operand" "")
19149 (match_operand 5 "memory_operand" "")))
19150 (use (match_operand 2 "register_operand" ""))
19151 (use (match_operand:SI 3 "immediate_operand" ""))
19152 (clobber (match_operand 0 "register_operand" ""))
19153 (clobber (match_operand 1 "register_operand" ""))
19154 (clobber (match_dup 2))])]
19158 (define_insn "*cmpstrnqi_nz_1"
19159 [(set (reg:CC FLAGS_REG)
19160 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19161 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19162 (use (match_operand:SI 6 "register_operand" "2"))
19163 (use (match_operand:SI 3 "immediate_operand" "i"))
19164 (clobber (match_operand:SI 0 "register_operand" "=S"))
19165 (clobber (match_operand:SI 1 "register_operand" "=D"))
19166 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19169 [(set_attr "type" "str")
19170 (set_attr "mode" "QI")
19171 (set_attr "prefix_rep" "1")])
19173 (define_insn "*cmpstrnqi_nz_rex_1"
19174 [(set (reg:CC FLAGS_REG)
19175 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19176 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19177 (use (match_operand:DI 6 "register_operand" "2"))
19178 (use (match_operand:SI 3 "immediate_operand" "i"))
19179 (clobber (match_operand:DI 0 "register_operand" "=S"))
19180 (clobber (match_operand:DI 1 "register_operand" "=D"))
19181 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19184 [(set_attr "type" "str")
19185 (set_attr "mode" "QI")
19186 (set_attr "prefix_rep" "1")])
19188 ;; The same, but the count is not known to not be zero.
19190 (define_expand "cmpstrnqi_1"
19191 [(parallel [(set (reg:CC FLAGS_REG)
19192 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19194 (compare:CC (match_operand 4 "memory_operand" "")
19195 (match_operand 5 "memory_operand" ""))
19197 (use (match_operand:SI 3 "immediate_operand" ""))
19198 (use (reg:CC FLAGS_REG))
19199 (clobber (match_operand 0 "register_operand" ""))
19200 (clobber (match_operand 1 "register_operand" ""))
19201 (clobber (match_dup 2))])]
19205 (define_insn "*cmpstrnqi_1"
19206 [(set (reg:CC FLAGS_REG)
19207 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19209 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19210 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19212 (use (match_operand:SI 3 "immediate_operand" "i"))
19213 (use (reg:CC FLAGS_REG))
19214 (clobber (match_operand:SI 0 "register_operand" "=S"))
19215 (clobber (match_operand:SI 1 "register_operand" "=D"))
19216 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19219 [(set_attr "type" "str")
19220 (set_attr "mode" "QI")
19221 (set_attr "prefix_rep" "1")])
19223 (define_insn "*cmpstrnqi_rex_1"
19224 [(set (reg:CC FLAGS_REG)
19225 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19227 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19228 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19230 (use (match_operand:SI 3 "immediate_operand" "i"))
19231 (use (reg:CC FLAGS_REG))
19232 (clobber (match_operand:DI 0 "register_operand" "=S"))
19233 (clobber (match_operand:DI 1 "register_operand" "=D"))
19234 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19237 [(set_attr "type" "str")
19238 (set_attr "mode" "QI")
19239 (set_attr "prefix_rep" "1")])
19241 (define_expand "strlensi"
19242 [(set (match_operand:SI 0 "register_operand" "")
19243 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19244 (match_operand:QI 2 "immediate_operand" "")
19245 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19248 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19254 (define_expand "strlendi"
19255 [(set (match_operand:DI 0 "register_operand" "")
19256 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19257 (match_operand:QI 2 "immediate_operand" "")
19258 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19261 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19267 (define_expand "strlenqi_1"
19268 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19269 (clobber (match_operand 1 "register_operand" ""))
19270 (clobber (reg:CC FLAGS_REG))])]
19274 (define_insn "*strlenqi_1"
19275 [(set (match_operand:SI 0 "register_operand" "=&c")
19276 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19277 (match_operand:QI 2 "register_operand" "a")
19278 (match_operand:SI 3 "immediate_operand" "i")
19279 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19280 (clobber (match_operand:SI 1 "register_operand" "=D"))
19281 (clobber (reg:CC FLAGS_REG))]
19284 [(set_attr "type" "str")
19285 (set_attr "mode" "QI")
19286 (set_attr "prefix_rep" "1")])
19288 (define_insn "*strlenqi_rex_1"
19289 [(set (match_operand:DI 0 "register_operand" "=&c")
19290 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19291 (match_operand:QI 2 "register_operand" "a")
19292 (match_operand:DI 3 "immediate_operand" "i")
19293 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19294 (clobber (match_operand:DI 1 "register_operand" "=D"))
19295 (clobber (reg:CC FLAGS_REG))]
19298 [(set_attr "type" "str")
19299 (set_attr "mode" "QI")
19300 (set_attr "prefix_rep" "1")])
19302 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19303 ;; handled in combine, but it is not currently up to the task.
19304 ;; When used for their truth value, the cmpstrn* expanders generate
19313 ;; The intermediate three instructions are unnecessary.
19315 ;; This one handles cmpstrn*_nz_1...
19318 (set (reg:CC FLAGS_REG)
19319 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19320 (mem:BLK (match_operand 5 "register_operand" ""))))
19321 (use (match_operand 6 "register_operand" ""))
19322 (use (match_operand:SI 3 "immediate_operand" ""))
19323 (clobber (match_operand 0 "register_operand" ""))
19324 (clobber (match_operand 1 "register_operand" ""))
19325 (clobber (match_operand 2 "register_operand" ""))])
19326 (set (match_operand:QI 7 "register_operand" "")
19327 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19328 (set (match_operand:QI 8 "register_operand" "")
19329 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19330 (set (reg FLAGS_REG)
19331 (compare (match_dup 7) (match_dup 8)))
19333 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19335 (set (reg:CC FLAGS_REG)
19336 (compare:CC (mem:BLK (match_dup 4))
19337 (mem:BLK (match_dup 5))))
19338 (use (match_dup 6))
19339 (use (match_dup 3))
19340 (clobber (match_dup 0))
19341 (clobber (match_dup 1))
19342 (clobber (match_dup 2))])]
19345 ;; ...and this one handles cmpstrn*_1.
19348 (set (reg:CC FLAGS_REG)
19349 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19351 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19352 (mem:BLK (match_operand 5 "register_operand" "")))
19354 (use (match_operand:SI 3 "immediate_operand" ""))
19355 (use (reg:CC FLAGS_REG))
19356 (clobber (match_operand 0 "register_operand" ""))
19357 (clobber (match_operand 1 "register_operand" ""))
19358 (clobber (match_operand 2 "register_operand" ""))])
19359 (set (match_operand:QI 7 "register_operand" "")
19360 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19361 (set (match_operand:QI 8 "register_operand" "")
19362 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19363 (set (reg FLAGS_REG)
19364 (compare (match_dup 7) (match_dup 8)))
19366 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19368 (set (reg:CC FLAGS_REG)
19369 (if_then_else:CC (ne (match_dup 6)
19371 (compare:CC (mem:BLK (match_dup 4))
19372 (mem:BLK (match_dup 5)))
19374 (use (match_dup 3))
19375 (use (reg:CC FLAGS_REG))
19376 (clobber (match_dup 0))
19377 (clobber (match_dup 1))
19378 (clobber (match_dup 2))])]
19383 ;; Conditional move instructions.
19385 (define_expand "movdicc"
19386 [(set (match_operand:DI 0 "register_operand" "")
19387 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19388 (match_operand:DI 2 "general_operand" "")
19389 (match_operand:DI 3 "general_operand" "")))]
19391 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19393 (define_insn "x86_movdicc_0_m1_rex64"
19394 [(set (match_operand:DI 0 "register_operand" "=r")
19395 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19398 (clobber (reg:CC FLAGS_REG))]
19401 ; Since we don't have the proper number of operands for an alu insn,
19402 ; fill in all the blanks.
19403 [(set_attr "type" "alu")
19404 (set_attr "pent_pair" "pu")
19405 (set_attr "memory" "none")
19406 (set_attr "imm_disp" "false")
19407 (set_attr "mode" "DI")
19408 (set_attr "length_immediate" "0")])
19410 (define_insn "*movdicc_c_rex64"
19411 [(set (match_operand:DI 0 "register_operand" "=r,r")
19412 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19413 [(reg FLAGS_REG) (const_int 0)])
19414 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19415 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19416 "TARGET_64BIT && TARGET_CMOVE
19417 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19419 cmov%O2%C1\t{%2, %0|%0, %2}
19420 cmov%O2%c1\t{%3, %0|%0, %3}"
19421 [(set_attr "type" "icmov")
19422 (set_attr "mode" "DI")])
19424 (define_expand "movsicc"
19425 [(set (match_operand:SI 0 "register_operand" "")
19426 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19427 (match_operand:SI 2 "general_operand" "")
19428 (match_operand:SI 3 "general_operand" "")))]
19430 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19432 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19433 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19434 ;; So just document what we're doing explicitly.
19436 (define_insn "x86_movsicc_0_m1"
19437 [(set (match_operand:SI 0 "register_operand" "=r")
19438 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19441 (clobber (reg:CC FLAGS_REG))]
19444 ; Since we don't have the proper number of operands for an alu insn,
19445 ; fill in all the blanks.
19446 [(set_attr "type" "alu")
19447 (set_attr "pent_pair" "pu")
19448 (set_attr "memory" "none")
19449 (set_attr "imm_disp" "false")
19450 (set_attr "mode" "SI")
19451 (set_attr "length_immediate" "0")])
19453 (define_insn "*movsicc_noc"
19454 [(set (match_operand:SI 0 "register_operand" "=r,r")
19455 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19456 [(reg FLAGS_REG) (const_int 0)])
19457 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19458 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19460 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19462 cmov%O2%C1\t{%2, %0|%0, %2}
19463 cmov%O2%c1\t{%3, %0|%0, %3}"
19464 [(set_attr "type" "icmov")
19465 (set_attr "mode" "SI")])
19467 (define_expand "movhicc"
19468 [(set (match_operand:HI 0 "register_operand" "")
19469 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19470 (match_operand:HI 2 "general_operand" "")
19471 (match_operand:HI 3 "general_operand" "")))]
19472 "TARGET_HIMODE_MATH"
19473 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19475 (define_insn "*movhicc_noc"
19476 [(set (match_operand:HI 0 "register_operand" "=r,r")
19477 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19478 [(reg FLAGS_REG) (const_int 0)])
19479 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19480 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19482 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19484 cmov%O2%C1\t{%2, %0|%0, %2}
19485 cmov%O2%c1\t{%3, %0|%0, %3}"
19486 [(set_attr "type" "icmov")
19487 (set_attr "mode" "HI")])
19489 (define_expand "movqicc"
19490 [(set (match_operand:QI 0 "register_operand" "")
19491 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19492 (match_operand:QI 2 "general_operand" "")
19493 (match_operand:QI 3 "general_operand" "")))]
19494 "TARGET_QIMODE_MATH"
19495 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19497 (define_insn_and_split "*movqicc_noc"
19498 [(set (match_operand:QI 0 "register_operand" "=r,r")
19499 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19500 [(match_operand 4 "flags_reg_operand" "")
19502 (match_operand:QI 2 "register_operand" "r,0")
19503 (match_operand:QI 3 "register_operand" "0,r")))]
19504 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19506 "&& reload_completed"
19507 [(set (match_dup 0)
19508 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19511 "operands[0] = gen_lowpart (SImode, operands[0]);
19512 operands[2] = gen_lowpart (SImode, operands[2]);
19513 operands[3] = gen_lowpart (SImode, operands[3]);"
19514 [(set_attr "type" "icmov")
19515 (set_attr "mode" "SI")])
19517 (define_expand "movsfcc"
19518 [(set (match_operand:SF 0 "register_operand" "")
19519 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19520 (match_operand:SF 2 "register_operand" "")
19521 (match_operand:SF 3 "register_operand" "")))]
19522 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19523 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19525 (define_insn "*movsfcc_1_387"
19526 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19527 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19528 [(reg FLAGS_REG) (const_int 0)])
19529 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19530 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19531 "TARGET_80387 && TARGET_CMOVE
19532 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19534 fcmov%F1\t{%2, %0|%0, %2}
19535 fcmov%f1\t{%3, %0|%0, %3}
19536 cmov%O2%C1\t{%2, %0|%0, %2}
19537 cmov%O2%c1\t{%3, %0|%0, %3}"
19538 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19539 (set_attr "mode" "SF,SF,SI,SI")])
19541 (define_expand "movdfcc"
19542 [(set (match_operand:DF 0 "register_operand" "")
19543 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19544 (match_operand:DF 2 "register_operand" "")
19545 (match_operand:DF 3 "register_operand" "")))]
19546 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19547 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19549 (define_insn "*movdfcc_1"
19550 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19551 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19552 [(reg FLAGS_REG) (const_int 0)])
19553 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19554 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19555 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19556 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19558 fcmov%F1\t{%2, %0|%0, %2}
19559 fcmov%f1\t{%3, %0|%0, %3}
19562 [(set_attr "type" "fcmov,fcmov,multi,multi")
19563 (set_attr "mode" "DF")])
19565 (define_insn "*movdfcc_1_rex64"
19566 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19567 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19568 [(reg FLAGS_REG) (const_int 0)])
19569 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19570 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19571 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19572 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19574 fcmov%F1\t{%2, %0|%0, %2}
19575 fcmov%f1\t{%3, %0|%0, %3}
19576 cmov%O2%C1\t{%2, %0|%0, %2}
19577 cmov%O2%c1\t{%3, %0|%0, %3}"
19578 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19579 (set_attr "mode" "DF")])
19582 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19583 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19584 [(match_operand 4 "flags_reg_operand" "")
19586 (match_operand:DF 2 "nonimmediate_operand" "")
19587 (match_operand:DF 3 "nonimmediate_operand" "")))]
19588 "!TARGET_64BIT && reload_completed"
19589 [(set (match_dup 2)
19590 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19594 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19597 "split_di (operands+2, 1, operands+5, operands+6);
19598 split_di (operands+3, 1, operands+7, operands+8);
19599 split_di (operands, 1, operands+2, operands+3);")
19601 (define_expand "movxfcc"
19602 [(set (match_operand:XF 0 "register_operand" "")
19603 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19604 (match_operand:XF 2 "register_operand" "")
19605 (match_operand:XF 3 "register_operand" "")))]
19606 "TARGET_80387 && TARGET_CMOVE"
19607 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
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 "sminsf3"
19642 [(set (match_operand:SF 0 "register_operand" "=x")
19643 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19644 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19646 "minss\t{%2, %0|%0, %2}"
19647 [(set_attr "type" "sseadd")
19648 (set_attr "mode" "SF")])
19650 (define_insn "smaxsf3"
19651 [(set (match_operand:SF 0 "register_operand" "=x")
19652 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19653 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19655 "maxss\t{%2, %0|%0, %2}"
19656 [(set_attr "type" "sseadd")
19657 (set_attr "mode" "SF")])
19659 (define_insn "smindf3"
19660 [(set (match_operand:DF 0 "register_operand" "=x")
19661 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19662 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19663 "TARGET_SSE2 && TARGET_SSE_MATH"
19664 "minsd\t{%2, %0|%0, %2}"
19665 [(set_attr "type" "sseadd")
19666 (set_attr "mode" "DF")])
19668 (define_insn "smaxdf3"
19669 [(set (match_operand:DF 0 "register_operand" "=x")
19670 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19671 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19672 "TARGET_SSE2 && TARGET_SSE_MATH"
19673 "maxsd\t{%2, %0|%0, %2}"
19674 [(set_attr "type" "sseadd")
19675 (set_attr "mode" "DF")])
19677 ;; These versions of the min/max patterns implement exactly the operations
19678 ;; min = (op1 < op2 ? op1 : op2)
19679 ;; max = (!(op1 < op2) ? op1 : op2)
19680 ;; Their operands are not commutative, and thus they may be used in the
19681 ;; presence of -0.0 and NaN.
19683 (define_insn "*ieee_sminsf3"
19684 [(set (match_operand:SF 0 "register_operand" "=x")
19685 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19686 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19689 "minss\t{%2, %0|%0, %2}"
19690 [(set_attr "type" "sseadd")
19691 (set_attr "mode" "SF")])
19693 (define_insn "*ieee_smaxsf3"
19694 [(set (match_operand:SF 0 "register_operand" "=x")
19695 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19696 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19699 "maxss\t{%2, %0|%0, %2}"
19700 [(set_attr "type" "sseadd")
19701 (set_attr "mode" "SF")])
19703 (define_insn "*ieee_smindf3"
19704 [(set (match_operand:DF 0 "register_operand" "=x")
19705 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19706 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19708 "TARGET_SSE2 && TARGET_SSE_MATH"
19709 "minsd\t{%2, %0|%0, %2}"
19710 [(set_attr "type" "sseadd")
19711 (set_attr "mode" "DF")])
19713 (define_insn "*ieee_smaxdf3"
19714 [(set (match_operand:DF 0 "register_operand" "=x")
19715 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19716 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19718 "TARGET_SSE2 && TARGET_SSE_MATH"
19719 "maxsd\t{%2, %0|%0, %2}"
19720 [(set_attr "type" "sseadd")
19721 (set_attr "mode" "DF")])
19723 ;; Make two stack loads independent:
19725 ;; fld %st(0) -> fld bb
19726 ;; fmul bb fmul %st(1), %st
19728 ;; Actually we only match the last two instructions for simplicity.
19730 [(set (match_operand 0 "fp_register_operand" "")
19731 (match_operand 1 "fp_register_operand" ""))
19733 (match_operator 2 "binary_fp_operator"
19735 (match_operand 3 "memory_operand" "")]))]
19736 "REGNO (operands[0]) != REGNO (operands[1])"
19737 [(set (match_dup 0) (match_dup 3))
19738 (set (match_dup 0) (match_dup 4))]
19740 ;; The % modifier is not operational anymore in peephole2's, so we have to
19741 ;; swap the operands manually in the case of addition and multiplication.
19742 "if (COMMUTATIVE_ARITH_P (operands[2]))
19743 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19744 operands[0], operands[1]);
19746 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19747 operands[1], operands[0]);")
19749 ;; Conditional addition patterns
19750 (define_expand "addqicc"
19751 [(match_operand:QI 0 "register_operand" "")
19752 (match_operand 1 "comparison_operator" "")
19753 (match_operand:QI 2 "register_operand" "")
19754 (match_operand:QI 3 "const_int_operand" "")]
19756 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19758 (define_expand "addhicc"
19759 [(match_operand:HI 0 "register_operand" "")
19760 (match_operand 1 "comparison_operator" "")
19761 (match_operand:HI 2 "register_operand" "")
19762 (match_operand:HI 3 "const_int_operand" "")]
19764 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19766 (define_expand "addsicc"
19767 [(match_operand:SI 0 "register_operand" "")
19768 (match_operand 1 "comparison_operator" "")
19769 (match_operand:SI 2 "register_operand" "")
19770 (match_operand:SI 3 "const_int_operand" "")]
19772 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19774 (define_expand "adddicc"
19775 [(match_operand:DI 0 "register_operand" "")
19776 (match_operand 1 "comparison_operator" "")
19777 (match_operand:DI 2 "register_operand" "")
19778 (match_operand:DI 3 "const_int_operand" "")]
19780 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19783 ;; Misc patterns (?)
19785 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19786 ;; Otherwise there will be nothing to keep
19788 ;; [(set (reg ebp) (reg esp))]
19789 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19790 ;; (clobber (eflags)]
19791 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19793 ;; in proper program order.
19794 (define_insn "pro_epilogue_adjust_stack_1"
19795 [(set (match_operand:SI 0 "register_operand" "=r,r")
19796 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19797 (match_operand:SI 2 "immediate_operand" "i,i")))
19798 (clobber (reg:CC FLAGS_REG))
19799 (clobber (mem:BLK (scratch)))]
19802 switch (get_attr_type (insn))
19805 return "mov{l}\t{%1, %0|%0, %1}";
19808 if (CONST_INT_P (operands[2])
19809 && (INTVAL (operands[2]) == 128
19810 || (INTVAL (operands[2]) < 0
19811 && INTVAL (operands[2]) != -128)))
19813 operands[2] = GEN_INT (-INTVAL (operands[2]));
19814 return "sub{l}\t{%2, %0|%0, %2}";
19816 return "add{l}\t{%2, %0|%0, %2}";
19819 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19820 return "lea{l}\t{%a2, %0|%0, %a2}";
19823 gcc_unreachable ();
19826 [(set (attr "type")
19827 (cond [(eq_attr "alternative" "0")
19828 (const_string "alu")
19829 (match_operand:SI 2 "const0_operand" "")
19830 (const_string "imov")
19832 (const_string "lea")))
19833 (set_attr "mode" "SI")])
19835 (define_insn "pro_epilogue_adjust_stack_rex64"
19836 [(set (match_operand:DI 0 "register_operand" "=r,r")
19837 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19838 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19839 (clobber (reg:CC FLAGS_REG))
19840 (clobber (mem:BLK (scratch)))]
19843 switch (get_attr_type (insn))
19846 return "mov{q}\t{%1, %0|%0, %1}";
19849 if (CONST_INT_P (operands[2])
19850 /* Avoid overflows. */
19851 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19852 && (INTVAL (operands[2]) == 128
19853 || (INTVAL (operands[2]) < 0
19854 && INTVAL (operands[2]) != -128)))
19856 operands[2] = GEN_INT (-INTVAL (operands[2]));
19857 return "sub{q}\t{%2, %0|%0, %2}";
19859 return "add{q}\t{%2, %0|%0, %2}";
19862 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19863 return "lea{q}\t{%a2, %0|%0, %a2}";
19866 gcc_unreachable ();
19869 [(set (attr "type")
19870 (cond [(eq_attr "alternative" "0")
19871 (const_string "alu")
19872 (match_operand:DI 2 "const0_operand" "")
19873 (const_string "imov")
19875 (const_string "lea")))
19876 (set_attr "mode" "DI")])
19878 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19879 [(set (match_operand:DI 0 "register_operand" "=r,r")
19880 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19881 (match_operand:DI 3 "immediate_operand" "i,i")))
19882 (use (match_operand:DI 2 "register_operand" "r,r"))
19883 (clobber (reg:CC FLAGS_REG))
19884 (clobber (mem:BLK (scratch)))]
19887 switch (get_attr_type (insn))
19890 return "add{q}\t{%2, %0|%0, %2}";
19893 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19894 return "lea{q}\t{%a2, %0|%0, %a2}";
19897 gcc_unreachable ();
19900 [(set_attr "type" "alu,lea")
19901 (set_attr "mode" "DI")])
19903 (define_insn "allocate_stack_worker_32"
19904 [(set (match_operand:SI 0 "register_operand" "+a")
19905 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19906 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19907 (clobber (reg:CC FLAGS_REG))]
19908 "!TARGET_64BIT && TARGET_STACK_PROBE"
19910 [(set_attr "type" "multi")
19911 (set_attr "length" "5")])
19913 (define_insn "allocate_stack_worker_64"
19914 [(set (match_operand:DI 0 "register_operand" "=a")
19915 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19916 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19917 (clobber (reg:DI R10_REG))
19918 (clobber (reg:DI R11_REG))
19919 (clobber (reg:CC FLAGS_REG))]
19920 "TARGET_64BIT && TARGET_STACK_PROBE"
19922 [(set_attr "type" "multi")
19923 (set_attr "length" "5")])
19925 (define_expand "allocate_stack"
19926 [(match_operand 0 "register_operand" "")
19927 (match_operand 1 "general_operand" "")]
19928 "TARGET_STACK_PROBE"
19932 #ifndef CHECK_STACK_LIMIT
19933 #define CHECK_STACK_LIMIT 0
19936 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19937 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19939 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19940 stack_pointer_rtx, 0, OPTAB_DIRECT);
19941 if (x != stack_pointer_rtx)
19942 emit_move_insn (stack_pointer_rtx, x);
19946 x = copy_to_mode_reg (Pmode, operands[1]);
19948 x = gen_allocate_stack_worker_64 (x);
19950 x = gen_allocate_stack_worker_32 (x);
19954 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19958 (define_expand "builtin_setjmp_receiver"
19959 [(label_ref (match_operand 0 "" ""))]
19960 "!TARGET_64BIT && flag_pic"
19965 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19966 rtx label_rtx = gen_label_rtx ();
19967 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19968 xops[0] = xops[1] = picreg;
19969 xops[2] = gen_rtx_CONST (SImode,
19970 gen_rtx_MINUS (SImode,
19971 gen_rtx_LABEL_REF (SImode, label_rtx),
19972 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19973 ix86_expand_binary_operator (MINUS, SImode, xops);
19976 emit_insn (gen_set_got (pic_offset_table_rtx));
19980 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19983 [(set (match_operand 0 "register_operand" "")
19984 (match_operator 3 "promotable_binary_operator"
19985 [(match_operand 1 "register_operand" "")
19986 (match_operand 2 "aligned_operand" "")]))
19987 (clobber (reg:CC FLAGS_REG))]
19988 "! TARGET_PARTIAL_REG_STALL && reload_completed
19989 && ((GET_MODE (operands[0]) == HImode
19990 && ((!optimize_size && !TARGET_FAST_PREFIX)
19991 /* ??? next two lines just !satisfies_constraint_K (...) */
19992 || !CONST_INT_P (operands[2])
19993 || satisfies_constraint_K (operands[2])))
19994 || (GET_MODE (operands[0]) == QImode
19995 && (TARGET_PROMOTE_QImode || optimize_size)))"
19996 [(parallel [(set (match_dup 0)
19997 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19998 (clobber (reg:CC FLAGS_REG))])]
19999 "operands[0] = gen_lowpart (SImode, operands[0]);
20000 operands[1] = gen_lowpart (SImode, operands[1]);
20001 if (GET_CODE (operands[3]) != ASHIFT)
20002 operands[2] = gen_lowpart (SImode, operands[2]);
20003 PUT_MODE (operands[3], SImode);")
20005 ; Promote the QImode tests, as i386 has encoding of the AND
20006 ; instruction with 32-bit sign-extended immediate and thus the
20007 ; instruction size is unchanged, except in the %eax case for
20008 ; which it is increased by one byte, hence the ! optimize_size.
20010 [(set (match_operand 0 "flags_reg_operand" "")
20011 (match_operator 2 "compare_operator"
20012 [(and (match_operand 3 "aligned_operand" "")
20013 (match_operand 4 "const_int_operand" ""))
20015 (set (match_operand 1 "register_operand" "")
20016 (and (match_dup 3) (match_dup 4)))]
20017 "! TARGET_PARTIAL_REG_STALL && reload_completed
20019 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20020 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20021 /* Ensure that the operand will remain sign-extended immediate. */
20022 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20023 [(parallel [(set (match_dup 0)
20024 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20027 (and:SI (match_dup 3) (match_dup 4)))])]
20030 = gen_int_mode (INTVAL (operands[4])
20031 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20032 operands[1] = gen_lowpart (SImode, operands[1]);
20033 operands[3] = gen_lowpart (SImode, operands[3]);
20036 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20037 ; the TEST instruction with 32-bit sign-extended immediate and thus
20038 ; the instruction size would at least double, which is not what we
20039 ; want even with ! optimize_size.
20041 [(set (match_operand 0 "flags_reg_operand" "")
20042 (match_operator 1 "compare_operator"
20043 [(and (match_operand:HI 2 "aligned_operand" "")
20044 (match_operand:HI 3 "const_int_operand" ""))
20046 "! TARGET_PARTIAL_REG_STALL && reload_completed
20047 && ! TARGET_FAST_PREFIX
20049 /* Ensure that the operand will remain sign-extended immediate. */
20050 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20051 [(set (match_dup 0)
20052 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20056 = gen_int_mode (INTVAL (operands[3])
20057 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20058 operands[2] = gen_lowpart (SImode, operands[2]);
20062 [(set (match_operand 0 "register_operand" "")
20063 (neg (match_operand 1 "register_operand" "")))
20064 (clobber (reg:CC FLAGS_REG))]
20065 "! TARGET_PARTIAL_REG_STALL && reload_completed
20066 && (GET_MODE (operands[0]) == HImode
20067 || (GET_MODE (operands[0]) == QImode
20068 && (TARGET_PROMOTE_QImode || optimize_size)))"
20069 [(parallel [(set (match_dup 0)
20070 (neg:SI (match_dup 1)))
20071 (clobber (reg:CC FLAGS_REG))])]
20072 "operands[0] = gen_lowpart (SImode, operands[0]);
20073 operands[1] = gen_lowpart (SImode, operands[1]);")
20076 [(set (match_operand 0 "register_operand" "")
20077 (not (match_operand 1 "register_operand" "")))]
20078 "! TARGET_PARTIAL_REG_STALL && reload_completed
20079 && (GET_MODE (operands[0]) == HImode
20080 || (GET_MODE (operands[0]) == QImode
20081 && (TARGET_PROMOTE_QImode || optimize_size)))"
20082 [(set (match_dup 0)
20083 (not:SI (match_dup 1)))]
20084 "operands[0] = gen_lowpart (SImode, operands[0]);
20085 operands[1] = gen_lowpart (SImode, operands[1]);")
20088 [(set (match_operand 0 "register_operand" "")
20089 (if_then_else (match_operator 1 "comparison_operator"
20090 [(reg FLAGS_REG) (const_int 0)])
20091 (match_operand 2 "register_operand" "")
20092 (match_operand 3 "register_operand" "")))]
20093 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20094 && (GET_MODE (operands[0]) == HImode
20095 || (GET_MODE (operands[0]) == QImode
20096 && (TARGET_PROMOTE_QImode || optimize_size)))"
20097 [(set (match_dup 0)
20098 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20099 "operands[0] = gen_lowpart (SImode, operands[0]);
20100 operands[2] = gen_lowpart (SImode, operands[2]);
20101 operands[3] = gen_lowpart (SImode, operands[3]);")
20104 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20105 ;; transform a complex memory operation into two memory to register operations.
20107 ;; Don't push memory operands
20109 [(set (match_operand:SI 0 "push_operand" "")
20110 (match_operand:SI 1 "memory_operand" ""))
20111 (match_scratch:SI 2 "r")]
20112 "!optimize_size && !TARGET_PUSH_MEMORY
20113 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20114 [(set (match_dup 2) (match_dup 1))
20115 (set (match_dup 0) (match_dup 2))]
20119 [(set (match_operand:DI 0 "push_operand" "")
20120 (match_operand:DI 1 "memory_operand" ""))
20121 (match_scratch:DI 2 "r")]
20122 "!optimize_size && !TARGET_PUSH_MEMORY
20123 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20124 [(set (match_dup 2) (match_dup 1))
20125 (set (match_dup 0) (match_dup 2))]
20128 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20131 [(set (match_operand:SF 0 "push_operand" "")
20132 (match_operand:SF 1 "memory_operand" ""))
20133 (match_scratch:SF 2 "r")]
20134 "!optimize_size && !TARGET_PUSH_MEMORY
20135 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20136 [(set (match_dup 2) (match_dup 1))
20137 (set (match_dup 0) (match_dup 2))]
20141 [(set (match_operand:HI 0 "push_operand" "")
20142 (match_operand:HI 1 "memory_operand" ""))
20143 (match_scratch:HI 2 "r")]
20144 "!optimize_size && !TARGET_PUSH_MEMORY
20145 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20146 [(set (match_dup 2) (match_dup 1))
20147 (set (match_dup 0) (match_dup 2))]
20151 [(set (match_operand:QI 0 "push_operand" "")
20152 (match_operand:QI 1 "memory_operand" ""))
20153 (match_scratch:QI 2 "q")]
20154 "!optimize_size && !TARGET_PUSH_MEMORY
20155 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20156 [(set (match_dup 2) (match_dup 1))
20157 (set (match_dup 0) (match_dup 2))]
20160 ;; Don't move an immediate directly to memory when the instruction
20163 [(match_scratch:SI 1 "r")
20164 (set (match_operand:SI 0 "memory_operand" "")
20167 && ! TARGET_USE_MOV0
20168 && TARGET_SPLIT_LONG_MOVES
20169 && get_attr_length (insn) >= ix86_cost->large_insn
20170 && peep2_regno_dead_p (0, FLAGS_REG)"
20171 [(parallel [(set (match_dup 1) (const_int 0))
20172 (clobber (reg:CC FLAGS_REG))])
20173 (set (match_dup 0) (match_dup 1))]
20177 [(match_scratch:HI 1 "r")
20178 (set (match_operand:HI 0 "memory_operand" "")
20181 && ! TARGET_USE_MOV0
20182 && TARGET_SPLIT_LONG_MOVES
20183 && get_attr_length (insn) >= ix86_cost->large_insn
20184 && peep2_regno_dead_p (0, FLAGS_REG)"
20185 [(parallel [(set (match_dup 2) (const_int 0))
20186 (clobber (reg:CC FLAGS_REG))])
20187 (set (match_dup 0) (match_dup 1))]
20188 "operands[2] = gen_lowpart (SImode, operands[1]);")
20191 [(match_scratch:QI 1 "q")
20192 (set (match_operand:QI 0 "memory_operand" "")
20195 && ! TARGET_USE_MOV0
20196 && TARGET_SPLIT_LONG_MOVES
20197 && get_attr_length (insn) >= ix86_cost->large_insn
20198 && peep2_regno_dead_p (0, FLAGS_REG)"
20199 [(parallel [(set (match_dup 2) (const_int 0))
20200 (clobber (reg:CC FLAGS_REG))])
20201 (set (match_dup 0) (match_dup 1))]
20202 "operands[2] = gen_lowpart (SImode, operands[1]);")
20205 [(match_scratch:SI 2 "r")
20206 (set (match_operand:SI 0 "memory_operand" "")
20207 (match_operand:SI 1 "immediate_operand" ""))]
20209 && TARGET_SPLIT_LONG_MOVES
20210 && get_attr_length (insn) >= ix86_cost->large_insn"
20211 [(set (match_dup 2) (match_dup 1))
20212 (set (match_dup 0) (match_dup 2))]
20216 [(match_scratch:HI 2 "r")
20217 (set (match_operand:HI 0 "memory_operand" "")
20218 (match_operand:HI 1 "immediate_operand" ""))]
20220 && TARGET_SPLIT_LONG_MOVES
20221 && get_attr_length (insn) >= ix86_cost->large_insn"
20222 [(set (match_dup 2) (match_dup 1))
20223 (set (match_dup 0) (match_dup 2))]
20227 [(match_scratch:QI 2 "q")
20228 (set (match_operand:QI 0 "memory_operand" "")
20229 (match_operand:QI 1 "immediate_operand" ""))]
20231 && TARGET_SPLIT_LONG_MOVES
20232 && get_attr_length (insn) >= ix86_cost->large_insn"
20233 [(set (match_dup 2) (match_dup 1))
20234 (set (match_dup 0) (match_dup 2))]
20237 ;; Don't compare memory with zero, load and use a test instead.
20239 [(set (match_operand 0 "flags_reg_operand" "")
20240 (match_operator 1 "compare_operator"
20241 [(match_operand:SI 2 "memory_operand" "")
20243 (match_scratch:SI 3 "r")]
20244 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20245 [(set (match_dup 3) (match_dup 2))
20246 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20249 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20250 ;; Don't split NOTs with a displacement operand, because resulting XOR
20251 ;; will not be pairable anyway.
20253 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20254 ;; represented using a modRM byte. The XOR replacement is long decoded,
20255 ;; so this split helps here as well.
20257 ;; Note: Can't do this as a regular split because we can't get proper
20258 ;; lifetime information then.
20261 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20262 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20264 && ((TARGET_NOT_UNPAIRABLE
20265 && (!MEM_P (operands[0])
20266 || !memory_displacement_operand (operands[0], SImode)))
20267 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20268 && peep2_regno_dead_p (0, FLAGS_REG)"
20269 [(parallel [(set (match_dup 0)
20270 (xor:SI (match_dup 1) (const_int -1)))
20271 (clobber (reg:CC FLAGS_REG))])]
20275 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20276 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20278 && ((TARGET_NOT_UNPAIRABLE
20279 && (!MEM_P (operands[0])
20280 || !memory_displacement_operand (operands[0], HImode)))
20281 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20282 && peep2_regno_dead_p (0, FLAGS_REG)"
20283 [(parallel [(set (match_dup 0)
20284 (xor:HI (match_dup 1) (const_int -1)))
20285 (clobber (reg:CC FLAGS_REG))])]
20289 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20290 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20292 && ((TARGET_NOT_UNPAIRABLE
20293 && (!MEM_P (operands[0])
20294 || !memory_displacement_operand (operands[0], QImode)))
20295 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20296 && peep2_regno_dead_p (0, FLAGS_REG)"
20297 [(parallel [(set (match_dup 0)
20298 (xor:QI (match_dup 1) (const_int -1)))
20299 (clobber (reg:CC FLAGS_REG))])]
20302 ;; Non pairable "test imm, reg" instructions can be translated to
20303 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20304 ;; byte opcode instead of two, have a short form for byte operands),
20305 ;; so do it for other CPUs as well. Given that the value was dead,
20306 ;; this should not create any new dependencies. Pass on the sub-word
20307 ;; versions if we're concerned about partial register stalls.
20310 [(set (match_operand 0 "flags_reg_operand" "")
20311 (match_operator 1 "compare_operator"
20312 [(and:SI (match_operand:SI 2 "register_operand" "")
20313 (match_operand:SI 3 "immediate_operand" ""))
20315 "ix86_match_ccmode (insn, CCNOmode)
20316 && (true_regnum (operands[2]) != AX_REG
20317 || satisfies_constraint_K (operands[3]))
20318 && peep2_reg_dead_p (1, operands[2])"
20320 [(set (match_dup 0)
20321 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20324 (and:SI (match_dup 2) (match_dup 3)))])]
20327 ;; We don't need to handle HImode case, because it will be promoted to SImode
20328 ;; on ! TARGET_PARTIAL_REG_STALL
20331 [(set (match_operand 0 "flags_reg_operand" "")
20332 (match_operator 1 "compare_operator"
20333 [(and:QI (match_operand:QI 2 "register_operand" "")
20334 (match_operand:QI 3 "immediate_operand" ""))
20336 "! TARGET_PARTIAL_REG_STALL
20337 && ix86_match_ccmode (insn, CCNOmode)
20338 && true_regnum (operands[2]) != AX_REG
20339 && peep2_reg_dead_p (1, operands[2])"
20341 [(set (match_dup 0)
20342 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20345 (and:QI (match_dup 2) (match_dup 3)))])]
20349 [(set (match_operand 0 "flags_reg_operand" "")
20350 (match_operator 1 "compare_operator"
20353 (match_operand 2 "ext_register_operand" "")
20356 (match_operand 3 "const_int_operand" ""))
20358 "! TARGET_PARTIAL_REG_STALL
20359 && ix86_match_ccmode (insn, CCNOmode)
20360 && true_regnum (operands[2]) != AX_REG
20361 && peep2_reg_dead_p (1, operands[2])"
20362 [(parallel [(set (match_dup 0)
20371 (set (zero_extract:SI (match_dup 2)
20382 ;; Don't do logical operations with memory inputs.
20384 [(match_scratch:SI 2 "r")
20385 (parallel [(set (match_operand:SI 0 "register_operand" "")
20386 (match_operator:SI 3 "arith_or_logical_operator"
20388 (match_operand:SI 1 "memory_operand" "")]))
20389 (clobber (reg:CC FLAGS_REG))])]
20390 "! optimize_size && ! TARGET_READ_MODIFY"
20391 [(set (match_dup 2) (match_dup 1))
20392 (parallel [(set (match_dup 0)
20393 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20394 (clobber (reg:CC FLAGS_REG))])]
20398 [(match_scratch:SI 2 "r")
20399 (parallel [(set (match_operand:SI 0 "register_operand" "")
20400 (match_operator:SI 3 "arith_or_logical_operator"
20401 [(match_operand:SI 1 "memory_operand" "")
20403 (clobber (reg:CC FLAGS_REG))])]
20404 "! optimize_size && ! TARGET_READ_MODIFY"
20405 [(set (match_dup 2) (match_dup 1))
20406 (parallel [(set (match_dup 0)
20407 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20408 (clobber (reg:CC FLAGS_REG))])]
20411 ; Don't do logical operations with memory outputs
20413 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20414 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20415 ; the same decoder scheduling characteristics as the original.
20418 [(match_scratch:SI 2 "r")
20419 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20420 (match_operator:SI 3 "arith_or_logical_operator"
20422 (match_operand:SI 1 "nonmemory_operand" "")]))
20423 (clobber (reg:CC FLAGS_REG))])]
20424 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20425 [(set (match_dup 2) (match_dup 0))
20426 (parallel [(set (match_dup 2)
20427 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20428 (clobber (reg:CC FLAGS_REG))])
20429 (set (match_dup 0) (match_dup 2))]
20433 [(match_scratch:SI 2 "r")
20434 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20435 (match_operator:SI 3 "arith_or_logical_operator"
20436 [(match_operand:SI 1 "nonmemory_operand" "")
20438 (clobber (reg:CC FLAGS_REG))])]
20439 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20440 [(set (match_dup 2) (match_dup 0))
20441 (parallel [(set (match_dup 2)
20442 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20443 (clobber (reg:CC FLAGS_REG))])
20444 (set (match_dup 0) (match_dup 2))]
20447 ;; Attempt to always use XOR for zeroing registers.
20449 [(set (match_operand 0 "register_operand" "")
20450 (match_operand 1 "const0_operand" ""))]
20451 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20452 && (! TARGET_USE_MOV0 || optimize_size)
20453 && GENERAL_REG_P (operands[0])
20454 && peep2_regno_dead_p (0, FLAGS_REG)"
20455 [(parallel [(set (match_dup 0) (const_int 0))
20456 (clobber (reg:CC FLAGS_REG))])]
20458 operands[0] = gen_lowpart (word_mode, operands[0]);
20462 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20464 "(GET_MODE (operands[0]) == QImode
20465 || GET_MODE (operands[0]) == HImode)
20466 && (! TARGET_USE_MOV0 || optimize_size)
20467 && peep2_regno_dead_p (0, FLAGS_REG)"
20468 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20469 (clobber (reg:CC FLAGS_REG))])])
20471 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20473 [(set (match_operand 0 "register_operand" "")
20475 "(GET_MODE (operands[0]) == HImode
20476 || GET_MODE (operands[0]) == SImode
20477 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20478 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20479 && peep2_regno_dead_p (0, FLAGS_REG)"
20480 [(parallel [(set (match_dup 0) (const_int -1))
20481 (clobber (reg:CC FLAGS_REG))])]
20482 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20485 ;; Attempt to convert simple leas to adds. These can be created by
20488 [(set (match_operand:SI 0 "register_operand" "")
20489 (plus:SI (match_dup 0)
20490 (match_operand:SI 1 "nonmemory_operand" "")))]
20491 "peep2_regno_dead_p (0, FLAGS_REG)"
20492 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20493 (clobber (reg:CC FLAGS_REG))])]
20497 [(set (match_operand:SI 0 "register_operand" "")
20498 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20499 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20500 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20501 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20502 (clobber (reg:CC FLAGS_REG))])]
20503 "operands[2] = gen_lowpart (SImode, operands[2]);")
20506 [(set (match_operand:DI 0 "register_operand" "")
20507 (plus:DI (match_dup 0)
20508 (match_operand:DI 1 "x86_64_general_operand" "")))]
20509 "peep2_regno_dead_p (0, FLAGS_REG)"
20510 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20511 (clobber (reg:CC FLAGS_REG))])]
20515 [(set (match_operand:SI 0 "register_operand" "")
20516 (mult:SI (match_dup 0)
20517 (match_operand:SI 1 "const_int_operand" "")))]
20518 "exact_log2 (INTVAL (operands[1])) >= 0
20519 && peep2_regno_dead_p (0, FLAGS_REG)"
20520 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20521 (clobber (reg:CC FLAGS_REG))])]
20522 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20525 [(set (match_operand:DI 0 "register_operand" "")
20526 (mult:DI (match_dup 0)
20527 (match_operand:DI 1 "const_int_operand" "")))]
20528 "exact_log2 (INTVAL (operands[1])) >= 0
20529 && peep2_regno_dead_p (0, FLAGS_REG)"
20530 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20531 (clobber (reg:CC FLAGS_REG))])]
20532 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20535 [(set (match_operand:SI 0 "register_operand" "")
20536 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20537 (match_operand:DI 2 "const_int_operand" "")) 0))]
20538 "exact_log2 (INTVAL (operands[2])) >= 0
20539 && REGNO (operands[0]) == REGNO (operands[1])
20540 && peep2_regno_dead_p (0, FLAGS_REG)"
20541 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20542 (clobber (reg:CC FLAGS_REG))])]
20543 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20545 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20546 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20547 ;; many CPUs it is also faster, since special hardware to avoid esp
20548 ;; dependencies is present.
20550 ;; While some of these conversions may be done using splitters, we use peepholes
20551 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20553 ;; Convert prologue esp subtractions to push.
20554 ;; We need register to push. In order to keep verify_flow_info happy we have
20556 ;; - use scratch and clobber it in order to avoid dependencies
20557 ;; - use already live register
20558 ;; We can't use the second way right now, since there is no reliable way how to
20559 ;; verify that given register is live. First choice will also most likely in
20560 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20561 ;; call clobbered registers are dead. We may want to use base pointer as an
20562 ;; alternative when no register is available later.
20565 [(match_scratch:SI 0 "r")
20566 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20567 (clobber (reg:CC FLAGS_REG))
20568 (clobber (mem:BLK (scratch)))])]
20569 "optimize_size || !TARGET_SUB_ESP_4"
20570 [(clobber (match_dup 0))
20571 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20572 (clobber (mem:BLK (scratch)))])])
20575 [(match_scratch:SI 0 "r")
20576 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20577 (clobber (reg:CC FLAGS_REG))
20578 (clobber (mem:BLK (scratch)))])]
20579 "optimize_size || !TARGET_SUB_ESP_8"
20580 [(clobber (match_dup 0))
20581 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20582 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20583 (clobber (mem:BLK (scratch)))])])
20585 ;; Convert esp subtractions to push.
20587 [(match_scratch:SI 0 "r")
20588 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20589 (clobber (reg:CC FLAGS_REG))])]
20590 "optimize_size || !TARGET_SUB_ESP_4"
20591 [(clobber (match_dup 0))
20592 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20595 [(match_scratch:SI 0 "r")
20596 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20597 (clobber (reg:CC FLAGS_REG))])]
20598 "optimize_size || !TARGET_SUB_ESP_8"
20599 [(clobber (match_dup 0))
20600 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20601 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20603 ;; Convert epilogue deallocator to pop.
20605 [(match_scratch:SI 0 "r")
20606 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20607 (clobber (reg:CC FLAGS_REG))
20608 (clobber (mem:BLK (scratch)))])]
20609 "optimize_size || !TARGET_ADD_ESP_4"
20610 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20611 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20612 (clobber (mem:BLK (scratch)))])]
20615 ;; Two pops case is tricky, since pop causes dependency on destination register.
20616 ;; We use two registers if available.
20618 [(match_scratch:SI 0 "r")
20619 (match_scratch:SI 1 "r")
20620 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20621 (clobber (reg:CC FLAGS_REG))
20622 (clobber (mem:BLK (scratch)))])]
20623 "optimize_size || !TARGET_ADD_ESP_8"
20624 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20625 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20626 (clobber (mem:BLK (scratch)))])
20627 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20628 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20632 [(match_scratch:SI 0 "r")
20633 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20634 (clobber (reg:CC FLAGS_REG))
20635 (clobber (mem:BLK (scratch)))])]
20637 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20638 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20639 (clobber (mem:BLK (scratch)))])
20640 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20641 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20644 ;; Convert esp additions to pop.
20646 [(match_scratch:SI 0 "r")
20647 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20648 (clobber (reg:CC FLAGS_REG))])]
20650 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20651 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20654 ;; Two pops case is tricky, since pop causes dependency on destination register.
20655 ;; We use two registers if available.
20657 [(match_scratch:SI 0 "r")
20658 (match_scratch:SI 1 "r")
20659 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20660 (clobber (reg:CC FLAGS_REG))])]
20662 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20663 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20664 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20665 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20669 [(match_scratch:SI 0 "r")
20670 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20671 (clobber (reg:CC FLAGS_REG))])]
20673 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20674 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20675 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20676 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20679 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20680 ;; required and register dies. Similarly for 128 to plus -128.
20682 [(set (match_operand 0 "flags_reg_operand" "")
20683 (match_operator 1 "compare_operator"
20684 [(match_operand 2 "register_operand" "")
20685 (match_operand 3 "const_int_operand" "")]))]
20686 "(INTVAL (operands[3]) == -1
20687 || INTVAL (operands[3]) == 1
20688 || INTVAL (operands[3]) == 128)
20689 && ix86_match_ccmode (insn, CCGCmode)
20690 && peep2_reg_dead_p (1, operands[2])"
20691 [(parallel [(set (match_dup 0)
20692 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20693 (clobber (match_dup 2))])]
20697 [(match_scratch:DI 0 "r")
20698 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20699 (clobber (reg:CC FLAGS_REG))
20700 (clobber (mem:BLK (scratch)))])]
20701 "optimize_size || !TARGET_SUB_ESP_4"
20702 [(clobber (match_dup 0))
20703 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20704 (clobber (mem:BLK (scratch)))])])
20707 [(match_scratch:DI 0 "r")
20708 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20709 (clobber (reg:CC FLAGS_REG))
20710 (clobber (mem:BLK (scratch)))])]
20711 "optimize_size || !TARGET_SUB_ESP_8"
20712 [(clobber (match_dup 0))
20713 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20714 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20715 (clobber (mem:BLK (scratch)))])])
20717 ;; Convert esp subtractions to push.
20719 [(match_scratch:DI 0 "r")
20720 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20721 (clobber (reg:CC FLAGS_REG))])]
20722 "optimize_size || !TARGET_SUB_ESP_4"
20723 [(clobber (match_dup 0))
20724 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20727 [(match_scratch:DI 0 "r")
20728 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20729 (clobber (reg:CC FLAGS_REG))])]
20730 "optimize_size || !TARGET_SUB_ESP_8"
20731 [(clobber (match_dup 0))
20732 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20733 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20735 ;; Convert epilogue deallocator to pop.
20737 [(match_scratch:DI 0 "r")
20738 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20739 (clobber (reg:CC FLAGS_REG))
20740 (clobber (mem:BLK (scratch)))])]
20741 "optimize_size || !TARGET_ADD_ESP_4"
20742 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20743 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20744 (clobber (mem:BLK (scratch)))])]
20747 ;; Two pops case is tricky, since pop causes dependency on destination register.
20748 ;; We use two registers if available.
20750 [(match_scratch:DI 0 "r")
20751 (match_scratch:DI 1 "r")
20752 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20753 (clobber (reg:CC FLAGS_REG))
20754 (clobber (mem:BLK (scratch)))])]
20755 "optimize_size || !TARGET_ADD_ESP_8"
20756 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20757 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20758 (clobber (mem:BLK (scratch)))])
20759 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20760 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20764 [(match_scratch:DI 0 "r")
20765 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20766 (clobber (reg:CC FLAGS_REG))
20767 (clobber (mem:BLK (scratch)))])]
20769 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20770 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20771 (clobber (mem:BLK (scratch)))])
20772 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20773 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20776 ;; Convert esp additions to pop.
20778 [(match_scratch:DI 0 "r")
20779 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20780 (clobber (reg:CC FLAGS_REG))])]
20782 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20783 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20786 ;; Two pops case is tricky, since pop causes dependency on destination register.
20787 ;; We use two registers if available.
20789 [(match_scratch:DI 0 "r")
20790 (match_scratch:DI 1 "r")
20791 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20792 (clobber (reg:CC FLAGS_REG))])]
20794 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20795 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20796 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20797 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20801 [(match_scratch:DI 0 "r")
20802 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20803 (clobber (reg:CC FLAGS_REG))])]
20805 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20806 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20807 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20808 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20811 ;; Convert imul by three, five and nine into lea
20814 [(set (match_operand:SI 0 "register_operand" "")
20815 (mult:SI (match_operand:SI 1 "register_operand" "")
20816 (match_operand:SI 2 "const_int_operand" "")))
20817 (clobber (reg:CC FLAGS_REG))])]
20818 "INTVAL (operands[2]) == 3
20819 || INTVAL (operands[2]) == 5
20820 || INTVAL (operands[2]) == 9"
20821 [(set (match_dup 0)
20822 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20824 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20828 [(set (match_operand:SI 0 "register_operand" "")
20829 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20830 (match_operand:SI 2 "const_int_operand" "")))
20831 (clobber (reg:CC FLAGS_REG))])]
20833 && (INTVAL (operands[2]) == 3
20834 || INTVAL (operands[2]) == 5
20835 || INTVAL (operands[2]) == 9)"
20836 [(set (match_dup 0) (match_dup 1))
20838 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20840 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20844 [(set (match_operand:DI 0 "register_operand" "")
20845 (mult:DI (match_operand:DI 1 "register_operand" "")
20846 (match_operand:DI 2 "const_int_operand" "")))
20847 (clobber (reg:CC FLAGS_REG))])]
20849 && (INTVAL (operands[2]) == 3
20850 || INTVAL (operands[2]) == 5
20851 || INTVAL (operands[2]) == 9)"
20852 [(set (match_dup 0)
20853 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20855 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20859 [(set (match_operand:DI 0 "register_operand" "")
20860 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20861 (match_operand:DI 2 "const_int_operand" "")))
20862 (clobber (reg:CC FLAGS_REG))])]
20865 && (INTVAL (operands[2]) == 3
20866 || INTVAL (operands[2]) == 5
20867 || INTVAL (operands[2]) == 9)"
20868 [(set (match_dup 0) (match_dup 1))
20870 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20872 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20874 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20875 ;; imul $32bit_imm, reg, reg is direct decoded.
20877 [(match_scratch:DI 3 "r")
20878 (parallel [(set (match_operand:DI 0 "register_operand" "")
20879 (mult:DI (match_operand:DI 1 "memory_operand" "")
20880 (match_operand:DI 2 "immediate_operand" "")))
20881 (clobber (reg:CC FLAGS_REG))])]
20882 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20883 && !satisfies_constraint_K (operands[2])"
20884 [(set (match_dup 3) (match_dup 1))
20885 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20886 (clobber (reg:CC FLAGS_REG))])]
20890 [(match_scratch:SI 3 "r")
20891 (parallel [(set (match_operand:SI 0 "register_operand" "")
20892 (mult:SI (match_operand:SI 1 "memory_operand" "")
20893 (match_operand:SI 2 "immediate_operand" "")))
20894 (clobber (reg:CC FLAGS_REG))])]
20895 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20896 && !satisfies_constraint_K (operands[2])"
20897 [(set (match_dup 3) (match_dup 1))
20898 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20899 (clobber (reg:CC FLAGS_REG))])]
20903 [(match_scratch:SI 3 "r")
20904 (parallel [(set (match_operand:DI 0 "register_operand" "")
20906 (mult:SI (match_operand:SI 1 "memory_operand" "")
20907 (match_operand:SI 2 "immediate_operand" ""))))
20908 (clobber (reg:CC FLAGS_REG))])]
20909 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20910 && !satisfies_constraint_K (operands[2])"
20911 [(set (match_dup 3) (match_dup 1))
20912 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20913 (clobber (reg:CC FLAGS_REG))])]
20916 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20917 ;; Convert it into imul reg, reg
20918 ;; It would be better to force assembler to encode instruction using long
20919 ;; immediate, but there is apparently no way to do so.
20921 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20922 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20923 (match_operand:DI 2 "const_int_operand" "")))
20924 (clobber (reg:CC FLAGS_REG))])
20925 (match_scratch:DI 3 "r")]
20926 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20927 && satisfies_constraint_K (operands[2])"
20928 [(set (match_dup 3) (match_dup 2))
20929 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20930 (clobber (reg:CC FLAGS_REG))])]
20932 if (!rtx_equal_p (operands[0], operands[1]))
20933 emit_move_insn (operands[0], operands[1]);
20937 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20938 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20939 (match_operand:SI 2 "const_int_operand" "")))
20940 (clobber (reg:CC FLAGS_REG))])
20941 (match_scratch:SI 3 "r")]
20942 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20943 && satisfies_constraint_K (operands[2])"
20944 [(set (match_dup 3) (match_dup 2))
20945 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20946 (clobber (reg:CC FLAGS_REG))])]
20948 if (!rtx_equal_p (operands[0], operands[1]))
20949 emit_move_insn (operands[0], operands[1]);
20953 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20954 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20955 (match_operand:HI 2 "immediate_operand" "")))
20956 (clobber (reg:CC FLAGS_REG))])
20957 (match_scratch:HI 3 "r")]
20958 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20959 [(set (match_dup 3) (match_dup 2))
20960 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20961 (clobber (reg:CC FLAGS_REG))])]
20963 if (!rtx_equal_p (operands[0], operands[1]))
20964 emit_move_insn (operands[0], operands[1]);
20967 ;; After splitting up read-modify operations, array accesses with memory
20968 ;; operands might end up in form:
20970 ;; movl 4(%esp), %edx
20972 ;; instead of pre-splitting:
20974 ;; addl 4(%esp), %eax
20976 ;; movl 4(%esp), %edx
20977 ;; leal (%edx,%eax,4), %eax
20980 [(parallel [(set (match_operand 0 "register_operand" "")
20981 (ashift (match_operand 1 "register_operand" "")
20982 (match_operand 2 "const_int_operand" "")))
20983 (clobber (reg:CC FLAGS_REG))])
20984 (set (match_operand 3 "register_operand")
20985 (match_operand 4 "x86_64_general_operand" ""))
20986 (parallel [(set (match_operand 5 "register_operand" "")
20987 (plus (match_operand 6 "register_operand" "")
20988 (match_operand 7 "register_operand" "")))
20989 (clobber (reg:CC FLAGS_REG))])]
20990 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20991 /* Validate MODE for lea. */
20992 && ((!TARGET_PARTIAL_REG_STALL
20993 && (GET_MODE (operands[0]) == QImode
20994 || GET_MODE (operands[0]) == HImode))
20995 || GET_MODE (operands[0]) == SImode
20996 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20997 /* We reorder load and the shift. */
20998 && !rtx_equal_p (operands[1], operands[3])
20999 && !reg_overlap_mentioned_p (operands[0], operands[4])
21000 /* Last PLUS must consist of operand 0 and 3. */
21001 && !rtx_equal_p (operands[0], operands[3])
21002 && (rtx_equal_p (operands[3], operands[6])
21003 || rtx_equal_p (operands[3], operands[7]))
21004 && (rtx_equal_p (operands[0], operands[6])
21005 || rtx_equal_p (operands[0], operands[7]))
21006 /* The intermediate operand 0 must die or be same as output. */
21007 && (rtx_equal_p (operands[0], operands[5])
21008 || peep2_reg_dead_p (3, operands[0]))"
21009 [(set (match_dup 3) (match_dup 4))
21010 (set (match_dup 0) (match_dup 1))]
21012 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21013 int scale = 1 << INTVAL (operands[2]);
21014 rtx index = gen_lowpart (Pmode, operands[1]);
21015 rtx base = gen_lowpart (Pmode, operands[3]);
21016 rtx dest = gen_lowpart (mode, operands[5]);
21018 operands[1] = gen_rtx_PLUS (Pmode, base,
21019 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21021 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21022 operands[0] = dest;
21025 ;; Call-value patterns last so that the wildcard operand does not
21026 ;; disrupt insn-recog's switch tables.
21028 (define_insn "*call_value_pop_0"
21029 [(set (match_operand 0 "" "")
21030 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21031 (match_operand:SI 2 "" "")))
21032 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21033 (match_operand:SI 3 "immediate_operand" "")))]
21036 if (SIBLING_CALL_P (insn))
21039 return "call\t%P1";
21041 [(set_attr "type" "callv")])
21043 (define_insn "*call_value_pop_1"
21044 [(set (match_operand 0 "" "")
21045 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21046 (match_operand:SI 2 "" "")))
21047 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21048 (match_operand:SI 3 "immediate_operand" "i")))]
21051 if (constant_call_address_operand (operands[1], Pmode))
21053 if (SIBLING_CALL_P (insn))
21056 return "call\t%P1";
21058 if (SIBLING_CALL_P (insn))
21061 return "call\t%A1";
21063 [(set_attr "type" "callv")])
21065 (define_insn "*call_value_0"
21066 [(set (match_operand 0 "" "")
21067 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21068 (match_operand:SI 2 "" "")))]
21071 if (SIBLING_CALL_P (insn))
21074 return "call\t%P1";
21076 [(set_attr "type" "callv")])
21078 (define_insn "*call_value_0_rex64"
21079 [(set (match_operand 0 "" "")
21080 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21081 (match_operand:DI 2 "const_int_operand" "")))]
21084 if (SIBLING_CALL_P (insn))
21087 return "call\t%P1";
21089 [(set_attr "type" "callv")])
21091 (define_insn "*call_value_1"
21092 [(set (match_operand 0 "" "")
21093 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21094 (match_operand:SI 2 "" "")))]
21095 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21097 if (constant_call_address_operand (operands[1], Pmode))
21098 return "call\t%P1";
21099 return "call\t%A1";
21101 [(set_attr "type" "callv")])
21103 (define_insn "*sibcall_value_1"
21104 [(set (match_operand 0 "" "")
21105 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21106 (match_operand:SI 2 "" "")))]
21107 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21109 if (constant_call_address_operand (operands[1], Pmode))
21113 [(set_attr "type" "callv")])
21115 (define_insn "*call_value_1_rex64"
21116 [(set (match_operand 0 "" "")
21117 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21118 (match_operand:DI 2 "" "")))]
21119 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21120 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21122 if (constant_call_address_operand (operands[1], Pmode))
21123 return "call\t%P1";
21124 return "call\t%A1";
21126 [(set_attr "type" "callv")])
21128 (define_insn "*call_value_1_rex64_large"
21129 [(set (match_operand 0 "" "")
21130 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21131 (match_operand:DI 2 "" "")))]
21132 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21134 [(set_attr "type" "callv")])
21136 (define_insn "*sibcall_value_1_rex64"
21137 [(set (match_operand 0 "" "")
21138 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21139 (match_operand:DI 2 "" "")))]
21140 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21142 [(set_attr "type" "callv")])
21144 (define_insn "*sibcall_value_1_rex64_v"
21145 [(set (match_operand 0 "" "")
21146 (call (mem:QI (reg:DI R11_REG))
21147 (match_operand:DI 1 "" "")))]
21148 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21150 [(set_attr "type" "callv")])
21152 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21153 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21154 ;; caught for use by garbage collectors and the like. Using an insn that
21155 ;; maps to SIGILL makes it more likely the program will rightfully die.
21156 ;; Keeping with tradition, "6" is in honor of #UD.
21157 (define_insn "trap"
21158 [(trap_if (const_int 1) (const_int 6))]
21160 { return ASM_SHORT "0x0b0f"; }
21161 [(set_attr "length" "2")])
21163 (define_expand "sse_prologue_save"
21164 [(parallel [(set (match_operand:BLK 0 "" "")
21165 (unspec:BLK [(reg:DI 21)
21172 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21173 (use (match_operand:DI 1 "register_operand" ""))
21174 (use (match_operand:DI 2 "immediate_operand" ""))
21175 (use (label_ref:DI (match_operand 3 "" "")))])]
21179 (define_insn "*sse_prologue_save_insn"
21180 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21181 (match_operand:DI 4 "const_int_operand" "n")))
21182 (unspec:BLK [(reg:DI 21)
21189 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21190 (use (match_operand:DI 1 "register_operand" "r"))
21191 (use (match_operand:DI 2 "const_int_operand" "i"))
21192 (use (label_ref:DI (match_operand 3 "" "X")))]
21194 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21195 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21199 operands[0] = gen_rtx_MEM (Pmode,
21200 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21201 output_asm_insn (\"jmp\\t%A1\", operands);
21202 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21204 operands[4] = adjust_address (operands[0], DImode, i*16);
21205 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21206 PUT_MODE (operands[4], TImode);
21207 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21208 output_asm_insn (\"rex\", operands);
21209 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21211 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21212 CODE_LABEL_NUMBER (operands[3]));
21216 [(set_attr "type" "other")
21217 (set_attr "length_immediate" "0")
21218 (set_attr "length_address" "0")
21219 (set_attr "length" "135")
21220 (set_attr "memory" "store")
21221 (set_attr "modrm" "0")
21222 (set_attr "mode" "DI")])
21224 (define_expand "prefetch"
21225 [(prefetch (match_operand 0 "address_operand" "")
21226 (match_operand:SI 1 "const_int_operand" "")
21227 (match_operand:SI 2 "const_int_operand" ""))]
21228 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21230 int rw = INTVAL (operands[1]);
21231 int locality = INTVAL (operands[2]);
21233 gcc_assert (rw == 0 || rw == 1);
21234 gcc_assert (locality >= 0 && locality <= 3);
21235 gcc_assert (GET_MODE (operands[0]) == Pmode
21236 || GET_MODE (operands[0]) == VOIDmode);
21238 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21239 supported by SSE counterpart or the SSE prefetch is not available
21240 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21242 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21243 operands[2] = GEN_INT (3);
21245 operands[1] = const0_rtx;
21248 (define_insn "*prefetch_sse"
21249 [(prefetch (match_operand:SI 0 "address_operand" "p")
21251 (match_operand:SI 1 "const_int_operand" ""))]
21252 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21254 static const char * const patterns[4] = {
21255 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21258 int locality = INTVAL (operands[1]);
21259 gcc_assert (locality >= 0 && locality <= 3);
21261 return patterns[locality];
21263 [(set_attr "type" "sse")
21264 (set_attr "memory" "none")])
21266 (define_insn "*prefetch_sse_rex"
21267 [(prefetch (match_operand:DI 0 "address_operand" "p")
21269 (match_operand:SI 1 "const_int_operand" ""))]
21270 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21272 static const char * const patterns[4] = {
21273 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21276 int locality = INTVAL (operands[1]);
21277 gcc_assert (locality >= 0 && locality <= 3);
21279 return patterns[locality];
21281 [(set_attr "type" "sse")
21282 (set_attr "memory" "none")])
21284 (define_insn "*prefetch_3dnow"
21285 [(prefetch (match_operand:SI 0 "address_operand" "p")
21286 (match_operand:SI 1 "const_int_operand" "n")
21288 "TARGET_3DNOW && !TARGET_64BIT"
21290 if (INTVAL (operands[1]) == 0)
21291 return "prefetch\t%a0";
21293 return "prefetchw\t%a0";
21295 [(set_attr "type" "mmx")
21296 (set_attr "memory" "none")])
21298 (define_insn "*prefetch_3dnow_rex"
21299 [(prefetch (match_operand:DI 0 "address_operand" "p")
21300 (match_operand:SI 1 "const_int_operand" "n")
21302 "TARGET_3DNOW && TARGET_64BIT"
21304 if (INTVAL (operands[1]) == 0)
21305 return "prefetch\t%a0";
21307 return "prefetchw\t%a0";
21309 [(set_attr "type" "mmx")
21310 (set_attr "memory" "none")])
21312 (define_expand "stack_protect_set"
21313 [(match_operand 0 "memory_operand" "")
21314 (match_operand 1 "memory_operand" "")]
21317 #ifdef TARGET_THREAD_SSP_OFFSET
21319 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21320 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21322 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21323 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21326 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21328 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21333 (define_insn "stack_protect_set_si"
21334 [(set (match_operand:SI 0 "memory_operand" "=m")
21335 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21336 (set (match_scratch:SI 2 "=&r") (const_int 0))
21337 (clobber (reg:CC FLAGS_REG))]
21339 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21340 [(set_attr "type" "multi")])
21342 (define_insn "stack_protect_set_di"
21343 [(set (match_operand:DI 0 "memory_operand" "=m")
21344 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21345 (set (match_scratch:DI 2 "=&r") (const_int 0))
21346 (clobber (reg:CC FLAGS_REG))]
21348 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21349 [(set_attr "type" "multi")])
21351 (define_insn "stack_tls_protect_set_si"
21352 [(set (match_operand:SI 0 "memory_operand" "=m")
21353 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21354 (set (match_scratch:SI 2 "=&r") (const_int 0))
21355 (clobber (reg:CC FLAGS_REG))]
21357 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21358 [(set_attr "type" "multi")])
21360 (define_insn "stack_tls_protect_set_di"
21361 [(set (match_operand:DI 0 "memory_operand" "=m")
21362 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21363 (set (match_scratch:DI 2 "=&r") (const_int 0))
21364 (clobber (reg:CC FLAGS_REG))]
21367 /* The kernel uses a different segment register for performance reasons; a
21368 system call would not have to trash the userspace segment register,
21369 which would be expensive */
21370 if (ix86_cmodel != CM_KERNEL)
21371 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21373 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21375 [(set_attr "type" "multi")])
21377 (define_expand "stack_protect_test"
21378 [(match_operand 0 "memory_operand" "")
21379 (match_operand 1 "memory_operand" "")
21380 (match_operand 2 "" "")]
21383 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21384 ix86_compare_op0 = operands[0];
21385 ix86_compare_op1 = operands[1];
21386 ix86_compare_emitted = flags;
21388 #ifdef TARGET_THREAD_SSP_OFFSET
21390 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21391 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21393 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21394 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21397 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21399 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21401 emit_jump_insn (gen_beq (operands[2]));
21405 (define_insn "stack_protect_test_si"
21406 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21407 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21408 (match_operand:SI 2 "memory_operand" "m")]
21410 (clobber (match_scratch:SI 3 "=&r"))]
21412 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21413 [(set_attr "type" "multi")])
21415 (define_insn "stack_protect_test_di"
21416 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21417 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21418 (match_operand:DI 2 "memory_operand" "m")]
21420 (clobber (match_scratch:DI 3 "=&r"))]
21422 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21423 [(set_attr "type" "multi")])
21425 (define_insn "stack_tls_protect_test_si"
21426 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21427 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21428 (match_operand:SI 2 "const_int_operand" "i")]
21429 UNSPEC_SP_TLS_TEST))
21430 (clobber (match_scratch:SI 3 "=r"))]
21432 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21433 [(set_attr "type" "multi")])
21435 (define_insn "stack_tls_protect_test_di"
21436 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21437 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21438 (match_operand:DI 2 "const_int_operand" "i")]
21439 UNSPEC_SP_TLS_TEST))
21440 (clobber (match_scratch:DI 3 "=r"))]
21443 /* The kernel uses a different segment register for performance reasons; a
21444 system call would not have to trash the userspace segment register,
21445 which would be expensive */
21446 if (ix86_cmodel != CM_KERNEL)
21447 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21449 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21451 [(set_attr "type" "multi")])
21453 (define_mode_iterator CRC32MODE [QI HI SI])
21454 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21455 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21457 (define_insn "sse4_2_crc32<mode>"
21458 [(set (match_operand:SI 0 "register_operand" "=r")
21460 [(match_operand:SI 1 "register_operand" "0")
21461 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21464 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21465 [(set_attr "type" "sselog1")
21466 (set_attr "prefix_rep" "1")
21467 (set_attr "prefix_extra" "1")
21468 (set_attr "mode" "SI")])
21470 (define_insn "sse4_2_crc32di"
21471 [(set (match_operand:DI 0 "register_operand" "=r")
21473 [(match_operand:DI 1 "register_operand" "0")
21474 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21476 "TARGET_SSE4_2 && TARGET_64BIT"
21477 "crc32q\t{%2, %0|%0, %2}"
21478 [(set_attr "type" "sselog1")
21479 (set_attr "prefix_rep" "1")
21480 (set_attr "prefix_extra" "1")
21481 (set_attr "mode" "DI")])
21485 (include "sync.md")