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
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 2, 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 COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; The special asm out single letter directives following a '%' are:
31 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
33 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
34 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
35 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
36 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
37 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
38 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
39 ;; 'J' Print the appropriate jump operand.
41 ;; 'b' Print the QImode name of the register for the indicated operand.
42 ;; %b0 would print %al if operands[0] is reg 0.
43 ;; 'w' Likewise, print the HImode name of the register.
44 ;; 'k' Likewise, print the SImode name of the register.
45 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
46 ;; 'y' Print "st(0)" instead of "st" as a register.
51 [; Relocation specifiers
64 (UNSPEC_STACK_ALLOC 11)
66 (UNSPEC_SSE_PROLOGUE_SAVE 13)
70 (UNSPEC_SET_GOT_OFFSET 17)
75 (UNSPEC_TLS_LD_BASE 20)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
88 (UNSPEC_TRUNC_NOOP 39)
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 40)
99 (UNSPEC_NOP 48) ; prevents combiner cleverness
110 ; Generic math support
112 (UNSPEC_IEEE_MIN 51) ; not commutative
113 (UNSPEC_IEEE_MAX 52) ; not commutative
128 (UNSPEC_FRNDINT_FLOOR 70)
129 (UNSPEC_FRNDINT_CEIL 71)
130 (UNSPEC_FRNDINT_TRUNC 72)
131 (UNSPEC_FRNDINT_MASK_PM 73)
132 (UNSPEC_FIST_FLOOR 74)
133 (UNSPEC_FIST_CEIL 75)
135 ; x87 Double output FP
136 (UNSPEC_SINCOS_COS 80)
137 (UNSPEC_SINCOS_SIN 81)
138 (UNSPEC_XTRACT_FRACT 84)
139 (UNSPEC_XTRACT_EXP 85)
140 (UNSPEC_FSCALE_FRACT 86)
141 (UNSPEC_FSCALE_EXP 87)
152 (UNSPEC_SP_TLS_SET 102)
153 (UNSPEC_SP_TLS_TEST 103)
163 (UNSPEC_INSERTQI 132)
168 (UNSPEC_INSERTPS 135)
170 (UNSPEC_MOVNTDQA 137)
172 (UNSPEC_PHMINPOSUW 139)
179 (UNSPEC_PCMPESTR 144)
180 (UNSPEC_PCMPISTR 145)
184 [(UNSPECV_BLOCKAGE 0)
185 (UNSPECV_STACK_PROBE 1)
194 (UNSPECV_CMPXCHG_1 10)
195 (UNSPECV_CMPXCHG_2 11)
200 ;; Registers by name.
211 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
214 ;; In C guard expressions, put expressions which may be compile-time
215 ;; constants first. This allows for better optimization. For
216 ;; example, write "TARGET_64BIT && reload_completed", not
217 ;; "reload_completed && TARGET_64BIT".
220 ;; Processor type. This attribute must exactly match the processor_type
221 ;; enumeration in i386.h.
222 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
223 nocona,core2,generic32,generic64,amdfam10"
224 (const (symbol_ref "ix86_tune")))
226 ;; A basic instruction type. Refinements due to arguments to be
227 ;; provided in other attributes.
230 alu,alu1,negnot,imov,imovx,lea,
231 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
232 icmp,test,ibr,setcc,icmov,
233 push,pop,call,callv,leave,
235 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
236 sselog,sselog1,sseiadd,sseishft,sseimul,
237 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
238 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
239 (const_string "other"))
241 ;; Main data type used by the insn
243 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
244 (const_string "unknown"))
246 ;; The CPU unit operations uses.
247 (define_attr "unit" "integer,i387,sse,mmx,unknown"
248 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
249 (const_string "i387")
250 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
251 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
253 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
255 (eq_attr "type" "other")
256 (const_string "unknown")]
257 (const_string "integer")))
259 ;; The (bounding maximum) length of an instruction immediate.
260 (define_attr "length_immediate" ""
261 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
264 (eq_attr "unit" "i387,sse,mmx")
266 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
268 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
269 (eq_attr "type" "imov,test")
270 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
271 (eq_attr "type" "call")
272 (if_then_else (match_operand 0 "constant_call_address_operand" "")
275 (eq_attr "type" "callv")
276 (if_then_else (match_operand 1 "constant_call_address_operand" "")
279 ;; We don't know the size before shorten_branches. Expect
280 ;; the instruction to fit for better scheduling.
281 (eq_attr "type" "ibr")
284 (symbol_ref "/* Update immediate_length and other attributes! */
285 gcc_unreachable (),1")))
287 ;; The (bounding maximum) length of an instruction address.
288 (define_attr "length_address" ""
289 (cond [(eq_attr "type" "str,other,multi,fxch")
291 (and (eq_attr "type" "call")
292 (match_operand 0 "constant_call_address_operand" ""))
294 (and (eq_attr "type" "callv")
295 (match_operand 1 "constant_call_address_operand" ""))
298 (symbol_ref "ix86_attr_length_address_default (insn)")))
300 ;; Set when length prefix is used.
301 (define_attr "prefix_data16" ""
302 (if_then_else (ior (eq_attr "mode" "HI")
303 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
307 ;; Set when string REP prefix is used.
308 (define_attr "prefix_rep" ""
309 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
313 ;; Set when 0f opcode prefix is used.
314 (define_attr "prefix_0f" ""
316 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
317 (eq_attr "unit" "sse,mmx"))
321 ;; Set when REX opcode prefix is used.
322 (define_attr "prefix_rex" ""
323 (cond [(and (eq_attr "mode" "DI")
324 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
326 (and (eq_attr "mode" "QI")
327 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
330 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
336 ;; There are also additional prefixes in SSSE3.
337 (define_attr "prefix_extra" "" (const_int 0))
339 ;; Set when modrm byte is used.
340 (define_attr "modrm" ""
341 (cond [(eq_attr "type" "str,leave")
343 (eq_attr "unit" "i387")
345 (and (eq_attr "type" "incdec")
346 (ior (match_operand:SI 1 "register_operand" "")
347 (match_operand:HI 1 "register_operand" "")))
349 (and (eq_attr "type" "push")
350 (not (match_operand 1 "memory_operand" "")))
352 (and (eq_attr "type" "pop")
353 (not (match_operand 0 "memory_operand" "")))
355 (and (eq_attr "type" "imov")
356 (ior (and (match_operand 0 "register_operand" "")
357 (match_operand 1 "immediate_operand" ""))
358 (ior (and (match_operand 0 "ax_reg_operand" "")
359 (match_operand 1 "memory_displacement_only_operand" ""))
360 (and (match_operand 0 "memory_displacement_only_operand" "")
361 (match_operand 1 "ax_reg_operand" "")))))
363 (and (eq_attr "type" "call")
364 (match_operand 0 "constant_call_address_operand" ""))
366 (and (eq_attr "type" "callv")
367 (match_operand 1 "constant_call_address_operand" ""))
372 ;; The (bounding maximum) length of an instruction in bytes.
373 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
374 ;; Later we may want to split them and compute proper length as for
376 (define_attr "length" ""
377 (cond [(eq_attr "type" "other,multi,fistp,frndint")
379 (eq_attr "type" "fcmp")
381 (eq_attr "unit" "i387")
383 (plus (attr "prefix_data16")
384 (attr "length_address")))]
385 (plus (plus (attr "modrm")
386 (plus (attr "prefix_0f")
387 (plus (attr "prefix_rex")
388 (plus (attr "prefix_extra")
390 (plus (attr "prefix_rep")
391 (plus (attr "prefix_data16")
392 (plus (attr "length_immediate")
393 (attr "length_address")))))))
395 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
396 ;; `store' if there is a simple memory reference therein, or `unknown'
397 ;; if the instruction is complex.
399 (define_attr "memory" "none,load,store,both,unknown"
400 (cond [(eq_attr "type" "other,multi,str")
401 (const_string "unknown")
402 (eq_attr "type" "lea,fcmov,fpspc")
403 (const_string "none")
404 (eq_attr "type" "fistp,leave")
405 (const_string "both")
406 (eq_attr "type" "frndint")
407 (const_string "load")
408 (eq_attr "type" "push")
409 (if_then_else (match_operand 1 "memory_operand" "")
410 (const_string "both")
411 (const_string "store"))
412 (eq_attr "type" "pop")
413 (if_then_else (match_operand 0 "memory_operand" "")
414 (const_string "both")
415 (const_string "load"))
416 (eq_attr "type" "setcc")
417 (if_then_else (match_operand 0 "memory_operand" "")
418 (const_string "store")
419 (const_string "none"))
420 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
421 (if_then_else (ior (match_operand 0 "memory_operand" "")
422 (match_operand 1 "memory_operand" ""))
423 (const_string "load")
424 (const_string "none"))
425 (eq_attr "type" "ibr")
426 (if_then_else (match_operand 0 "memory_operand" "")
427 (const_string "load")
428 (const_string "none"))
429 (eq_attr "type" "call")
430 (if_then_else (match_operand 0 "constant_call_address_operand" "")
431 (const_string "none")
432 (const_string "load"))
433 (eq_attr "type" "callv")
434 (if_then_else (match_operand 1 "constant_call_address_operand" "")
435 (const_string "none")
436 (const_string "load"))
437 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
438 (match_operand 1 "memory_operand" ""))
439 (const_string "both")
440 (and (match_operand 0 "memory_operand" "")
441 (match_operand 1 "memory_operand" ""))
442 (const_string "both")
443 (match_operand 0 "memory_operand" "")
444 (const_string "store")
445 (match_operand 1 "memory_operand" "")
446 (const_string "load")
448 "!alu1,negnot,ishift1,
449 imov,imovx,icmp,test,bitmanip,
451 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
452 mmx,mmxmov,mmxcmp,mmxcvt")
453 (match_operand 2 "memory_operand" ""))
454 (const_string "load")
455 (and (eq_attr "type" "icmov")
456 (match_operand 3 "memory_operand" ""))
457 (const_string "load")
459 (const_string "none")))
461 ;; Indicates if an instruction has both an immediate and a displacement.
463 (define_attr "imm_disp" "false,true,unknown"
464 (cond [(eq_attr "type" "other,multi")
465 (const_string "unknown")
466 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
467 (and (match_operand 0 "memory_displacement_operand" "")
468 (match_operand 1 "immediate_operand" "")))
469 (const_string "true")
470 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
471 (and (match_operand 0 "memory_displacement_operand" "")
472 (match_operand 2 "immediate_operand" "")))
473 (const_string "true")
475 (const_string "false")))
477 ;; Indicates if an FP operation has an integer source.
479 (define_attr "fp_int_src" "false,true"
480 (const_string "false"))
482 ;; Defines rounding mode of an FP operation.
484 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
485 (const_string "any"))
487 ;; Describe a user's asm statement.
488 (define_asm_attributes
489 [(set_attr "length" "128")
490 (set_attr "type" "multi")])
492 ;; All x87 floating point modes
493 (define_mode_macro X87MODEF [SF DF XF])
495 ;; x87 SFmode and DFMode floating point modes
496 (define_mode_macro X87MODEF12 [SF DF])
498 ;; All integer modes handled by x87 fisttp operator.
499 (define_mode_macro X87MODEI [HI SI DI])
501 ;; All integer modes handled by integer x87 operators.
502 (define_mode_macro X87MODEI12 [HI SI])
504 ;; All SSE floating point modes
505 (define_mode_macro SSEMODEF [SF DF])
507 ;; All integer modes handled by SSE cvtts?2si* operators.
508 (define_mode_macro SSEMODEI24 [SI DI])
510 ;; SSE asm suffix for floating point modes
511 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
513 ;; SSE vector mode corresponding to a scalar mode
514 (define_mode_attr ssevecmode
515 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
517 ;; Scheduling descriptions
519 (include "pentium.md")
522 (include "athlon.md")
526 ;; Operand and operator predicates and constraints
528 (include "predicates.md")
529 (include "constraints.md")
532 ;; Compare instructions.
534 ;; All compare insns have expanders that save the operands away without
535 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
536 ;; after the cmp) will actually emit the cmpM.
538 (define_expand "cmpti"
539 [(set (reg:CC FLAGS_REG)
540 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
541 (match_operand:TI 1 "x86_64_general_operand" "")))]
544 if (MEM_P (operands[0]) && MEM_P (operands[1]))
545 operands[0] = force_reg (TImode, operands[0]);
546 ix86_compare_op0 = operands[0];
547 ix86_compare_op1 = operands[1];
551 (define_expand "cmpdi"
552 [(set (reg:CC FLAGS_REG)
553 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
554 (match_operand:DI 1 "x86_64_general_operand" "")))]
557 if (MEM_P (operands[0]) && MEM_P (operands[1]))
558 operands[0] = force_reg (DImode, operands[0]);
559 ix86_compare_op0 = operands[0];
560 ix86_compare_op1 = operands[1];
564 (define_expand "cmpsi"
565 [(set (reg:CC FLAGS_REG)
566 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
567 (match_operand:SI 1 "general_operand" "")))]
570 if (MEM_P (operands[0]) && MEM_P (operands[1]))
571 operands[0] = force_reg (SImode, operands[0]);
572 ix86_compare_op0 = operands[0];
573 ix86_compare_op1 = operands[1];
577 (define_expand "cmphi"
578 [(set (reg:CC FLAGS_REG)
579 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
580 (match_operand:HI 1 "general_operand" "")))]
583 if (MEM_P (operands[0]) && MEM_P (operands[1]))
584 operands[0] = force_reg (HImode, operands[0]);
585 ix86_compare_op0 = operands[0];
586 ix86_compare_op1 = operands[1];
590 (define_expand "cmpqi"
591 [(set (reg:CC FLAGS_REG)
592 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
593 (match_operand:QI 1 "general_operand" "")))]
596 if (MEM_P (operands[0]) && MEM_P (operands[1]))
597 operands[0] = force_reg (QImode, operands[0]);
598 ix86_compare_op0 = operands[0];
599 ix86_compare_op1 = operands[1];
603 (define_insn "cmpdi_ccno_1_rex64"
604 [(set (reg FLAGS_REG)
605 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
606 (match_operand:DI 1 "const0_operand" "n,n")))]
607 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
610 cmp{q}\t{%1, %0|%0, %1}"
611 [(set_attr "type" "test,icmp")
612 (set_attr "length_immediate" "0,1")
613 (set_attr "mode" "DI")])
615 (define_insn "*cmpdi_minus_1_rex64"
616 [(set (reg FLAGS_REG)
617 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
618 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
620 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
621 "cmp{q}\t{%1, %0|%0, %1}"
622 [(set_attr "type" "icmp")
623 (set_attr "mode" "DI")])
625 (define_expand "cmpdi_1_rex64"
626 [(set (reg:CC FLAGS_REG)
627 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
628 (match_operand:DI 1 "general_operand" "")))]
632 (define_insn "cmpdi_1_insn_rex64"
633 [(set (reg FLAGS_REG)
634 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
635 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
636 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
637 "cmp{q}\t{%1, %0|%0, %1}"
638 [(set_attr "type" "icmp")
639 (set_attr "mode" "DI")])
642 (define_insn "*cmpsi_ccno_1"
643 [(set (reg FLAGS_REG)
644 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
645 (match_operand:SI 1 "const0_operand" "n,n")))]
646 "ix86_match_ccmode (insn, CCNOmode)"
649 cmp{l}\t{%1, %0|%0, %1}"
650 [(set_attr "type" "test,icmp")
651 (set_attr "length_immediate" "0,1")
652 (set_attr "mode" "SI")])
654 (define_insn "*cmpsi_minus_1"
655 [(set (reg FLAGS_REG)
656 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
657 (match_operand:SI 1 "general_operand" "ri,mr"))
659 "ix86_match_ccmode (insn, CCGOCmode)"
660 "cmp{l}\t{%1, %0|%0, %1}"
661 [(set_attr "type" "icmp")
662 (set_attr "mode" "SI")])
664 (define_expand "cmpsi_1"
665 [(set (reg:CC FLAGS_REG)
666 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
667 (match_operand:SI 1 "general_operand" "ri,mr")))]
671 (define_insn "*cmpsi_1_insn"
672 [(set (reg FLAGS_REG)
673 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
674 (match_operand:SI 1 "general_operand" "ri,mr")))]
675 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
676 && ix86_match_ccmode (insn, CCmode)"
677 "cmp{l}\t{%1, %0|%0, %1}"
678 [(set_attr "type" "icmp")
679 (set_attr "mode" "SI")])
681 (define_insn "*cmphi_ccno_1"
682 [(set (reg FLAGS_REG)
683 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
684 (match_operand:HI 1 "const0_operand" "n,n")))]
685 "ix86_match_ccmode (insn, CCNOmode)"
688 cmp{w}\t{%1, %0|%0, %1}"
689 [(set_attr "type" "test,icmp")
690 (set_attr "length_immediate" "0,1")
691 (set_attr "mode" "HI")])
693 (define_insn "*cmphi_minus_1"
694 [(set (reg FLAGS_REG)
695 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
696 (match_operand:HI 1 "general_operand" "ri,mr"))
698 "ix86_match_ccmode (insn, CCGOCmode)"
699 "cmp{w}\t{%1, %0|%0, %1}"
700 [(set_attr "type" "icmp")
701 (set_attr "mode" "HI")])
703 (define_insn "*cmphi_1"
704 [(set (reg FLAGS_REG)
705 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
706 (match_operand:HI 1 "general_operand" "ri,mr")))]
707 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
708 && ix86_match_ccmode (insn, CCmode)"
709 "cmp{w}\t{%1, %0|%0, %1}"
710 [(set_attr "type" "icmp")
711 (set_attr "mode" "HI")])
713 (define_insn "*cmpqi_ccno_1"
714 [(set (reg FLAGS_REG)
715 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
716 (match_operand:QI 1 "const0_operand" "n,n")))]
717 "ix86_match_ccmode (insn, CCNOmode)"
720 cmp{b}\t{$0, %0|%0, 0}"
721 [(set_attr "type" "test,icmp")
722 (set_attr "length_immediate" "0,1")
723 (set_attr "mode" "QI")])
725 (define_insn "*cmpqi_1"
726 [(set (reg FLAGS_REG)
727 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
728 (match_operand:QI 1 "general_operand" "qi,mq")))]
729 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
730 && ix86_match_ccmode (insn, CCmode)"
731 "cmp{b}\t{%1, %0|%0, %1}"
732 [(set_attr "type" "icmp")
733 (set_attr "mode" "QI")])
735 (define_insn "*cmpqi_minus_1"
736 [(set (reg FLAGS_REG)
737 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
738 (match_operand:QI 1 "general_operand" "qi,mq"))
740 "ix86_match_ccmode (insn, CCGOCmode)"
741 "cmp{b}\t{%1, %0|%0, %1}"
742 [(set_attr "type" "icmp")
743 (set_attr "mode" "QI")])
745 (define_insn "*cmpqi_ext_1"
746 [(set (reg FLAGS_REG)
748 (match_operand:QI 0 "general_operand" "Qm")
751 (match_operand 1 "ext_register_operand" "Q")
754 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
755 "cmp{b}\t{%h1, %0|%0, %h1}"
756 [(set_attr "type" "icmp")
757 (set_attr "mode" "QI")])
759 (define_insn "*cmpqi_ext_1_rex64"
760 [(set (reg FLAGS_REG)
762 (match_operand:QI 0 "register_operand" "Q")
765 (match_operand 1 "ext_register_operand" "Q")
768 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
769 "cmp{b}\t{%h1, %0|%0, %h1}"
770 [(set_attr "type" "icmp")
771 (set_attr "mode" "QI")])
773 (define_insn "*cmpqi_ext_2"
774 [(set (reg FLAGS_REG)
778 (match_operand 0 "ext_register_operand" "Q")
781 (match_operand:QI 1 "const0_operand" "n")))]
782 "ix86_match_ccmode (insn, CCNOmode)"
784 [(set_attr "type" "test")
785 (set_attr "length_immediate" "0")
786 (set_attr "mode" "QI")])
788 (define_expand "cmpqi_ext_3"
789 [(set (reg:CC FLAGS_REG)
793 (match_operand 0 "ext_register_operand" "")
796 (match_operand:QI 1 "general_operand" "")))]
800 (define_insn "cmpqi_ext_3_insn"
801 [(set (reg FLAGS_REG)
805 (match_operand 0 "ext_register_operand" "Q")
808 (match_operand:QI 1 "general_operand" "Qmn")))]
809 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
810 "cmp{b}\t{%1, %h0|%h0, %1}"
811 [(set_attr "type" "icmp")
812 (set_attr "mode" "QI")])
814 (define_insn "cmpqi_ext_3_insn_rex64"
815 [(set (reg FLAGS_REG)
819 (match_operand 0 "ext_register_operand" "Q")
822 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
823 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
824 "cmp{b}\t{%1, %h0|%h0, %1}"
825 [(set_attr "type" "icmp")
826 (set_attr "mode" "QI")])
828 (define_insn "*cmpqi_ext_4"
829 [(set (reg FLAGS_REG)
833 (match_operand 0 "ext_register_operand" "Q")
838 (match_operand 1 "ext_register_operand" "Q")
841 "ix86_match_ccmode (insn, CCmode)"
842 "cmp{b}\t{%h1, %h0|%h0, %h1}"
843 [(set_attr "type" "icmp")
844 (set_attr "mode" "QI")])
846 ;; These implement float point compares.
847 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
848 ;; which would allow mix and match FP modes on the compares. Which is what
849 ;; the old patterns did, but with many more of them.
851 (define_expand "cmpxf"
852 [(set (reg:CC FLAGS_REG)
853 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
854 (match_operand:XF 1 "nonmemory_operand" "")))]
857 ix86_compare_op0 = operands[0];
858 ix86_compare_op1 = operands[1];
862 (define_expand "cmp<mode>"
863 [(set (reg:CC FLAGS_REG)
864 (compare:CC (match_operand:SSEMODEF 0 "cmp_fp_expander_operand" "")
865 (match_operand:SSEMODEF 1 "cmp_fp_expander_operand" "")))]
866 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
868 ix86_compare_op0 = operands[0];
869 ix86_compare_op1 = operands[1];
873 ;; FP compares, step 1:
874 ;; Set the FP condition codes.
876 ;; CCFPmode compare with exceptions
877 ;; CCFPUmode compare with no exceptions
879 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
880 ;; used to manage the reg stack popping would not be preserved.
882 (define_insn "*cmpfp_0"
883 [(set (match_operand:HI 0 "register_operand" "=a")
886 (match_operand 1 "register_operand" "f")
887 (match_operand 2 "const0_operand" "X"))]
889 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
890 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
891 "* return output_fp_compare (insn, operands, 0, 0);"
892 [(set_attr "type" "multi")
893 (set_attr "unit" "i387")
895 (cond [(match_operand:SF 1 "" "")
897 (match_operand:DF 1 "" "")
900 (const_string "XF")))])
902 (define_insn "*cmpfp_xf"
903 [(set (match_operand:HI 0 "register_operand" "=a")
906 (match_operand:XF 1 "register_operand" "f")
907 (match_operand:XF 2 "register_operand" "f"))]
910 "* return output_fp_compare (insn, operands, 0, 0);"
911 [(set_attr "type" "multi")
912 (set_attr "unit" "i387")
913 (set_attr "mode" "XF")])
915 (define_insn "*cmpfp_<mode>"
916 [(set (match_operand:HI 0 "register_operand" "=a")
919 (match_operand:X87MODEF12 1 "register_operand" "f")
920 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm"))]
923 "* return output_fp_compare (insn, operands, 0, 0);"
924 [(set_attr "type" "multi")
925 (set_attr "unit" "i387")
926 (set_attr "mode" "<MODE>")])
928 (define_insn "*cmpfp_u"
929 [(set (match_operand:HI 0 "register_operand" "=a")
932 (match_operand 1 "register_operand" "f")
933 (match_operand 2 "register_operand" "f"))]
935 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
936 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
937 "* return output_fp_compare (insn, operands, 0, 1);"
938 [(set_attr "type" "multi")
939 (set_attr "unit" "i387")
941 (cond [(match_operand:SF 1 "" "")
943 (match_operand:DF 1 "" "")
946 (const_string "XF")))])
948 (define_insn "*cmpfp_<mode>"
949 [(set (match_operand:HI 0 "register_operand" "=a")
952 (match_operand 1 "register_operand" "f")
953 (match_operator 3 "float_operator"
954 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
956 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
957 && TARGET_USE_<MODE>MODE_FIOP
958 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
959 "* return output_fp_compare (insn, operands, 0, 0);"
960 [(set_attr "type" "multi")
961 (set_attr "unit" "i387")
962 (set_attr "fp_int_src" "true")
963 (set_attr "mode" "<MODE>")])
965 ;; FP compares, step 2
966 ;; Move the fpsw to ax.
968 (define_insn "x86_fnstsw_1"
969 [(set (match_operand:HI 0 "register_operand" "=a")
970 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
973 [(set_attr "length" "2")
974 (set_attr "mode" "SI")
975 (set_attr "unit" "i387")])
977 ;; FP compares, step 3
978 ;; Get ax into flags, general case.
980 (define_insn "x86_sahf_1"
981 [(set (reg:CC FLAGS_REG)
982 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
986 #ifdef HAVE_AS_IX86_SAHF
989 return ".byte\t0x9e";
992 [(set_attr "length" "1")
993 (set_attr "athlon_decode" "vector")
994 (set_attr "amdfam10_decode" "direct")
995 (set_attr "mode" "SI")])
997 ;; Pentium Pro can do steps 1 through 3 in one go.
998 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
999 (define_insn "*cmpfp_i_mixed"
1000 [(set (reg:CCFP FLAGS_REG)
1001 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1002 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1003 "TARGET_MIX_SSE_I387
1004 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1005 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006 "* return output_fp_compare (insn, operands, 1, 0);"
1007 [(set_attr "type" "fcmp,ssecomi")
1009 (if_then_else (match_operand:SF 1 "" "")
1011 (const_string "DF")))
1012 (set_attr "athlon_decode" "vector")
1013 (set_attr "amdfam10_decode" "direct")])
1015 (define_insn "*cmpfp_i_sse"
1016 [(set (reg:CCFP FLAGS_REG)
1017 (compare:CCFP (match_operand 0 "register_operand" "x")
1018 (match_operand 1 "nonimmediate_operand" "xm")))]
1020 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022 "* return output_fp_compare (insn, operands, 1, 0);"
1023 [(set_attr "type" "ssecomi")
1025 (if_then_else (match_operand:SF 1 "" "")
1027 (const_string "DF")))
1028 (set_attr "athlon_decode" "vector")
1029 (set_attr "amdfam10_decode" "direct")])
1031 (define_insn "*cmpfp_i_i387"
1032 [(set (reg:CCFP FLAGS_REG)
1033 (compare:CCFP (match_operand 0 "register_operand" "f")
1034 (match_operand 1 "register_operand" "f")))]
1035 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1037 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1038 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039 "* return output_fp_compare (insn, operands, 1, 0);"
1040 [(set_attr "type" "fcmp")
1042 (cond [(match_operand:SF 1 "" "")
1044 (match_operand:DF 1 "" "")
1047 (const_string "XF")))
1048 (set_attr "athlon_decode" "vector")
1049 (set_attr "amdfam10_decode" "direct")])
1051 (define_insn "*cmpfp_iu_mixed"
1052 [(set (reg:CCFPU FLAGS_REG)
1053 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1054 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1055 "TARGET_MIX_SSE_I387
1056 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1057 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1058 "* return output_fp_compare (insn, operands, 1, 1);"
1059 [(set_attr "type" "fcmp,ssecomi")
1061 (if_then_else (match_operand:SF 1 "" "")
1063 (const_string "DF")))
1064 (set_attr "athlon_decode" "vector")
1065 (set_attr "amdfam10_decode" "direct")])
1067 (define_insn "*cmpfp_iu_sse"
1068 [(set (reg:CCFPU FLAGS_REG)
1069 (compare:CCFPU (match_operand 0 "register_operand" "x")
1070 (match_operand 1 "nonimmediate_operand" "xm")))]
1072 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1073 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1074 "* return output_fp_compare (insn, operands, 1, 1);"
1075 [(set_attr "type" "ssecomi")
1077 (if_then_else (match_operand:SF 1 "" "")
1079 (const_string "DF")))
1080 (set_attr "athlon_decode" "vector")
1081 (set_attr "amdfam10_decode" "direct")])
1083 (define_insn "*cmpfp_iu_387"
1084 [(set (reg:CCFPU FLAGS_REG)
1085 (compare:CCFPU (match_operand 0 "register_operand" "f")
1086 (match_operand 1 "register_operand" "f")))]
1087 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1089 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1090 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1091 "* return output_fp_compare (insn, operands, 1, 1);"
1092 [(set_attr "type" "fcmp")
1094 (cond [(match_operand:SF 1 "" "")
1096 (match_operand:DF 1 "" "")
1099 (const_string "XF")))
1100 (set_attr "athlon_decode" "vector")
1101 (set_attr "amdfam10_decode" "direct")])
1103 ;; Move instructions.
1105 ;; General case of fullword move.
1107 (define_expand "movsi"
1108 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1109 (match_operand:SI 1 "general_operand" ""))]
1111 "ix86_expand_move (SImode, operands); DONE;")
1113 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1116 ;; %%% We don't use a post-inc memory reference because x86 is not a
1117 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1118 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1119 ;; targets without our curiosities, and it is just as easy to represent
1120 ;; this differently.
1122 (define_insn "*pushsi2"
1123 [(set (match_operand:SI 0 "push_operand" "=<")
1124 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1127 [(set_attr "type" "push")
1128 (set_attr "mode" "SI")])
1130 ;; For 64BIT abi we always round up to 8 bytes.
1131 (define_insn "*pushsi2_rex64"
1132 [(set (match_operand:SI 0 "push_operand" "=X")
1133 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1136 [(set_attr "type" "push")
1137 (set_attr "mode" "SI")])
1139 (define_insn "*pushsi2_prologue"
1140 [(set (match_operand:SI 0 "push_operand" "=<")
1141 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1142 (clobber (mem:BLK (scratch)))]
1145 [(set_attr "type" "push")
1146 (set_attr "mode" "SI")])
1148 (define_insn "*popsi1_epilogue"
1149 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1150 (mem:SI (reg:SI SP_REG)))
1151 (set (reg:SI SP_REG)
1152 (plus:SI (reg:SI SP_REG) (const_int 4)))
1153 (clobber (mem:BLK (scratch)))]
1156 [(set_attr "type" "pop")
1157 (set_attr "mode" "SI")])
1159 (define_insn "popsi1"
1160 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1161 (mem:SI (reg:SI SP_REG)))
1162 (set (reg:SI SP_REG)
1163 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1166 [(set_attr "type" "pop")
1167 (set_attr "mode" "SI")])
1169 (define_insn "*movsi_xor"
1170 [(set (match_operand:SI 0 "register_operand" "=r")
1171 (match_operand:SI 1 "const0_operand" "i"))
1172 (clobber (reg:CC FLAGS_REG))]
1173 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1175 [(set_attr "type" "alu1")
1176 (set_attr "mode" "SI")
1177 (set_attr "length_immediate" "0")])
1179 (define_insn "*movsi_or"
1180 [(set (match_operand:SI 0 "register_operand" "=r")
1181 (match_operand:SI 1 "immediate_operand" "i"))
1182 (clobber (reg:CC FLAGS_REG))]
1184 && operands[1] == constm1_rtx
1185 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1187 operands[1] = constm1_rtx;
1188 return "or{l}\t{%1, %0|%0, %1}";
1190 [(set_attr "type" "alu1")
1191 (set_attr "mode" "SI")
1192 (set_attr "length_immediate" "1")])
1194 (define_insn "*movsi_1"
1195 [(set (match_operand:SI 0 "nonimmediate_operand"
1196 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1197 (match_operand:SI 1 "general_operand"
1198 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1199 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1201 switch (get_attr_type (insn))
1204 if (get_attr_mode (insn) == MODE_TI)
1205 return "pxor\t%0, %0";
1206 return "xorps\t%0, %0";
1209 switch (get_attr_mode (insn))
1212 return "movdqa\t{%1, %0|%0, %1}";
1214 return "movaps\t{%1, %0|%0, %1}";
1216 return "movd\t{%1, %0|%0, %1}";
1218 return "movss\t{%1, %0|%0, %1}";
1224 return "pxor\t%0, %0";
1227 if (get_attr_mode (insn) == MODE_DI)
1228 return "movq\t{%1, %0|%0, %1}";
1229 return "movd\t{%1, %0|%0, %1}";
1232 return "lea{l}\t{%1, %0|%0, %1}";
1235 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1236 return "mov{l}\t{%1, %0|%0, %1}";
1240 (cond [(eq_attr "alternative" "2")
1241 (const_string "mmxadd")
1242 (eq_attr "alternative" "3,4,5")
1243 (const_string "mmxmov")
1244 (eq_attr "alternative" "6")
1245 (const_string "sselog1")
1246 (eq_attr "alternative" "7,8,9,10,11")
1247 (const_string "ssemov")
1248 (match_operand:DI 1 "pic_32bit_operand" "")
1249 (const_string "lea")
1251 (const_string "imov")))
1253 (cond [(eq_attr "alternative" "2,3")
1255 (eq_attr "alternative" "6,7")
1257 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1258 (const_string "V4SF")
1259 (const_string "TI"))
1260 (and (eq_attr "alternative" "8,9,10,11")
1261 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1264 (const_string "SI")))])
1266 ;; Stores and loads of ax to arbitrary constant address.
1267 ;; We fake an second form of instruction to force reload to load address
1268 ;; into register when rax is not available
1269 (define_insn "*movabssi_1_rex64"
1270 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1271 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1272 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1274 movabs{l}\t{%1, %P0|%P0, %1}
1275 mov{l}\t{%1, %a0|%a0, %1}"
1276 [(set_attr "type" "imov")
1277 (set_attr "modrm" "0,*")
1278 (set_attr "length_address" "8,0")
1279 (set_attr "length_immediate" "0,*")
1280 (set_attr "memory" "store")
1281 (set_attr "mode" "SI")])
1283 (define_insn "*movabssi_2_rex64"
1284 [(set (match_operand:SI 0 "register_operand" "=a,r")
1285 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1286 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1288 movabs{l}\t{%P1, %0|%0, %P1}
1289 mov{l}\t{%a1, %0|%0, %a1}"
1290 [(set_attr "type" "imov")
1291 (set_attr "modrm" "0,*")
1292 (set_attr "length_address" "8,0")
1293 (set_attr "length_immediate" "0")
1294 (set_attr "memory" "load")
1295 (set_attr "mode" "SI")])
1297 (define_insn "*swapsi"
1298 [(set (match_operand:SI 0 "register_operand" "+r")
1299 (match_operand:SI 1 "register_operand" "+r"))
1304 [(set_attr "type" "imov")
1305 (set_attr "mode" "SI")
1306 (set_attr "pent_pair" "np")
1307 (set_attr "athlon_decode" "vector")
1308 (set_attr "amdfam10_decode" "double")])
1310 (define_expand "movhi"
1311 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1312 (match_operand:HI 1 "general_operand" ""))]
1314 "ix86_expand_move (HImode, operands); DONE;")
1316 (define_insn "*pushhi2"
1317 [(set (match_operand:HI 0 "push_operand" "=X")
1318 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1321 [(set_attr "type" "push")
1322 (set_attr "mode" "SI")])
1324 ;; For 64BIT abi we always round up to 8 bytes.
1325 (define_insn "*pushhi2_rex64"
1326 [(set (match_operand:HI 0 "push_operand" "=X")
1327 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1330 [(set_attr "type" "push")
1331 (set_attr "mode" "DI")])
1333 (define_insn "*movhi_1"
1334 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1335 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1336 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1338 switch (get_attr_type (insn))
1341 /* movzwl is faster than movw on p2 due to partial word stalls,
1342 though not as fast as an aligned movl. */
1343 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1345 if (get_attr_mode (insn) == MODE_SI)
1346 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1348 return "mov{w}\t{%1, %0|%0, %1}";
1352 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1353 (const_string "imov")
1354 (and (eq_attr "alternative" "0")
1355 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1357 (eq (symbol_ref "TARGET_HIMODE_MATH")
1359 (const_string "imov")
1360 (and (eq_attr "alternative" "1,2")
1361 (match_operand:HI 1 "aligned_operand" ""))
1362 (const_string "imov")
1363 (and (ne (symbol_ref "TARGET_MOVX")
1365 (eq_attr "alternative" "0,2"))
1366 (const_string "imovx")
1368 (const_string "imov")))
1370 (cond [(eq_attr "type" "imovx")
1372 (and (eq_attr "alternative" "1,2")
1373 (match_operand:HI 1 "aligned_operand" ""))
1375 (and (eq_attr "alternative" "0")
1376 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1378 (eq (symbol_ref "TARGET_HIMODE_MATH")
1382 (const_string "HI")))])
1384 ;; Stores and loads of ax to arbitrary constant address.
1385 ;; We fake an second form of instruction to force reload to load address
1386 ;; into register when rax is not available
1387 (define_insn "*movabshi_1_rex64"
1388 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1389 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1390 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1392 movabs{w}\t{%1, %P0|%P0, %1}
1393 mov{w}\t{%1, %a0|%a0, %1}"
1394 [(set_attr "type" "imov")
1395 (set_attr "modrm" "0,*")
1396 (set_attr "length_address" "8,0")
1397 (set_attr "length_immediate" "0,*")
1398 (set_attr "memory" "store")
1399 (set_attr "mode" "HI")])
1401 (define_insn "*movabshi_2_rex64"
1402 [(set (match_operand:HI 0 "register_operand" "=a,r")
1403 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1404 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1406 movabs{w}\t{%P1, %0|%0, %P1}
1407 mov{w}\t{%a1, %0|%0, %a1}"
1408 [(set_attr "type" "imov")
1409 (set_attr "modrm" "0,*")
1410 (set_attr "length_address" "8,0")
1411 (set_attr "length_immediate" "0")
1412 (set_attr "memory" "load")
1413 (set_attr "mode" "HI")])
1415 (define_insn "*swaphi_1"
1416 [(set (match_operand:HI 0 "register_operand" "+r")
1417 (match_operand:HI 1 "register_operand" "+r"))
1420 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1422 [(set_attr "type" "imov")
1423 (set_attr "mode" "SI")
1424 (set_attr "pent_pair" "np")
1425 (set_attr "athlon_decode" "vector")
1426 (set_attr "amdfam10_decode" "double")])
1428 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1429 (define_insn "*swaphi_2"
1430 [(set (match_operand:HI 0 "register_operand" "+r")
1431 (match_operand:HI 1 "register_operand" "+r"))
1434 "TARGET_PARTIAL_REG_STALL"
1436 [(set_attr "type" "imov")
1437 (set_attr "mode" "HI")
1438 (set_attr "pent_pair" "np")
1439 (set_attr "athlon_decode" "vector")])
1441 (define_expand "movstricthi"
1442 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1443 (match_operand:HI 1 "general_operand" ""))]
1444 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1446 /* Don't generate memory->memory moves, go through a register */
1447 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1448 operands[1] = force_reg (HImode, operands[1]);
1451 (define_insn "*movstricthi_1"
1452 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1453 (match_operand:HI 1 "general_operand" "rn,m"))]
1454 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1455 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1456 "mov{w}\t{%1, %0|%0, %1}"
1457 [(set_attr "type" "imov")
1458 (set_attr "mode" "HI")])
1460 (define_insn "*movstricthi_xor"
1461 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1462 (match_operand:HI 1 "const0_operand" "i"))
1463 (clobber (reg:CC FLAGS_REG))]
1465 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1467 [(set_attr "type" "alu1")
1468 (set_attr "mode" "HI")
1469 (set_attr "length_immediate" "0")])
1471 (define_expand "movqi"
1472 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1473 (match_operand:QI 1 "general_operand" ""))]
1475 "ix86_expand_move (QImode, operands); DONE;")
1477 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1478 ;; "push a byte". But actually we use pushl, which has the effect
1479 ;; of rounding the amount pushed up to a word.
1481 (define_insn "*pushqi2"
1482 [(set (match_operand:QI 0 "push_operand" "=X")
1483 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1486 [(set_attr "type" "push")
1487 (set_attr "mode" "SI")])
1489 ;; For 64BIT abi we always round up to 8 bytes.
1490 (define_insn "*pushqi2_rex64"
1491 [(set (match_operand:QI 0 "push_operand" "=X")
1492 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1495 [(set_attr "type" "push")
1496 (set_attr "mode" "DI")])
1498 ;; Situation is quite tricky about when to choose full sized (SImode) move
1499 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1500 ;; partial register dependency machines (such as AMD Athlon), where QImode
1501 ;; moves issue extra dependency and for partial register stalls machines
1502 ;; that don't use QImode patterns (and QImode move cause stall on the next
1505 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1506 ;; register stall machines with, where we use QImode instructions, since
1507 ;; partial register stall can be caused there. Then we use movzx.
1508 (define_insn "*movqi_1"
1509 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1510 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1511 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1513 switch (get_attr_type (insn))
1516 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1517 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1519 if (get_attr_mode (insn) == MODE_SI)
1520 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1522 return "mov{b}\t{%1, %0|%0, %1}";
1526 (cond [(and (eq_attr "alternative" "5")
1527 (not (match_operand:QI 1 "aligned_operand" "")))
1528 (const_string "imovx")
1529 (ne (symbol_ref "optimize_size") (const_int 0))
1530 (const_string "imov")
1531 (and (eq_attr "alternative" "3")
1532 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1534 (eq (symbol_ref "TARGET_QIMODE_MATH")
1536 (const_string "imov")
1537 (eq_attr "alternative" "3,5")
1538 (const_string "imovx")
1539 (and (ne (symbol_ref "TARGET_MOVX")
1541 (eq_attr "alternative" "2"))
1542 (const_string "imovx")
1544 (const_string "imov")))
1546 (cond [(eq_attr "alternative" "3,4,5")
1548 (eq_attr "alternative" "6")
1550 (eq_attr "type" "imovx")
1552 (and (eq_attr "type" "imov")
1553 (and (eq_attr "alternative" "0,1")
1554 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1556 (and (eq (symbol_ref "optimize_size")
1558 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1561 ;; Avoid partial register stalls when not using QImode arithmetic
1562 (and (eq_attr "type" "imov")
1563 (and (eq_attr "alternative" "0,1")
1564 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1566 (eq (symbol_ref "TARGET_QIMODE_MATH")
1570 (const_string "QI")))])
1572 (define_expand "reload_outqi"
1573 [(parallel [(match_operand:QI 0 "" "=m")
1574 (match_operand:QI 1 "register_operand" "r")
1575 (match_operand:QI 2 "register_operand" "=&q")])]
1579 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1581 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1582 if (! q_regs_operand (op1, QImode))
1584 emit_insn (gen_movqi (op2, op1));
1587 emit_insn (gen_movqi (op0, op1));
1591 (define_insn "*swapqi_1"
1592 [(set (match_operand:QI 0 "register_operand" "+r")
1593 (match_operand:QI 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" "vector")])
1604 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1605 (define_insn "*swapqi_2"
1606 [(set (match_operand:QI 0 "register_operand" "+q")
1607 (match_operand:QI 1 "register_operand" "+q"))
1610 "TARGET_PARTIAL_REG_STALL"
1612 [(set_attr "type" "imov")
1613 (set_attr "mode" "QI")
1614 (set_attr "pent_pair" "np")
1615 (set_attr "athlon_decode" "vector")])
1617 (define_expand "movstrictqi"
1618 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1619 (match_operand:QI 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 (QImode, operands[1]);
1627 (define_insn "*movstrictqi_1"
1628 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1629 (match_operand:QI 1 "general_operand" "*qn,m"))]
1630 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1631 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1632 "mov{b}\t{%1, %0|%0, %1}"
1633 [(set_attr "type" "imov")
1634 (set_attr "mode" "QI")])
1636 (define_insn "*movstrictqi_xor"
1637 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1638 (match_operand:QI 1 "const0_operand" "i"))
1639 (clobber (reg:CC FLAGS_REG))]
1640 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1642 [(set_attr "type" "alu1")
1643 (set_attr "mode" "QI")
1644 (set_attr "length_immediate" "0")])
1646 (define_insn "*movsi_extv_1"
1647 [(set (match_operand:SI 0 "register_operand" "=R")
1648 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1652 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1653 [(set_attr "type" "imovx")
1654 (set_attr "mode" "SI")])
1656 (define_insn "*movhi_extv_1"
1657 [(set (match_operand:HI 0 "register_operand" "=R")
1658 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1662 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1663 [(set_attr "type" "imovx")
1664 (set_attr "mode" "SI")])
1666 (define_insn "*movqi_extv_1"
1667 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1668 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1673 switch (get_attr_type (insn))
1676 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1678 return "mov{b}\t{%h1, %0|%0, %h1}";
1682 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1683 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1684 (ne (symbol_ref "TARGET_MOVX")
1686 (const_string "imovx")
1687 (const_string "imov")))
1689 (if_then_else (eq_attr "type" "imovx")
1691 (const_string "QI")))])
1693 (define_insn "*movqi_extv_1_rex64"
1694 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1695 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1700 switch (get_attr_type (insn))
1703 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1705 return "mov{b}\t{%h1, %0|%0, %h1}";
1709 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1710 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1711 (ne (symbol_ref "TARGET_MOVX")
1713 (const_string "imovx")
1714 (const_string "imov")))
1716 (if_then_else (eq_attr "type" "imovx")
1718 (const_string "QI")))])
1720 ;; Stores and loads of ax to arbitrary constant address.
1721 ;; We fake an second form of instruction to force reload to load address
1722 ;; into register when rax is not available
1723 (define_insn "*movabsqi_1_rex64"
1724 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1725 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1726 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1728 movabs{b}\t{%1, %P0|%P0, %1}
1729 mov{b}\t{%1, %a0|%a0, %1}"
1730 [(set_attr "type" "imov")
1731 (set_attr "modrm" "0,*")
1732 (set_attr "length_address" "8,0")
1733 (set_attr "length_immediate" "0,*")
1734 (set_attr "memory" "store")
1735 (set_attr "mode" "QI")])
1737 (define_insn "*movabsqi_2_rex64"
1738 [(set (match_operand:QI 0 "register_operand" "=a,r")
1739 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1740 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1742 movabs{b}\t{%P1, %0|%0, %P1}
1743 mov{b}\t{%a1, %0|%0, %a1}"
1744 [(set_attr "type" "imov")
1745 (set_attr "modrm" "0,*")
1746 (set_attr "length_address" "8,0")
1747 (set_attr "length_immediate" "0")
1748 (set_attr "memory" "load")
1749 (set_attr "mode" "QI")])
1751 (define_insn "*movdi_extzv_1"
1752 [(set (match_operand:DI 0 "register_operand" "=R")
1753 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1757 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1758 [(set_attr "type" "imovx")
1759 (set_attr "mode" "DI")])
1761 (define_insn "*movsi_extzv_1"
1762 [(set (match_operand:SI 0 "register_operand" "=R")
1763 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1767 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1768 [(set_attr "type" "imovx")
1769 (set_attr "mode" "SI")])
1771 (define_insn "*movqi_extzv_2"
1772 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1773 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1778 switch (get_attr_type (insn))
1781 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1783 return "mov{b}\t{%h1, %0|%0, %h1}";
1787 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1788 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1789 (ne (symbol_ref "TARGET_MOVX")
1791 (const_string "imovx")
1792 (const_string "imov")))
1794 (if_then_else (eq_attr "type" "imovx")
1796 (const_string "QI")))])
1798 (define_insn "*movqi_extzv_2_rex64"
1799 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1800 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1805 switch (get_attr_type (insn))
1808 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1810 return "mov{b}\t{%h1, %0|%0, %h1}";
1814 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1815 (ne (symbol_ref "TARGET_MOVX")
1817 (const_string "imovx")
1818 (const_string "imov")))
1820 (if_then_else (eq_attr "type" "imovx")
1822 (const_string "QI")))])
1824 (define_insn "movsi_insv_1"
1825 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1828 (match_operand:SI 1 "general_operand" "Qmn"))]
1830 "mov{b}\t{%b1, %h0|%h0, %b1}"
1831 [(set_attr "type" "imov")
1832 (set_attr "mode" "QI")])
1834 (define_insn "*movsi_insv_1_rex64"
1835 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1838 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1840 "mov{b}\t{%b1, %h0|%h0, %b1}"
1841 [(set_attr "type" "imov")
1842 (set_attr "mode" "QI")])
1844 (define_insn "movdi_insv_1_rex64"
1845 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1848 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1850 "mov{b}\t{%b1, %h0|%h0, %b1}"
1851 [(set_attr "type" "imov")
1852 (set_attr "mode" "QI")])
1854 (define_insn "*movqi_insv_2"
1855 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1858 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1861 "mov{b}\t{%h1, %h0|%h0, %h1}"
1862 [(set_attr "type" "imov")
1863 (set_attr "mode" "QI")])
1865 (define_expand "movdi"
1866 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1867 (match_operand:DI 1 "general_operand" ""))]
1869 "ix86_expand_move (DImode, operands); DONE;")
1871 (define_insn "*pushdi"
1872 [(set (match_operand:DI 0 "push_operand" "=<")
1873 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1877 (define_insn "*pushdi2_rex64"
1878 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1879 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1884 [(set_attr "type" "push,multi")
1885 (set_attr "mode" "DI")])
1887 ;; Convert impossible pushes of immediate to existing instructions.
1888 ;; First try to get scratch register and go through it. In case this
1889 ;; fails, push sign extended lower part first and then overwrite
1890 ;; upper part by 32bit move.
1892 [(match_scratch:DI 2 "r")
1893 (set (match_operand:DI 0 "push_operand" "")
1894 (match_operand:DI 1 "immediate_operand" ""))]
1895 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1896 && !x86_64_immediate_operand (operands[1], DImode)"
1897 [(set (match_dup 2) (match_dup 1))
1898 (set (match_dup 0) (match_dup 2))]
1901 ;; We need to define this as both peepholer and splitter for case
1902 ;; peephole2 pass is not run.
1903 ;; "&& 1" is needed to keep it from matching the previous pattern.
1905 [(set (match_operand:DI 0 "push_operand" "")
1906 (match_operand:DI 1 "immediate_operand" ""))]
1907 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1908 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1909 [(set (match_dup 0) (match_dup 1))
1910 (set (match_dup 2) (match_dup 3))]
1911 "split_di (operands + 1, 1, operands + 2, operands + 3);
1912 operands[1] = gen_lowpart (DImode, operands[2]);
1913 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1918 [(set (match_operand:DI 0 "push_operand" "")
1919 (match_operand:DI 1 "immediate_operand" ""))]
1920 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1921 ? flow2_completed : reload_completed)
1922 && !symbolic_operand (operands[1], DImode)
1923 && !x86_64_immediate_operand (operands[1], DImode)"
1924 [(set (match_dup 0) (match_dup 1))
1925 (set (match_dup 2) (match_dup 3))]
1926 "split_di (operands + 1, 1, operands + 2, operands + 3);
1927 operands[1] = gen_lowpart (DImode, operands[2]);
1928 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1932 (define_insn "*pushdi2_prologue_rex64"
1933 [(set (match_operand:DI 0 "push_operand" "=<")
1934 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1935 (clobber (mem:BLK (scratch)))]
1938 [(set_attr "type" "push")
1939 (set_attr "mode" "DI")])
1941 (define_insn "*popdi1_epilogue_rex64"
1942 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1943 (mem:DI (reg:DI SP_REG)))
1944 (set (reg:DI SP_REG)
1945 (plus:DI (reg:DI SP_REG) (const_int 8)))
1946 (clobber (mem:BLK (scratch)))]
1949 [(set_attr "type" "pop")
1950 (set_attr "mode" "DI")])
1952 (define_insn "popdi1"
1953 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1954 (mem:DI (reg:DI SP_REG)))
1955 (set (reg:DI SP_REG)
1956 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1959 [(set_attr "type" "pop")
1960 (set_attr "mode" "DI")])
1962 (define_insn "*movdi_xor_rex64"
1963 [(set (match_operand:DI 0 "register_operand" "=r")
1964 (match_operand:DI 1 "const0_operand" "i"))
1965 (clobber (reg:CC FLAGS_REG))]
1966 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1967 && reload_completed"
1969 [(set_attr "type" "alu1")
1970 (set_attr "mode" "SI")
1971 (set_attr "length_immediate" "0")])
1973 (define_insn "*movdi_or_rex64"
1974 [(set (match_operand:DI 0 "register_operand" "=r")
1975 (match_operand:DI 1 "const_int_operand" "i"))
1976 (clobber (reg:CC FLAGS_REG))]
1977 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
1979 && operands[1] == constm1_rtx"
1981 operands[1] = constm1_rtx;
1982 return "or{q}\t{%1, %0|%0, %1}";
1984 [(set_attr "type" "alu1")
1985 (set_attr "mode" "DI")
1986 (set_attr "length_immediate" "1")])
1988 (define_insn "*movdi_2"
1989 [(set (match_operand:DI 0 "nonimmediate_operand"
1990 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
1991 (match_operand:DI 1 "general_operand"
1992 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
1993 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1998 movq\t{%1, %0|%0, %1}
1999 movq\t{%1, %0|%0, %1}
2001 movq\t{%1, %0|%0, %1}
2002 movdqa\t{%1, %0|%0, %1}
2003 movq\t{%1, %0|%0, %1}
2005 movlps\t{%1, %0|%0, %1}
2006 movaps\t{%1, %0|%0, %1}
2007 movlps\t{%1, %0|%0, %1}"
2008 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2009 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2012 [(set (match_operand:DI 0 "push_operand" "")
2013 (match_operand:DI 1 "general_operand" ""))]
2014 "!TARGET_64BIT && reload_completed
2015 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2017 "ix86_split_long_move (operands); DONE;")
2019 ;; %%% This multiword shite has got to go.
2021 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2022 (match_operand:DI 1 "general_operand" ""))]
2023 "!TARGET_64BIT && reload_completed
2024 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2025 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2027 "ix86_split_long_move (operands); DONE;")
2029 (define_insn "*movdi_1_rex64"
2030 [(set (match_operand:DI 0 "nonimmediate_operand"
2031 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2032 (match_operand:DI 1 "general_operand"
2033 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2034 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2036 switch (get_attr_type (insn))
2039 if (SSE_REG_P (operands[0]))
2040 return "movq2dq\t{%1, %0|%0, %1}";
2042 return "movdq2q\t{%1, %0|%0, %1}";
2045 if (get_attr_mode (insn) == MODE_TI)
2046 return "movdqa\t{%1, %0|%0, %1}";
2050 /* Moves from and into integer register is done using movd
2051 opcode with REX prefix. */
2052 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2053 return "movd\t{%1, %0|%0, %1}";
2054 return "movq\t{%1, %0|%0, %1}";
2058 return "pxor\t%0, %0";
2064 return "lea{q}\t{%a1, %0|%0, %a1}";
2067 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2068 if (get_attr_mode (insn) == MODE_SI)
2069 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2070 else if (which_alternative == 2)
2071 return "movabs{q}\t{%1, %0|%0, %1}";
2073 return "mov{q}\t{%1, %0|%0, %1}";
2077 (cond [(eq_attr "alternative" "5")
2078 (const_string "mmxadd")
2079 (eq_attr "alternative" "6,7,8,9,10")
2080 (const_string "mmxmov")
2081 (eq_attr "alternative" "11")
2082 (const_string "sselog1")
2083 (eq_attr "alternative" "12,13,14,15,16")
2084 (const_string "ssemov")
2085 (eq_attr "alternative" "17,18")
2086 (const_string "ssecvt")
2087 (eq_attr "alternative" "4")
2088 (const_string "multi")
2089 (match_operand:DI 1 "pic_32bit_operand" "")
2090 (const_string "lea")
2092 (const_string "imov")))
2093 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2094 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2095 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2097 ;; Stores and loads of ax to arbitrary constant address.
2098 ;; We fake an second form of instruction to force reload to load address
2099 ;; into register when rax is not available
2100 (define_insn "*movabsdi_1_rex64"
2101 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2102 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2103 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2105 movabs{q}\t{%1, %P0|%P0, %1}
2106 mov{q}\t{%1, %a0|%a0, %1}"
2107 [(set_attr "type" "imov")
2108 (set_attr "modrm" "0,*")
2109 (set_attr "length_address" "8,0")
2110 (set_attr "length_immediate" "0,*")
2111 (set_attr "memory" "store")
2112 (set_attr "mode" "DI")])
2114 (define_insn "*movabsdi_2_rex64"
2115 [(set (match_operand:DI 0 "register_operand" "=a,r")
2116 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2117 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2119 movabs{q}\t{%P1, %0|%0, %P1}
2120 mov{q}\t{%a1, %0|%0, %a1}"
2121 [(set_attr "type" "imov")
2122 (set_attr "modrm" "0,*")
2123 (set_attr "length_address" "8,0")
2124 (set_attr "length_immediate" "0")
2125 (set_attr "memory" "load")
2126 (set_attr "mode" "DI")])
2128 ;; Convert impossible stores of immediate to existing instructions.
2129 ;; First try to get scratch register and go through it. In case this
2130 ;; fails, move by 32bit parts.
2132 [(match_scratch:DI 2 "r")
2133 (set (match_operand:DI 0 "memory_operand" "")
2134 (match_operand:DI 1 "immediate_operand" ""))]
2135 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2136 && !x86_64_immediate_operand (operands[1], DImode)"
2137 [(set (match_dup 2) (match_dup 1))
2138 (set (match_dup 0) (match_dup 2))]
2141 ;; We need to define this as both peepholer and splitter for case
2142 ;; peephole2 pass is not run.
2143 ;; "&& 1" is needed to keep it from matching the previous pattern.
2145 [(set (match_operand:DI 0 "memory_operand" "")
2146 (match_operand:DI 1 "immediate_operand" ""))]
2147 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2148 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2149 [(set (match_dup 2) (match_dup 3))
2150 (set (match_dup 4) (match_dup 5))]
2151 "split_di (operands, 2, operands + 2, operands + 4);")
2154 [(set (match_operand:DI 0 "memory_operand" "")
2155 (match_operand:DI 1 "immediate_operand" ""))]
2156 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2157 ? flow2_completed : reload_completed)
2158 && !symbolic_operand (operands[1], DImode)
2159 && !x86_64_immediate_operand (operands[1], DImode)"
2160 [(set (match_dup 2) (match_dup 3))
2161 (set (match_dup 4) (match_dup 5))]
2162 "split_di (operands, 2, operands + 2, operands + 4);")
2164 (define_insn "*swapdi_rex64"
2165 [(set (match_operand:DI 0 "register_operand" "+r")
2166 (match_operand:DI 1 "register_operand" "+r"))
2171 [(set_attr "type" "imov")
2172 (set_attr "mode" "DI")
2173 (set_attr "pent_pair" "np")
2174 (set_attr "athlon_decode" "vector")
2175 (set_attr "amdfam10_decode" "double")])
2177 (define_expand "movti"
2178 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2179 (match_operand:TI 1 "nonimmediate_operand" ""))]
2180 "TARGET_SSE || TARGET_64BIT"
2183 ix86_expand_move (TImode, operands);
2184 else if (push_operand (operands[0], TImode))
2185 ix86_expand_push (TImode, operands[1]);
2187 ix86_expand_vector_move (TImode, operands);
2191 (define_insn "*movti_internal"
2192 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2193 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2194 "TARGET_SSE && !TARGET_64BIT
2195 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2197 switch (which_alternative)
2200 if (get_attr_mode (insn) == MODE_V4SF)
2201 return "xorps\t%0, %0";
2203 return "pxor\t%0, %0";
2206 if (get_attr_mode (insn) == MODE_V4SF)
2207 return "movaps\t{%1, %0|%0, %1}";
2209 return "movdqa\t{%1, %0|%0, %1}";
2214 [(set_attr "type" "sselog1,ssemov,ssemov")
2216 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2217 (ne (symbol_ref "optimize_size") (const_int 0)))
2218 (const_string "V4SF")
2219 (and (eq_attr "alternative" "2")
2220 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2222 (const_string "V4SF")]
2223 (const_string "TI")))])
2225 (define_insn "*movti_rex64"
2226 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2227 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2229 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2231 switch (which_alternative)
2237 if (get_attr_mode (insn) == MODE_V4SF)
2238 return "xorps\t%0, %0";
2240 return "pxor\t%0, %0";
2243 if (get_attr_mode (insn) == MODE_V4SF)
2244 return "movaps\t{%1, %0|%0, %1}";
2246 return "movdqa\t{%1, %0|%0, %1}";
2251 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2253 (cond [(eq_attr "alternative" "2,3")
2255 (ne (symbol_ref "optimize_size")
2257 (const_string "V4SF")
2258 (const_string "TI"))
2259 (eq_attr "alternative" "4")
2261 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2263 (ne (symbol_ref "optimize_size")
2265 (const_string "V4SF")
2266 (const_string "TI"))]
2267 (const_string "DI")))])
2270 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2271 (match_operand:TI 1 "general_operand" ""))]
2272 "reload_completed && !SSE_REG_P (operands[0])
2273 && !SSE_REG_P (operands[1])"
2275 "ix86_split_long_move (operands); DONE;")
2277 ;; This expands to what emit_move_complex would generate if we didn't
2278 ;; have a movti pattern. Having this avoids problems with reload on
2279 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2280 ;; to have around all the time.
2281 (define_expand "movcdi"
2282 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2283 (match_operand:CDI 1 "general_operand" ""))]
2286 if (push_operand (operands[0], CDImode))
2287 emit_move_complex_push (CDImode, operands[0], operands[1]);
2289 emit_move_complex_parts (operands[0], operands[1]);
2293 (define_expand "movsf"
2294 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2295 (match_operand:SF 1 "general_operand" ""))]
2297 "ix86_expand_move (SFmode, operands); DONE;")
2299 (define_insn "*pushsf"
2300 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2301 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2304 /* Anything else should be already split before reg-stack. */
2305 gcc_assert (which_alternative == 1);
2306 return "push{l}\t%1";
2308 [(set_attr "type" "multi,push,multi")
2309 (set_attr "unit" "i387,*,*")
2310 (set_attr "mode" "SF,SI,SF")])
2312 (define_insn "*pushsf_rex64"
2313 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2314 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2317 /* Anything else should be already split before reg-stack. */
2318 gcc_assert (which_alternative == 1);
2319 return "push{q}\t%q1";
2321 [(set_attr "type" "multi,push,multi")
2322 (set_attr "unit" "i387,*,*")
2323 (set_attr "mode" "SF,DI,SF")])
2326 [(set (match_operand:SF 0 "push_operand" "")
2327 (match_operand:SF 1 "memory_operand" ""))]
2329 && MEM_P (operands[1])
2330 && (operands[2] = find_constant_src (insn))"
2335 ;; %%% Kill this when call knows how to work this out.
2337 [(set (match_operand:SF 0 "push_operand" "")
2338 (match_operand:SF 1 "any_fp_register_operand" ""))]
2340 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2341 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2344 [(set (match_operand:SF 0 "push_operand" "")
2345 (match_operand:SF 1 "any_fp_register_operand" ""))]
2347 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2348 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2350 (define_insn "*movsf_1"
2351 [(set (match_operand:SF 0 "nonimmediate_operand"
2352 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2353 (match_operand:SF 1 "general_operand"
2354 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2355 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2356 && (reload_in_progress || reload_completed
2357 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2358 || (!TARGET_SSE_MATH && optimize_size
2359 && standard_80387_constant_p (operands[1]))
2360 || GET_CODE (operands[1]) != CONST_DOUBLE
2361 || memory_operand (operands[0], SFmode))"
2363 switch (which_alternative)
2367 return output_387_reg_move (insn, operands);
2370 return standard_80387_constant_opcode (operands[1]);
2374 return "mov{l}\t{%1, %0|%0, %1}";
2376 if (get_attr_mode (insn) == MODE_TI)
2377 return "pxor\t%0, %0";
2379 return "xorps\t%0, %0";
2381 if (get_attr_mode (insn) == MODE_V4SF)
2382 return "movaps\t{%1, %0|%0, %1}";
2384 return "movss\t{%1, %0|%0, %1}";
2386 return "movss\t{%1, %0|%0, %1}";
2389 case 12: case 13: case 14: case 15:
2390 return "movd\t{%1, %0|%0, %1}";
2393 return "movq\t{%1, %0|%0, %1}";
2399 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2401 (cond [(eq_attr "alternative" "3,4,9,10")
2403 (eq_attr "alternative" "5")
2405 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2407 (ne (symbol_ref "TARGET_SSE2")
2409 (eq (symbol_ref "optimize_size")
2412 (const_string "V4SF"))
2413 /* For architectures resolving dependencies on
2414 whole SSE registers use APS move to break dependency
2415 chains, otherwise use short move to avoid extra work.
2417 Do the same for architectures resolving dependencies on
2418 the parts. While in DF mode it is better to always handle
2419 just register parts, the SF mode is different due to lack
2420 of instructions to load just part of the register. It is
2421 better to maintain the whole registers in single format
2422 to avoid problems on using packed logical operations. */
2423 (eq_attr "alternative" "6")
2425 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2427 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2429 (const_string "V4SF")
2430 (const_string "SF"))
2431 (eq_attr "alternative" "11")
2432 (const_string "DI")]
2433 (const_string "SF")))])
2435 (define_insn "*swapsf"
2436 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2437 (match_operand:SF 1 "fp_register_operand" "+f"))
2440 "reload_completed || TARGET_80387"
2442 if (STACK_TOP_P (operands[0]))
2447 [(set_attr "type" "fxch")
2448 (set_attr "mode" "SF")])
2450 (define_expand "movdf"
2451 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2452 (match_operand:DF 1 "general_operand" ""))]
2454 "ix86_expand_move (DFmode, operands); DONE;")
2456 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2457 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2458 ;; On the average, pushdf using integers can be still shorter. Allow this
2459 ;; pattern for optimize_size too.
2461 (define_insn "*pushdf_nointeger"
2462 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2463 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2464 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2466 /* This insn should be already split before reg-stack. */
2469 [(set_attr "type" "multi")
2470 (set_attr "unit" "i387,*,*,*")
2471 (set_attr "mode" "DF,SI,SI,DF")])
2473 (define_insn "*pushdf_integer"
2474 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2475 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2476 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2478 /* This insn should be already split before reg-stack. */
2481 [(set_attr "type" "multi")
2482 (set_attr "unit" "i387,*,*")
2483 (set_attr "mode" "DF,SI,DF")])
2485 ;; %%% Kill this when call knows how to work this out.
2487 [(set (match_operand:DF 0 "push_operand" "")
2488 (match_operand:DF 1 "any_fp_register_operand" ""))]
2489 "!TARGET_64BIT && reload_completed"
2490 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2491 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2495 [(set (match_operand:DF 0 "push_operand" "")
2496 (match_operand:DF 1 "any_fp_register_operand" ""))]
2497 "TARGET_64BIT && reload_completed"
2498 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2499 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2503 [(set (match_operand:DF 0 "push_operand" "")
2504 (match_operand:DF 1 "general_operand" ""))]
2507 "ix86_split_long_move (operands); DONE;")
2509 ;; Moving is usually shorter when only FP registers are used. This separate
2510 ;; movdf pattern avoids the use of integer registers for FP operations
2511 ;; when optimizing for size.
2513 (define_insn "*movdf_nointeger"
2514 [(set (match_operand:DF 0 "nonimmediate_operand"
2515 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2516 (match_operand:DF 1 "general_operand"
2517 "fm,f,G,*roF,F*r,C ,Y2*x,mY2*x,Y2*x"))]
2518 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2519 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2520 && (reload_in_progress || reload_completed
2521 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2522 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2523 && standard_80387_constant_p (operands[1]))
2524 || GET_CODE (operands[1]) != CONST_DOUBLE
2525 || memory_operand (operands[0], DFmode))"
2527 switch (which_alternative)
2531 return output_387_reg_move (insn, operands);
2534 return standard_80387_constant_opcode (operands[1]);
2540 switch (get_attr_mode (insn))
2543 return "xorps\t%0, %0";
2545 return "xorpd\t%0, %0";
2547 return "pxor\t%0, %0";
2554 switch (get_attr_mode (insn))
2557 return "movaps\t{%1, %0|%0, %1}";
2559 return "movapd\t{%1, %0|%0, %1}";
2561 return "movdqa\t{%1, %0|%0, %1}";
2563 return "movq\t{%1, %0|%0, %1}";
2565 return "movsd\t{%1, %0|%0, %1}";
2567 return "movlpd\t{%1, %0|%0, %1}";
2569 return "movlps\t{%1, %0|%0, %1}";
2578 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2580 (cond [(eq_attr "alternative" "0,1,2")
2582 (eq_attr "alternative" "3,4")
2585 /* For SSE1, we have many fewer alternatives. */
2586 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2587 (cond [(eq_attr "alternative" "5,6")
2588 (const_string "V4SF")
2590 (const_string "V2SF"))
2592 /* xorps is one byte shorter. */
2593 (eq_attr "alternative" "5")
2594 (cond [(ne (symbol_ref "optimize_size")
2596 (const_string "V4SF")
2597 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2601 (const_string "V2DF"))
2603 /* For architectures resolving dependencies on
2604 whole SSE registers use APD move to break dependency
2605 chains, otherwise use short move to avoid extra work.
2607 movaps encodes one byte shorter. */
2608 (eq_attr "alternative" "6")
2610 [(ne (symbol_ref "optimize_size")
2612 (const_string "V4SF")
2613 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2615 (const_string "V2DF")
2617 (const_string "DF"))
2618 /* For architectures resolving dependencies on register
2619 parts we may avoid extra work to zero out upper part
2621 (eq_attr "alternative" "7")
2623 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2625 (const_string "V1DF")
2626 (const_string "DF"))
2628 (const_string "DF")))])
2630 (define_insn "*movdf_integer_rex64"
2631 [(set (match_operand:DF 0 "nonimmediate_operand"
2632 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2633 (match_operand:DF 1 "general_operand"
2634 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2635 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2636 && (reload_in_progress || reload_completed
2637 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2638 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2639 && standard_80387_constant_p (operands[1]))
2640 || GET_CODE (operands[1]) != CONST_DOUBLE
2641 || memory_operand (operands[0], DFmode))"
2643 switch (which_alternative)
2647 return output_387_reg_move (insn, operands);
2650 return standard_80387_constant_opcode (operands[1]);
2657 switch (get_attr_mode (insn))
2660 return "xorps\t%0, %0";
2662 return "xorpd\t%0, %0";
2664 return "pxor\t%0, %0";
2671 switch (get_attr_mode (insn))
2674 return "movaps\t{%1, %0|%0, %1}";
2676 return "movapd\t{%1, %0|%0, %1}";
2678 return "movdqa\t{%1, %0|%0, %1}";
2680 return "movq\t{%1, %0|%0, %1}";
2682 return "movsd\t{%1, %0|%0, %1}";
2684 return "movlpd\t{%1, %0|%0, %1}";
2686 return "movlps\t{%1, %0|%0, %1}";
2693 return "movd\t{%1, %0|%0, %1}";
2699 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2701 (cond [(eq_attr "alternative" "0,1,2")
2703 (eq_attr "alternative" "3,4,9,10")
2706 /* For SSE1, we have many fewer alternatives. */
2707 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2708 (cond [(eq_attr "alternative" "5,6")
2709 (const_string "V4SF")
2711 (const_string "V2SF"))
2713 /* xorps is one byte shorter. */
2714 (eq_attr "alternative" "5")
2715 (cond [(ne (symbol_ref "optimize_size")
2717 (const_string "V4SF")
2718 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2722 (const_string "V2DF"))
2724 /* For architectures resolving dependencies on
2725 whole SSE registers use APD move to break dependency
2726 chains, otherwise use short move to avoid extra work.
2728 movaps encodes one byte shorter. */
2729 (eq_attr "alternative" "6")
2731 [(ne (symbol_ref "optimize_size")
2733 (const_string "V4SF")
2734 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2736 (const_string "V2DF")
2738 (const_string "DF"))
2739 /* For architectures resolving dependencies on register
2740 parts we may avoid extra work to zero out upper part
2742 (eq_attr "alternative" "7")
2744 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2746 (const_string "V1DF")
2747 (const_string "DF"))
2749 (const_string "DF")))])
2751 (define_insn "*movdf_integer"
2752 [(set (match_operand:DF 0 "nonimmediate_operand"
2753 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2754 (match_operand:DF 1 "general_operand"
2755 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2756 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2757 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2758 && (reload_in_progress || reload_completed
2759 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2760 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2761 && standard_80387_constant_p (operands[1]))
2762 || GET_CODE (operands[1]) != CONST_DOUBLE
2763 || memory_operand (operands[0], DFmode))"
2765 switch (which_alternative)
2769 return output_387_reg_move (insn, operands);
2772 return standard_80387_constant_opcode (operands[1]);
2779 switch (get_attr_mode (insn))
2782 return "xorps\t%0, %0";
2784 return "xorpd\t%0, %0";
2786 return "pxor\t%0, %0";
2793 switch (get_attr_mode (insn))
2796 return "movaps\t{%1, %0|%0, %1}";
2798 return "movapd\t{%1, %0|%0, %1}";
2800 return "movdqa\t{%1, %0|%0, %1}";
2802 return "movq\t{%1, %0|%0, %1}";
2804 return "movsd\t{%1, %0|%0, %1}";
2806 return "movlpd\t{%1, %0|%0, %1}";
2808 return "movlps\t{%1, %0|%0, %1}";
2817 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2819 (cond [(eq_attr "alternative" "0,1,2")
2821 (eq_attr "alternative" "3,4")
2824 /* For SSE1, we have many fewer alternatives. */
2825 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2826 (cond [(eq_attr "alternative" "5,6")
2827 (const_string "V4SF")
2829 (const_string "V2SF"))
2831 /* xorps is one byte shorter. */
2832 (eq_attr "alternative" "5")
2833 (cond [(ne (symbol_ref "optimize_size")
2835 (const_string "V4SF")
2836 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2840 (const_string "V2DF"))
2842 /* For architectures resolving dependencies on
2843 whole SSE registers use APD move to break dependency
2844 chains, otherwise use short move to avoid extra work.
2846 movaps encodes one byte shorter. */
2847 (eq_attr "alternative" "6")
2849 [(ne (symbol_ref "optimize_size")
2851 (const_string "V4SF")
2852 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2854 (const_string "V2DF")
2856 (const_string "DF"))
2857 /* For architectures resolving dependencies on register
2858 parts we may avoid extra work to zero out upper part
2860 (eq_attr "alternative" "7")
2862 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2864 (const_string "V1DF")
2865 (const_string "DF"))
2867 (const_string "DF")))])
2870 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2871 (match_operand:DF 1 "general_operand" ""))]
2873 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2874 && ! (ANY_FP_REG_P (operands[0]) ||
2875 (GET_CODE (operands[0]) == SUBREG
2876 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2877 && ! (ANY_FP_REG_P (operands[1]) ||
2878 (GET_CODE (operands[1]) == SUBREG
2879 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2881 "ix86_split_long_move (operands); DONE;")
2883 (define_insn "*swapdf"
2884 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2885 (match_operand:DF 1 "fp_register_operand" "+f"))
2888 "reload_completed || TARGET_80387"
2890 if (STACK_TOP_P (operands[0]))
2895 [(set_attr "type" "fxch")
2896 (set_attr "mode" "DF")])
2898 (define_expand "movxf"
2899 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2900 (match_operand:XF 1 "general_operand" ""))]
2902 "ix86_expand_move (XFmode, operands); DONE;")
2904 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2905 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2906 ;; Pushing using integer instructions is longer except for constants
2907 ;; and direct memory references.
2908 ;; (assuming that any given constant is pushed only once, but this ought to be
2909 ;; handled elsewhere).
2911 (define_insn "*pushxf_nointeger"
2912 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2913 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2916 /* This insn should be already split before reg-stack. */
2919 [(set_attr "type" "multi")
2920 (set_attr "unit" "i387,*,*")
2921 (set_attr "mode" "XF,SI,SI")])
2923 (define_insn "*pushxf_integer"
2924 [(set (match_operand:XF 0 "push_operand" "=<,<")
2925 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2928 /* This insn should be already split before reg-stack. */
2931 [(set_attr "type" "multi")
2932 (set_attr "unit" "i387,*")
2933 (set_attr "mode" "XF,SI")])
2936 [(set (match_operand 0 "push_operand" "")
2937 (match_operand 1 "general_operand" ""))]
2939 && (GET_MODE (operands[0]) == XFmode
2940 || GET_MODE (operands[0]) == DFmode)
2941 && !ANY_FP_REG_P (operands[1])"
2943 "ix86_split_long_move (operands); DONE;")
2946 [(set (match_operand:XF 0 "push_operand" "")
2947 (match_operand:XF 1 "any_fp_register_operand" ""))]
2949 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2950 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2951 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2954 [(set (match_operand:XF 0 "push_operand" "")
2955 (match_operand:XF 1 "any_fp_register_operand" ""))]
2957 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2958 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2959 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2961 ;; Do not use integer registers when optimizing for size
2962 (define_insn "*movxf_nointeger"
2963 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2964 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2966 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2967 && (reload_in_progress || reload_completed
2968 || (optimize_size && standard_80387_constant_p (operands[1]))
2969 || GET_CODE (operands[1]) != CONST_DOUBLE
2970 || memory_operand (operands[0], XFmode))"
2972 switch (which_alternative)
2976 return output_387_reg_move (insn, operands);
2979 return standard_80387_constant_opcode (operands[1]);
2987 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2988 (set_attr "mode" "XF,XF,XF,SI,SI")])
2990 (define_insn "*movxf_integer"
2991 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2992 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2994 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2995 && (reload_in_progress || reload_completed
2996 || (optimize_size && standard_80387_constant_p (operands[1]))
2997 || GET_CODE (operands[1]) != CONST_DOUBLE
2998 || memory_operand (operands[0], XFmode))"
3000 switch (which_alternative)
3004 return output_387_reg_move (insn, operands);
3007 return standard_80387_constant_opcode (operands[1]);
3016 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3017 (set_attr "mode" "XF,XF,XF,SI,SI")])
3020 [(set (match_operand 0 "nonimmediate_operand" "")
3021 (match_operand 1 "general_operand" ""))]
3023 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3024 && GET_MODE (operands[0]) == XFmode
3025 && ! (ANY_FP_REG_P (operands[0]) ||
3026 (GET_CODE (operands[0]) == SUBREG
3027 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3028 && ! (ANY_FP_REG_P (operands[1]) ||
3029 (GET_CODE (operands[1]) == SUBREG
3030 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3032 "ix86_split_long_move (operands); DONE;")
3035 [(set (match_operand 0 "register_operand" "")
3036 (match_operand 1 "memory_operand" ""))]
3038 && MEM_P (operands[1])
3039 && (GET_MODE (operands[0]) == XFmode
3040 || GET_MODE (operands[0]) == SFmode
3041 || GET_MODE (operands[0]) == DFmode)
3042 && (operands[2] = find_constant_src (insn))"
3043 [(set (match_dup 0) (match_dup 2))]
3045 rtx c = operands[2];
3046 rtx r = operands[0];
3048 if (GET_CODE (r) == SUBREG)
3053 if (!standard_sse_constant_p (c))
3056 else if (FP_REG_P (r))
3058 if (!standard_80387_constant_p (c))
3061 else if (MMX_REG_P (r))
3066 [(set (match_operand 0 "register_operand" "")
3067 (float_extend (match_operand 1 "memory_operand" "")))]
3069 && MEM_P (operands[1])
3070 && (GET_MODE (operands[0]) == XFmode
3071 || GET_MODE (operands[0]) == SFmode
3072 || GET_MODE (operands[0]) == DFmode)
3073 && (operands[2] = find_constant_src (insn))"
3074 [(set (match_dup 0) (match_dup 2))]
3076 rtx c = operands[2];
3077 rtx r = operands[0];
3079 if (GET_CODE (r) == SUBREG)
3084 if (!standard_sse_constant_p (c))
3087 else if (FP_REG_P (r))
3089 if (!standard_80387_constant_p (c))
3092 else if (MMX_REG_P (r))
3096 (define_insn "swapxf"
3097 [(set (match_operand:XF 0 "register_operand" "+f")
3098 (match_operand:XF 1 "register_operand" "+f"))
3103 if (STACK_TOP_P (operands[0]))
3108 [(set_attr "type" "fxch")
3109 (set_attr "mode" "XF")])
3111 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3113 [(set (match_operand:X87MODEF 0 "register_operand" "")
3114 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3115 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3116 && (standard_80387_constant_p (operands[1]) == 8
3117 || standard_80387_constant_p (operands[1]) == 9)"
3118 [(set (match_dup 0)(match_dup 1))
3120 (neg:X87MODEF (match_dup 0)))]
3124 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3125 if (real_isnegzero (&r))
3126 operands[1] = CONST0_RTX (<MODE>mode);
3128 operands[1] = CONST1_RTX (<MODE>mode);
3131 (define_expand "movtf"
3132 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3133 (match_operand:TF 1 "nonimmediate_operand" ""))]
3136 ix86_expand_move (TFmode, operands);
3140 (define_insn "*movtf_internal"
3141 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3142 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3144 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3146 switch (which_alternative)
3152 if (get_attr_mode (insn) == MODE_V4SF)
3153 return "xorps\t%0, %0";
3155 return "pxor\t%0, %0";
3158 if (get_attr_mode (insn) == MODE_V4SF)
3159 return "movaps\t{%1, %0|%0, %1}";
3161 return "movdqa\t{%1, %0|%0, %1}";
3166 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3168 (cond [(eq_attr "alternative" "2,3")
3170 (ne (symbol_ref "optimize_size")
3172 (const_string "V4SF")
3173 (const_string "TI"))
3174 (eq_attr "alternative" "4")
3176 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3178 (ne (symbol_ref "optimize_size")
3180 (const_string "V4SF")
3181 (const_string "TI"))]
3182 (const_string "DI")))])
3185 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3186 (match_operand:TF 1 "general_operand" ""))]
3187 "reload_completed && !SSE_REG_P (operands[0])
3188 && !SSE_REG_P (operands[1])"
3190 "ix86_split_long_move (operands); DONE;")
3192 ;; Zero extension instructions
3194 (define_expand "zero_extendhisi2"
3195 [(set (match_operand:SI 0 "register_operand" "")
3196 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3199 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3201 operands[1] = force_reg (HImode, operands[1]);
3202 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3207 (define_insn "zero_extendhisi2_and"
3208 [(set (match_operand:SI 0 "register_operand" "=r")
3209 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3210 (clobber (reg:CC FLAGS_REG))]
3211 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3213 [(set_attr "type" "alu1")
3214 (set_attr "mode" "SI")])
3217 [(set (match_operand:SI 0 "register_operand" "")
3218 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3219 (clobber (reg:CC FLAGS_REG))]
3220 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3221 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3222 (clobber (reg:CC FLAGS_REG))])]
3225 (define_insn "*zero_extendhisi2_movzwl"
3226 [(set (match_operand:SI 0 "register_operand" "=r")
3227 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3228 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3229 "movz{wl|x}\t{%1, %0|%0, %1}"
3230 [(set_attr "type" "imovx")
3231 (set_attr "mode" "SI")])
3233 (define_expand "zero_extendqihi2"
3235 [(set (match_operand:HI 0 "register_operand" "")
3236 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3237 (clobber (reg:CC FLAGS_REG))])]
3241 (define_insn "*zero_extendqihi2_and"
3242 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3243 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3244 (clobber (reg:CC FLAGS_REG))]
3245 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3247 [(set_attr "type" "alu1")
3248 (set_attr "mode" "HI")])
3250 (define_insn "*zero_extendqihi2_movzbw_and"
3251 [(set (match_operand:HI 0 "register_operand" "=r,r")
3252 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3253 (clobber (reg:CC FLAGS_REG))]
3254 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3256 [(set_attr "type" "imovx,alu1")
3257 (set_attr "mode" "HI")])
3259 ; zero extend to SImode here to avoid partial register stalls
3260 (define_insn "*zero_extendqihi2_movzbl"
3261 [(set (match_operand:HI 0 "register_operand" "=r")
3262 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3263 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3264 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3265 [(set_attr "type" "imovx")
3266 (set_attr "mode" "SI")])
3268 ;; For the movzbw case strip only the clobber
3270 [(set (match_operand:HI 0 "register_operand" "")
3271 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3272 (clobber (reg:CC FLAGS_REG))]
3274 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3275 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3276 [(set (match_operand:HI 0 "register_operand" "")
3277 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3279 ;; When source and destination does not overlap, clear destination
3280 ;; first and then do the movb
3282 [(set (match_operand:HI 0 "register_operand" "")
3283 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3284 (clobber (reg:CC FLAGS_REG))]
3286 && ANY_QI_REG_P (operands[0])
3287 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3288 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3289 [(set (match_dup 0) (const_int 0))
3290 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3291 "operands[2] = gen_lowpart (QImode, operands[0]);")
3293 ;; Rest is handled by single and.
3295 [(set (match_operand:HI 0 "register_operand" "")
3296 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3297 (clobber (reg:CC FLAGS_REG))]
3299 && true_regnum (operands[0]) == true_regnum (operands[1])"
3300 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3301 (clobber (reg:CC FLAGS_REG))])]
3304 (define_expand "zero_extendqisi2"
3306 [(set (match_operand:SI 0 "register_operand" "")
3307 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3308 (clobber (reg:CC FLAGS_REG))])]
3312 (define_insn "*zero_extendqisi2_and"
3313 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3314 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3315 (clobber (reg:CC FLAGS_REG))]
3316 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3318 [(set_attr "type" "alu1")
3319 (set_attr "mode" "SI")])
3321 (define_insn "*zero_extendqisi2_movzbw_and"
3322 [(set (match_operand:SI 0 "register_operand" "=r,r")
3323 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3324 (clobber (reg:CC FLAGS_REG))]
3325 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3327 [(set_attr "type" "imovx,alu1")
3328 (set_attr "mode" "SI")])
3330 (define_insn "*zero_extendqisi2_movzbw"
3331 [(set (match_operand:SI 0 "register_operand" "=r")
3332 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3333 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3334 "movz{bl|x}\t{%1, %0|%0, %1}"
3335 [(set_attr "type" "imovx")
3336 (set_attr "mode" "SI")])
3338 ;; For the movzbl case strip only the clobber
3340 [(set (match_operand:SI 0 "register_operand" "")
3341 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3342 (clobber (reg:CC FLAGS_REG))]
3344 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3345 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3347 (zero_extend:SI (match_dup 1)))])
3349 ;; When source and destination does not overlap, clear destination
3350 ;; first and then do the movb
3352 [(set (match_operand:SI 0 "register_operand" "")
3353 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3354 (clobber (reg:CC FLAGS_REG))]
3356 && ANY_QI_REG_P (operands[0])
3357 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3358 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3359 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3360 [(set (match_dup 0) (const_int 0))
3361 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3362 "operands[2] = gen_lowpart (QImode, operands[0]);")
3364 ;; Rest is handled by single and.
3366 [(set (match_operand:SI 0 "register_operand" "")
3367 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3368 (clobber (reg:CC FLAGS_REG))]
3370 && true_regnum (operands[0]) == true_regnum (operands[1])"
3371 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3372 (clobber (reg:CC FLAGS_REG))])]
3375 ;; %%% Kill me once multi-word ops are sane.
3376 (define_expand "zero_extendsidi2"
3377 [(set (match_operand:DI 0 "register_operand" "=r")
3378 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3383 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3388 (define_insn "zero_extendsidi2_32"
3389 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3391 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3392 (clobber (reg:CC FLAGS_REG))]
3398 movd\t{%1, %0|%0, %1}
3399 movd\t{%1, %0|%0, %1}
3400 movd\t{%1, %0|%0, %1}
3401 movd\t{%1, %0|%0, %1}"
3402 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3403 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3405 (define_insn "zero_extendsidi2_rex64"
3406 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3408 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3411 mov\t{%k1, %k0|%k0, %k1}
3413 movd\t{%1, %0|%0, %1}
3414 movd\t{%1, %0|%0, %1}
3415 movd\t{%1, %0|%0, %1}
3416 movd\t{%1, %0|%0, %1}"
3417 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3418 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3421 [(set (match_operand:DI 0 "memory_operand" "")
3422 (zero_extend:DI (match_dup 0)))]
3424 [(set (match_dup 4) (const_int 0))]
3425 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3428 [(set (match_operand:DI 0 "register_operand" "")
3429 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3430 (clobber (reg:CC FLAGS_REG))]
3431 "!TARGET_64BIT && reload_completed
3432 && true_regnum (operands[0]) == true_regnum (operands[1])"
3433 [(set (match_dup 4) (const_int 0))]
3434 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3437 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3438 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3439 (clobber (reg:CC FLAGS_REG))]
3440 "!TARGET_64BIT && reload_completed
3441 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3442 [(set (match_dup 3) (match_dup 1))
3443 (set (match_dup 4) (const_int 0))]
3444 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3446 (define_insn "zero_extendhidi2"
3447 [(set (match_operand:DI 0 "register_operand" "=r")
3448 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3450 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3451 [(set_attr "type" "imovx")
3452 (set_attr "mode" "DI")])
3454 (define_insn "zero_extendqidi2"
3455 [(set (match_operand:DI 0 "register_operand" "=r")
3456 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3458 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3459 [(set_attr "type" "imovx")
3460 (set_attr "mode" "DI")])
3462 ;; Sign extension instructions
3464 (define_expand "extendsidi2"
3465 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3466 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3467 (clobber (reg:CC FLAGS_REG))
3468 (clobber (match_scratch:SI 2 ""))])]
3473 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3478 (define_insn "*extendsidi2_1"
3479 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3480 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3481 (clobber (reg:CC FLAGS_REG))
3482 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3486 (define_insn "extendsidi2_rex64"
3487 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3488 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3492 movs{lq|x}\t{%1,%0|%0, %1}"
3493 [(set_attr "type" "imovx")
3494 (set_attr "mode" "DI")
3495 (set_attr "prefix_0f" "0")
3496 (set_attr "modrm" "0,1")])
3498 (define_insn "extendhidi2"
3499 [(set (match_operand:DI 0 "register_operand" "=r")
3500 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3502 "movs{wq|x}\t{%1,%0|%0, %1}"
3503 [(set_attr "type" "imovx")
3504 (set_attr "mode" "DI")])
3506 (define_insn "extendqidi2"
3507 [(set (match_operand:DI 0 "register_operand" "=r")
3508 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3510 "movs{bq|x}\t{%1,%0|%0, %1}"
3511 [(set_attr "type" "imovx")
3512 (set_attr "mode" "DI")])
3514 ;; Extend to memory case when source register does die.
3516 [(set (match_operand:DI 0 "memory_operand" "")
3517 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3518 (clobber (reg:CC FLAGS_REG))
3519 (clobber (match_operand:SI 2 "register_operand" ""))]
3521 && dead_or_set_p (insn, operands[1])
3522 && !reg_mentioned_p (operands[1], operands[0]))"
3523 [(set (match_dup 3) (match_dup 1))
3524 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3525 (clobber (reg:CC FLAGS_REG))])
3526 (set (match_dup 4) (match_dup 1))]
3527 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3529 ;; Extend to memory case when source register does not die.
3531 [(set (match_operand:DI 0 "memory_operand" "")
3532 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3533 (clobber (reg:CC FLAGS_REG))
3534 (clobber (match_operand:SI 2 "register_operand" ""))]
3538 split_di (&operands[0], 1, &operands[3], &operands[4]);
3540 emit_move_insn (operands[3], operands[1]);
3542 /* Generate a cltd if possible and doing so it profitable. */
3543 if (true_regnum (operands[1]) == 0
3544 && true_regnum (operands[2]) == 1
3545 && (optimize_size || TARGET_USE_CLTD))
3547 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3551 emit_move_insn (operands[2], operands[1]);
3552 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3554 emit_move_insn (operands[4], operands[2]);
3558 ;; Extend to register case. Optimize case where source and destination
3559 ;; registers match and cases where we can use cltd.
3561 [(set (match_operand:DI 0 "register_operand" "")
3562 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3563 (clobber (reg:CC FLAGS_REG))
3564 (clobber (match_scratch:SI 2 ""))]
3568 split_di (&operands[0], 1, &operands[3], &operands[4]);
3570 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3571 emit_move_insn (operands[3], operands[1]);
3573 /* Generate a cltd if possible and doing so it profitable. */
3574 if (true_regnum (operands[3]) == 0
3575 && (optimize_size || TARGET_USE_CLTD))
3577 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3581 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3582 emit_move_insn (operands[4], operands[1]);
3584 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3588 (define_insn "extendhisi2"
3589 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3590 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3593 switch (get_attr_prefix_0f (insn))
3596 return "{cwtl|cwde}";
3598 return "movs{wl|x}\t{%1,%0|%0, %1}";
3601 [(set_attr "type" "imovx")
3602 (set_attr "mode" "SI")
3603 (set (attr "prefix_0f")
3604 ;; movsx is short decodable while cwtl is vector decoded.
3605 (if_then_else (and (eq_attr "cpu" "!k6")
3606 (eq_attr "alternative" "0"))
3608 (const_string "1")))
3610 (if_then_else (eq_attr "prefix_0f" "0")
3612 (const_string "1")))])
3614 (define_insn "*extendhisi2_zext"
3615 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3617 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3620 switch (get_attr_prefix_0f (insn))
3623 return "{cwtl|cwde}";
3625 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3628 [(set_attr "type" "imovx")
3629 (set_attr "mode" "SI")
3630 (set (attr "prefix_0f")
3631 ;; movsx is short decodable while cwtl is vector decoded.
3632 (if_then_else (and (eq_attr "cpu" "!k6")
3633 (eq_attr "alternative" "0"))
3635 (const_string "1")))
3637 (if_then_else (eq_attr "prefix_0f" "0")
3639 (const_string "1")))])
3641 (define_insn "extendqihi2"
3642 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3643 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3646 switch (get_attr_prefix_0f (insn))
3649 return "{cbtw|cbw}";
3651 return "movs{bw|x}\t{%1,%0|%0, %1}";
3654 [(set_attr "type" "imovx")
3655 (set_attr "mode" "HI")
3656 (set (attr "prefix_0f")
3657 ;; movsx is short decodable while cwtl is vector decoded.
3658 (if_then_else (and (eq_attr "cpu" "!k6")
3659 (eq_attr "alternative" "0"))
3661 (const_string "1")))
3663 (if_then_else (eq_attr "prefix_0f" "0")
3665 (const_string "1")))])
3667 (define_insn "extendqisi2"
3668 [(set (match_operand:SI 0 "register_operand" "=r")
3669 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3671 "movs{bl|x}\t{%1,%0|%0, %1}"
3672 [(set_attr "type" "imovx")
3673 (set_attr "mode" "SI")])
3675 (define_insn "*extendqisi2_zext"
3676 [(set (match_operand:DI 0 "register_operand" "=r")
3678 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3680 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3681 [(set_attr "type" "imovx")
3682 (set_attr "mode" "SI")])
3684 ;; Conversions between float and double.
3686 ;; These are all no-ops in the model used for the 80387. So just
3689 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3690 (define_insn "*dummy_extendsfdf2"
3691 [(set (match_operand:DF 0 "push_operand" "=<")
3692 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3697 [(set (match_operand:DF 0 "push_operand" "")
3698 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3700 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3701 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3704 [(set (match_operand:DF 0 "push_operand" "")
3705 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3707 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3708 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3710 (define_insn "*dummy_extendsfxf2"
3711 [(set (match_operand:XF 0 "push_operand" "=<")
3712 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3717 [(set (match_operand:XF 0 "push_operand" "")
3718 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3720 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3721 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3722 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3725 [(set (match_operand:XF 0 "push_operand" "")
3726 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3728 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3729 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3730 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3733 [(set (match_operand:XF 0 "push_operand" "")
3734 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3736 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3737 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3738 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3741 [(set (match_operand:XF 0 "push_operand" "")
3742 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3744 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3745 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3746 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3748 (define_expand "extendsfdf2"
3749 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3750 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3751 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3753 /* ??? Needed for compress_float_constant since all fp constants
3754 are LEGITIMATE_CONSTANT_P. */
3755 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3757 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3758 && standard_80387_constant_p (operands[1]) > 0)
3760 operands[1] = simplify_const_unary_operation
3761 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3762 emit_move_insn_1 (operands[0], operands[1]);
3765 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3769 (define_insn "*extendsfdf2_mixed"
3770 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3772 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3773 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3775 switch (which_alternative)
3779 return output_387_reg_move (insn, operands);
3782 return "cvtss2sd\t{%1, %0|%0, %1}";
3788 [(set_attr "type" "fmov,fmov,ssecvt")
3789 (set_attr "mode" "SF,XF,DF")])
3791 (define_insn "*extendsfdf2_sse"
3792 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3793 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3794 "TARGET_SSE2 && TARGET_SSE_MATH"
3795 "cvtss2sd\t{%1, %0|%0, %1}"
3796 [(set_attr "type" "ssecvt")
3797 (set_attr "mode" "DF")])
3799 (define_insn "*extendsfdf2_i387"
3800 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3801 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3803 "* return output_387_reg_move (insn, operands);"
3804 [(set_attr "type" "fmov")
3805 (set_attr "mode" "SF,XF")])
3807 (define_expand "extend<mode>xf2"
3808 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3809 (float_extend:XF (match_operand:X87MODEF12 1 "general_operand" "")))]
3812 /* ??? Needed for compress_float_constant since all fp constants
3813 are LEGITIMATE_CONSTANT_P. */
3814 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3816 if (standard_80387_constant_p (operands[1]) > 0)
3818 operands[1] = simplify_const_unary_operation
3819 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3820 emit_move_insn_1 (operands[0], operands[1]);
3823 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3827 (define_insn "*extend<mode>xf2_i387"
3828 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3830 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,f")))]
3832 "* return output_387_reg_move (insn, operands);"
3833 [(set_attr "type" "fmov")
3834 (set_attr "mode" "<MODE>,XF")])
3836 ;; %%% This seems bad bad news.
3837 ;; This cannot output into an f-reg because there is no way to be sure
3838 ;; of truncating in that case. Otherwise this is just like a simple move
3839 ;; insn. So we pretend we can output to a reg in order to get better
3840 ;; register preferencing, but we really use a stack slot.
3842 ;; Conversion from DFmode to SFmode.
3844 (define_expand "truncdfsf2"
3845 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3847 (match_operand:DF 1 "nonimmediate_operand" "")))]
3848 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3850 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3852 else if (flag_unsafe_math_optimizations)
3856 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3857 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3862 (define_expand "truncdfsf2_with_temp"
3863 [(parallel [(set (match_operand:SF 0 "" "")
3864 (float_truncate:SF (match_operand:DF 1 "" "")))
3865 (clobber (match_operand:SF 2 "" ""))])]
3868 (define_insn "*truncdfsf_fast_mixed"
3869 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
3871 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3872 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3874 switch (which_alternative)
3878 return output_387_reg_move (insn, operands);
3880 return "cvtsd2ss\t{%1, %0|%0, %1}";
3885 [(set_attr "type" "fmov,fmov,ssecvt")
3886 (set_attr "mode" "SF")])
3888 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3889 ;; because nothing we do here is unsafe.
3890 (define_insn "*truncdfsf_fast_sse"
3891 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3893 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3894 "TARGET_SSE2 && TARGET_SSE_MATH"
3895 "cvtsd2ss\t{%1, %0|%0, %1}"
3896 [(set_attr "type" "ssecvt")
3897 (set_attr "mode" "SF")])
3899 (define_insn "*truncdfsf_fast_i387"
3900 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3902 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3903 "TARGET_80387 && flag_unsafe_math_optimizations"
3904 "* return output_387_reg_move (insn, operands);"
3905 [(set_attr "type" "fmov")
3906 (set_attr "mode" "SF")])
3908 (define_insn "*truncdfsf_mixed"
3909 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
3911 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
3912 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3913 "TARGET_MIX_SSE_I387"
3915 switch (which_alternative)
3918 return output_387_reg_move (insn, operands);
3923 return "cvtsd2ss\t{%1, %0|%0, %1}";
3928 [(set_attr "type" "fmov,multi,ssecvt")
3929 (set_attr "unit" "*,i387,*")
3930 (set_attr "mode" "SF")])
3932 (define_insn "*truncdfsf_i387"
3933 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3935 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3936 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3939 switch (which_alternative)
3942 return output_387_reg_move (insn, operands);
3950 [(set_attr "type" "fmov,multi")
3951 (set_attr "unit" "*,i387")
3952 (set_attr "mode" "SF")])
3954 (define_insn "*truncdfsf2_i387_1"
3955 [(set (match_operand:SF 0 "memory_operand" "=m")
3957 (match_operand:DF 1 "register_operand" "f")))]
3959 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3960 && !TARGET_MIX_SSE_I387"
3961 "* return output_387_reg_move (insn, operands);"
3962 [(set_attr "type" "fmov")
3963 (set_attr "mode" "SF")])
3966 [(set (match_operand:SF 0 "register_operand" "")
3968 (match_operand:DF 1 "fp_register_operand" "")))
3969 (clobber (match_operand 2 "" ""))]
3971 [(set (match_dup 2) (match_dup 1))
3972 (set (match_dup 0) (match_dup 2))]
3974 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3977 ;; Conversion from XFmode to {SF,DF}mode
3979 (define_expand "truncxf<mode>2"
3980 [(parallel [(set (match_operand:X87MODEF12 0 "nonimmediate_operand" "")
3981 (float_truncate:X87MODEF12
3982 (match_operand:XF 1 "register_operand" "")))
3983 (clobber (match_dup 2))])]
3986 if (flag_unsafe_math_optimizations)
3988 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
3989 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
3990 if (reg != operands[0])
3991 emit_move_insn (operands[0], reg);
3995 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
3998 (define_insn "*truncxfsf2_mixed"
3999 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4001 (match_operand:XF 1 "register_operand" "f,f")))
4002 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4005 gcc_assert (!which_alternative);
4006 return output_387_reg_move (insn, operands);
4008 [(set_attr "type" "fmov,multi")
4009 (set_attr "unit" "*,i387")
4010 (set_attr "mode" "SF")])
4012 (define_insn "*truncxfdf2_mixed"
4013 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4015 (match_operand:XF 1 "register_operand" "f,f")))
4016 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4019 gcc_assert (!which_alternative);
4020 return output_387_reg_move (insn, operands);
4022 [(set_attr "type" "fmov,multi")
4023 (set_attr "unit" "*,i387")
4024 (set_attr "mode" "DF")])
4026 (define_insn "truncxf<mode>2_i387_noop"
4027 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
4028 (float_truncate:X87MODEF12
4029 (match_operand:XF 1 "register_operand" "f")))]
4030 "TARGET_80387 && flag_unsafe_math_optimizations"
4031 "* return output_387_reg_move (insn, operands);"
4032 [(set_attr "type" "fmov")
4033 (set_attr "mode" "<MODE>")])
4035 (define_insn "*truncxf<mode>2_i387"
4036 [(set (match_operand:X87MODEF12 0 "memory_operand" "=m")
4037 (float_truncate:X87MODEF12
4038 (match_operand:XF 1 "register_operand" "f")))]
4040 "* return output_387_reg_move (insn, operands);"
4041 [(set_attr "type" "fmov")
4042 (set_attr "mode" "<MODE>")])
4045 [(set (match_operand:X87MODEF12 0 "register_operand" "")
4046 (float_truncate:X87MODEF12
4047 (match_operand:XF 1 "register_operand" "")))
4048 (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4049 "TARGET_80387 && reload_completed"
4050 [(set (match_dup 2) (float_truncate:X87MODEF12 (match_dup 1)))
4051 (set (match_dup 0) (match_dup 2))]
4055 [(set (match_operand:X87MODEF12 0 "memory_operand" "")
4056 (float_truncate:X87MODEF12
4057 (match_operand:XF 1 "register_operand" "")))
4058 (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4060 [(set (match_dup 0) (float_truncate:X87MODEF12 (match_dup 1)))]
4063 ;; Signed conversion to DImode.
4065 (define_expand "fix_truncxfdi2"
4066 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4067 (fix:DI (match_operand:XF 1 "register_operand" "")))
4068 (clobber (reg:CC FLAGS_REG))])]
4073 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4078 (define_expand "fix_trunc<mode>di2"
4079 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4080 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4081 (clobber (reg:CC FLAGS_REG))])]
4082 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4085 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4087 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4090 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4092 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4093 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4094 if (out != operands[0])
4095 emit_move_insn (operands[0], out);
4100 ;; Signed conversion to SImode.
4102 (define_expand "fix_truncxfsi2"
4103 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4104 (fix:SI (match_operand:XF 1 "register_operand" "")))
4105 (clobber (reg:CC FLAGS_REG))])]
4110 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4115 (define_expand "fix_trunc<mode>si2"
4116 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4117 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4118 (clobber (reg:CC FLAGS_REG))])]
4119 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4122 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4124 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4127 if (SSE_FLOAT_MODE_P (<MODE>mode))
4129 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4130 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4131 if (out != operands[0])
4132 emit_move_insn (operands[0], out);
4137 ;; Signed conversion to HImode.
4139 (define_expand "fix_trunc<mode>hi2"
4140 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4141 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4142 (clobber (reg:CC FLAGS_REG))])]
4144 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4148 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4153 ;; Unsigned conversion to SImode.
4155 (define_expand "fixuns_trunc<mode>si2"
4157 [(set (match_operand:SI 0 "register_operand" "")
4159 (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4161 (clobber (match_scratch:<ssevecmode> 3 ""))
4162 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4163 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4165 enum machine_mode mode = <MODE>mode;
4166 enum machine_mode vecmode = <ssevecmode>mode;
4167 REAL_VALUE_TYPE TWO31r;
4170 real_ldexp (&TWO31r, &dconst1, 31);
4171 two31 = const_double_from_real_value (TWO31r, mode);
4172 two31 = ix86_build_const_vector (mode, true, two31);
4173 operands[2] = force_reg (vecmode, two31);
4176 (define_insn_and_split "*fixuns_trunc<mode>_1"
4177 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4179 (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4180 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4181 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4182 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4183 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4185 "&& reload_completed"
4188 ix86_split_convert_uns_si_sse (operands);
4192 ;; Unsigned conversion to HImode.
4193 ;; Without these patterns, we'll try the unsigned SI conversion which
4194 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4196 (define_expand "fixuns_trunc<mode>hi2"
4198 (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4199 (set (match_operand:HI 0 "nonimmediate_operand" "")
4200 (subreg:HI (match_dup 2) 0))]
4201 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4202 "operands[2] = gen_reg_rtx (SImode);")
4204 ;; When SSE is available, it is always faster to use it!
4205 (define_insn "fix_trunc<mode>di_sse"
4206 [(set (match_operand:DI 0 "register_operand" "=r,r")
4207 (fix:DI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4208 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4209 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4210 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4211 [(set_attr "type" "sseicvt")
4212 (set_attr "mode" "<MODE>")
4213 (set_attr "athlon_decode" "double,vector")
4214 (set_attr "amdfam10_decode" "double,double")])
4216 (define_insn "fix_trunc<mode>si_sse"
4217 [(set (match_operand:SI 0 "register_operand" "=r,r")
4218 (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4219 "SSE_FLOAT_MODE_P (<MODE>mode)
4220 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4221 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4222 [(set_attr "type" "sseicvt")
4223 (set_attr "mode" "<MODE>")
4224 (set_attr "athlon_decode" "double,vector")
4225 (set_attr "amdfam10_decode" "double,double")])
4227 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4229 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4230 (match_operand:SSEMODEF 1 "memory_operand" ""))
4231 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4232 (fix:SSEMODEI24 (match_dup 0)))]
4233 "TARGET_SHORTEN_X87_SSE
4234 && peep2_reg_dead_p (2, operands[0])"
4235 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4238 ;; Avoid vector decoded forms of the instruction.
4240 [(match_scratch:DF 2 "Y2")
4241 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4242 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4243 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4244 [(set (match_dup 2) (match_dup 1))
4245 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4249 [(match_scratch:SF 2 "x")
4250 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4251 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4252 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4253 [(set (match_dup 2) (match_dup 1))
4254 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4257 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4258 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4259 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4260 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4262 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4263 && (TARGET_64BIT || <MODE>mode != DImode))
4265 && !(reload_completed || reload_in_progress)"
4270 if (memory_operand (operands[0], VOIDmode))
4271 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4274 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4275 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4281 [(set_attr "type" "fisttp")
4282 (set_attr "mode" "<MODE>")])
4284 (define_insn "fix_trunc<mode>_i387_fisttp"
4285 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4286 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4287 (clobber (match_scratch:XF 2 "=&1f"))]
4288 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4290 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4291 && (TARGET_64BIT || <MODE>mode != DImode))
4292 && TARGET_SSE_MATH)"
4293 "* return output_fix_trunc (insn, operands, 1);"
4294 [(set_attr "type" "fisttp")
4295 (set_attr "mode" "<MODE>")])
4297 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4298 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4299 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4300 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4301 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4302 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4304 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4305 && (TARGET_64BIT || <MODE>mode != DImode))
4306 && TARGET_SSE_MATH)"
4308 [(set_attr "type" "fisttp")
4309 (set_attr "mode" "<MODE>")])
4312 [(set (match_operand:X87MODEI 0 "register_operand" "")
4313 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4314 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4315 (clobber (match_scratch 3 ""))]
4317 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4318 (clobber (match_dup 3))])
4319 (set (match_dup 0) (match_dup 2))]
4323 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4324 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4325 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4326 (clobber (match_scratch 3 ""))]
4328 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4329 (clobber (match_dup 3))])]
4332 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4333 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4334 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4335 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4336 ;; function in i386.c.
4337 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4338 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4339 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4340 (clobber (reg:CC FLAGS_REG))]
4341 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4343 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4344 && (TARGET_64BIT || <MODE>mode != DImode))
4345 && !(reload_completed || reload_in_progress)"
4350 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4352 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4353 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4354 if (memory_operand (operands[0], VOIDmode))
4355 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4356 operands[2], operands[3]));
4359 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4360 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4361 operands[2], operands[3],
4366 [(set_attr "type" "fistp")
4367 (set_attr "i387_cw" "trunc")
4368 (set_attr "mode" "<MODE>")])
4370 (define_insn "fix_truncdi_i387"
4371 [(set (match_operand:DI 0 "memory_operand" "=m")
4372 (fix:DI (match_operand 1 "register_operand" "f")))
4373 (use (match_operand:HI 2 "memory_operand" "m"))
4374 (use (match_operand:HI 3 "memory_operand" "m"))
4375 (clobber (match_scratch:XF 4 "=&1f"))]
4376 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4378 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4379 "* return output_fix_trunc (insn, operands, 0);"
4380 [(set_attr "type" "fistp")
4381 (set_attr "i387_cw" "trunc")
4382 (set_attr "mode" "DI")])
4384 (define_insn "fix_truncdi_i387_with_temp"
4385 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4386 (fix:DI (match_operand 1 "register_operand" "f,f")))
4387 (use (match_operand:HI 2 "memory_operand" "m,m"))
4388 (use (match_operand:HI 3 "memory_operand" "m,m"))
4389 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4390 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4391 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4393 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4395 [(set_attr "type" "fistp")
4396 (set_attr "i387_cw" "trunc")
4397 (set_attr "mode" "DI")])
4400 [(set (match_operand:DI 0 "register_operand" "")
4401 (fix:DI (match_operand 1 "register_operand" "")))
4402 (use (match_operand:HI 2 "memory_operand" ""))
4403 (use (match_operand:HI 3 "memory_operand" ""))
4404 (clobber (match_operand:DI 4 "memory_operand" ""))
4405 (clobber (match_scratch 5 ""))]
4407 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4410 (clobber (match_dup 5))])
4411 (set (match_dup 0) (match_dup 4))]
4415 [(set (match_operand:DI 0 "memory_operand" "")
4416 (fix:DI (match_operand 1 "register_operand" "")))
4417 (use (match_operand:HI 2 "memory_operand" ""))
4418 (use (match_operand:HI 3 "memory_operand" ""))
4419 (clobber (match_operand:DI 4 "memory_operand" ""))
4420 (clobber (match_scratch 5 ""))]
4422 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4425 (clobber (match_dup 5))])]
4428 (define_insn "fix_trunc<mode>_i387"
4429 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4430 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4431 (use (match_operand:HI 2 "memory_operand" "m"))
4432 (use (match_operand:HI 3 "memory_operand" "m"))]
4433 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4435 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4436 "* return output_fix_trunc (insn, operands, 0);"
4437 [(set_attr "type" "fistp")
4438 (set_attr "i387_cw" "trunc")
4439 (set_attr "mode" "<MODE>")])
4441 (define_insn "fix_trunc<mode>_i387_with_temp"
4442 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4443 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4444 (use (match_operand:HI 2 "memory_operand" "m,m"))
4445 (use (match_operand:HI 3 "memory_operand" "m,m"))
4446 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4447 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4449 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4451 [(set_attr "type" "fistp")
4452 (set_attr "i387_cw" "trunc")
4453 (set_attr "mode" "<MODE>")])
4456 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4457 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4458 (use (match_operand:HI 2 "memory_operand" ""))
4459 (use (match_operand:HI 3 "memory_operand" ""))
4460 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4462 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4464 (use (match_dup 3))])
4465 (set (match_dup 0) (match_dup 4))]
4469 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4470 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4471 (use (match_operand:HI 2 "memory_operand" ""))
4472 (use (match_operand:HI 3 "memory_operand" ""))
4473 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4475 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4477 (use (match_dup 3))])]
4480 (define_insn "x86_fnstcw_1"
4481 [(set (match_operand:HI 0 "memory_operand" "=m")
4482 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4485 [(set_attr "length" "2")
4486 (set_attr "mode" "HI")
4487 (set_attr "unit" "i387")])
4489 (define_insn "x86_fldcw_1"
4490 [(set (reg:HI FPCR_REG)
4491 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4494 [(set_attr "length" "2")
4495 (set_attr "mode" "HI")
4496 (set_attr "unit" "i387")
4497 (set_attr "athlon_decode" "vector")
4498 (set_attr "amdfam10_decode" "vector")])
4500 ;; Conversion between fixed point and floating point.
4502 ;; Even though we only accept memory inputs, the backend _really_
4503 ;; wants to be able to do this between registers.
4505 (define_expand "floathi<mode>2"
4506 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4507 (float:SSEMODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4508 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4510 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4513 (gen_floatsi<mode>2 (operands[0],
4514 convert_to_mode (SImode, operands[1], 0)));
4519 (define_insn "*floathi<mode>2_i387"
4520 [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4522 (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4524 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4525 || TARGET_MIX_SSE_I387)"
4529 [(set_attr "type" "fmov,multi")
4530 (set_attr "mode" "<MODE>")
4531 (set_attr "unit" "*,i387")
4532 (set_attr "fp_int_src" "true")])
4534 (define_expand "floatsi<mode>2"
4535 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4536 (float:SSEMODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4537 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4540 (define_insn "*floatsisf2_mixed"
4541 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4542 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4543 "TARGET_MIX_SSE_I387"
4547 cvtsi2ss\t{%1, %0|%0, %1}
4548 cvtsi2ss\t{%1, %0|%0, %1}"
4549 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4550 (set_attr "mode" "SF")
4551 (set_attr "unit" "*,i387,*,*")
4552 (set_attr "athlon_decode" "*,*,vector,double")
4553 (set_attr "amdfam10_decode" "*,*,vector,double")
4554 (set_attr "fp_int_src" "true")])
4556 (define_insn "*floatsisf2_sse"
4557 [(set (match_operand:SF 0 "register_operand" "=x,x")
4558 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4560 "cvtsi2ss\t{%1, %0|%0, %1}"
4561 [(set_attr "type" "sseicvt")
4562 (set_attr "mode" "SF")
4563 (set_attr "athlon_decode" "vector,double")
4564 (set_attr "amdfam10_decode" "vector,double")
4565 (set_attr "fp_int_src" "true")])
4567 (define_insn "*floatsidf2_mixed"
4568 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4569 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4570 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4574 cvtsi2sd\t{%1, %0|%0, %1}
4575 cvtsi2sd\t{%1, %0|%0, %1}"
4576 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4577 (set_attr "mode" "DF")
4578 (set_attr "unit" "*,i387,*,*")
4579 (set_attr "athlon_decode" "*,*,double,direct")
4580 (set_attr "amdfam10_decode" "*,*,vector,double")
4581 (set_attr "fp_int_src" "true")])
4583 (define_insn "*floatsidf2_sse"
4584 [(set (match_operand:DF 0 "register_operand" "=x,x")
4585 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4586 "TARGET_SSE2 && TARGET_SSE_MATH"
4587 "cvtsi2sd\t{%1, %0|%0, %1}"
4588 [(set_attr "type" "sseicvt")
4589 (set_attr "mode" "DF")
4590 (set_attr "athlon_decode" "double,direct")
4591 (set_attr "amdfam10_decode" "vector,double")
4592 (set_attr "fp_int_src" "true")])
4594 (define_insn "*floatsi<mode>2_i387"
4595 [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4597 (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4602 [(set_attr "type" "fmov,multi")
4603 (set_attr "mode" "<MODE>")
4604 (set_attr "unit" "*,i387")
4605 (set_attr "fp_int_src" "true")])
4607 (define_expand "floatdisf2"
4608 [(set (match_operand:SF 0 "register_operand" "")
4609 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4610 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4613 (define_insn "*floatdisf2_mixed"
4614 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4615 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4616 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4620 cvtsi2ss{q}\t{%1, %0|%0, %1}
4621 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4622 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4623 (set_attr "mode" "SF")
4624 (set_attr "unit" "*,i387,*,*")
4625 (set_attr "athlon_decode" "*,*,vector,double")
4626 (set_attr "amdfam10_decode" "*,*,vector,double")
4627 (set_attr "fp_int_src" "true")])
4629 (define_insn "*floatdisf2_sse"
4630 [(set (match_operand:SF 0 "register_operand" "=x,x")
4631 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4632 "TARGET_64BIT && TARGET_SSE_MATH"
4633 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4634 [(set_attr "type" "sseicvt")
4635 (set_attr "mode" "SF")
4636 (set_attr "athlon_decode" "vector,double")
4637 (set_attr "amdfam10_decode" "vector,double")
4638 (set_attr "fp_int_src" "true")])
4640 (define_expand "floatdidf2"
4641 [(set (match_operand:DF 0 "register_operand" "")
4642 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4643 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4645 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4647 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4652 (define_insn "*floatdidf2_mixed"
4653 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4654 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4655 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4659 cvtsi2sd{q}\t{%1, %0|%0, %1}
4660 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4661 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4662 (set_attr "mode" "DF")
4663 (set_attr "unit" "*,i387,*,*")
4664 (set_attr "athlon_decode" "*,*,double,direct")
4665 (set_attr "amdfam10_decode" "*,*,vector,double")
4666 (set_attr "fp_int_src" "true")])
4668 (define_insn "*floatdidf2_sse"
4669 [(set (match_operand:DF 0 "register_operand" "=x,x")
4670 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4671 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4672 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4673 [(set_attr "type" "sseicvt")
4674 (set_attr "mode" "DF")
4675 (set_attr "athlon_decode" "double,direct")
4676 (set_attr "amdfam10_decode" "vector,double")
4677 (set_attr "fp_int_src" "true")])
4679 (define_insn "*floatdi<mode>2_i387"
4680 [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4682 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4687 [(set_attr "type" "fmov,multi")
4688 (set_attr "mode" "<MODE>")
4689 (set_attr "unit" "*,i387")
4690 (set_attr "fp_int_src" "true")])
4692 (define_insn "float<mode>xf2"
4693 [(set (match_operand:XF 0 "register_operand" "=f,f")
4694 (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
4699 [(set_attr "type" "fmov,multi")
4700 (set_attr "mode" "XF")
4701 (set_attr "unit" "*,i387")
4702 (set_attr "fp_int_src" "true")])
4704 ;; %%% Kill these when reload knows how to do it.
4706 [(set (match_operand 0 "fp_register_operand" "")
4707 (float (match_operand 1 "register_operand" "")))]
4709 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
4712 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4713 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4714 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4715 ix86_free_from_memory (GET_MODE (operands[1]));
4719 (define_expand "floatunssisf2"
4720 [(use (match_operand:SF 0 "register_operand" ""))
4721 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4724 if (TARGET_SSE_MATH && TARGET_SSE2)
4725 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
4727 x86_emit_floatuns (operands);
4731 (define_expand "floatunssidf2"
4732 [(use (match_operand:DF 0 "register_operand" ""))
4733 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4734 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
4735 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
4737 (define_expand "floatunsdisf2"
4738 [(use (match_operand:SF 0 "register_operand" ""))
4739 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4740 "TARGET_64BIT && TARGET_SSE_MATH"
4741 "x86_emit_floatuns (operands); DONE;")
4743 (define_expand "floatunsdidf2"
4744 [(use (match_operand:DF 0 "register_operand" ""))
4745 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4746 "TARGET_SSE_MATH && TARGET_SSE2
4747 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
4750 x86_emit_floatuns (operands);
4752 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
4758 ;; %%% splits for addditi3
4760 (define_expand "addti3"
4761 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4762 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4763 (match_operand:TI 2 "x86_64_general_operand" "")))
4764 (clobber (reg:CC FLAGS_REG))]
4766 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4768 (define_insn "*addti3_1"
4769 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4770 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4771 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4772 (clobber (reg:CC FLAGS_REG))]
4773 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4777 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4778 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4779 (match_operand:TI 2 "x86_64_general_operand" "")))
4780 (clobber (reg:CC FLAGS_REG))]
4781 "TARGET_64BIT && reload_completed"
4782 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4784 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4785 (parallel [(set (match_dup 3)
4786 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4789 (clobber (reg:CC FLAGS_REG))])]
4790 "split_ti (operands+0, 1, operands+0, operands+3);
4791 split_ti (operands+1, 1, operands+1, operands+4);
4792 split_ti (operands+2, 1, operands+2, operands+5);")
4794 ;; %%% splits for addsidi3
4795 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4796 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4797 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4799 (define_expand "adddi3"
4800 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4801 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4802 (match_operand:DI 2 "x86_64_general_operand" "")))
4803 (clobber (reg:CC FLAGS_REG))]
4805 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4807 (define_insn "*adddi3_1"
4808 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4809 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4810 (match_operand:DI 2 "general_operand" "roiF,riF")))
4811 (clobber (reg:CC FLAGS_REG))]
4812 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4816 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4817 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4818 (match_operand:DI 2 "general_operand" "")))
4819 (clobber (reg:CC FLAGS_REG))]
4820 "!TARGET_64BIT && reload_completed"
4821 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4823 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4824 (parallel [(set (match_dup 3)
4825 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4828 (clobber (reg:CC FLAGS_REG))])]
4829 "split_di (operands+0, 1, operands+0, operands+3);
4830 split_di (operands+1, 1, operands+1, operands+4);
4831 split_di (operands+2, 1, operands+2, operands+5);")
4833 (define_insn "adddi3_carry_rex64"
4834 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4835 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4836 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4837 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4838 (clobber (reg:CC FLAGS_REG))]
4839 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4840 "adc{q}\t{%2, %0|%0, %2}"
4841 [(set_attr "type" "alu")
4842 (set_attr "pent_pair" "pu")
4843 (set_attr "mode" "DI")])
4845 (define_insn "*adddi3_cc_rex64"
4846 [(set (reg:CC FLAGS_REG)
4847 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4848 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4850 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4851 (plus:DI (match_dup 1) (match_dup 2)))]
4852 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4853 "add{q}\t{%2, %0|%0, %2}"
4854 [(set_attr "type" "alu")
4855 (set_attr "mode" "DI")])
4857 (define_insn "addqi3_carry"
4858 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4859 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4860 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4861 (match_operand:QI 2 "general_operand" "qi,qm")))
4862 (clobber (reg:CC FLAGS_REG))]
4863 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4864 "adc{b}\t{%2, %0|%0, %2}"
4865 [(set_attr "type" "alu")
4866 (set_attr "pent_pair" "pu")
4867 (set_attr "mode" "QI")])
4869 (define_insn "addhi3_carry"
4870 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4871 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4872 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4873 (match_operand:HI 2 "general_operand" "ri,rm")))
4874 (clobber (reg:CC FLAGS_REG))]
4875 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4876 "adc{w}\t{%2, %0|%0, %2}"
4877 [(set_attr "type" "alu")
4878 (set_attr "pent_pair" "pu")
4879 (set_attr "mode" "HI")])
4881 (define_insn "addsi3_carry"
4882 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4883 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4884 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4885 (match_operand:SI 2 "general_operand" "ri,rm")))
4886 (clobber (reg:CC FLAGS_REG))]
4887 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4888 "adc{l}\t{%2, %0|%0, %2}"
4889 [(set_attr "type" "alu")
4890 (set_attr "pent_pair" "pu")
4891 (set_attr "mode" "SI")])
4893 (define_insn "*addsi3_carry_zext"
4894 [(set (match_operand:DI 0 "register_operand" "=r")
4896 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4897 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4898 (match_operand:SI 2 "general_operand" "rim"))))
4899 (clobber (reg:CC FLAGS_REG))]
4900 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4901 "adc{l}\t{%2, %k0|%k0, %2}"
4902 [(set_attr "type" "alu")
4903 (set_attr "pent_pair" "pu")
4904 (set_attr "mode" "SI")])
4906 (define_insn "*addsi3_cc"
4907 [(set (reg:CC FLAGS_REG)
4908 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4909 (match_operand:SI 2 "general_operand" "ri,rm")]
4911 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4912 (plus:SI (match_dup 1) (match_dup 2)))]
4913 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4914 "add{l}\t{%2, %0|%0, %2}"
4915 [(set_attr "type" "alu")
4916 (set_attr "mode" "SI")])
4918 (define_insn "addqi3_cc"
4919 [(set (reg:CC FLAGS_REG)
4920 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4921 (match_operand:QI 2 "general_operand" "qi,qm")]
4923 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4924 (plus:QI (match_dup 1) (match_dup 2)))]
4925 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4926 "add{b}\t{%2, %0|%0, %2}"
4927 [(set_attr "type" "alu")
4928 (set_attr "mode" "QI")])
4930 (define_expand "addsi3"
4931 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4932 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4933 (match_operand:SI 2 "general_operand" "")))
4934 (clobber (reg:CC FLAGS_REG))])]
4936 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4938 (define_insn "*lea_1"
4939 [(set (match_operand:SI 0 "register_operand" "=r")
4940 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4942 "lea{l}\t{%a1, %0|%0, %a1}"
4943 [(set_attr "type" "lea")
4944 (set_attr "mode" "SI")])
4946 (define_insn "*lea_1_rex64"
4947 [(set (match_operand:SI 0 "register_operand" "=r")
4948 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4950 "lea{l}\t{%a1, %0|%0, %a1}"
4951 [(set_attr "type" "lea")
4952 (set_attr "mode" "SI")])
4954 (define_insn "*lea_1_zext"
4955 [(set (match_operand:DI 0 "register_operand" "=r")
4957 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4959 "lea{l}\t{%a1, %k0|%k0, %a1}"
4960 [(set_attr "type" "lea")
4961 (set_attr "mode" "SI")])
4963 (define_insn "*lea_2_rex64"
4964 [(set (match_operand:DI 0 "register_operand" "=r")
4965 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4967 "lea{q}\t{%a1, %0|%0, %a1}"
4968 [(set_attr "type" "lea")
4969 (set_attr "mode" "DI")])
4971 ;; The lea patterns for non-Pmodes needs to be matched by several
4972 ;; insns converted to real lea by splitters.
4974 (define_insn_and_split "*lea_general_1"
4975 [(set (match_operand 0 "register_operand" "=r")
4976 (plus (plus (match_operand 1 "index_register_operand" "l")
4977 (match_operand 2 "register_operand" "r"))
4978 (match_operand 3 "immediate_operand" "i")))]
4979 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4980 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4981 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4982 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4983 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4984 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4985 || GET_MODE (operands[3]) == VOIDmode)"
4987 "&& reload_completed"
4991 operands[0] = gen_lowpart (SImode, operands[0]);
4992 operands[1] = gen_lowpart (Pmode, operands[1]);
4993 operands[2] = gen_lowpart (Pmode, operands[2]);
4994 operands[3] = gen_lowpart (Pmode, operands[3]);
4995 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4997 if (Pmode != SImode)
4998 pat = gen_rtx_SUBREG (SImode, pat, 0);
4999 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5002 [(set_attr "type" "lea")
5003 (set_attr "mode" "SI")])
5005 (define_insn_and_split "*lea_general_1_zext"
5006 [(set (match_operand:DI 0 "register_operand" "=r")
5008 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5009 (match_operand:SI 2 "register_operand" "r"))
5010 (match_operand:SI 3 "immediate_operand" "i"))))]
5013 "&& reload_completed"
5015 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5017 (match_dup 3)) 0)))]
5019 operands[1] = gen_lowpart (Pmode, operands[1]);
5020 operands[2] = gen_lowpart (Pmode, operands[2]);
5021 operands[3] = gen_lowpart (Pmode, operands[3]);
5023 [(set_attr "type" "lea")
5024 (set_attr "mode" "SI")])
5026 (define_insn_and_split "*lea_general_2"
5027 [(set (match_operand 0 "register_operand" "=r")
5028 (plus (mult (match_operand 1 "index_register_operand" "l")
5029 (match_operand 2 "const248_operand" "i"))
5030 (match_operand 3 "nonmemory_operand" "ri")))]
5031 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5032 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5033 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5034 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5035 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5036 || GET_MODE (operands[3]) == VOIDmode)"
5038 "&& reload_completed"
5042 operands[0] = gen_lowpart (SImode, operands[0]);
5043 operands[1] = gen_lowpart (Pmode, operands[1]);
5044 operands[3] = gen_lowpart (Pmode, operands[3]);
5045 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5047 if (Pmode != SImode)
5048 pat = gen_rtx_SUBREG (SImode, pat, 0);
5049 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5052 [(set_attr "type" "lea")
5053 (set_attr "mode" "SI")])
5055 (define_insn_and_split "*lea_general_2_zext"
5056 [(set (match_operand:DI 0 "register_operand" "=r")
5058 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5059 (match_operand:SI 2 "const248_operand" "n"))
5060 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5063 "&& reload_completed"
5065 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5067 (match_dup 3)) 0)))]
5069 operands[1] = gen_lowpart (Pmode, operands[1]);
5070 operands[3] = gen_lowpart (Pmode, operands[3]);
5072 [(set_attr "type" "lea")
5073 (set_attr "mode" "SI")])
5075 (define_insn_and_split "*lea_general_3"
5076 [(set (match_operand 0 "register_operand" "=r")
5077 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5078 (match_operand 2 "const248_operand" "i"))
5079 (match_operand 3 "register_operand" "r"))
5080 (match_operand 4 "immediate_operand" "i")))]
5081 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5082 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5083 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5084 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5085 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5087 "&& reload_completed"
5091 operands[0] = gen_lowpart (SImode, operands[0]);
5092 operands[1] = gen_lowpart (Pmode, operands[1]);
5093 operands[3] = gen_lowpart (Pmode, operands[3]);
5094 operands[4] = gen_lowpart (Pmode, operands[4]);
5095 pat = gen_rtx_PLUS (Pmode,
5096 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5100 if (Pmode != SImode)
5101 pat = gen_rtx_SUBREG (SImode, pat, 0);
5102 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5105 [(set_attr "type" "lea")
5106 (set_attr "mode" "SI")])
5108 (define_insn_and_split "*lea_general_3_zext"
5109 [(set (match_operand:DI 0 "register_operand" "=r")
5111 (plus:SI (plus:SI (mult:SI
5112 (match_operand:SI 1 "index_register_operand" "l")
5113 (match_operand:SI 2 "const248_operand" "n"))
5114 (match_operand:SI 3 "register_operand" "r"))
5115 (match_operand:SI 4 "immediate_operand" "i"))))]
5118 "&& reload_completed"
5120 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5123 (match_dup 4)) 0)))]
5125 operands[1] = gen_lowpart (Pmode, operands[1]);
5126 operands[3] = gen_lowpart (Pmode, operands[3]);
5127 operands[4] = gen_lowpart (Pmode, operands[4]);
5129 [(set_attr "type" "lea")
5130 (set_attr "mode" "SI")])
5132 (define_insn "*adddi_1_rex64"
5133 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5134 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5135 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5136 (clobber (reg:CC FLAGS_REG))]
5137 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5139 switch (get_attr_type (insn))
5142 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5143 return "lea{q}\t{%a2, %0|%0, %a2}";
5146 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5147 if (operands[2] == const1_rtx)
5148 return "inc{q}\t%0";
5151 gcc_assert (operands[2] == constm1_rtx);
5152 return "dec{q}\t%0";
5156 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5158 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5159 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5160 if (CONST_INT_P (operands[2])
5161 /* Avoid overflows. */
5162 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5163 && (INTVAL (operands[2]) == 128
5164 || (INTVAL (operands[2]) < 0
5165 && INTVAL (operands[2]) != -128)))
5167 operands[2] = GEN_INT (-INTVAL (operands[2]));
5168 return "sub{q}\t{%2, %0|%0, %2}";
5170 return "add{q}\t{%2, %0|%0, %2}";
5174 (cond [(eq_attr "alternative" "2")
5175 (const_string "lea")
5176 ; Current assemblers are broken and do not allow @GOTOFF in
5177 ; ought but a memory context.
5178 (match_operand:DI 2 "pic_symbolic_operand" "")
5179 (const_string "lea")
5180 (match_operand:DI 2 "incdec_operand" "")
5181 (const_string "incdec")
5183 (const_string "alu")))
5184 (set_attr "mode" "DI")])
5186 ;; Convert lea to the lea pattern to avoid flags dependency.
5188 [(set (match_operand:DI 0 "register_operand" "")
5189 (plus:DI (match_operand:DI 1 "register_operand" "")
5190 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5191 (clobber (reg:CC FLAGS_REG))]
5192 "TARGET_64BIT && reload_completed
5193 && true_regnum (operands[0]) != true_regnum (operands[1])"
5195 (plus:DI (match_dup 1)
5199 (define_insn "*adddi_2_rex64"
5200 [(set (reg FLAGS_REG)
5202 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5203 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5205 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5206 (plus:DI (match_dup 1) (match_dup 2)))]
5207 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5208 && ix86_binary_operator_ok (PLUS, DImode, operands)
5209 /* Current assemblers are broken and do not allow @GOTOFF in
5210 ought but a memory context. */
5211 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5213 switch (get_attr_type (insn))
5216 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5217 if (operands[2] == const1_rtx)
5218 return "inc{q}\t%0";
5221 gcc_assert (operands[2] == constm1_rtx);
5222 return "dec{q}\t%0";
5226 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5227 /* ???? We ought to handle there the 32bit case too
5228 - do we need new constraint? */
5229 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5230 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5231 if (CONST_INT_P (operands[2])
5232 /* Avoid overflows. */
5233 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5234 && (INTVAL (operands[2]) == 128
5235 || (INTVAL (operands[2]) < 0
5236 && INTVAL (operands[2]) != -128)))
5238 operands[2] = GEN_INT (-INTVAL (operands[2]));
5239 return "sub{q}\t{%2, %0|%0, %2}";
5241 return "add{q}\t{%2, %0|%0, %2}";
5245 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5246 (const_string "incdec")
5247 (const_string "alu")))
5248 (set_attr "mode" "DI")])
5250 (define_insn "*adddi_3_rex64"
5251 [(set (reg FLAGS_REG)
5252 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5253 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5254 (clobber (match_scratch:DI 0 "=r"))]
5256 && ix86_match_ccmode (insn, CCZmode)
5257 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5258 /* Current assemblers are broken and do not allow @GOTOFF in
5259 ought but a memory context. */
5260 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5262 switch (get_attr_type (insn))
5265 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5266 if (operands[2] == const1_rtx)
5267 return "inc{q}\t%0";
5270 gcc_assert (operands[2] == constm1_rtx);
5271 return "dec{q}\t%0";
5275 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5276 /* ???? We ought to handle there the 32bit case too
5277 - do we need new constraint? */
5278 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5279 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5280 if (CONST_INT_P (operands[2])
5281 /* Avoid overflows. */
5282 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5283 && (INTVAL (operands[2]) == 128
5284 || (INTVAL (operands[2]) < 0
5285 && INTVAL (operands[2]) != -128)))
5287 operands[2] = GEN_INT (-INTVAL (operands[2]));
5288 return "sub{q}\t{%2, %0|%0, %2}";
5290 return "add{q}\t{%2, %0|%0, %2}";
5294 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5295 (const_string "incdec")
5296 (const_string "alu")))
5297 (set_attr "mode" "DI")])
5299 ; For comparisons against 1, -1 and 128, we may generate better code
5300 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5301 ; is matched then. We can't accept general immediate, because for
5302 ; case of overflows, the result is messed up.
5303 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5305 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5306 ; only for comparisons not depending on it.
5307 (define_insn "*adddi_4_rex64"
5308 [(set (reg FLAGS_REG)
5309 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5310 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5311 (clobber (match_scratch:DI 0 "=rm"))]
5313 && ix86_match_ccmode (insn, CCGCmode)"
5315 switch (get_attr_type (insn))
5318 if (operands[2] == constm1_rtx)
5319 return "inc{q}\t%0";
5322 gcc_assert (operands[2] == const1_rtx);
5323 return "dec{q}\t%0";
5327 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5328 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5329 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5330 if ((INTVAL (operands[2]) == -128
5331 || (INTVAL (operands[2]) > 0
5332 && INTVAL (operands[2]) != 128))
5333 /* Avoid overflows. */
5334 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5335 return "sub{q}\t{%2, %0|%0, %2}";
5336 operands[2] = GEN_INT (-INTVAL (operands[2]));
5337 return "add{q}\t{%2, %0|%0, %2}";
5341 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5342 (const_string "incdec")
5343 (const_string "alu")))
5344 (set_attr "mode" "DI")])
5346 (define_insn "*adddi_5_rex64"
5347 [(set (reg FLAGS_REG)
5349 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5350 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5352 (clobber (match_scratch:DI 0 "=r"))]
5354 && ix86_match_ccmode (insn, CCGOCmode)
5355 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5356 /* Current assemblers are broken and do not allow @GOTOFF in
5357 ought but a memory context. */
5358 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5360 switch (get_attr_type (insn))
5363 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5364 if (operands[2] == const1_rtx)
5365 return "inc{q}\t%0";
5368 gcc_assert (operands[2] == constm1_rtx);
5369 return "dec{q}\t%0";
5373 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5374 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5375 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5376 if (CONST_INT_P (operands[2])
5377 /* Avoid overflows. */
5378 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5379 && (INTVAL (operands[2]) == 128
5380 || (INTVAL (operands[2]) < 0
5381 && INTVAL (operands[2]) != -128)))
5383 operands[2] = GEN_INT (-INTVAL (operands[2]));
5384 return "sub{q}\t{%2, %0|%0, %2}";
5386 return "add{q}\t{%2, %0|%0, %2}";
5390 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5391 (const_string "incdec")
5392 (const_string "alu")))
5393 (set_attr "mode" "DI")])
5396 (define_insn "*addsi_1"
5397 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5398 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5399 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5400 (clobber (reg:CC FLAGS_REG))]
5401 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5403 switch (get_attr_type (insn))
5406 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5407 return "lea{l}\t{%a2, %0|%0, %a2}";
5410 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5411 if (operands[2] == const1_rtx)
5412 return "inc{l}\t%0";
5415 gcc_assert (operands[2] == constm1_rtx);
5416 return "dec{l}\t%0";
5420 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5422 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5423 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5424 if (CONST_INT_P (operands[2])
5425 && (INTVAL (operands[2]) == 128
5426 || (INTVAL (operands[2]) < 0
5427 && INTVAL (operands[2]) != -128)))
5429 operands[2] = GEN_INT (-INTVAL (operands[2]));
5430 return "sub{l}\t{%2, %0|%0, %2}";
5432 return "add{l}\t{%2, %0|%0, %2}";
5436 (cond [(eq_attr "alternative" "2")
5437 (const_string "lea")
5438 ; Current assemblers are broken and do not allow @GOTOFF in
5439 ; ought but a memory context.
5440 (match_operand:SI 2 "pic_symbolic_operand" "")
5441 (const_string "lea")
5442 (match_operand:SI 2 "incdec_operand" "")
5443 (const_string "incdec")
5445 (const_string "alu")))
5446 (set_attr "mode" "SI")])
5448 ;; Convert lea to the lea pattern to avoid flags dependency.
5450 [(set (match_operand 0 "register_operand" "")
5451 (plus (match_operand 1 "register_operand" "")
5452 (match_operand 2 "nonmemory_operand" "")))
5453 (clobber (reg:CC FLAGS_REG))]
5455 && true_regnum (operands[0]) != true_regnum (operands[1])"
5459 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5460 may confuse gen_lowpart. */
5461 if (GET_MODE (operands[0]) != Pmode)
5463 operands[1] = gen_lowpart (Pmode, operands[1]);
5464 operands[2] = gen_lowpart (Pmode, operands[2]);
5466 operands[0] = gen_lowpart (SImode, operands[0]);
5467 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5468 if (Pmode != SImode)
5469 pat = gen_rtx_SUBREG (SImode, pat, 0);
5470 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5474 ;; It may seem that nonimmediate operand is proper one for operand 1.
5475 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5476 ;; we take care in ix86_binary_operator_ok to not allow two memory
5477 ;; operands so proper swapping will be done in reload. This allow
5478 ;; patterns constructed from addsi_1 to match.
5479 (define_insn "addsi_1_zext"
5480 [(set (match_operand:DI 0 "register_operand" "=r,r")
5482 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5483 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5484 (clobber (reg:CC FLAGS_REG))]
5485 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5487 switch (get_attr_type (insn))
5490 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5491 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5494 if (operands[2] == const1_rtx)
5495 return "inc{l}\t%k0";
5498 gcc_assert (operands[2] == constm1_rtx);
5499 return "dec{l}\t%k0";
5503 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5504 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5505 if (CONST_INT_P (operands[2])
5506 && (INTVAL (operands[2]) == 128
5507 || (INTVAL (operands[2]) < 0
5508 && INTVAL (operands[2]) != -128)))
5510 operands[2] = GEN_INT (-INTVAL (operands[2]));
5511 return "sub{l}\t{%2, %k0|%k0, %2}";
5513 return "add{l}\t{%2, %k0|%k0, %2}";
5517 (cond [(eq_attr "alternative" "1")
5518 (const_string "lea")
5519 ; Current assemblers are broken and do not allow @GOTOFF in
5520 ; ought but a memory context.
5521 (match_operand:SI 2 "pic_symbolic_operand" "")
5522 (const_string "lea")
5523 (match_operand:SI 2 "incdec_operand" "")
5524 (const_string "incdec")
5526 (const_string "alu")))
5527 (set_attr "mode" "SI")])
5529 ;; Convert lea to the lea pattern to avoid flags dependency.
5531 [(set (match_operand:DI 0 "register_operand" "")
5533 (plus:SI (match_operand:SI 1 "register_operand" "")
5534 (match_operand:SI 2 "nonmemory_operand" ""))))
5535 (clobber (reg:CC FLAGS_REG))]
5536 "TARGET_64BIT && reload_completed
5537 && true_regnum (operands[0]) != true_regnum (operands[1])"
5539 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5541 operands[1] = gen_lowpart (Pmode, operands[1]);
5542 operands[2] = gen_lowpart (Pmode, operands[2]);
5545 (define_insn "*addsi_2"
5546 [(set (reg FLAGS_REG)
5548 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5549 (match_operand:SI 2 "general_operand" "rmni,rni"))
5551 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5552 (plus:SI (match_dup 1) (match_dup 2)))]
5553 "ix86_match_ccmode (insn, CCGOCmode)
5554 && ix86_binary_operator_ok (PLUS, SImode, operands)
5555 /* Current assemblers are broken and do not allow @GOTOFF in
5556 ought but a memory context. */
5557 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5559 switch (get_attr_type (insn))
5562 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5563 if (operands[2] == const1_rtx)
5564 return "inc{l}\t%0";
5567 gcc_assert (operands[2] == constm1_rtx);
5568 return "dec{l}\t%0";
5572 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5573 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5574 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5575 if (CONST_INT_P (operands[2])
5576 && (INTVAL (operands[2]) == 128
5577 || (INTVAL (operands[2]) < 0
5578 && INTVAL (operands[2]) != -128)))
5580 operands[2] = GEN_INT (-INTVAL (operands[2]));
5581 return "sub{l}\t{%2, %0|%0, %2}";
5583 return "add{l}\t{%2, %0|%0, %2}";
5587 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5588 (const_string "incdec")
5589 (const_string "alu")))
5590 (set_attr "mode" "SI")])
5592 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5593 (define_insn "*addsi_2_zext"
5594 [(set (reg FLAGS_REG)
5596 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5597 (match_operand:SI 2 "general_operand" "rmni"))
5599 (set (match_operand:DI 0 "register_operand" "=r")
5600 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5601 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5602 && ix86_binary_operator_ok (PLUS, SImode, operands)
5603 /* Current assemblers are broken and do not allow @GOTOFF in
5604 ought but a memory context. */
5605 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5607 switch (get_attr_type (insn))
5610 if (operands[2] == const1_rtx)
5611 return "inc{l}\t%k0";
5614 gcc_assert (operands[2] == constm1_rtx);
5615 return "dec{l}\t%k0";
5619 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5620 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5621 if (CONST_INT_P (operands[2])
5622 && (INTVAL (operands[2]) == 128
5623 || (INTVAL (operands[2]) < 0
5624 && INTVAL (operands[2]) != -128)))
5626 operands[2] = GEN_INT (-INTVAL (operands[2]));
5627 return "sub{l}\t{%2, %k0|%k0, %2}";
5629 return "add{l}\t{%2, %k0|%k0, %2}";
5633 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5634 (const_string "incdec")
5635 (const_string "alu")))
5636 (set_attr "mode" "SI")])
5638 (define_insn "*addsi_3"
5639 [(set (reg FLAGS_REG)
5640 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5641 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5642 (clobber (match_scratch:SI 0 "=r"))]
5643 "ix86_match_ccmode (insn, CCZmode)
5644 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5645 /* Current assemblers are broken and do not allow @GOTOFF in
5646 ought but a memory context. */
5647 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5649 switch (get_attr_type (insn))
5652 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5653 if (operands[2] == const1_rtx)
5654 return "inc{l}\t%0";
5657 gcc_assert (operands[2] == constm1_rtx);
5658 return "dec{l}\t%0";
5662 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5663 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5664 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5665 if (CONST_INT_P (operands[2])
5666 && (INTVAL (operands[2]) == 128
5667 || (INTVAL (operands[2]) < 0
5668 && INTVAL (operands[2]) != -128)))
5670 operands[2] = GEN_INT (-INTVAL (operands[2]));
5671 return "sub{l}\t{%2, %0|%0, %2}";
5673 return "add{l}\t{%2, %0|%0, %2}";
5677 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5678 (const_string "incdec")
5679 (const_string "alu")))
5680 (set_attr "mode" "SI")])
5682 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5683 (define_insn "*addsi_3_zext"
5684 [(set (reg FLAGS_REG)
5685 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5686 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5687 (set (match_operand:DI 0 "register_operand" "=r")
5688 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5689 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5690 && ix86_binary_operator_ok (PLUS, SImode, operands)
5691 /* Current assemblers are broken and do not allow @GOTOFF in
5692 ought but a memory context. */
5693 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5695 switch (get_attr_type (insn))
5698 if (operands[2] == const1_rtx)
5699 return "inc{l}\t%k0";
5702 gcc_assert (operands[2] == constm1_rtx);
5703 return "dec{l}\t%k0";
5707 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5708 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5709 if (CONST_INT_P (operands[2])
5710 && (INTVAL (operands[2]) == 128
5711 || (INTVAL (operands[2]) < 0
5712 && INTVAL (operands[2]) != -128)))
5714 operands[2] = GEN_INT (-INTVAL (operands[2]));
5715 return "sub{l}\t{%2, %k0|%k0, %2}";
5717 return "add{l}\t{%2, %k0|%k0, %2}";
5721 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5722 (const_string "incdec")
5723 (const_string "alu")))
5724 (set_attr "mode" "SI")])
5726 ; For comparisons against 1, -1 and 128, we may generate better code
5727 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5728 ; is matched then. We can't accept general immediate, because for
5729 ; case of overflows, the result is messed up.
5730 ; This pattern also don't hold of 0x80000000, since the value overflows
5732 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5733 ; only for comparisons not depending on it.
5734 (define_insn "*addsi_4"
5735 [(set (reg FLAGS_REG)
5736 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5737 (match_operand:SI 2 "const_int_operand" "n")))
5738 (clobber (match_scratch:SI 0 "=rm"))]
5739 "ix86_match_ccmode (insn, CCGCmode)
5740 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5742 switch (get_attr_type (insn))
5745 if (operands[2] == constm1_rtx)
5746 return "inc{l}\t%0";
5749 gcc_assert (operands[2] == const1_rtx);
5750 return "dec{l}\t%0";
5754 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5755 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5756 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5757 if ((INTVAL (operands[2]) == -128
5758 || (INTVAL (operands[2]) > 0
5759 && INTVAL (operands[2]) != 128)))
5760 return "sub{l}\t{%2, %0|%0, %2}";
5761 operands[2] = GEN_INT (-INTVAL (operands[2]));
5762 return "add{l}\t{%2, %0|%0, %2}";
5766 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5767 (const_string "incdec")
5768 (const_string "alu")))
5769 (set_attr "mode" "SI")])
5771 (define_insn "*addsi_5"
5772 [(set (reg FLAGS_REG)
5774 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5775 (match_operand:SI 2 "general_operand" "rmni"))
5777 (clobber (match_scratch:SI 0 "=r"))]
5778 "ix86_match_ccmode (insn, CCGOCmode)
5779 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5780 /* Current assemblers are broken and do not allow @GOTOFF in
5781 ought but a memory context. */
5782 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5784 switch (get_attr_type (insn))
5787 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5788 if (operands[2] == const1_rtx)
5789 return "inc{l}\t%0";
5792 gcc_assert (operands[2] == constm1_rtx);
5793 return "dec{l}\t%0";
5797 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5798 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5799 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5800 if (CONST_INT_P (operands[2])
5801 && (INTVAL (operands[2]) == 128
5802 || (INTVAL (operands[2]) < 0
5803 && INTVAL (operands[2]) != -128)))
5805 operands[2] = GEN_INT (-INTVAL (operands[2]));
5806 return "sub{l}\t{%2, %0|%0, %2}";
5808 return "add{l}\t{%2, %0|%0, %2}";
5812 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5813 (const_string "incdec")
5814 (const_string "alu")))
5815 (set_attr "mode" "SI")])
5817 (define_expand "addhi3"
5818 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5819 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5820 (match_operand:HI 2 "general_operand" "")))
5821 (clobber (reg:CC FLAGS_REG))])]
5822 "TARGET_HIMODE_MATH"
5823 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5825 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5826 ;; type optimizations enabled by define-splits. This is not important
5827 ;; for PII, and in fact harmful because of partial register stalls.
5829 (define_insn "*addhi_1_lea"
5830 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5831 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5832 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5833 (clobber (reg:CC FLAGS_REG))]
5834 "!TARGET_PARTIAL_REG_STALL
5835 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5837 switch (get_attr_type (insn))
5842 if (operands[2] == const1_rtx)
5843 return "inc{w}\t%0";
5846 gcc_assert (operands[2] == constm1_rtx);
5847 return "dec{w}\t%0";
5851 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5852 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5853 if (CONST_INT_P (operands[2])
5854 && (INTVAL (operands[2]) == 128
5855 || (INTVAL (operands[2]) < 0
5856 && INTVAL (operands[2]) != -128)))
5858 operands[2] = GEN_INT (-INTVAL (operands[2]));
5859 return "sub{w}\t{%2, %0|%0, %2}";
5861 return "add{w}\t{%2, %0|%0, %2}";
5865 (if_then_else (eq_attr "alternative" "2")
5866 (const_string "lea")
5867 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5868 (const_string "incdec")
5869 (const_string "alu"))))
5870 (set_attr "mode" "HI,HI,SI")])
5872 (define_insn "*addhi_1"
5873 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5874 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5875 (match_operand:HI 2 "general_operand" "ri,rm")))
5876 (clobber (reg:CC FLAGS_REG))]
5877 "TARGET_PARTIAL_REG_STALL
5878 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5880 switch (get_attr_type (insn))
5883 if (operands[2] == const1_rtx)
5884 return "inc{w}\t%0";
5887 gcc_assert (operands[2] == constm1_rtx);
5888 return "dec{w}\t%0";
5892 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5893 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5894 if (CONST_INT_P (operands[2])
5895 && (INTVAL (operands[2]) == 128
5896 || (INTVAL (operands[2]) < 0
5897 && INTVAL (operands[2]) != -128)))
5899 operands[2] = GEN_INT (-INTVAL (operands[2]));
5900 return "sub{w}\t{%2, %0|%0, %2}";
5902 return "add{w}\t{%2, %0|%0, %2}";
5906 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5907 (const_string "incdec")
5908 (const_string "alu")))
5909 (set_attr "mode" "HI")])
5911 (define_insn "*addhi_2"
5912 [(set (reg FLAGS_REG)
5914 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5915 (match_operand:HI 2 "general_operand" "rmni,rni"))
5917 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5918 (plus:HI (match_dup 1) (match_dup 2)))]
5919 "ix86_match_ccmode (insn, CCGOCmode)
5920 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5922 switch (get_attr_type (insn))
5925 if (operands[2] == const1_rtx)
5926 return "inc{w}\t%0";
5929 gcc_assert (operands[2] == constm1_rtx);
5930 return "dec{w}\t%0";
5934 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5935 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5936 if (CONST_INT_P (operands[2])
5937 && (INTVAL (operands[2]) == 128
5938 || (INTVAL (operands[2]) < 0
5939 && INTVAL (operands[2]) != -128)))
5941 operands[2] = GEN_INT (-INTVAL (operands[2]));
5942 return "sub{w}\t{%2, %0|%0, %2}";
5944 return "add{w}\t{%2, %0|%0, %2}";
5948 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5949 (const_string "incdec")
5950 (const_string "alu")))
5951 (set_attr "mode" "HI")])
5953 (define_insn "*addhi_3"
5954 [(set (reg FLAGS_REG)
5955 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5956 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5957 (clobber (match_scratch:HI 0 "=r"))]
5958 "ix86_match_ccmode (insn, CCZmode)
5959 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5961 switch (get_attr_type (insn))
5964 if (operands[2] == const1_rtx)
5965 return "inc{w}\t%0";
5968 gcc_assert (operands[2] == constm1_rtx);
5969 return "dec{w}\t%0";
5973 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5974 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5975 if (CONST_INT_P (operands[2])
5976 && (INTVAL (operands[2]) == 128
5977 || (INTVAL (operands[2]) < 0
5978 && INTVAL (operands[2]) != -128)))
5980 operands[2] = GEN_INT (-INTVAL (operands[2]));
5981 return "sub{w}\t{%2, %0|%0, %2}";
5983 return "add{w}\t{%2, %0|%0, %2}";
5987 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5988 (const_string "incdec")
5989 (const_string "alu")))
5990 (set_attr "mode" "HI")])
5992 ; See comments above addsi_4 for details.
5993 (define_insn "*addhi_4"
5994 [(set (reg FLAGS_REG)
5995 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5996 (match_operand:HI 2 "const_int_operand" "n")))
5997 (clobber (match_scratch:HI 0 "=rm"))]
5998 "ix86_match_ccmode (insn, CCGCmode)
5999 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6001 switch (get_attr_type (insn))
6004 if (operands[2] == constm1_rtx)
6005 return "inc{w}\t%0";
6008 gcc_assert (operands[2] == const1_rtx);
6009 return "dec{w}\t%0";
6013 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6014 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6015 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6016 if ((INTVAL (operands[2]) == -128
6017 || (INTVAL (operands[2]) > 0
6018 && INTVAL (operands[2]) != 128)))
6019 return "sub{w}\t{%2, %0|%0, %2}";
6020 operands[2] = GEN_INT (-INTVAL (operands[2]));
6021 return "add{w}\t{%2, %0|%0, %2}";
6025 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6026 (const_string "incdec")
6027 (const_string "alu")))
6028 (set_attr "mode" "SI")])
6031 (define_insn "*addhi_5"
6032 [(set (reg FLAGS_REG)
6034 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6035 (match_operand:HI 2 "general_operand" "rmni"))
6037 (clobber (match_scratch:HI 0 "=r"))]
6038 "ix86_match_ccmode (insn, CCGOCmode)
6039 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6041 switch (get_attr_type (insn))
6044 if (operands[2] == const1_rtx)
6045 return "inc{w}\t%0";
6048 gcc_assert (operands[2] == constm1_rtx);
6049 return "dec{w}\t%0";
6053 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6054 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6055 if (CONST_INT_P (operands[2])
6056 && (INTVAL (operands[2]) == 128
6057 || (INTVAL (operands[2]) < 0
6058 && INTVAL (operands[2]) != -128)))
6060 operands[2] = GEN_INT (-INTVAL (operands[2]));
6061 return "sub{w}\t{%2, %0|%0, %2}";
6063 return "add{w}\t{%2, %0|%0, %2}";
6067 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6068 (const_string "incdec")
6069 (const_string "alu")))
6070 (set_attr "mode" "HI")])
6072 (define_expand "addqi3"
6073 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6074 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6075 (match_operand:QI 2 "general_operand" "")))
6076 (clobber (reg:CC FLAGS_REG))])]
6077 "TARGET_QIMODE_MATH"
6078 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6080 ;; %%% Potential partial reg stall on alternative 2. What to do?
6081 (define_insn "*addqi_1_lea"
6082 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6083 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6084 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6085 (clobber (reg:CC FLAGS_REG))]
6086 "!TARGET_PARTIAL_REG_STALL
6087 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6089 int widen = (which_alternative == 2);
6090 switch (get_attr_type (insn))
6095 if (operands[2] == const1_rtx)
6096 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6099 gcc_assert (operands[2] == constm1_rtx);
6100 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6104 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6105 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6106 if (CONST_INT_P (operands[2])
6107 && (INTVAL (operands[2]) == 128
6108 || (INTVAL (operands[2]) < 0
6109 && INTVAL (operands[2]) != -128)))
6111 operands[2] = GEN_INT (-INTVAL (operands[2]));
6113 return "sub{l}\t{%2, %k0|%k0, %2}";
6115 return "sub{b}\t{%2, %0|%0, %2}";
6118 return "add{l}\t{%k2, %k0|%k0, %k2}";
6120 return "add{b}\t{%2, %0|%0, %2}";
6124 (if_then_else (eq_attr "alternative" "3")
6125 (const_string "lea")
6126 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6127 (const_string "incdec")
6128 (const_string "alu"))))
6129 (set_attr "mode" "QI,QI,SI,SI")])
6131 (define_insn "*addqi_1"
6132 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6133 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6134 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6135 (clobber (reg:CC FLAGS_REG))]
6136 "TARGET_PARTIAL_REG_STALL
6137 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6139 int widen = (which_alternative == 2);
6140 switch (get_attr_type (insn))
6143 if (operands[2] == const1_rtx)
6144 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6147 gcc_assert (operands[2] == constm1_rtx);
6148 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6152 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6153 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6154 if (CONST_INT_P (operands[2])
6155 && (INTVAL (operands[2]) == 128
6156 || (INTVAL (operands[2]) < 0
6157 && INTVAL (operands[2]) != -128)))
6159 operands[2] = GEN_INT (-INTVAL (operands[2]));
6161 return "sub{l}\t{%2, %k0|%k0, %2}";
6163 return "sub{b}\t{%2, %0|%0, %2}";
6166 return "add{l}\t{%k2, %k0|%k0, %k2}";
6168 return "add{b}\t{%2, %0|%0, %2}";
6172 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6173 (const_string "incdec")
6174 (const_string "alu")))
6175 (set_attr "mode" "QI,QI,SI")])
6177 (define_insn "*addqi_1_slp"
6178 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6179 (plus:QI (match_dup 0)
6180 (match_operand:QI 1 "general_operand" "qn,qnm")))
6181 (clobber (reg:CC FLAGS_REG))]
6182 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6183 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6185 switch (get_attr_type (insn))
6188 if (operands[1] == const1_rtx)
6189 return "inc{b}\t%0";
6192 gcc_assert (operands[1] == constm1_rtx);
6193 return "dec{b}\t%0";
6197 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6198 if (CONST_INT_P (operands[1])
6199 && INTVAL (operands[1]) < 0)
6201 operands[1] = GEN_INT (-INTVAL (operands[1]));
6202 return "sub{b}\t{%1, %0|%0, %1}";
6204 return "add{b}\t{%1, %0|%0, %1}";
6208 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6209 (const_string "incdec")
6210 (const_string "alu1")))
6211 (set (attr "memory")
6212 (if_then_else (match_operand 1 "memory_operand" "")
6213 (const_string "load")
6214 (const_string "none")))
6215 (set_attr "mode" "QI")])
6217 (define_insn "*addqi_2"
6218 [(set (reg FLAGS_REG)
6220 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6221 (match_operand:QI 2 "general_operand" "qmni,qni"))
6223 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6224 (plus:QI (match_dup 1) (match_dup 2)))]
6225 "ix86_match_ccmode (insn, CCGOCmode)
6226 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6228 switch (get_attr_type (insn))
6231 if (operands[2] == const1_rtx)
6232 return "inc{b}\t%0";
6235 gcc_assert (operands[2] == constm1_rtx
6236 || (CONST_INT_P (operands[2])
6237 && INTVAL (operands[2]) == 255));
6238 return "dec{b}\t%0";
6242 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6243 if (CONST_INT_P (operands[2])
6244 && INTVAL (operands[2]) < 0)
6246 operands[2] = GEN_INT (-INTVAL (operands[2]));
6247 return "sub{b}\t{%2, %0|%0, %2}";
6249 return "add{b}\t{%2, %0|%0, %2}";
6253 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6254 (const_string "incdec")
6255 (const_string "alu")))
6256 (set_attr "mode" "QI")])
6258 (define_insn "*addqi_3"
6259 [(set (reg FLAGS_REG)
6260 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6261 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6262 (clobber (match_scratch:QI 0 "=q"))]
6263 "ix86_match_ccmode (insn, CCZmode)
6264 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6266 switch (get_attr_type (insn))
6269 if (operands[2] == const1_rtx)
6270 return "inc{b}\t%0";
6273 gcc_assert (operands[2] == constm1_rtx
6274 || (CONST_INT_P (operands[2])
6275 && INTVAL (operands[2]) == 255));
6276 return "dec{b}\t%0";
6280 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6281 if (CONST_INT_P (operands[2])
6282 && INTVAL (operands[2]) < 0)
6284 operands[2] = GEN_INT (-INTVAL (operands[2]));
6285 return "sub{b}\t{%2, %0|%0, %2}";
6287 return "add{b}\t{%2, %0|%0, %2}";
6291 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6292 (const_string "incdec")
6293 (const_string "alu")))
6294 (set_attr "mode" "QI")])
6296 ; See comments above addsi_4 for details.
6297 (define_insn "*addqi_4"
6298 [(set (reg FLAGS_REG)
6299 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6300 (match_operand:QI 2 "const_int_operand" "n")))
6301 (clobber (match_scratch:QI 0 "=qm"))]
6302 "ix86_match_ccmode (insn, CCGCmode)
6303 && (INTVAL (operands[2]) & 0xff) != 0x80"
6305 switch (get_attr_type (insn))
6308 if (operands[2] == constm1_rtx
6309 || (CONST_INT_P (operands[2])
6310 && INTVAL (operands[2]) == 255))
6311 return "inc{b}\t%0";
6314 gcc_assert (operands[2] == const1_rtx);
6315 return "dec{b}\t%0";
6319 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6320 if (INTVAL (operands[2]) < 0)
6322 operands[2] = GEN_INT (-INTVAL (operands[2]));
6323 return "add{b}\t{%2, %0|%0, %2}";
6325 return "sub{b}\t{%2, %0|%0, %2}";
6329 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6330 (const_string "incdec")
6331 (const_string "alu")))
6332 (set_attr "mode" "QI")])
6335 (define_insn "*addqi_5"
6336 [(set (reg FLAGS_REG)
6338 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6339 (match_operand:QI 2 "general_operand" "qmni"))
6341 (clobber (match_scratch:QI 0 "=q"))]
6342 "ix86_match_ccmode (insn, CCGOCmode)
6343 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6345 switch (get_attr_type (insn))
6348 if (operands[2] == const1_rtx)
6349 return "inc{b}\t%0";
6352 gcc_assert (operands[2] == constm1_rtx
6353 || (CONST_INT_P (operands[2])
6354 && INTVAL (operands[2]) == 255));
6355 return "dec{b}\t%0";
6359 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6360 if (CONST_INT_P (operands[2])
6361 && INTVAL (operands[2]) < 0)
6363 operands[2] = GEN_INT (-INTVAL (operands[2]));
6364 return "sub{b}\t{%2, %0|%0, %2}";
6366 return "add{b}\t{%2, %0|%0, %2}";
6370 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6371 (const_string "incdec")
6372 (const_string "alu")))
6373 (set_attr "mode" "QI")])
6376 (define_insn "addqi_ext_1"
6377 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6382 (match_operand 1 "ext_register_operand" "0")
6385 (match_operand:QI 2 "general_operand" "Qmn")))
6386 (clobber (reg:CC FLAGS_REG))]
6389 switch (get_attr_type (insn))
6392 if (operands[2] == const1_rtx)
6393 return "inc{b}\t%h0";
6396 gcc_assert (operands[2] == constm1_rtx
6397 || (CONST_INT_P (operands[2])
6398 && INTVAL (operands[2]) == 255));
6399 return "dec{b}\t%h0";
6403 return "add{b}\t{%2, %h0|%h0, %2}";
6407 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6408 (const_string "incdec")
6409 (const_string "alu")))
6410 (set_attr "mode" "QI")])
6412 (define_insn "*addqi_ext_1_rex64"
6413 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6418 (match_operand 1 "ext_register_operand" "0")
6421 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6422 (clobber (reg:CC FLAGS_REG))]
6425 switch (get_attr_type (insn))
6428 if (operands[2] == const1_rtx)
6429 return "inc{b}\t%h0";
6432 gcc_assert (operands[2] == constm1_rtx
6433 || (CONST_INT_P (operands[2])
6434 && INTVAL (operands[2]) == 255));
6435 return "dec{b}\t%h0";
6439 return "add{b}\t{%2, %h0|%h0, %2}";
6443 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6444 (const_string "incdec")
6445 (const_string "alu")))
6446 (set_attr "mode" "QI")])
6448 (define_insn "*addqi_ext_2"
6449 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6454 (match_operand 1 "ext_register_operand" "%0")
6458 (match_operand 2 "ext_register_operand" "Q")
6461 (clobber (reg:CC FLAGS_REG))]
6463 "add{b}\t{%h2, %h0|%h0, %h2}"
6464 [(set_attr "type" "alu")
6465 (set_attr "mode" "QI")])
6467 ;; The patterns that match these are at the end of this file.
6469 (define_expand "addxf3"
6470 [(set (match_operand:XF 0 "register_operand" "")
6471 (plus:XF (match_operand:XF 1 "register_operand" "")
6472 (match_operand:XF 2 "register_operand" "")))]
6476 (define_expand "adddf3"
6477 [(set (match_operand:DF 0 "register_operand" "")
6478 (plus:DF (match_operand:DF 1 "register_operand" "")
6479 (match_operand:DF 2 "nonimmediate_operand" "")))]
6480 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6483 (define_expand "addsf3"
6484 [(set (match_operand:SF 0 "register_operand" "")
6485 (plus:SF (match_operand:SF 1 "register_operand" "")
6486 (match_operand:SF 2 "nonimmediate_operand" "")))]
6487 "TARGET_80387 || TARGET_SSE_MATH"
6490 ;; Subtract instructions
6492 ;; %%% splits for subditi3
6494 (define_expand "subti3"
6495 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6496 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6497 (match_operand:TI 2 "x86_64_general_operand" "")))
6498 (clobber (reg:CC FLAGS_REG))])]
6500 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6502 (define_insn "*subti3_1"
6503 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6504 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6505 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6506 (clobber (reg:CC FLAGS_REG))]
6507 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6511 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6512 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6513 (match_operand:TI 2 "x86_64_general_operand" "")))
6514 (clobber (reg:CC FLAGS_REG))]
6515 "TARGET_64BIT && reload_completed"
6516 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6517 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6518 (parallel [(set (match_dup 3)
6519 (minus:DI (match_dup 4)
6520 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6522 (clobber (reg:CC FLAGS_REG))])]
6523 "split_ti (operands+0, 1, operands+0, operands+3);
6524 split_ti (operands+1, 1, operands+1, operands+4);
6525 split_ti (operands+2, 1, operands+2, operands+5);")
6527 ;; %%% splits for subsidi3
6529 (define_expand "subdi3"
6530 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6531 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6532 (match_operand:DI 2 "x86_64_general_operand" "")))
6533 (clobber (reg:CC FLAGS_REG))])]
6535 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6537 (define_insn "*subdi3_1"
6538 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6539 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6540 (match_operand:DI 2 "general_operand" "roiF,riF")))
6541 (clobber (reg:CC FLAGS_REG))]
6542 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6546 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6547 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6548 (match_operand:DI 2 "general_operand" "")))
6549 (clobber (reg:CC FLAGS_REG))]
6550 "!TARGET_64BIT && reload_completed"
6551 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6552 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6553 (parallel [(set (match_dup 3)
6554 (minus:SI (match_dup 4)
6555 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6557 (clobber (reg:CC FLAGS_REG))])]
6558 "split_di (operands+0, 1, operands+0, operands+3);
6559 split_di (operands+1, 1, operands+1, operands+4);
6560 split_di (operands+2, 1, operands+2, operands+5);")
6562 (define_insn "subdi3_carry_rex64"
6563 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6564 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6565 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6566 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6567 (clobber (reg:CC FLAGS_REG))]
6568 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6569 "sbb{q}\t{%2, %0|%0, %2}"
6570 [(set_attr "type" "alu")
6571 (set_attr "pent_pair" "pu")
6572 (set_attr "mode" "DI")])
6574 (define_insn "*subdi_1_rex64"
6575 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6576 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6577 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6578 (clobber (reg:CC FLAGS_REG))]
6579 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6580 "sub{q}\t{%2, %0|%0, %2}"
6581 [(set_attr "type" "alu")
6582 (set_attr "mode" "DI")])
6584 (define_insn "*subdi_2_rex64"
6585 [(set (reg FLAGS_REG)
6587 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6588 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6590 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6591 (minus:DI (match_dup 1) (match_dup 2)))]
6592 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6593 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6594 "sub{q}\t{%2, %0|%0, %2}"
6595 [(set_attr "type" "alu")
6596 (set_attr "mode" "DI")])
6598 (define_insn "*subdi_3_rex63"
6599 [(set (reg FLAGS_REG)
6600 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6601 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6602 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6603 (minus:DI (match_dup 1) (match_dup 2)))]
6604 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6605 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6606 "sub{q}\t{%2, %0|%0, %2}"
6607 [(set_attr "type" "alu")
6608 (set_attr "mode" "DI")])
6610 (define_insn "subqi3_carry"
6611 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6612 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6613 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6614 (match_operand:QI 2 "general_operand" "qi,qm"))))
6615 (clobber (reg:CC FLAGS_REG))]
6616 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6617 "sbb{b}\t{%2, %0|%0, %2}"
6618 [(set_attr "type" "alu")
6619 (set_attr "pent_pair" "pu")
6620 (set_attr "mode" "QI")])
6622 (define_insn "subhi3_carry"
6623 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6624 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6625 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6626 (match_operand:HI 2 "general_operand" "ri,rm"))))
6627 (clobber (reg:CC FLAGS_REG))]
6628 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6629 "sbb{w}\t{%2, %0|%0, %2}"
6630 [(set_attr "type" "alu")
6631 (set_attr "pent_pair" "pu")
6632 (set_attr "mode" "HI")])
6634 (define_insn "subsi3_carry"
6635 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6636 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6637 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6638 (match_operand:SI 2 "general_operand" "ri,rm"))))
6639 (clobber (reg:CC FLAGS_REG))]
6640 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6641 "sbb{l}\t{%2, %0|%0, %2}"
6642 [(set_attr "type" "alu")
6643 (set_attr "pent_pair" "pu")
6644 (set_attr "mode" "SI")])
6646 (define_insn "subsi3_carry_zext"
6647 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6649 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6650 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6651 (match_operand:SI 2 "general_operand" "ri,rm")))))
6652 (clobber (reg:CC FLAGS_REG))]
6653 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6654 "sbb{l}\t{%2, %k0|%k0, %2}"
6655 [(set_attr "type" "alu")
6656 (set_attr "pent_pair" "pu")
6657 (set_attr "mode" "SI")])
6659 (define_expand "subsi3"
6660 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6661 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6662 (match_operand:SI 2 "general_operand" "")))
6663 (clobber (reg:CC FLAGS_REG))])]
6665 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6667 (define_insn "*subsi_1"
6668 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6669 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6670 (match_operand:SI 2 "general_operand" "ri,rm")))
6671 (clobber (reg:CC FLAGS_REG))]
6672 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6673 "sub{l}\t{%2, %0|%0, %2}"
6674 [(set_attr "type" "alu")
6675 (set_attr "mode" "SI")])
6677 (define_insn "*subsi_1_zext"
6678 [(set (match_operand:DI 0 "register_operand" "=r")
6680 (minus:SI (match_operand:SI 1 "register_operand" "0")
6681 (match_operand:SI 2 "general_operand" "rim"))))
6682 (clobber (reg:CC FLAGS_REG))]
6683 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6684 "sub{l}\t{%2, %k0|%k0, %2}"
6685 [(set_attr "type" "alu")
6686 (set_attr "mode" "SI")])
6688 (define_insn "*subsi_2"
6689 [(set (reg FLAGS_REG)
6691 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6692 (match_operand:SI 2 "general_operand" "ri,rm"))
6694 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6695 (minus:SI (match_dup 1) (match_dup 2)))]
6696 "ix86_match_ccmode (insn, CCGOCmode)
6697 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6698 "sub{l}\t{%2, %0|%0, %2}"
6699 [(set_attr "type" "alu")
6700 (set_attr "mode" "SI")])
6702 (define_insn "*subsi_2_zext"
6703 [(set (reg FLAGS_REG)
6705 (minus:SI (match_operand:SI 1 "register_operand" "0")
6706 (match_operand:SI 2 "general_operand" "rim"))
6708 (set (match_operand:DI 0 "register_operand" "=r")
6710 (minus:SI (match_dup 1)
6712 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6713 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6714 "sub{l}\t{%2, %k0|%k0, %2}"
6715 [(set_attr "type" "alu")
6716 (set_attr "mode" "SI")])
6718 (define_insn "*subsi_3"
6719 [(set (reg FLAGS_REG)
6720 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6721 (match_operand:SI 2 "general_operand" "ri,rm")))
6722 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6723 (minus:SI (match_dup 1) (match_dup 2)))]
6724 "ix86_match_ccmode (insn, CCmode)
6725 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6726 "sub{l}\t{%2, %0|%0, %2}"
6727 [(set_attr "type" "alu")
6728 (set_attr "mode" "SI")])
6730 (define_insn "*subsi_3_zext"
6731 [(set (reg FLAGS_REG)
6732 (compare (match_operand:SI 1 "register_operand" "0")
6733 (match_operand:SI 2 "general_operand" "rim")))
6734 (set (match_operand:DI 0 "register_operand" "=r")
6736 (minus:SI (match_dup 1)
6738 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6739 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6740 "sub{l}\t{%2, %1|%1, %2}"
6741 [(set_attr "type" "alu")
6742 (set_attr "mode" "DI")])
6744 (define_expand "subhi3"
6745 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6746 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6747 (match_operand:HI 2 "general_operand" "")))
6748 (clobber (reg:CC FLAGS_REG))])]
6749 "TARGET_HIMODE_MATH"
6750 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6752 (define_insn "*subhi_1"
6753 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6754 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6755 (match_operand:HI 2 "general_operand" "ri,rm")))
6756 (clobber (reg:CC FLAGS_REG))]
6757 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6758 "sub{w}\t{%2, %0|%0, %2}"
6759 [(set_attr "type" "alu")
6760 (set_attr "mode" "HI")])
6762 (define_insn "*subhi_2"
6763 [(set (reg FLAGS_REG)
6765 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6766 (match_operand:HI 2 "general_operand" "ri,rm"))
6768 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6769 (minus:HI (match_dup 1) (match_dup 2)))]
6770 "ix86_match_ccmode (insn, CCGOCmode)
6771 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6772 "sub{w}\t{%2, %0|%0, %2}"
6773 [(set_attr "type" "alu")
6774 (set_attr "mode" "HI")])
6776 (define_insn "*subhi_3"
6777 [(set (reg FLAGS_REG)
6778 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6779 (match_operand:HI 2 "general_operand" "ri,rm")))
6780 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6781 (minus:HI (match_dup 1) (match_dup 2)))]
6782 "ix86_match_ccmode (insn, CCmode)
6783 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6784 "sub{w}\t{%2, %0|%0, %2}"
6785 [(set_attr "type" "alu")
6786 (set_attr "mode" "HI")])
6788 (define_expand "subqi3"
6789 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6790 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6791 (match_operand:QI 2 "general_operand" "")))
6792 (clobber (reg:CC FLAGS_REG))])]
6793 "TARGET_QIMODE_MATH"
6794 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6796 (define_insn "*subqi_1"
6797 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6798 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6799 (match_operand:QI 2 "general_operand" "qn,qmn")))
6800 (clobber (reg:CC FLAGS_REG))]
6801 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6802 "sub{b}\t{%2, %0|%0, %2}"
6803 [(set_attr "type" "alu")
6804 (set_attr "mode" "QI")])
6806 (define_insn "*subqi_1_slp"
6807 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6808 (minus:QI (match_dup 0)
6809 (match_operand:QI 1 "general_operand" "qn,qmn")))
6810 (clobber (reg:CC FLAGS_REG))]
6811 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6812 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6813 "sub{b}\t{%1, %0|%0, %1}"
6814 [(set_attr "type" "alu1")
6815 (set_attr "mode" "QI")])
6817 (define_insn "*subqi_2"
6818 [(set (reg FLAGS_REG)
6820 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6821 (match_operand:QI 2 "general_operand" "qi,qm"))
6823 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6824 (minus:HI (match_dup 1) (match_dup 2)))]
6825 "ix86_match_ccmode (insn, CCGOCmode)
6826 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6827 "sub{b}\t{%2, %0|%0, %2}"
6828 [(set_attr "type" "alu")
6829 (set_attr "mode" "QI")])
6831 (define_insn "*subqi_3"
6832 [(set (reg FLAGS_REG)
6833 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6834 (match_operand:QI 2 "general_operand" "qi,qm")))
6835 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6836 (minus:HI (match_dup 1) (match_dup 2)))]
6837 "ix86_match_ccmode (insn, CCmode)
6838 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6839 "sub{b}\t{%2, %0|%0, %2}"
6840 [(set_attr "type" "alu")
6841 (set_attr "mode" "QI")])
6843 ;; The patterns that match these are at the end of this file.
6845 (define_expand "subxf3"
6846 [(set (match_operand:XF 0 "register_operand" "")
6847 (minus:XF (match_operand:XF 1 "register_operand" "")
6848 (match_operand:XF 2 "register_operand" "")))]
6852 (define_expand "subdf3"
6853 [(set (match_operand:DF 0 "register_operand" "")
6854 (minus:DF (match_operand:DF 1 "register_operand" "")
6855 (match_operand:DF 2 "nonimmediate_operand" "")))]
6856 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6859 (define_expand "subsf3"
6860 [(set (match_operand:SF 0 "register_operand" "")
6861 (minus:SF (match_operand:SF 1 "register_operand" "")
6862 (match_operand:SF 2 "nonimmediate_operand" "")))]
6863 "TARGET_80387 || TARGET_SSE_MATH"
6866 ;; Multiply instructions
6868 (define_expand "muldi3"
6869 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6870 (mult:DI (match_operand:DI 1 "register_operand" "")
6871 (match_operand:DI 2 "x86_64_general_operand" "")))
6872 (clobber (reg:CC FLAGS_REG))])]
6877 ;; IMUL reg64, reg64, imm8 Direct
6878 ;; IMUL reg64, mem64, imm8 VectorPath
6879 ;; IMUL reg64, reg64, imm32 Direct
6880 ;; IMUL reg64, mem64, imm32 VectorPath
6881 ;; IMUL reg64, reg64 Direct
6882 ;; IMUL reg64, mem64 Direct
6884 (define_insn "*muldi3_1_rex64"
6885 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6886 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6887 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6888 (clobber (reg:CC FLAGS_REG))]
6890 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6892 imul{q}\t{%2, %1, %0|%0, %1, %2}
6893 imul{q}\t{%2, %1, %0|%0, %1, %2}
6894 imul{q}\t{%2, %0|%0, %2}"
6895 [(set_attr "type" "imul")
6896 (set_attr "prefix_0f" "0,0,1")
6897 (set (attr "athlon_decode")
6898 (cond [(eq_attr "cpu" "athlon")
6899 (const_string "vector")
6900 (eq_attr "alternative" "1")
6901 (const_string "vector")
6902 (and (eq_attr "alternative" "2")
6903 (match_operand 1 "memory_operand" ""))
6904 (const_string "vector")]
6905 (const_string "direct")))
6906 (set (attr "amdfam10_decode")
6907 (cond [(and (eq_attr "alternative" "0,1")
6908 (match_operand 1 "memory_operand" ""))
6909 (const_string "vector")]
6910 (const_string "direct")))
6911 (set_attr "mode" "DI")])
6913 (define_expand "mulsi3"
6914 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6915 (mult:SI (match_operand:SI 1 "register_operand" "")
6916 (match_operand:SI 2 "general_operand" "")))
6917 (clobber (reg:CC FLAGS_REG))])]
6922 ;; IMUL reg32, reg32, imm8 Direct
6923 ;; IMUL reg32, mem32, imm8 VectorPath
6924 ;; IMUL reg32, reg32, imm32 Direct
6925 ;; IMUL reg32, mem32, imm32 VectorPath
6926 ;; IMUL reg32, reg32 Direct
6927 ;; IMUL reg32, mem32 Direct
6929 (define_insn "*mulsi3_1"
6930 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6931 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6932 (match_operand:SI 2 "general_operand" "K,i,mr")))
6933 (clobber (reg:CC FLAGS_REG))]
6934 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6936 imul{l}\t{%2, %1, %0|%0, %1, %2}
6937 imul{l}\t{%2, %1, %0|%0, %1, %2}
6938 imul{l}\t{%2, %0|%0, %2}"
6939 [(set_attr "type" "imul")
6940 (set_attr "prefix_0f" "0,0,1")
6941 (set (attr "athlon_decode")
6942 (cond [(eq_attr "cpu" "athlon")
6943 (const_string "vector")
6944 (eq_attr "alternative" "1")
6945 (const_string "vector")
6946 (and (eq_attr "alternative" "2")
6947 (match_operand 1 "memory_operand" ""))
6948 (const_string "vector")]
6949 (const_string "direct")))
6950 (set (attr "amdfam10_decode")
6951 (cond [(and (eq_attr "alternative" "0,1")
6952 (match_operand 1 "memory_operand" ""))
6953 (const_string "vector")]
6954 (const_string "direct")))
6955 (set_attr "mode" "SI")])
6957 (define_insn "*mulsi3_1_zext"
6958 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6960 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6961 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6962 (clobber (reg:CC FLAGS_REG))]
6964 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6966 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6967 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6968 imul{l}\t{%2, %k0|%k0, %2}"
6969 [(set_attr "type" "imul")
6970 (set_attr "prefix_0f" "0,0,1")
6971 (set (attr "athlon_decode")
6972 (cond [(eq_attr "cpu" "athlon")
6973 (const_string "vector")
6974 (eq_attr "alternative" "1")
6975 (const_string "vector")
6976 (and (eq_attr "alternative" "2")
6977 (match_operand 1 "memory_operand" ""))
6978 (const_string "vector")]
6979 (const_string "direct")))
6980 (set (attr "amdfam10_decode")
6981 (cond [(and (eq_attr "alternative" "0,1")
6982 (match_operand 1 "memory_operand" ""))
6983 (const_string "vector")]
6984 (const_string "direct")))
6985 (set_attr "mode" "SI")])
6987 (define_expand "mulhi3"
6988 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6989 (mult:HI (match_operand:HI 1 "register_operand" "")
6990 (match_operand:HI 2 "general_operand" "")))
6991 (clobber (reg:CC FLAGS_REG))])]
6992 "TARGET_HIMODE_MATH"
6996 ;; IMUL reg16, reg16, imm8 VectorPath
6997 ;; IMUL reg16, mem16, imm8 VectorPath
6998 ;; IMUL reg16, reg16, imm16 VectorPath
6999 ;; IMUL reg16, mem16, imm16 VectorPath
7000 ;; IMUL reg16, reg16 Direct
7001 ;; IMUL reg16, mem16 Direct
7002 (define_insn "*mulhi3_1"
7003 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7004 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7005 (match_operand:HI 2 "general_operand" "K,i,mr")))
7006 (clobber (reg:CC FLAGS_REG))]
7007 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7009 imul{w}\t{%2, %1, %0|%0, %1, %2}
7010 imul{w}\t{%2, %1, %0|%0, %1, %2}
7011 imul{w}\t{%2, %0|%0, %2}"
7012 [(set_attr "type" "imul")
7013 (set_attr "prefix_0f" "0,0,1")
7014 (set (attr "athlon_decode")
7015 (cond [(eq_attr "cpu" "athlon")
7016 (const_string "vector")
7017 (eq_attr "alternative" "1,2")
7018 (const_string "vector")]
7019 (const_string "direct")))
7020 (set (attr "amdfam10_decode")
7021 (cond [(eq_attr "alternative" "0,1")
7022 (const_string "vector")]
7023 (const_string "direct")))
7024 (set_attr "mode" "HI")])
7026 (define_expand "mulqi3"
7027 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7028 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7029 (match_operand:QI 2 "register_operand" "")))
7030 (clobber (reg:CC FLAGS_REG))])]
7031 "TARGET_QIMODE_MATH"
7038 (define_insn "*mulqi3_1"
7039 [(set (match_operand:QI 0 "register_operand" "=a")
7040 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7041 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7042 (clobber (reg:CC FLAGS_REG))]
7044 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7046 [(set_attr "type" "imul")
7047 (set_attr "length_immediate" "0")
7048 (set (attr "athlon_decode")
7049 (if_then_else (eq_attr "cpu" "athlon")
7050 (const_string "vector")
7051 (const_string "direct")))
7052 (set_attr "amdfam10_decode" "direct")
7053 (set_attr "mode" "QI")])
7055 (define_expand "umulqihi3"
7056 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7057 (mult:HI (zero_extend:HI
7058 (match_operand:QI 1 "nonimmediate_operand" ""))
7060 (match_operand:QI 2 "register_operand" ""))))
7061 (clobber (reg:CC FLAGS_REG))])]
7062 "TARGET_QIMODE_MATH"
7065 (define_insn "*umulqihi3_1"
7066 [(set (match_operand:HI 0 "register_operand" "=a")
7067 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7068 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7069 (clobber (reg:CC FLAGS_REG))]
7071 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7073 [(set_attr "type" "imul")
7074 (set_attr "length_immediate" "0")
7075 (set (attr "athlon_decode")
7076 (if_then_else (eq_attr "cpu" "athlon")
7077 (const_string "vector")
7078 (const_string "direct")))
7079 (set_attr "amdfam10_decode" "direct")
7080 (set_attr "mode" "QI")])
7082 (define_expand "mulqihi3"
7083 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7084 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7085 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7086 (clobber (reg:CC FLAGS_REG))])]
7087 "TARGET_QIMODE_MATH"
7090 (define_insn "*mulqihi3_insn"
7091 [(set (match_operand:HI 0 "register_operand" "=a")
7092 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7093 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7094 (clobber (reg:CC FLAGS_REG))]
7096 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7098 [(set_attr "type" "imul")
7099 (set_attr "length_immediate" "0")
7100 (set (attr "athlon_decode")
7101 (if_then_else (eq_attr "cpu" "athlon")
7102 (const_string "vector")
7103 (const_string "direct")))
7104 (set_attr "amdfam10_decode" "direct")
7105 (set_attr "mode" "QI")])
7107 (define_expand "umulditi3"
7108 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7109 (mult:TI (zero_extend:TI
7110 (match_operand:DI 1 "nonimmediate_operand" ""))
7112 (match_operand:DI 2 "register_operand" ""))))
7113 (clobber (reg:CC FLAGS_REG))])]
7117 (define_insn "*umulditi3_insn"
7118 [(set (match_operand:TI 0 "register_operand" "=A")
7119 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7120 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7121 (clobber (reg:CC FLAGS_REG))]
7123 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7125 [(set_attr "type" "imul")
7126 (set_attr "length_immediate" "0")
7127 (set (attr "athlon_decode")
7128 (if_then_else (eq_attr "cpu" "athlon")
7129 (const_string "vector")
7130 (const_string "double")))
7131 (set_attr "amdfam10_decode" "double")
7132 (set_attr "mode" "DI")])
7134 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7135 (define_expand "umulsidi3"
7136 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7137 (mult:DI (zero_extend:DI
7138 (match_operand:SI 1 "nonimmediate_operand" ""))
7140 (match_operand:SI 2 "register_operand" ""))))
7141 (clobber (reg:CC FLAGS_REG))])]
7145 (define_insn "*umulsidi3_insn"
7146 [(set (match_operand:DI 0 "register_operand" "=A")
7147 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7148 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7149 (clobber (reg:CC FLAGS_REG))]
7151 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7153 [(set_attr "type" "imul")
7154 (set_attr "length_immediate" "0")
7155 (set (attr "athlon_decode")
7156 (if_then_else (eq_attr "cpu" "athlon")
7157 (const_string "vector")
7158 (const_string "double")))
7159 (set_attr "amdfam10_decode" "double")
7160 (set_attr "mode" "SI")])
7162 (define_expand "mulditi3"
7163 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7164 (mult:TI (sign_extend:TI
7165 (match_operand:DI 1 "nonimmediate_operand" ""))
7167 (match_operand:DI 2 "register_operand" ""))))
7168 (clobber (reg:CC FLAGS_REG))])]
7172 (define_insn "*mulditi3_insn"
7173 [(set (match_operand:TI 0 "register_operand" "=A")
7174 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7175 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7176 (clobber (reg:CC FLAGS_REG))]
7178 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7180 [(set_attr "type" "imul")
7181 (set_attr "length_immediate" "0")
7182 (set (attr "athlon_decode")
7183 (if_then_else (eq_attr "cpu" "athlon")
7184 (const_string "vector")
7185 (const_string "double")))
7186 (set_attr "amdfam10_decode" "double")
7187 (set_attr "mode" "DI")])
7189 (define_expand "mulsidi3"
7190 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7191 (mult:DI (sign_extend:DI
7192 (match_operand:SI 1 "nonimmediate_operand" ""))
7194 (match_operand:SI 2 "register_operand" ""))))
7195 (clobber (reg:CC FLAGS_REG))])]
7199 (define_insn "*mulsidi3_insn"
7200 [(set (match_operand:DI 0 "register_operand" "=A")
7201 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7202 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7203 (clobber (reg:CC FLAGS_REG))]
7205 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7207 [(set_attr "type" "imul")
7208 (set_attr "length_immediate" "0")
7209 (set (attr "athlon_decode")
7210 (if_then_else (eq_attr "cpu" "athlon")
7211 (const_string "vector")
7212 (const_string "double")))
7213 (set_attr "amdfam10_decode" "double")
7214 (set_attr "mode" "SI")])
7216 (define_expand "umuldi3_highpart"
7217 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7220 (mult:TI (zero_extend:TI
7221 (match_operand:DI 1 "nonimmediate_operand" ""))
7223 (match_operand:DI 2 "register_operand" "")))
7225 (clobber (match_scratch:DI 3 ""))
7226 (clobber (reg:CC FLAGS_REG))])]
7230 (define_insn "*umuldi3_highpart_rex64"
7231 [(set (match_operand:DI 0 "register_operand" "=d")
7234 (mult:TI (zero_extend:TI
7235 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7237 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7239 (clobber (match_scratch:DI 3 "=1"))
7240 (clobber (reg:CC FLAGS_REG))]
7242 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7244 [(set_attr "type" "imul")
7245 (set_attr "length_immediate" "0")
7246 (set (attr "athlon_decode")
7247 (if_then_else (eq_attr "cpu" "athlon")
7248 (const_string "vector")
7249 (const_string "double")))
7250 (set_attr "amdfam10_decode" "double")
7251 (set_attr "mode" "DI")])
7253 (define_expand "umulsi3_highpart"
7254 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7257 (mult:DI (zero_extend:DI
7258 (match_operand:SI 1 "nonimmediate_operand" ""))
7260 (match_operand:SI 2 "register_operand" "")))
7262 (clobber (match_scratch:SI 3 ""))
7263 (clobber (reg:CC FLAGS_REG))])]
7267 (define_insn "*umulsi3_highpart_insn"
7268 [(set (match_operand:SI 0 "register_operand" "=d")
7271 (mult:DI (zero_extend:DI
7272 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7274 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7276 (clobber (match_scratch:SI 3 "=1"))
7277 (clobber (reg:CC FLAGS_REG))]
7278 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7280 [(set_attr "type" "imul")
7281 (set_attr "length_immediate" "0")
7282 (set (attr "athlon_decode")
7283 (if_then_else (eq_attr "cpu" "athlon")
7284 (const_string "vector")
7285 (const_string "double")))
7286 (set_attr "amdfam10_decode" "double")
7287 (set_attr "mode" "SI")])
7289 (define_insn "*umulsi3_highpart_zext"
7290 [(set (match_operand:DI 0 "register_operand" "=d")
7291 (zero_extend:DI (truncate:SI
7293 (mult:DI (zero_extend:DI
7294 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7296 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7298 (clobber (match_scratch:SI 3 "=1"))
7299 (clobber (reg:CC FLAGS_REG))]
7301 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7303 [(set_attr "type" "imul")
7304 (set_attr "length_immediate" "0")
7305 (set (attr "athlon_decode")
7306 (if_then_else (eq_attr "cpu" "athlon")
7307 (const_string "vector")
7308 (const_string "double")))
7309 (set_attr "amdfam10_decode" "double")
7310 (set_attr "mode" "SI")])
7312 (define_expand "smuldi3_highpart"
7313 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7316 (mult:TI (sign_extend:TI
7317 (match_operand:DI 1 "nonimmediate_operand" ""))
7319 (match_operand:DI 2 "register_operand" "")))
7321 (clobber (match_scratch:DI 3 ""))
7322 (clobber (reg:CC FLAGS_REG))])]
7326 (define_insn "*smuldi3_highpart_rex64"
7327 [(set (match_operand:DI 0 "register_operand" "=d")
7330 (mult:TI (sign_extend:TI
7331 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7333 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7335 (clobber (match_scratch:DI 3 "=1"))
7336 (clobber (reg:CC FLAGS_REG))]
7338 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7340 [(set_attr "type" "imul")
7341 (set (attr "athlon_decode")
7342 (if_then_else (eq_attr "cpu" "athlon")
7343 (const_string "vector")
7344 (const_string "double")))
7345 (set_attr "amdfam10_decode" "double")
7346 (set_attr "mode" "DI")])
7348 (define_expand "smulsi3_highpart"
7349 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7352 (mult:DI (sign_extend:DI
7353 (match_operand:SI 1 "nonimmediate_operand" ""))
7355 (match_operand:SI 2 "register_operand" "")))
7357 (clobber (match_scratch:SI 3 ""))
7358 (clobber (reg:CC FLAGS_REG))])]
7362 (define_insn "*smulsi3_highpart_insn"
7363 [(set (match_operand:SI 0 "register_operand" "=d")
7366 (mult:DI (sign_extend:DI
7367 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7369 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7371 (clobber (match_scratch:SI 3 "=1"))
7372 (clobber (reg:CC FLAGS_REG))]
7373 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7375 [(set_attr "type" "imul")
7376 (set (attr "athlon_decode")
7377 (if_then_else (eq_attr "cpu" "athlon")
7378 (const_string "vector")
7379 (const_string "double")))
7380 (set_attr "amdfam10_decode" "double")
7381 (set_attr "mode" "SI")])
7383 (define_insn "*smulsi3_highpart_zext"
7384 [(set (match_operand:DI 0 "register_operand" "=d")
7385 (zero_extend:DI (truncate:SI
7387 (mult:DI (sign_extend:DI
7388 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7390 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7392 (clobber (match_scratch:SI 3 "=1"))
7393 (clobber (reg:CC FLAGS_REG))]
7395 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7397 [(set_attr "type" "imul")
7398 (set (attr "athlon_decode")
7399 (if_then_else (eq_attr "cpu" "athlon")
7400 (const_string "vector")
7401 (const_string "double")))
7402 (set_attr "amdfam10_decode" "double")
7403 (set_attr "mode" "SI")])
7405 ;; The patterns that match these are at the end of this file.
7407 (define_expand "mulxf3"
7408 [(set (match_operand:XF 0 "register_operand" "")
7409 (mult:XF (match_operand:XF 1 "register_operand" "")
7410 (match_operand:XF 2 "register_operand" "")))]
7414 (define_expand "muldf3"
7415 [(set (match_operand:DF 0 "register_operand" "")
7416 (mult:DF (match_operand:DF 1 "register_operand" "")
7417 (match_operand:DF 2 "nonimmediate_operand" "")))]
7418 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7421 (define_expand "mulsf3"
7422 [(set (match_operand:SF 0 "register_operand" "")
7423 (mult:SF (match_operand:SF 1 "register_operand" "")
7424 (match_operand:SF 2 "nonimmediate_operand" "")))]
7425 "TARGET_80387 || TARGET_SSE_MATH"
7428 ;; Divide instructions
7430 (define_insn "divqi3"
7431 [(set (match_operand:QI 0 "register_operand" "=a")
7432 (div:QI (match_operand:HI 1 "register_operand" "0")
7433 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7434 (clobber (reg:CC FLAGS_REG))]
7435 "TARGET_QIMODE_MATH"
7437 [(set_attr "type" "idiv")
7438 (set_attr "mode" "QI")])
7440 (define_insn "udivqi3"
7441 [(set (match_operand:QI 0 "register_operand" "=a")
7442 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7443 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7444 (clobber (reg:CC FLAGS_REG))]
7445 "TARGET_QIMODE_MATH"
7447 [(set_attr "type" "idiv")
7448 (set_attr "mode" "QI")])
7450 ;; The patterns that match these are at the end of this file.
7452 (define_expand "divxf3"
7453 [(set (match_operand:XF 0 "register_operand" "")
7454 (div:XF (match_operand:XF 1 "register_operand" "")
7455 (match_operand:XF 2 "register_operand" "")))]
7459 (define_expand "divdf3"
7460 [(set (match_operand:DF 0 "register_operand" "")
7461 (div:DF (match_operand:DF 1 "register_operand" "")
7462 (match_operand:DF 2 "nonimmediate_operand" "")))]
7463 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7466 (define_expand "divsf3"
7467 [(set (match_operand:SF 0 "register_operand" "")
7468 (div:SF (match_operand:SF 1 "register_operand" "")
7469 (match_operand:SF 2 "nonimmediate_operand" "")))]
7470 "TARGET_80387 || TARGET_SSE_MATH"
7473 ;; Remainder instructions.
7475 (define_expand "divmoddi4"
7476 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7477 (div:DI (match_operand:DI 1 "register_operand" "")
7478 (match_operand:DI 2 "nonimmediate_operand" "")))
7479 (set (match_operand:DI 3 "register_operand" "")
7480 (mod:DI (match_dup 1) (match_dup 2)))
7481 (clobber (reg:CC FLAGS_REG))])]
7485 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7486 ;; Penalize eax case slightly because it results in worse scheduling
7488 (define_insn "*divmoddi4_nocltd_rex64"
7489 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7490 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7491 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7492 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7493 (mod:DI (match_dup 2) (match_dup 3)))
7494 (clobber (reg:CC FLAGS_REG))]
7495 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7497 [(set_attr "type" "multi")])
7499 (define_insn "*divmoddi4_cltd_rex64"
7500 [(set (match_operand:DI 0 "register_operand" "=a")
7501 (div:DI (match_operand:DI 2 "register_operand" "a")
7502 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7503 (set (match_operand:DI 1 "register_operand" "=&d")
7504 (mod:DI (match_dup 2) (match_dup 3)))
7505 (clobber (reg:CC FLAGS_REG))]
7506 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7508 [(set_attr "type" "multi")])
7510 (define_insn "*divmoddi_noext_rex64"
7511 [(set (match_operand:DI 0 "register_operand" "=a")
7512 (div:DI (match_operand:DI 1 "register_operand" "0")
7513 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7514 (set (match_operand:DI 3 "register_operand" "=d")
7515 (mod:DI (match_dup 1) (match_dup 2)))
7516 (use (match_operand:DI 4 "register_operand" "3"))
7517 (clobber (reg:CC FLAGS_REG))]
7520 [(set_attr "type" "idiv")
7521 (set_attr "mode" "DI")])
7524 [(set (match_operand:DI 0 "register_operand" "")
7525 (div:DI (match_operand:DI 1 "register_operand" "")
7526 (match_operand:DI 2 "nonimmediate_operand" "")))
7527 (set (match_operand:DI 3 "register_operand" "")
7528 (mod:DI (match_dup 1) (match_dup 2)))
7529 (clobber (reg:CC FLAGS_REG))]
7530 "TARGET_64BIT && reload_completed"
7531 [(parallel [(set (match_dup 3)
7532 (ashiftrt:DI (match_dup 4) (const_int 63)))
7533 (clobber (reg:CC FLAGS_REG))])
7534 (parallel [(set (match_dup 0)
7535 (div:DI (reg:DI 0) (match_dup 2)))
7537 (mod:DI (reg:DI 0) (match_dup 2)))
7539 (clobber (reg:CC FLAGS_REG))])]
7541 /* Avoid use of cltd in favor of a mov+shift. */
7542 if (!TARGET_USE_CLTD && !optimize_size)
7544 if (true_regnum (operands[1]))
7545 emit_move_insn (operands[0], operands[1]);
7547 emit_move_insn (operands[3], operands[1]);
7548 operands[4] = operands[3];
7552 gcc_assert (!true_regnum (operands[1]));
7553 operands[4] = operands[1];
7558 (define_expand "divmodsi4"
7559 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7560 (div:SI (match_operand:SI 1 "register_operand" "")
7561 (match_operand:SI 2 "nonimmediate_operand" "")))
7562 (set (match_operand:SI 3 "register_operand" "")
7563 (mod:SI (match_dup 1) (match_dup 2)))
7564 (clobber (reg:CC FLAGS_REG))])]
7568 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7569 ;; Penalize eax case slightly because it results in worse scheduling
7571 (define_insn "*divmodsi4_nocltd"
7572 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7573 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7574 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7575 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7576 (mod:SI (match_dup 2) (match_dup 3)))
7577 (clobber (reg:CC FLAGS_REG))]
7578 "!optimize_size && !TARGET_USE_CLTD"
7580 [(set_attr "type" "multi")])
7582 (define_insn "*divmodsi4_cltd"
7583 [(set (match_operand:SI 0 "register_operand" "=a")
7584 (div:SI (match_operand:SI 2 "register_operand" "a")
7585 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7586 (set (match_operand:SI 1 "register_operand" "=&d")
7587 (mod:SI (match_dup 2) (match_dup 3)))
7588 (clobber (reg:CC FLAGS_REG))]
7589 "optimize_size || TARGET_USE_CLTD"
7591 [(set_attr "type" "multi")])
7593 (define_insn "*divmodsi_noext"
7594 [(set (match_operand:SI 0 "register_operand" "=a")
7595 (div:SI (match_operand:SI 1 "register_operand" "0")
7596 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7597 (set (match_operand:SI 3 "register_operand" "=d")
7598 (mod:SI (match_dup 1) (match_dup 2)))
7599 (use (match_operand:SI 4 "register_operand" "3"))
7600 (clobber (reg:CC FLAGS_REG))]
7603 [(set_attr "type" "idiv")
7604 (set_attr "mode" "SI")])
7607 [(set (match_operand:SI 0 "register_operand" "")
7608 (div:SI (match_operand:SI 1 "register_operand" "")
7609 (match_operand:SI 2 "nonimmediate_operand" "")))
7610 (set (match_operand:SI 3 "register_operand" "")
7611 (mod:SI (match_dup 1) (match_dup 2)))
7612 (clobber (reg:CC FLAGS_REG))]
7614 [(parallel [(set (match_dup 3)
7615 (ashiftrt:SI (match_dup 4) (const_int 31)))
7616 (clobber (reg:CC FLAGS_REG))])
7617 (parallel [(set (match_dup 0)
7618 (div:SI (reg:SI 0) (match_dup 2)))
7620 (mod:SI (reg:SI 0) (match_dup 2)))
7622 (clobber (reg:CC FLAGS_REG))])]
7624 /* Avoid use of cltd in favor of a mov+shift. */
7625 if (!TARGET_USE_CLTD && !optimize_size)
7627 if (true_regnum (operands[1]))
7628 emit_move_insn (operands[0], operands[1]);
7630 emit_move_insn (operands[3], operands[1]);
7631 operands[4] = operands[3];
7635 gcc_assert (!true_regnum (operands[1]));
7636 operands[4] = operands[1];
7640 (define_insn "divmodhi4"
7641 [(set (match_operand:HI 0 "register_operand" "=a")
7642 (div:HI (match_operand:HI 1 "register_operand" "0")
7643 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7644 (set (match_operand:HI 3 "register_operand" "=&d")
7645 (mod:HI (match_dup 1) (match_dup 2)))
7646 (clobber (reg:CC FLAGS_REG))]
7647 "TARGET_HIMODE_MATH"
7649 [(set_attr "type" "multi")
7650 (set_attr "length_immediate" "0")
7651 (set_attr "mode" "SI")])
7653 (define_insn "udivmoddi4"
7654 [(set (match_operand:DI 0 "register_operand" "=a")
7655 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7656 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7657 (set (match_operand:DI 3 "register_operand" "=&d")
7658 (umod:DI (match_dup 1) (match_dup 2)))
7659 (clobber (reg:CC FLAGS_REG))]
7661 "xor{q}\t%3, %3\;div{q}\t%2"
7662 [(set_attr "type" "multi")
7663 (set_attr "length_immediate" "0")
7664 (set_attr "mode" "DI")])
7666 (define_insn "*udivmoddi4_noext"
7667 [(set (match_operand:DI 0 "register_operand" "=a")
7668 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7669 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7670 (set (match_operand:DI 3 "register_operand" "=d")
7671 (umod:DI (match_dup 1) (match_dup 2)))
7673 (clobber (reg:CC FLAGS_REG))]
7676 [(set_attr "type" "idiv")
7677 (set_attr "mode" "DI")])
7680 [(set (match_operand:DI 0 "register_operand" "")
7681 (udiv:DI (match_operand:DI 1 "register_operand" "")
7682 (match_operand:DI 2 "nonimmediate_operand" "")))
7683 (set (match_operand:DI 3 "register_operand" "")
7684 (umod:DI (match_dup 1) (match_dup 2)))
7685 (clobber (reg:CC FLAGS_REG))]
7686 "TARGET_64BIT && reload_completed"
7687 [(set (match_dup 3) (const_int 0))
7688 (parallel [(set (match_dup 0)
7689 (udiv:DI (match_dup 1) (match_dup 2)))
7691 (umod:DI (match_dup 1) (match_dup 2)))
7693 (clobber (reg:CC FLAGS_REG))])]
7696 (define_insn "udivmodsi4"
7697 [(set (match_operand:SI 0 "register_operand" "=a")
7698 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7699 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7700 (set (match_operand:SI 3 "register_operand" "=&d")
7701 (umod:SI (match_dup 1) (match_dup 2)))
7702 (clobber (reg:CC FLAGS_REG))]
7704 "xor{l}\t%3, %3\;div{l}\t%2"
7705 [(set_attr "type" "multi")
7706 (set_attr "length_immediate" "0")
7707 (set_attr "mode" "SI")])
7709 (define_insn "*udivmodsi4_noext"
7710 [(set (match_operand:SI 0 "register_operand" "=a")
7711 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7712 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7713 (set (match_operand:SI 3 "register_operand" "=d")
7714 (umod:SI (match_dup 1) (match_dup 2)))
7716 (clobber (reg:CC FLAGS_REG))]
7719 [(set_attr "type" "idiv")
7720 (set_attr "mode" "SI")])
7723 [(set (match_operand:SI 0 "register_operand" "")
7724 (udiv:SI (match_operand:SI 1 "register_operand" "")
7725 (match_operand:SI 2 "nonimmediate_operand" "")))
7726 (set (match_operand:SI 3 "register_operand" "")
7727 (umod:SI (match_dup 1) (match_dup 2)))
7728 (clobber (reg:CC FLAGS_REG))]
7730 [(set (match_dup 3) (const_int 0))
7731 (parallel [(set (match_dup 0)
7732 (udiv:SI (match_dup 1) (match_dup 2)))
7734 (umod:SI (match_dup 1) (match_dup 2)))
7736 (clobber (reg:CC FLAGS_REG))])]
7739 (define_expand "udivmodhi4"
7740 [(set (match_dup 4) (const_int 0))
7741 (parallel [(set (match_operand:HI 0 "register_operand" "")
7742 (udiv:HI (match_operand:HI 1 "register_operand" "")
7743 (match_operand:HI 2 "nonimmediate_operand" "")))
7744 (set (match_operand:HI 3 "register_operand" "")
7745 (umod:HI (match_dup 1) (match_dup 2)))
7747 (clobber (reg:CC FLAGS_REG))])]
7748 "TARGET_HIMODE_MATH"
7749 "operands[4] = gen_reg_rtx (HImode);")
7751 (define_insn "*udivmodhi_noext"
7752 [(set (match_operand:HI 0 "register_operand" "=a")
7753 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7754 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7755 (set (match_operand:HI 3 "register_operand" "=d")
7756 (umod:HI (match_dup 1) (match_dup 2)))
7757 (use (match_operand:HI 4 "register_operand" "3"))
7758 (clobber (reg:CC FLAGS_REG))]
7761 [(set_attr "type" "idiv")
7762 (set_attr "mode" "HI")])
7764 ;; We cannot use div/idiv for double division, because it causes
7765 ;; "division by zero" on the overflow and that's not what we expect
7766 ;; from truncate. Because true (non truncating) double division is
7767 ;; never generated, we can't create this insn anyway.
7770 ; [(set (match_operand:SI 0 "register_operand" "=a")
7772 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7774 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7775 ; (set (match_operand:SI 3 "register_operand" "=d")
7777 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7778 ; (clobber (reg:CC FLAGS_REG))]
7780 ; "div{l}\t{%2, %0|%0, %2}"
7781 ; [(set_attr "type" "idiv")])
7783 ;;- Logical AND instructions
7785 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7786 ;; Note that this excludes ah.
7788 (define_insn "*testdi_1_rex64"
7789 [(set (reg FLAGS_REG)
7791 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7792 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7794 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7795 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7797 test{l}\t{%k1, %k0|%k0, %k1}
7798 test{l}\t{%k1, %k0|%k0, %k1}
7799 test{q}\t{%1, %0|%0, %1}
7800 test{q}\t{%1, %0|%0, %1}
7801 test{q}\t{%1, %0|%0, %1}"
7802 [(set_attr "type" "test")
7803 (set_attr "modrm" "0,1,0,1,1")
7804 (set_attr "mode" "SI,SI,DI,DI,DI")
7805 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7807 (define_insn "testsi_1"
7808 [(set (reg FLAGS_REG)
7810 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7811 (match_operand:SI 1 "general_operand" "in,in,rin"))
7813 "ix86_match_ccmode (insn, CCNOmode)
7814 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7815 "test{l}\t{%1, %0|%0, %1}"
7816 [(set_attr "type" "test")
7817 (set_attr "modrm" "0,1,1")
7818 (set_attr "mode" "SI")
7819 (set_attr "pent_pair" "uv,np,uv")])
7821 (define_expand "testsi_ccno_1"
7822 [(set (reg:CCNO FLAGS_REG)
7824 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7825 (match_operand:SI 1 "nonmemory_operand" ""))
7830 (define_insn "*testhi_1"
7831 [(set (reg FLAGS_REG)
7832 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7833 (match_operand:HI 1 "general_operand" "n,n,rn"))
7835 "ix86_match_ccmode (insn, CCNOmode)
7836 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7837 "test{w}\t{%1, %0|%0, %1}"
7838 [(set_attr "type" "test")
7839 (set_attr "modrm" "0,1,1")
7840 (set_attr "mode" "HI")
7841 (set_attr "pent_pair" "uv,np,uv")])
7843 (define_expand "testqi_ccz_1"
7844 [(set (reg:CCZ FLAGS_REG)
7845 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7846 (match_operand:QI 1 "nonmemory_operand" ""))
7851 (define_insn "*testqi_1_maybe_si"
7852 [(set (reg FLAGS_REG)
7855 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7856 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7858 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7859 && ix86_match_ccmode (insn,
7860 CONST_INT_P (operands[1])
7861 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7863 if (which_alternative == 3)
7865 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7866 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7867 return "test{l}\t{%1, %k0|%k0, %1}";
7869 return "test{b}\t{%1, %0|%0, %1}";
7871 [(set_attr "type" "test")
7872 (set_attr "modrm" "0,1,1,1")
7873 (set_attr "mode" "QI,QI,QI,SI")
7874 (set_attr "pent_pair" "uv,np,uv,np")])
7876 (define_insn "*testqi_1"
7877 [(set (reg FLAGS_REG)
7880 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7881 (match_operand:QI 1 "general_operand" "n,n,qn"))
7883 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7884 && ix86_match_ccmode (insn, CCNOmode)"
7885 "test{b}\t{%1, %0|%0, %1}"
7886 [(set_attr "type" "test")
7887 (set_attr "modrm" "0,1,1")
7888 (set_attr "mode" "QI")
7889 (set_attr "pent_pair" "uv,np,uv")])
7891 (define_expand "testqi_ext_ccno_0"
7892 [(set (reg:CCNO FLAGS_REG)
7896 (match_operand 0 "ext_register_operand" "")
7899 (match_operand 1 "const_int_operand" ""))
7904 (define_insn "*testqi_ext_0"
7905 [(set (reg FLAGS_REG)
7909 (match_operand 0 "ext_register_operand" "Q")
7912 (match_operand 1 "const_int_operand" "n"))
7914 "ix86_match_ccmode (insn, CCNOmode)"
7915 "test{b}\t{%1, %h0|%h0, %1}"
7916 [(set_attr "type" "test")
7917 (set_attr "mode" "QI")
7918 (set_attr "length_immediate" "1")
7919 (set_attr "pent_pair" "np")])
7921 (define_insn "*testqi_ext_1"
7922 [(set (reg FLAGS_REG)
7926 (match_operand 0 "ext_register_operand" "Q")
7930 (match_operand:QI 1 "general_operand" "Qm")))
7932 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7933 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7934 "test{b}\t{%1, %h0|%h0, %1}"
7935 [(set_attr "type" "test")
7936 (set_attr "mode" "QI")])
7938 (define_insn "*testqi_ext_1_rex64"
7939 [(set (reg FLAGS_REG)
7943 (match_operand 0 "ext_register_operand" "Q")
7947 (match_operand:QI 1 "register_operand" "Q")))
7949 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7950 "test{b}\t{%1, %h0|%h0, %1}"
7951 [(set_attr "type" "test")
7952 (set_attr "mode" "QI")])
7954 (define_insn "*testqi_ext_2"
7955 [(set (reg FLAGS_REG)
7959 (match_operand 0 "ext_register_operand" "Q")
7963 (match_operand 1 "ext_register_operand" "Q")
7967 "ix86_match_ccmode (insn, CCNOmode)"
7968 "test{b}\t{%h1, %h0|%h0, %h1}"
7969 [(set_attr "type" "test")
7970 (set_attr "mode" "QI")])
7972 ;; Combine likes to form bit extractions for some tests. Humor it.
7973 (define_insn "*testqi_ext_3"
7974 [(set (reg FLAGS_REG)
7975 (compare (zero_extract:SI
7976 (match_operand 0 "nonimmediate_operand" "rm")
7977 (match_operand:SI 1 "const_int_operand" "")
7978 (match_operand:SI 2 "const_int_operand" ""))
7980 "ix86_match_ccmode (insn, CCNOmode)
7981 && INTVAL (operands[1]) > 0
7982 && INTVAL (operands[2]) >= 0
7983 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7984 && (GET_MODE (operands[0]) == SImode
7985 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7986 || GET_MODE (operands[0]) == HImode
7987 || GET_MODE (operands[0]) == QImode)"
7990 (define_insn "*testqi_ext_3_rex64"
7991 [(set (reg FLAGS_REG)
7992 (compare (zero_extract:DI
7993 (match_operand 0 "nonimmediate_operand" "rm")
7994 (match_operand:DI 1 "const_int_operand" "")
7995 (match_operand:DI 2 "const_int_operand" ""))
7998 && ix86_match_ccmode (insn, CCNOmode)
7999 && INTVAL (operands[1]) > 0
8000 && INTVAL (operands[2]) >= 0
8001 /* Ensure that resulting mask is zero or sign extended operand. */
8002 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8003 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8004 && INTVAL (operands[1]) > 32))
8005 && (GET_MODE (operands[0]) == SImode
8006 || GET_MODE (operands[0]) == DImode
8007 || GET_MODE (operands[0]) == HImode
8008 || GET_MODE (operands[0]) == QImode)"
8012 [(set (match_operand 0 "flags_reg_operand" "")
8013 (match_operator 1 "compare_operator"
8015 (match_operand 2 "nonimmediate_operand" "")
8016 (match_operand 3 "const_int_operand" "")
8017 (match_operand 4 "const_int_operand" ""))
8019 "ix86_match_ccmode (insn, CCNOmode)"
8020 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8022 rtx val = operands[2];
8023 HOST_WIDE_INT len = INTVAL (operands[3]);
8024 HOST_WIDE_INT pos = INTVAL (operands[4]);
8026 enum machine_mode mode, submode;
8028 mode = GET_MODE (val);
8031 /* ??? Combine likes to put non-volatile mem extractions in QImode
8032 no matter the size of the test. So find a mode that works. */
8033 if (! MEM_VOLATILE_P (val))
8035 mode = smallest_mode_for_size (pos + len, MODE_INT);
8036 val = adjust_address (val, mode, 0);
8039 else if (GET_CODE (val) == SUBREG
8040 && (submode = GET_MODE (SUBREG_REG (val)),
8041 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8042 && pos + len <= GET_MODE_BITSIZE (submode))
8044 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8046 val = SUBREG_REG (val);
8048 else if (mode == HImode && pos + len <= 8)
8050 /* Small HImode tests can be converted to QImode. */
8052 val = gen_lowpart (QImode, val);
8055 if (len == HOST_BITS_PER_WIDE_INT)
8058 mask = ((HOST_WIDE_INT)1 << len) - 1;
8061 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8064 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8065 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8066 ;; this is relatively important trick.
8067 ;; Do the conversion only post-reload to avoid limiting of the register class
8070 [(set (match_operand 0 "flags_reg_operand" "")
8071 (match_operator 1 "compare_operator"
8072 [(and (match_operand 2 "register_operand" "")
8073 (match_operand 3 "const_int_operand" ""))
8076 && QI_REG_P (operands[2])
8077 && GET_MODE (operands[2]) != QImode
8078 && ((ix86_match_ccmode (insn, CCZmode)
8079 && !(INTVAL (operands[3]) & ~(255 << 8)))
8080 || (ix86_match_ccmode (insn, CCNOmode)
8081 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8084 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8087 "operands[2] = gen_lowpart (SImode, operands[2]);
8088 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8091 [(set (match_operand 0 "flags_reg_operand" "")
8092 (match_operator 1 "compare_operator"
8093 [(and (match_operand 2 "nonimmediate_operand" "")
8094 (match_operand 3 "const_int_operand" ""))
8097 && GET_MODE (operands[2]) != QImode
8098 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8099 && ((ix86_match_ccmode (insn, CCZmode)
8100 && !(INTVAL (operands[3]) & ~255))
8101 || (ix86_match_ccmode (insn, CCNOmode)
8102 && !(INTVAL (operands[3]) & ~127)))"
8104 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8106 "operands[2] = gen_lowpart (QImode, operands[2]);
8107 operands[3] = gen_lowpart (QImode, operands[3]);")
8110 ;; %%% This used to optimize known byte-wide and operations to memory,
8111 ;; and sometimes to QImode registers. If this is considered useful,
8112 ;; it should be done with splitters.
8114 (define_expand "anddi3"
8115 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8116 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8117 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8118 (clobber (reg:CC FLAGS_REG))]
8120 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8122 (define_insn "*anddi_1_rex64"
8123 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8124 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8125 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8126 (clobber (reg:CC FLAGS_REG))]
8127 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8129 switch (get_attr_type (insn))
8133 enum machine_mode mode;
8135 gcc_assert (CONST_INT_P (operands[2]));
8136 if (INTVAL (operands[2]) == 0xff)
8140 gcc_assert (INTVAL (operands[2]) == 0xffff);
8144 operands[1] = gen_lowpart (mode, operands[1]);
8146 return "movz{bq|x}\t{%1,%0|%0, %1}";
8148 return "movz{wq|x}\t{%1,%0|%0, %1}";
8152 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8153 if (get_attr_mode (insn) == MODE_SI)
8154 return "and{l}\t{%k2, %k0|%k0, %k2}";
8156 return "and{q}\t{%2, %0|%0, %2}";
8159 [(set_attr "type" "alu,alu,alu,imovx")
8160 (set_attr "length_immediate" "*,*,*,0")
8161 (set_attr "mode" "SI,DI,DI,DI")])
8163 (define_insn "*anddi_2"
8164 [(set (reg FLAGS_REG)
8165 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8166 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8168 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8169 (and:DI (match_dup 1) (match_dup 2)))]
8170 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8171 && ix86_binary_operator_ok (AND, DImode, operands)"
8173 and{l}\t{%k2, %k0|%k0, %k2}
8174 and{q}\t{%2, %0|%0, %2}
8175 and{q}\t{%2, %0|%0, %2}"
8176 [(set_attr "type" "alu")
8177 (set_attr "mode" "SI,DI,DI")])
8179 (define_expand "andsi3"
8180 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8181 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8182 (match_operand:SI 2 "general_operand" "")))
8183 (clobber (reg:CC FLAGS_REG))]
8185 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8187 (define_insn "*andsi_1"
8188 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8189 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8190 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8191 (clobber (reg:CC FLAGS_REG))]
8192 "ix86_binary_operator_ok (AND, SImode, operands)"
8194 switch (get_attr_type (insn))
8198 enum machine_mode mode;
8200 gcc_assert (CONST_INT_P (operands[2]));
8201 if (INTVAL (operands[2]) == 0xff)
8205 gcc_assert (INTVAL (operands[2]) == 0xffff);
8209 operands[1] = gen_lowpart (mode, operands[1]);
8211 return "movz{bl|x}\t{%1,%0|%0, %1}";
8213 return "movz{wl|x}\t{%1,%0|%0, %1}";
8217 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8218 return "and{l}\t{%2, %0|%0, %2}";
8221 [(set_attr "type" "alu,alu,imovx")
8222 (set_attr "length_immediate" "*,*,0")
8223 (set_attr "mode" "SI")])
8226 [(set (match_operand 0 "register_operand" "")
8228 (const_int -65536)))
8229 (clobber (reg:CC FLAGS_REG))]
8230 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8231 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8232 "operands[1] = gen_lowpart (HImode, operands[0]);")
8235 [(set (match_operand 0 "ext_register_operand" "")
8238 (clobber (reg:CC FLAGS_REG))]
8239 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8240 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8241 "operands[1] = gen_lowpart (QImode, operands[0]);")
8244 [(set (match_operand 0 "ext_register_operand" "")
8246 (const_int -65281)))
8247 (clobber (reg:CC FLAGS_REG))]
8248 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8249 [(parallel [(set (zero_extract:SI (match_dup 0)
8253 (zero_extract:SI (match_dup 0)
8256 (zero_extract:SI (match_dup 0)
8259 (clobber (reg:CC FLAGS_REG))])]
8260 "operands[0] = gen_lowpart (SImode, operands[0]);")
8262 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8263 (define_insn "*andsi_1_zext"
8264 [(set (match_operand:DI 0 "register_operand" "=r")
8266 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8267 (match_operand:SI 2 "general_operand" "rim"))))
8268 (clobber (reg:CC FLAGS_REG))]
8269 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8270 "and{l}\t{%2, %k0|%k0, %2}"
8271 [(set_attr "type" "alu")
8272 (set_attr "mode" "SI")])
8274 (define_insn "*andsi_2"
8275 [(set (reg FLAGS_REG)
8276 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8277 (match_operand:SI 2 "general_operand" "rim,ri"))
8279 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8280 (and:SI (match_dup 1) (match_dup 2)))]
8281 "ix86_match_ccmode (insn, CCNOmode)
8282 && ix86_binary_operator_ok (AND, SImode, operands)"
8283 "and{l}\t{%2, %0|%0, %2}"
8284 [(set_attr "type" "alu")
8285 (set_attr "mode" "SI")])
8287 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8288 (define_insn "*andsi_2_zext"
8289 [(set (reg FLAGS_REG)
8290 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8291 (match_operand:SI 2 "general_operand" "rim"))
8293 (set (match_operand:DI 0 "register_operand" "=r")
8294 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8295 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8296 && ix86_binary_operator_ok (AND, SImode, operands)"
8297 "and{l}\t{%2, %k0|%k0, %2}"
8298 [(set_attr "type" "alu")
8299 (set_attr "mode" "SI")])
8301 (define_expand "andhi3"
8302 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8303 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8304 (match_operand:HI 2 "general_operand" "")))
8305 (clobber (reg:CC FLAGS_REG))]
8306 "TARGET_HIMODE_MATH"
8307 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8309 (define_insn "*andhi_1"
8310 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8311 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8312 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8313 (clobber (reg:CC FLAGS_REG))]
8314 "ix86_binary_operator_ok (AND, HImode, operands)"
8316 switch (get_attr_type (insn))
8319 gcc_assert (CONST_INT_P (operands[2]));
8320 gcc_assert (INTVAL (operands[2]) == 0xff);
8321 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8324 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8326 return "and{w}\t{%2, %0|%0, %2}";
8329 [(set_attr "type" "alu,alu,imovx")
8330 (set_attr "length_immediate" "*,*,0")
8331 (set_attr "mode" "HI,HI,SI")])
8333 (define_insn "*andhi_2"
8334 [(set (reg FLAGS_REG)
8335 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8336 (match_operand:HI 2 "general_operand" "rim,ri"))
8338 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8339 (and:HI (match_dup 1) (match_dup 2)))]
8340 "ix86_match_ccmode (insn, CCNOmode)
8341 && ix86_binary_operator_ok (AND, HImode, operands)"
8342 "and{w}\t{%2, %0|%0, %2}"
8343 [(set_attr "type" "alu")
8344 (set_attr "mode" "HI")])
8346 (define_expand "andqi3"
8347 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8348 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8349 (match_operand:QI 2 "general_operand" "")))
8350 (clobber (reg:CC FLAGS_REG))]
8351 "TARGET_QIMODE_MATH"
8352 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8354 ;; %%% Potential partial reg stall on alternative 2. What to do?
8355 (define_insn "*andqi_1"
8356 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8357 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8358 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8359 (clobber (reg:CC FLAGS_REG))]
8360 "ix86_binary_operator_ok (AND, QImode, operands)"
8362 and{b}\t{%2, %0|%0, %2}
8363 and{b}\t{%2, %0|%0, %2}
8364 and{l}\t{%k2, %k0|%k0, %k2}"
8365 [(set_attr "type" "alu")
8366 (set_attr "mode" "QI,QI,SI")])
8368 (define_insn "*andqi_1_slp"
8369 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8370 (and:QI (match_dup 0)
8371 (match_operand:QI 1 "general_operand" "qi,qmi")))
8372 (clobber (reg:CC FLAGS_REG))]
8373 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8374 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8375 "and{b}\t{%1, %0|%0, %1}"
8376 [(set_attr "type" "alu1")
8377 (set_attr "mode" "QI")])
8379 (define_insn "*andqi_2_maybe_si"
8380 [(set (reg FLAGS_REG)
8382 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8383 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8385 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8386 (and:QI (match_dup 1) (match_dup 2)))]
8387 "ix86_binary_operator_ok (AND, QImode, operands)
8388 && ix86_match_ccmode (insn,
8389 CONST_INT_P (operands[2])
8390 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8392 if (which_alternative == 2)
8394 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8395 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8396 return "and{l}\t{%2, %k0|%k0, %2}";
8398 return "and{b}\t{%2, %0|%0, %2}";
8400 [(set_attr "type" "alu")
8401 (set_attr "mode" "QI,QI,SI")])
8403 (define_insn "*andqi_2"
8404 [(set (reg FLAGS_REG)
8406 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8407 (match_operand:QI 2 "general_operand" "qim,qi"))
8409 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8410 (and:QI (match_dup 1) (match_dup 2)))]
8411 "ix86_match_ccmode (insn, CCNOmode)
8412 && ix86_binary_operator_ok (AND, QImode, operands)"
8413 "and{b}\t{%2, %0|%0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "mode" "QI")])
8417 (define_insn "*andqi_2_slp"
8418 [(set (reg FLAGS_REG)
8420 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8421 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8423 (set (strict_low_part (match_dup 0))
8424 (and:QI (match_dup 0) (match_dup 1)))]
8425 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8426 && ix86_match_ccmode (insn, CCNOmode)
8427 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8428 "and{b}\t{%1, %0|%0, %1}"
8429 [(set_attr "type" "alu1")
8430 (set_attr "mode" "QI")])
8432 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8433 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8434 ;; for a QImode operand, which of course failed.
8436 (define_insn "andqi_ext_0"
8437 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8442 (match_operand 1 "ext_register_operand" "0")
8445 (match_operand 2 "const_int_operand" "n")))
8446 (clobber (reg:CC FLAGS_REG))]
8448 "and{b}\t{%2, %h0|%h0, %2}"
8449 [(set_attr "type" "alu")
8450 (set_attr "length_immediate" "1")
8451 (set_attr "mode" "QI")])
8453 ;; Generated by peephole translating test to and. This shows up
8454 ;; often in fp comparisons.
8456 (define_insn "*andqi_ext_0_cc"
8457 [(set (reg FLAGS_REG)
8461 (match_operand 1 "ext_register_operand" "0")
8464 (match_operand 2 "const_int_operand" "n"))
8466 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8475 "ix86_match_ccmode (insn, CCNOmode)"
8476 "and{b}\t{%2, %h0|%h0, %2}"
8477 [(set_attr "type" "alu")
8478 (set_attr "length_immediate" "1")
8479 (set_attr "mode" "QI")])
8481 (define_insn "*andqi_ext_1"
8482 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8487 (match_operand 1 "ext_register_operand" "0")
8491 (match_operand:QI 2 "general_operand" "Qm"))))
8492 (clobber (reg:CC FLAGS_REG))]
8494 "and{b}\t{%2, %h0|%h0, %2}"
8495 [(set_attr "type" "alu")
8496 (set_attr "length_immediate" "0")
8497 (set_attr "mode" "QI")])
8499 (define_insn "*andqi_ext_1_rex64"
8500 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8505 (match_operand 1 "ext_register_operand" "0")
8509 (match_operand 2 "ext_register_operand" "Q"))))
8510 (clobber (reg:CC FLAGS_REG))]
8512 "and{b}\t{%2, %h0|%h0, %2}"
8513 [(set_attr "type" "alu")
8514 (set_attr "length_immediate" "0")
8515 (set_attr "mode" "QI")])
8517 (define_insn "*andqi_ext_2"
8518 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8523 (match_operand 1 "ext_register_operand" "%0")
8527 (match_operand 2 "ext_register_operand" "Q")
8530 (clobber (reg:CC FLAGS_REG))]
8532 "and{b}\t{%h2, %h0|%h0, %h2}"
8533 [(set_attr "type" "alu")
8534 (set_attr "length_immediate" "0")
8535 (set_attr "mode" "QI")])
8537 ;; Convert wide AND instructions with immediate operand to shorter QImode
8538 ;; equivalents when possible.
8539 ;; Don't do the splitting with memory operands, since it introduces risk
8540 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8541 ;; for size, but that can (should?) be handled by generic code instead.
8543 [(set (match_operand 0 "register_operand" "")
8544 (and (match_operand 1 "register_operand" "")
8545 (match_operand 2 "const_int_operand" "")))
8546 (clobber (reg:CC FLAGS_REG))]
8548 && QI_REG_P (operands[0])
8549 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8550 && !(~INTVAL (operands[2]) & ~(255 << 8))
8551 && GET_MODE (operands[0]) != QImode"
8552 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8553 (and:SI (zero_extract:SI (match_dup 1)
8554 (const_int 8) (const_int 8))
8556 (clobber (reg:CC FLAGS_REG))])]
8557 "operands[0] = gen_lowpart (SImode, operands[0]);
8558 operands[1] = gen_lowpart (SImode, operands[1]);
8559 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8561 ;; Since AND can be encoded with sign extended immediate, this is only
8562 ;; profitable when 7th bit is not set.
8564 [(set (match_operand 0 "register_operand" "")
8565 (and (match_operand 1 "general_operand" "")
8566 (match_operand 2 "const_int_operand" "")))
8567 (clobber (reg:CC FLAGS_REG))]
8569 && ANY_QI_REG_P (operands[0])
8570 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8571 && !(~INTVAL (operands[2]) & ~255)
8572 && !(INTVAL (operands[2]) & 128)
8573 && GET_MODE (operands[0]) != QImode"
8574 [(parallel [(set (strict_low_part (match_dup 0))
8575 (and:QI (match_dup 1)
8577 (clobber (reg:CC FLAGS_REG))])]
8578 "operands[0] = gen_lowpart (QImode, operands[0]);
8579 operands[1] = gen_lowpart (QImode, operands[1]);
8580 operands[2] = gen_lowpart (QImode, operands[2]);")
8582 ;; Logical inclusive OR instructions
8584 ;; %%% This used to optimize known byte-wide and operations to memory.
8585 ;; If this is considered useful, it should be done with splitters.
8587 (define_expand "iordi3"
8588 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8589 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8590 (match_operand:DI 2 "x86_64_general_operand" "")))
8591 (clobber (reg:CC FLAGS_REG))]
8593 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8595 (define_insn "*iordi_1_rex64"
8596 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8597 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8598 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8599 (clobber (reg:CC FLAGS_REG))]
8601 && ix86_binary_operator_ok (IOR, DImode, operands)"
8602 "or{q}\t{%2, %0|%0, %2}"
8603 [(set_attr "type" "alu")
8604 (set_attr "mode" "DI")])
8606 (define_insn "*iordi_2_rex64"
8607 [(set (reg FLAGS_REG)
8608 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8609 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8611 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8612 (ior:DI (match_dup 1) (match_dup 2)))]
8614 && ix86_match_ccmode (insn, CCNOmode)
8615 && ix86_binary_operator_ok (IOR, DImode, operands)"
8616 "or{q}\t{%2, %0|%0, %2}"
8617 [(set_attr "type" "alu")
8618 (set_attr "mode" "DI")])
8620 (define_insn "*iordi_3_rex64"
8621 [(set (reg FLAGS_REG)
8622 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8623 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8625 (clobber (match_scratch:DI 0 "=r"))]
8627 && ix86_match_ccmode (insn, CCNOmode)
8628 && ix86_binary_operator_ok (IOR, DImode, operands)"
8629 "or{q}\t{%2, %0|%0, %2}"
8630 [(set_attr "type" "alu")
8631 (set_attr "mode" "DI")])
8634 (define_expand "iorsi3"
8635 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8636 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8637 (match_operand:SI 2 "general_operand" "")))
8638 (clobber (reg:CC FLAGS_REG))]
8640 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8642 (define_insn "*iorsi_1"
8643 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8644 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8645 (match_operand:SI 2 "general_operand" "ri,rmi")))
8646 (clobber (reg:CC FLAGS_REG))]
8647 "ix86_binary_operator_ok (IOR, SImode, operands)"
8648 "or{l}\t{%2, %0|%0, %2}"
8649 [(set_attr "type" "alu")
8650 (set_attr "mode" "SI")])
8652 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8653 (define_insn "*iorsi_1_zext"
8654 [(set (match_operand:DI 0 "register_operand" "=rm")
8656 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8657 (match_operand:SI 2 "general_operand" "rim"))))
8658 (clobber (reg:CC FLAGS_REG))]
8659 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8660 "or{l}\t{%2, %k0|%k0, %2}"
8661 [(set_attr "type" "alu")
8662 (set_attr "mode" "SI")])
8664 (define_insn "*iorsi_1_zext_imm"
8665 [(set (match_operand:DI 0 "register_operand" "=rm")
8666 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8667 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8668 (clobber (reg:CC FLAGS_REG))]
8670 "or{l}\t{%2, %k0|%k0, %2}"
8671 [(set_attr "type" "alu")
8672 (set_attr "mode" "SI")])
8674 (define_insn "*iorsi_2"
8675 [(set (reg FLAGS_REG)
8676 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8677 (match_operand:SI 2 "general_operand" "rim,ri"))
8679 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8680 (ior:SI (match_dup 1) (match_dup 2)))]
8681 "ix86_match_ccmode (insn, CCNOmode)
8682 && ix86_binary_operator_ok (IOR, SImode, operands)"
8683 "or{l}\t{%2, %0|%0, %2}"
8684 [(set_attr "type" "alu")
8685 (set_attr "mode" "SI")])
8687 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8688 ;; ??? Special case for immediate operand is missing - it is tricky.
8689 (define_insn "*iorsi_2_zext"
8690 [(set (reg FLAGS_REG)
8691 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8692 (match_operand:SI 2 "general_operand" "rim"))
8694 (set (match_operand:DI 0 "register_operand" "=r")
8695 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8696 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8697 && ix86_binary_operator_ok (IOR, SImode, operands)"
8698 "or{l}\t{%2, %k0|%k0, %2}"
8699 [(set_attr "type" "alu")
8700 (set_attr "mode" "SI")])
8702 (define_insn "*iorsi_2_zext_imm"
8703 [(set (reg FLAGS_REG)
8704 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8705 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8707 (set (match_operand:DI 0 "register_operand" "=r")
8708 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8709 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8710 && ix86_binary_operator_ok (IOR, SImode, operands)"
8711 "or{l}\t{%2, %k0|%k0, %2}"
8712 [(set_attr "type" "alu")
8713 (set_attr "mode" "SI")])
8715 (define_insn "*iorsi_3"
8716 [(set (reg FLAGS_REG)
8717 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8718 (match_operand:SI 2 "general_operand" "rim"))
8720 (clobber (match_scratch:SI 0 "=r"))]
8721 "ix86_match_ccmode (insn, CCNOmode)
8722 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8723 "or{l}\t{%2, %0|%0, %2}"
8724 [(set_attr "type" "alu")
8725 (set_attr "mode" "SI")])
8727 (define_expand "iorhi3"
8728 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8729 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8730 (match_operand:HI 2 "general_operand" "")))
8731 (clobber (reg:CC FLAGS_REG))]
8732 "TARGET_HIMODE_MATH"
8733 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8735 (define_insn "*iorhi_1"
8736 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8737 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8738 (match_operand:HI 2 "general_operand" "rmi,ri")))
8739 (clobber (reg:CC FLAGS_REG))]
8740 "ix86_binary_operator_ok (IOR, HImode, operands)"
8741 "or{w}\t{%2, %0|%0, %2}"
8742 [(set_attr "type" "alu")
8743 (set_attr "mode" "HI")])
8745 (define_insn "*iorhi_2"
8746 [(set (reg FLAGS_REG)
8747 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8748 (match_operand:HI 2 "general_operand" "rim,ri"))
8750 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8751 (ior:HI (match_dup 1) (match_dup 2)))]
8752 "ix86_match_ccmode (insn, CCNOmode)
8753 && ix86_binary_operator_ok (IOR, HImode, operands)"
8754 "or{w}\t{%2, %0|%0, %2}"
8755 [(set_attr "type" "alu")
8756 (set_attr "mode" "HI")])
8758 (define_insn "*iorhi_3"
8759 [(set (reg FLAGS_REG)
8760 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8761 (match_operand:HI 2 "general_operand" "rim"))
8763 (clobber (match_scratch:HI 0 "=r"))]
8764 "ix86_match_ccmode (insn, CCNOmode)
8765 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8766 "or{w}\t{%2, %0|%0, %2}"
8767 [(set_attr "type" "alu")
8768 (set_attr "mode" "HI")])
8770 (define_expand "iorqi3"
8771 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8772 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8773 (match_operand:QI 2 "general_operand" "")))
8774 (clobber (reg:CC FLAGS_REG))]
8775 "TARGET_QIMODE_MATH"
8776 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8778 ;; %%% Potential partial reg stall on alternative 2. What to do?
8779 (define_insn "*iorqi_1"
8780 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8781 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8782 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8783 (clobber (reg:CC FLAGS_REG))]
8784 "ix86_binary_operator_ok (IOR, QImode, operands)"
8786 or{b}\t{%2, %0|%0, %2}
8787 or{b}\t{%2, %0|%0, %2}
8788 or{l}\t{%k2, %k0|%k0, %k2}"
8789 [(set_attr "type" "alu")
8790 (set_attr "mode" "QI,QI,SI")])
8792 (define_insn "*iorqi_1_slp"
8793 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8794 (ior:QI (match_dup 0)
8795 (match_operand:QI 1 "general_operand" "qmi,qi")))
8796 (clobber (reg:CC FLAGS_REG))]
8797 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8798 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8799 "or{b}\t{%1, %0|%0, %1}"
8800 [(set_attr "type" "alu1")
8801 (set_attr "mode" "QI")])
8803 (define_insn "*iorqi_2"
8804 [(set (reg FLAGS_REG)
8805 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8806 (match_operand:QI 2 "general_operand" "qim,qi"))
8808 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8809 (ior:QI (match_dup 1) (match_dup 2)))]
8810 "ix86_match_ccmode (insn, CCNOmode)
8811 && ix86_binary_operator_ok (IOR, QImode, operands)"
8812 "or{b}\t{%2, %0|%0, %2}"
8813 [(set_attr "type" "alu")
8814 (set_attr "mode" "QI")])
8816 (define_insn "*iorqi_2_slp"
8817 [(set (reg FLAGS_REG)
8818 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8819 (match_operand:QI 1 "general_operand" "qim,qi"))
8821 (set (strict_low_part (match_dup 0))
8822 (ior:QI (match_dup 0) (match_dup 1)))]
8823 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8824 && ix86_match_ccmode (insn, CCNOmode)
8825 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8826 "or{b}\t{%1, %0|%0, %1}"
8827 [(set_attr "type" "alu1")
8828 (set_attr "mode" "QI")])
8830 (define_insn "*iorqi_3"
8831 [(set (reg FLAGS_REG)
8832 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8833 (match_operand:QI 2 "general_operand" "qim"))
8835 (clobber (match_scratch:QI 0 "=q"))]
8836 "ix86_match_ccmode (insn, CCNOmode)
8837 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8838 "or{b}\t{%2, %0|%0, %2}"
8839 [(set_attr "type" "alu")
8840 (set_attr "mode" "QI")])
8842 (define_insn "iorqi_ext_0"
8843 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8848 (match_operand 1 "ext_register_operand" "0")
8851 (match_operand 2 "const_int_operand" "n")))
8852 (clobber (reg:CC FLAGS_REG))]
8853 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8854 "or{b}\t{%2, %h0|%h0, %2}"
8855 [(set_attr "type" "alu")
8856 (set_attr "length_immediate" "1")
8857 (set_attr "mode" "QI")])
8859 (define_insn "*iorqi_ext_1"
8860 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8865 (match_operand 1 "ext_register_operand" "0")
8869 (match_operand:QI 2 "general_operand" "Qm"))))
8870 (clobber (reg:CC FLAGS_REG))]
8872 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8873 "or{b}\t{%2, %h0|%h0, %2}"
8874 [(set_attr "type" "alu")
8875 (set_attr "length_immediate" "0")
8876 (set_attr "mode" "QI")])
8878 (define_insn "*iorqi_ext_1_rex64"
8879 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8884 (match_operand 1 "ext_register_operand" "0")
8888 (match_operand 2 "ext_register_operand" "Q"))))
8889 (clobber (reg:CC FLAGS_REG))]
8891 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8892 "or{b}\t{%2, %h0|%h0, %2}"
8893 [(set_attr "type" "alu")
8894 (set_attr "length_immediate" "0")
8895 (set_attr "mode" "QI")])
8897 (define_insn "*iorqi_ext_2"
8898 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8902 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8905 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8908 (clobber (reg:CC FLAGS_REG))]
8909 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8910 "ior{b}\t{%h2, %h0|%h0, %h2}"
8911 [(set_attr "type" "alu")
8912 (set_attr "length_immediate" "0")
8913 (set_attr "mode" "QI")])
8916 [(set (match_operand 0 "register_operand" "")
8917 (ior (match_operand 1 "register_operand" "")
8918 (match_operand 2 "const_int_operand" "")))
8919 (clobber (reg:CC FLAGS_REG))]
8921 && QI_REG_P (operands[0])
8922 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8923 && !(INTVAL (operands[2]) & ~(255 << 8))
8924 && GET_MODE (operands[0]) != QImode"
8925 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8926 (ior:SI (zero_extract:SI (match_dup 1)
8927 (const_int 8) (const_int 8))
8929 (clobber (reg:CC FLAGS_REG))])]
8930 "operands[0] = gen_lowpart (SImode, operands[0]);
8931 operands[1] = gen_lowpart (SImode, operands[1]);
8932 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8934 ;; Since OR can be encoded with sign extended immediate, this is only
8935 ;; profitable when 7th bit is set.
8937 [(set (match_operand 0 "register_operand" "")
8938 (ior (match_operand 1 "general_operand" "")
8939 (match_operand 2 "const_int_operand" "")))
8940 (clobber (reg:CC FLAGS_REG))]
8942 && ANY_QI_REG_P (operands[0])
8943 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8944 && !(INTVAL (operands[2]) & ~255)
8945 && (INTVAL (operands[2]) & 128)
8946 && GET_MODE (operands[0]) != QImode"
8947 [(parallel [(set (strict_low_part (match_dup 0))
8948 (ior:QI (match_dup 1)
8950 (clobber (reg:CC FLAGS_REG))])]
8951 "operands[0] = gen_lowpart (QImode, operands[0]);
8952 operands[1] = gen_lowpart (QImode, operands[1]);
8953 operands[2] = gen_lowpart (QImode, operands[2]);")
8955 ;; Logical XOR instructions
8957 ;; %%% This used to optimize known byte-wide and operations to memory.
8958 ;; If this is considered useful, it should be done with splitters.
8960 (define_expand "xordi3"
8961 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8962 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8963 (match_operand:DI 2 "x86_64_general_operand" "")))
8964 (clobber (reg:CC FLAGS_REG))]
8966 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8968 (define_insn "*xordi_1_rex64"
8969 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8970 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8971 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8972 (clobber (reg:CC FLAGS_REG))]
8974 && ix86_binary_operator_ok (XOR, DImode, operands)"
8976 xor{q}\t{%2, %0|%0, %2}
8977 xor{q}\t{%2, %0|%0, %2}"
8978 [(set_attr "type" "alu")
8979 (set_attr "mode" "DI,DI")])
8981 (define_insn "*xordi_2_rex64"
8982 [(set (reg FLAGS_REG)
8983 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8984 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8986 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8987 (xor:DI (match_dup 1) (match_dup 2)))]
8989 && ix86_match_ccmode (insn, CCNOmode)
8990 && ix86_binary_operator_ok (XOR, DImode, operands)"
8992 xor{q}\t{%2, %0|%0, %2}
8993 xor{q}\t{%2, %0|%0, %2}"
8994 [(set_attr "type" "alu")
8995 (set_attr "mode" "DI,DI")])
8997 (define_insn "*xordi_3_rex64"
8998 [(set (reg FLAGS_REG)
8999 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9000 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9002 (clobber (match_scratch:DI 0 "=r"))]
9004 && ix86_match_ccmode (insn, CCNOmode)
9005 && ix86_binary_operator_ok (XOR, DImode, operands)"
9006 "xor{q}\t{%2, %0|%0, %2}"
9007 [(set_attr "type" "alu")
9008 (set_attr "mode" "DI")])
9010 (define_expand "xorsi3"
9011 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9012 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9013 (match_operand:SI 2 "general_operand" "")))
9014 (clobber (reg:CC FLAGS_REG))]
9016 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9018 (define_insn "*xorsi_1"
9019 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9020 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9021 (match_operand:SI 2 "general_operand" "ri,rm")))
9022 (clobber (reg:CC FLAGS_REG))]
9023 "ix86_binary_operator_ok (XOR, SImode, operands)"
9024 "xor{l}\t{%2, %0|%0, %2}"
9025 [(set_attr "type" "alu")
9026 (set_attr "mode" "SI")])
9028 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9029 ;; Add speccase for immediates
9030 (define_insn "*xorsi_1_zext"
9031 [(set (match_operand:DI 0 "register_operand" "=r")
9033 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9034 (match_operand:SI 2 "general_operand" "rim"))))
9035 (clobber (reg:CC FLAGS_REG))]
9036 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9037 "xor{l}\t{%2, %k0|%k0, %2}"
9038 [(set_attr "type" "alu")
9039 (set_attr "mode" "SI")])
9041 (define_insn "*xorsi_1_zext_imm"
9042 [(set (match_operand:DI 0 "register_operand" "=r")
9043 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9044 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9045 (clobber (reg:CC FLAGS_REG))]
9046 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9047 "xor{l}\t{%2, %k0|%k0, %2}"
9048 [(set_attr "type" "alu")
9049 (set_attr "mode" "SI")])
9051 (define_insn "*xorsi_2"
9052 [(set (reg FLAGS_REG)
9053 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9054 (match_operand:SI 2 "general_operand" "rim,ri"))
9056 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9057 (xor:SI (match_dup 1) (match_dup 2)))]
9058 "ix86_match_ccmode (insn, CCNOmode)
9059 && ix86_binary_operator_ok (XOR, SImode, operands)"
9060 "xor{l}\t{%2, %0|%0, %2}"
9061 [(set_attr "type" "alu")
9062 (set_attr "mode" "SI")])
9064 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9065 ;; ??? Special case for immediate operand is missing - it is tricky.
9066 (define_insn "*xorsi_2_zext"
9067 [(set (reg FLAGS_REG)
9068 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9069 (match_operand:SI 2 "general_operand" "rim"))
9071 (set (match_operand:DI 0 "register_operand" "=r")
9072 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9073 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9074 && ix86_binary_operator_ok (XOR, SImode, operands)"
9075 "xor{l}\t{%2, %k0|%k0, %2}"
9076 [(set_attr "type" "alu")
9077 (set_attr "mode" "SI")])
9079 (define_insn "*xorsi_2_zext_imm"
9080 [(set (reg FLAGS_REG)
9081 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9082 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9084 (set (match_operand:DI 0 "register_operand" "=r")
9085 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9086 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9087 && ix86_binary_operator_ok (XOR, SImode, operands)"
9088 "xor{l}\t{%2, %k0|%k0, %2}"
9089 [(set_attr "type" "alu")
9090 (set_attr "mode" "SI")])
9092 (define_insn "*xorsi_3"
9093 [(set (reg FLAGS_REG)
9094 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9095 (match_operand:SI 2 "general_operand" "rim"))
9097 (clobber (match_scratch:SI 0 "=r"))]
9098 "ix86_match_ccmode (insn, CCNOmode)
9099 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9100 "xor{l}\t{%2, %0|%0, %2}"
9101 [(set_attr "type" "alu")
9102 (set_attr "mode" "SI")])
9104 (define_expand "xorhi3"
9105 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9106 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9107 (match_operand:HI 2 "general_operand" "")))
9108 (clobber (reg:CC FLAGS_REG))]
9109 "TARGET_HIMODE_MATH"
9110 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9112 (define_insn "*xorhi_1"
9113 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9114 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9115 (match_operand:HI 2 "general_operand" "rmi,ri")))
9116 (clobber (reg:CC FLAGS_REG))]
9117 "ix86_binary_operator_ok (XOR, HImode, operands)"
9118 "xor{w}\t{%2, %0|%0, %2}"
9119 [(set_attr "type" "alu")
9120 (set_attr "mode" "HI")])
9122 (define_insn "*xorhi_2"
9123 [(set (reg FLAGS_REG)
9124 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9125 (match_operand:HI 2 "general_operand" "rim,ri"))
9127 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9128 (xor:HI (match_dup 1) (match_dup 2)))]
9129 "ix86_match_ccmode (insn, CCNOmode)
9130 && ix86_binary_operator_ok (XOR, HImode, operands)"
9131 "xor{w}\t{%2, %0|%0, %2}"
9132 [(set_attr "type" "alu")
9133 (set_attr "mode" "HI")])
9135 (define_insn "*xorhi_3"
9136 [(set (reg FLAGS_REG)
9137 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9138 (match_operand:HI 2 "general_operand" "rim"))
9140 (clobber (match_scratch:HI 0 "=r"))]
9141 "ix86_match_ccmode (insn, CCNOmode)
9142 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9143 "xor{w}\t{%2, %0|%0, %2}"
9144 [(set_attr "type" "alu")
9145 (set_attr "mode" "HI")])
9147 (define_expand "xorqi3"
9148 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9149 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9150 (match_operand:QI 2 "general_operand" "")))
9151 (clobber (reg:CC FLAGS_REG))]
9152 "TARGET_QIMODE_MATH"
9153 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9155 ;; %%% Potential partial reg stall on alternative 2. What to do?
9156 (define_insn "*xorqi_1"
9157 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9158 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9159 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9160 (clobber (reg:CC FLAGS_REG))]
9161 "ix86_binary_operator_ok (XOR, QImode, operands)"
9163 xor{b}\t{%2, %0|%0, %2}
9164 xor{b}\t{%2, %0|%0, %2}
9165 xor{l}\t{%k2, %k0|%k0, %k2}"
9166 [(set_attr "type" "alu")
9167 (set_attr "mode" "QI,QI,SI")])
9169 (define_insn "*xorqi_1_slp"
9170 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9171 (xor:QI (match_dup 0)
9172 (match_operand:QI 1 "general_operand" "qi,qmi")))
9173 (clobber (reg:CC FLAGS_REG))]
9174 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9175 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9176 "xor{b}\t{%1, %0|%0, %1}"
9177 [(set_attr "type" "alu1")
9178 (set_attr "mode" "QI")])
9180 (define_insn "xorqi_ext_0"
9181 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9186 (match_operand 1 "ext_register_operand" "0")
9189 (match_operand 2 "const_int_operand" "n")))
9190 (clobber (reg:CC FLAGS_REG))]
9191 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9192 "xor{b}\t{%2, %h0|%h0, %2}"
9193 [(set_attr "type" "alu")
9194 (set_attr "length_immediate" "1")
9195 (set_attr "mode" "QI")])
9197 (define_insn "*xorqi_ext_1"
9198 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9203 (match_operand 1 "ext_register_operand" "0")
9207 (match_operand:QI 2 "general_operand" "Qm"))))
9208 (clobber (reg:CC FLAGS_REG))]
9210 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9211 "xor{b}\t{%2, %h0|%h0, %2}"
9212 [(set_attr "type" "alu")
9213 (set_attr "length_immediate" "0")
9214 (set_attr "mode" "QI")])
9216 (define_insn "*xorqi_ext_1_rex64"
9217 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9222 (match_operand 1 "ext_register_operand" "0")
9226 (match_operand 2 "ext_register_operand" "Q"))))
9227 (clobber (reg:CC FLAGS_REG))]
9229 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9230 "xor{b}\t{%2, %h0|%h0, %2}"
9231 [(set_attr "type" "alu")
9232 (set_attr "length_immediate" "0")
9233 (set_attr "mode" "QI")])
9235 (define_insn "*xorqi_ext_2"
9236 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9240 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9243 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9246 (clobber (reg:CC FLAGS_REG))]
9247 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9248 "xor{b}\t{%h2, %h0|%h0, %h2}"
9249 [(set_attr "type" "alu")
9250 (set_attr "length_immediate" "0")
9251 (set_attr "mode" "QI")])
9253 (define_insn "*xorqi_cc_1"
9254 [(set (reg FLAGS_REG)
9256 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9257 (match_operand:QI 2 "general_operand" "qim,qi"))
9259 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9260 (xor:QI (match_dup 1) (match_dup 2)))]
9261 "ix86_match_ccmode (insn, CCNOmode)
9262 && ix86_binary_operator_ok (XOR, QImode, operands)"
9263 "xor{b}\t{%2, %0|%0, %2}"
9264 [(set_attr "type" "alu")
9265 (set_attr "mode" "QI")])
9267 (define_insn "*xorqi_2_slp"
9268 [(set (reg FLAGS_REG)
9269 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9270 (match_operand:QI 1 "general_operand" "qim,qi"))
9272 (set (strict_low_part (match_dup 0))
9273 (xor:QI (match_dup 0) (match_dup 1)))]
9274 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9275 && ix86_match_ccmode (insn, CCNOmode)
9276 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9277 "xor{b}\t{%1, %0|%0, %1}"
9278 [(set_attr "type" "alu1")
9279 (set_attr "mode" "QI")])
9281 (define_insn "*xorqi_cc_2"
9282 [(set (reg FLAGS_REG)
9284 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9285 (match_operand:QI 2 "general_operand" "qim"))
9287 (clobber (match_scratch:QI 0 "=q"))]
9288 "ix86_match_ccmode (insn, CCNOmode)
9289 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9290 "xor{b}\t{%2, %0|%0, %2}"
9291 [(set_attr "type" "alu")
9292 (set_attr "mode" "QI")])
9294 (define_insn "*xorqi_cc_ext_1"
9295 [(set (reg FLAGS_REG)
9299 (match_operand 1 "ext_register_operand" "0")
9302 (match_operand:QI 2 "general_operand" "qmn"))
9304 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9308 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9310 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9311 "xor{b}\t{%2, %h0|%h0, %2}"
9312 [(set_attr "type" "alu")
9313 (set_attr "mode" "QI")])
9315 (define_insn "*xorqi_cc_ext_1_rex64"
9316 [(set (reg FLAGS_REG)
9320 (match_operand 1 "ext_register_operand" "0")
9323 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9325 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9329 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9331 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9332 "xor{b}\t{%2, %h0|%h0, %2}"
9333 [(set_attr "type" "alu")
9334 (set_attr "mode" "QI")])
9336 (define_expand "xorqi_cc_ext_1"
9338 (set (reg:CCNO FLAGS_REG)
9342 (match_operand 1 "ext_register_operand" "")
9345 (match_operand:QI 2 "general_operand" ""))
9347 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9351 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9357 [(set (match_operand 0 "register_operand" "")
9358 (xor (match_operand 1 "register_operand" "")
9359 (match_operand 2 "const_int_operand" "")))
9360 (clobber (reg:CC FLAGS_REG))]
9362 && QI_REG_P (operands[0])
9363 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9364 && !(INTVAL (operands[2]) & ~(255 << 8))
9365 && GET_MODE (operands[0]) != QImode"
9366 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9367 (xor:SI (zero_extract:SI (match_dup 1)
9368 (const_int 8) (const_int 8))
9370 (clobber (reg:CC FLAGS_REG))])]
9371 "operands[0] = gen_lowpart (SImode, operands[0]);
9372 operands[1] = gen_lowpart (SImode, operands[1]);
9373 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9375 ;; Since XOR can be encoded with sign extended immediate, this is only
9376 ;; profitable when 7th bit is set.
9378 [(set (match_operand 0 "register_operand" "")
9379 (xor (match_operand 1 "general_operand" "")
9380 (match_operand 2 "const_int_operand" "")))
9381 (clobber (reg:CC FLAGS_REG))]
9383 && ANY_QI_REG_P (operands[0])
9384 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9385 && !(INTVAL (operands[2]) & ~255)
9386 && (INTVAL (operands[2]) & 128)
9387 && GET_MODE (operands[0]) != QImode"
9388 [(parallel [(set (strict_low_part (match_dup 0))
9389 (xor:QI (match_dup 1)
9391 (clobber (reg:CC FLAGS_REG))])]
9392 "operands[0] = gen_lowpart (QImode, operands[0]);
9393 operands[1] = gen_lowpart (QImode, operands[1]);
9394 operands[2] = gen_lowpart (QImode, operands[2]);")
9396 ;; Negation instructions
9398 (define_expand "negti2"
9399 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9400 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9401 (clobber (reg:CC FLAGS_REG))])]
9403 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9405 (define_insn "*negti2_1"
9406 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9407 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9408 (clobber (reg:CC FLAGS_REG))]
9410 && ix86_unary_operator_ok (NEG, TImode, operands)"
9414 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9415 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9416 (clobber (reg:CC FLAGS_REG))]
9417 "TARGET_64BIT && reload_completed"
9419 [(set (reg:CCZ FLAGS_REG)
9420 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9421 (set (match_dup 0) (neg:DI (match_dup 2)))])
9424 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9427 (clobber (reg:CC FLAGS_REG))])
9430 (neg:DI (match_dup 1)))
9431 (clobber (reg:CC FLAGS_REG))])]
9432 "split_ti (operands+1, 1, operands+2, operands+3);
9433 split_ti (operands+0, 1, operands+0, operands+1);")
9435 (define_expand "negdi2"
9436 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9437 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9438 (clobber (reg:CC FLAGS_REG))])]
9440 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9442 (define_insn "*negdi2_1"
9443 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9444 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9445 (clobber (reg:CC FLAGS_REG))]
9447 && ix86_unary_operator_ok (NEG, DImode, operands)"
9451 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9452 (neg:DI (match_operand:DI 1 "general_operand" "")))
9453 (clobber (reg:CC FLAGS_REG))]
9454 "!TARGET_64BIT && reload_completed"
9456 [(set (reg:CCZ FLAGS_REG)
9457 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9458 (set (match_dup 0) (neg:SI (match_dup 2)))])
9461 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9464 (clobber (reg:CC FLAGS_REG))])
9467 (neg:SI (match_dup 1)))
9468 (clobber (reg:CC FLAGS_REG))])]
9469 "split_di (operands+1, 1, operands+2, operands+3);
9470 split_di (operands+0, 1, operands+0, operands+1);")
9472 (define_insn "*negdi2_1_rex64"
9473 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9474 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9475 (clobber (reg:CC FLAGS_REG))]
9476 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9478 [(set_attr "type" "negnot")
9479 (set_attr "mode" "DI")])
9481 ;; The problem with neg is that it does not perform (compare x 0),
9482 ;; it really performs (compare 0 x), which leaves us with the zero
9483 ;; flag being the only useful item.
9485 (define_insn "*negdi2_cmpz_rex64"
9486 [(set (reg:CCZ FLAGS_REG)
9487 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9489 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9490 (neg:DI (match_dup 1)))]
9491 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9493 [(set_attr "type" "negnot")
9494 (set_attr "mode" "DI")])
9497 (define_expand "negsi2"
9498 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9499 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9500 (clobber (reg:CC FLAGS_REG))])]
9502 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9504 (define_insn "*negsi2_1"
9505 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9506 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9507 (clobber (reg:CC FLAGS_REG))]
9508 "ix86_unary_operator_ok (NEG, SImode, operands)"
9510 [(set_attr "type" "negnot")
9511 (set_attr "mode" "SI")])
9513 ;; Combine is quite creative about this pattern.
9514 (define_insn "*negsi2_1_zext"
9515 [(set (match_operand:DI 0 "register_operand" "=r")
9516 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9519 (clobber (reg:CC FLAGS_REG))]
9520 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9522 [(set_attr "type" "negnot")
9523 (set_attr "mode" "SI")])
9525 ;; The problem with neg is that it does not perform (compare x 0),
9526 ;; it really performs (compare 0 x), which leaves us with the zero
9527 ;; flag being the only useful item.
9529 (define_insn "*negsi2_cmpz"
9530 [(set (reg:CCZ FLAGS_REG)
9531 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9533 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9534 (neg:SI (match_dup 1)))]
9535 "ix86_unary_operator_ok (NEG, SImode, operands)"
9537 [(set_attr "type" "negnot")
9538 (set_attr "mode" "SI")])
9540 (define_insn "*negsi2_cmpz_zext"
9541 [(set (reg:CCZ FLAGS_REG)
9542 (compare:CCZ (lshiftrt:DI
9544 (match_operand:DI 1 "register_operand" "0")
9548 (set (match_operand:DI 0 "register_operand" "=r")
9549 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9552 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9554 [(set_attr "type" "negnot")
9555 (set_attr "mode" "SI")])
9557 (define_expand "neghi2"
9558 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9559 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9560 (clobber (reg:CC FLAGS_REG))])]
9561 "TARGET_HIMODE_MATH"
9562 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9564 (define_insn "*neghi2_1"
9565 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9566 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9567 (clobber (reg:CC FLAGS_REG))]
9568 "ix86_unary_operator_ok (NEG, HImode, operands)"
9570 [(set_attr "type" "negnot")
9571 (set_attr "mode" "HI")])
9573 (define_insn "*neghi2_cmpz"
9574 [(set (reg:CCZ FLAGS_REG)
9575 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9577 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9578 (neg:HI (match_dup 1)))]
9579 "ix86_unary_operator_ok (NEG, HImode, operands)"
9581 [(set_attr "type" "negnot")
9582 (set_attr "mode" "HI")])
9584 (define_expand "negqi2"
9585 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9586 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9587 (clobber (reg:CC FLAGS_REG))])]
9588 "TARGET_QIMODE_MATH"
9589 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9591 (define_insn "*negqi2_1"
9592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9593 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9594 (clobber (reg:CC FLAGS_REG))]
9595 "ix86_unary_operator_ok (NEG, QImode, operands)"
9597 [(set_attr "type" "negnot")
9598 (set_attr "mode" "QI")])
9600 (define_insn "*negqi2_cmpz"
9601 [(set (reg:CCZ FLAGS_REG)
9602 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9604 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9605 (neg:QI (match_dup 1)))]
9606 "ix86_unary_operator_ok (NEG, QImode, operands)"
9608 [(set_attr "type" "negnot")
9609 (set_attr "mode" "QI")])
9611 ;; Changing of sign for FP values is doable using integer unit too.
9613 (define_expand "negsf2"
9614 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9615 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9616 "TARGET_80387 || TARGET_SSE_MATH"
9617 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9619 (define_expand "abssf2"
9620 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9621 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9622 "TARGET_80387 || TARGET_SSE_MATH"
9623 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9625 (define_insn "*absnegsf2_mixed"
9626 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9627 (match_operator:SF 3 "absneg_operator"
9628 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9629 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9630 (clobber (reg:CC FLAGS_REG))]
9631 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9632 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9635 (define_insn "*absnegsf2_sse"
9636 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9637 (match_operator:SF 3 "absneg_operator"
9638 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9639 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9640 (clobber (reg:CC FLAGS_REG))]
9642 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9645 (define_insn "*absnegsf2_i387"
9646 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9647 (match_operator:SF 3 "absneg_operator"
9648 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9649 (use (match_operand 2 "" ""))
9650 (clobber (reg:CC FLAGS_REG))]
9651 "TARGET_80387 && !TARGET_SSE_MATH
9652 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9655 (define_expand "copysignsf3"
9656 [(match_operand:SF 0 "register_operand" "")
9657 (match_operand:SF 1 "nonmemory_operand" "")
9658 (match_operand:SF 2 "register_operand" "")]
9661 ix86_expand_copysign (operands);
9665 (define_insn_and_split "copysignsf3_const"
9666 [(set (match_operand:SF 0 "register_operand" "=x")
9668 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9669 (match_operand:SF 2 "register_operand" "0")
9670 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9674 "&& reload_completed"
9677 ix86_split_copysign_const (operands);
9681 (define_insn "copysignsf3_var"
9682 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9684 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9685 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9686 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9687 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9689 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9694 [(set (match_operand:SF 0 "register_operand" "")
9696 [(match_operand:SF 2 "register_operand" "")
9697 (match_operand:SF 3 "register_operand" "")
9698 (match_operand:V4SF 4 "" "")
9699 (match_operand:V4SF 5 "" "")]
9701 (clobber (match_scratch:V4SF 1 ""))]
9702 "TARGET_SSE_MATH && reload_completed"
9705 ix86_split_copysign_var (operands);
9709 (define_expand "negdf2"
9710 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9711 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9712 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9713 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9715 (define_expand "absdf2"
9716 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9717 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9718 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9719 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9721 (define_insn "*absnegdf2_mixed"
9722 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
9723 (match_operator:DF 3 "absneg_operator"
9724 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9725 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
9726 (clobber (reg:CC FLAGS_REG))]
9727 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9728 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9731 (define_insn "*absnegdf2_sse"
9732 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
9733 (match_operator:DF 3 "absneg_operator"
9734 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
9735 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
9736 (clobber (reg:CC FLAGS_REG))]
9737 "TARGET_SSE2 && TARGET_SSE_MATH
9738 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9741 (define_insn "*absnegdf2_i387"
9742 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9743 (match_operator:DF 3 "absneg_operator"
9744 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9745 (use (match_operand 2 "" ""))
9746 (clobber (reg:CC FLAGS_REG))]
9747 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9748 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9751 (define_expand "copysigndf3"
9752 [(match_operand:DF 0 "register_operand" "")
9753 (match_operand:DF 1 "nonmemory_operand" "")
9754 (match_operand:DF 2 "register_operand" "")]
9755 "TARGET_SSE2 && TARGET_SSE_MATH"
9757 ix86_expand_copysign (operands);
9761 (define_insn_and_split "copysigndf3_const"
9762 [(set (match_operand:DF 0 "register_operand" "=x")
9764 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9765 (match_operand:DF 2 "register_operand" "0")
9766 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9768 "TARGET_SSE2 && TARGET_SSE_MATH"
9770 "&& reload_completed"
9773 ix86_split_copysign_const (operands);
9777 (define_insn "copysigndf3_var"
9778 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9780 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9781 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9782 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9783 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9785 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9786 "TARGET_SSE2 && TARGET_SSE_MATH"
9790 [(set (match_operand:DF 0 "register_operand" "")
9792 [(match_operand:DF 2 "register_operand" "")
9793 (match_operand:DF 3 "register_operand" "")
9794 (match_operand:V2DF 4 "" "")
9795 (match_operand:V2DF 5 "" "")]
9797 (clobber (match_scratch:V2DF 1 ""))]
9798 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9801 ix86_split_copysign_var (operands);
9805 (define_expand "negxf2"
9806 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9807 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9809 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9811 (define_expand "absxf2"
9812 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9813 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9815 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9817 (define_insn "*absnegxf2_i387"
9818 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9819 (match_operator:XF 3 "absneg_operator"
9820 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9821 (use (match_operand 2 "" ""))
9822 (clobber (reg:CC FLAGS_REG))]
9824 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9827 ;; Splitters for fp abs and neg.
9830 [(set (match_operand 0 "fp_register_operand" "")
9831 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9832 (use (match_operand 2 "" ""))
9833 (clobber (reg:CC FLAGS_REG))]
9835 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9838 [(set (match_operand 0 "register_operand" "")
9839 (match_operator 3 "absneg_operator"
9840 [(match_operand 1 "register_operand" "")]))
9841 (use (match_operand 2 "nonimmediate_operand" ""))
9842 (clobber (reg:CC FLAGS_REG))]
9843 "reload_completed && SSE_REG_P (operands[0])"
9844 [(set (match_dup 0) (match_dup 3))]
9846 enum machine_mode mode = GET_MODE (operands[0]);
9847 enum machine_mode vmode = GET_MODE (operands[2]);
9850 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9851 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9852 if (operands_match_p (operands[0], operands[2]))
9855 operands[1] = operands[2];
9858 if (GET_CODE (operands[3]) == ABS)
9859 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9861 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9866 [(set (match_operand:SF 0 "register_operand" "")
9867 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9868 (use (match_operand:V4SF 2 "" ""))
9869 (clobber (reg:CC FLAGS_REG))]
9871 [(parallel [(set (match_dup 0) (match_dup 1))
9872 (clobber (reg:CC FLAGS_REG))])]
9875 operands[0] = gen_lowpart (SImode, operands[0]);
9876 if (GET_CODE (operands[1]) == ABS)
9878 tmp = gen_int_mode (0x7fffffff, SImode);
9879 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9883 tmp = gen_int_mode (0x80000000, SImode);
9884 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9890 [(set (match_operand:DF 0 "register_operand" "")
9891 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9892 (use (match_operand 2 "" ""))
9893 (clobber (reg:CC FLAGS_REG))]
9895 [(parallel [(set (match_dup 0) (match_dup 1))
9896 (clobber (reg:CC FLAGS_REG))])]
9901 tmp = gen_lowpart (DImode, operands[0]);
9902 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9905 if (GET_CODE (operands[1]) == ABS)
9908 tmp = gen_rtx_NOT (DImode, tmp);
9912 operands[0] = gen_highpart (SImode, operands[0]);
9913 if (GET_CODE (operands[1]) == ABS)
9915 tmp = gen_int_mode (0x7fffffff, SImode);
9916 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9920 tmp = gen_int_mode (0x80000000, SImode);
9921 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9928 [(set (match_operand:XF 0 "register_operand" "")
9929 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9930 (use (match_operand 2 "" ""))
9931 (clobber (reg:CC FLAGS_REG))]
9933 [(parallel [(set (match_dup 0) (match_dup 1))
9934 (clobber (reg:CC FLAGS_REG))])]
9937 operands[0] = gen_rtx_REG (SImode,
9938 true_regnum (operands[0])
9939 + (TARGET_64BIT ? 1 : 2));
9940 if (GET_CODE (operands[1]) == ABS)
9942 tmp = GEN_INT (0x7fff);
9943 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9947 tmp = GEN_INT (0x8000);
9948 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9954 [(set (match_operand 0 "memory_operand" "")
9955 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9956 (use (match_operand 2 "" ""))
9957 (clobber (reg:CC FLAGS_REG))]
9959 [(parallel [(set (match_dup 0) (match_dup 1))
9960 (clobber (reg:CC FLAGS_REG))])]
9962 enum machine_mode mode = GET_MODE (operands[0]);
9963 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9966 operands[0] = adjust_address (operands[0], QImode, size - 1);
9967 if (GET_CODE (operands[1]) == ABS)
9969 tmp = gen_int_mode (0x7f, QImode);
9970 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9974 tmp = gen_int_mode (0x80, QImode);
9975 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9980 ;; Conditionalize these after reload. If they match before reload, we
9981 ;; lose the clobber and ability to use integer instructions.
9983 (define_insn "*negsf2_1"
9984 [(set (match_operand:SF 0 "register_operand" "=f")
9985 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9986 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9988 [(set_attr "type" "fsgn")
9989 (set_attr "mode" "SF")])
9991 (define_insn "*negdf2_1"
9992 [(set (match_operand:DF 0 "register_operand" "=f")
9993 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9994 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9996 [(set_attr "type" "fsgn")
9997 (set_attr "mode" "DF")])
9999 (define_insn "*negxf2_1"
10000 [(set (match_operand:XF 0 "register_operand" "=f")
10001 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10004 [(set_attr "type" "fsgn")
10005 (set_attr "mode" "XF")])
10007 (define_insn "*abssf2_1"
10008 [(set (match_operand:SF 0 "register_operand" "=f")
10009 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10010 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10012 [(set_attr "type" "fsgn")
10013 (set_attr "mode" "SF")])
10015 (define_insn "*absdf2_1"
10016 [(set (match_operand:DF 0 "register_operand" "=f")
10017 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10018 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10020 [(set_attr "type" "fsgn")
10021 (set_attr "mode" "DF")])
10023 (define_insn "*absxf2_1"
10024 [(set (match_operand:XF 0 "register_operand" "=f")
10025 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10028 [(set_attr "type" "fsgn")
10029 (set_attr "mode" "DF")])
10031 (define_insn "*negextendsfdf2"
10032 [(set (match_operand:DF 0 "register_operand" "=f")
10033 (neg:DF (float_extend:DF
10034 (match_operand:SF 1 "register_operand" "0"))))]
10035 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10037 [(set_attr "type" "fsgn")
10038 (set_attr "mode" "DF")])
10040 (define_insn "*negextenddfxf2"
10041 [(set (match_operand:XF 0 "register_operand" "=f")
10042 (neg:XF (float_extend:XF
10043 (match_operand:DF 1 "register_operand" "0"))))]
10046 [(set_attr "type" "fsgn")
10047 (set_attr "mode" "XF")])
10049 (define_insn "*negextendsfxf2"
10050 [(set (match_operand:XF 0 "register_operand" "=f")
10051 (neg:XF (float_extend:XF
10052 (match_operand:SF 1 "register_operand" "0"))))]
10055 [(set_attr "type" "fsgn")
10056 (set_attr "mode" "XF")])
10058 (define_insn "*absextendsfdf2"
10059 [(set (match_operand:DF 0 "register_operand" "=f")
10060 (abs:DF (float_extend:DF
10061 (match_operand:SF 1 "register_operand" "0"))))]
10062 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10064 [(set_attr "type" "fsgn")
10065 (set_attr "mode" "DF")])
10067 (define_insn "*absextenddfxf2"
10068 [(set (match_operand:XF 0 "register_operand" "=f")
10069 (abs:XF (float_extend:XF
10070 (match_operand:DF 1 "register_operand" "0"))))]
10073 [(set_attr "type" "fsgn")
10074 (set_attr "mode" "XF")])
10076 (define_insn "*absextendsfxf2"
10077 [(set (match_operand:XF 0 "register_operand" "=f")
10078 (abs:XF (float_extend:XF
10079 (match_operand:SF 1 "register_operand" "0"))))]
10082 [(set_attr "type" "fsgn")
10083 (set_attr "mode" "XF")])
10085 ;; One complement instructions
10087 (define_expand "one_cmpldi2"
10088 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10089 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10091 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10093 (define_insn "*one_cmpldi2_1_rex64"
10094 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10095 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10096 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10098 [(set_attr "type" "negnot")
10099 (set_attr "mode" "DI")])
10101 (define_insn "*one_cmpldi2_2_rex64"
10102 [(set (reg FLAGS_REG)
10103 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10105 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10106 (not:DI (match_dup 1)))]
10107 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10108 && ix86_unary_operator_ok (NOT, DImode, operands)"
10110 [(set_attr "type" "alu1")
10111 (set_attr "mode" "DI")])
10114 [(set (match_operand 0 "flags_reg_operand" "")
10115 (match_operator 2 "compare_operator"
10116 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10118 (set (match_operand:DI 1 "nonimmediate_operand" "")
10119 (not:DI (match_dup 3)))]
10120 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10121 [(parallel [(set (match_dup 0)
10123 [(xor:DI (match_dup 3) (const_int -1))
10126 (xor:DI (match_dup 3) (const_int -1)))])]
10129 (define_expand "one_cmplsi2"
10130 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10131 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10133 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10135 (define_insn "*one_cmplsi2_1"
10136 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10137 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10138 "ix86_unary_operator_ok (NOT, SImode, operands)"
10140 [(set_attr "type" "negnot")
10141 (set_attr "mode" "SI")])
10143 ;; ??? Currently never generated - xor is used instead.
10144 (define_insn "*one_cmplsi2_1_zext"
10145 [(set (match_operand:DI 0 "register_operand" "=r")
10146 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10147 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10149 [(set_attr "type" "negnot")
10150 (set_attr "mode" "SI")])
10152 (define_insn "*one_cmplsi2_2"
10153 [(set (reg FLAGS_REG)
10154 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10156 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10157 (not:SI (match_dup 1)))]
10158 "ix86_match_ccmode (insn, CCNOmode)
10159 && ix86_unary_operator_ok (NOT, SImode, operands)"
10161 [(set_attr "type" "alu1")
10162 (set_attr "mode" "SI")])
10165 [(set (match_operand 0 "flags_reg_operand" "")
10166 (match_operator 2 "compare_operator"
10167 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10169 (set (match_operand:SI 1 "nonimmediate_operand" "")
10170 (not:SI (match_dup 3)))]
10171 "ix86_match_ccmode (insn, CCNOmode)"
10172 [(parallel [(set (match_dup 0)
10173 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10176 (xor:SI (match_dup 3) (const_int -1)))])]
10179 ;; ??? Currently never generated - xor is used instead.
10180 (define_insn "*one_cmplsi2_2_zext"
10181 [(set (reg FLAGS_REG)
10182 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10184 (set (match_operand:DI 0 "register_operand" "=r")
10185 (zero_extend:DI (not:SI (match_dup 1))))]
10186 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10187 && ix86_unary_operator_ok (NOT, SImode, operands)"
10189 [(set_attr "type" "alu1")
10190 (set_attr "mode" "SI")])
10193 [(set (match_operand 0 "flags_reg_operand" "")
10194 (match_operator 2 "compare_operator"
10195 [(not:SI (match_operand:SI 3 "register_operand" ""))
10197 (set (match_operand:DI 1 "register_operand" "")
10198 (zero_extend:DI (not:SI (match_dup 3))))]
10199 "ix86_match_ccmode (insn, CCNOmode)"
10200 [(parallel [(set (match_dup 0)
10201 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10204 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10207 (define_expand "one_cmplhi2"
10208 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10209 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10210 "TARGET_HIMODE_MATH"
10211 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10213 (define_insn "*one_cmplhi2_1"
10214 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10215 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10216 "ix86_unary_operator_ok (NOT, HImode, operands)"
10218 [(set_attr "type" "negnot")
10219 (set_attr "mode" "HI")])
10221 (define_insn "*one_cmplhi2_2"
10222 [(set (reg FLAGS_REG)
10223 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10225 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10226 (not:HI (match_dup 1)))]
10227 "ix86_match_ccmode (insn, CCNOmode)
10228 && ix86_unary_operator_ok (NEG, HImode, operands)"
10230 [(set_attr "type" "alu1")
10231 (set_attr "mode" "HI")])
10234 [(set (match_operand 0 "flags_reg_operand" "")
10235 (match_operator 2 "compare_operator"
10236 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10238 (set (match_operand:HI 1 "nonimmediate_operand" "")
10239 (not:HI (match_dup 3)))]
10240 "ix86_match_ccmode (insn, CCNOmode)"
10241 [(parallel [(set (match_dup 0)
10242 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10245 (xor:HI (match_dup 3) (const_int -1)))])]
10248 ;; %%% Potential partial reg stall on alternative 1. What to do?
10249 (define_expand "one_cmplqi2"
10250 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10251 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10252 "TARGET_QIMODE_MATH"
10253 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10255 (define_insn "*one_cmplqi2_1"
10256 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10257 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10258 "ix86_unary_operator_ok (NOT, QImode, operands)"
10262 [(set_attr "type" "negnot")
10263 (set_attr "mode" "QI,SI")])
10265 (define_insn "*one_cmplqi2_2"
10266 [(set (reg FLAGS_REG)
10267 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10269 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10270 (not:QI (match_dup 1)))]
10271 "ix86_match_ccmode (insn, CCNOmode)
10272 && ix86_unary_operator_ok (NOT, QImode, operands)"
10274 [(set_attr "type" "alu1")
10275 (set_attr "mode" "QI")])
10278 [(set (match_operand 0 "flags_reg_operand" "")
10279 (match_operator 2 "compare_operator"
10280 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10282 (set (match_operand:QI 1 "nonimmediate_operand" "")
10283 (not:QI (match_dup 3)))]
10284 "ix86_match_ccmode (insn, CCNOmode)"
10285 [(parallel [(set (match_dup 0)
10286 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10289 (xor:QI (match_dup 3) (const_int -1)))])]
10292 ;; Arithmetic shift instructions
10294 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10295 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10296 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10297 ;; from the assembler input.
10299 ;; This instruction shifts the target reg/mem as usual, but instead of
10300 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10301 ;; is a left shift double, bits are taken from the high order bits of
10302 ;; reg, else if the insn is a shift right double, bits are taken from the
10303 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10304 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10306 ;; Since sh[lr]d does not change the `reg' operand, that is done
10307 ;; separately, making all shifts emit pairs of shift double and normal
10308 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10309 ;; support a 63 bit shift, each shift where the count is in a reg expands
10310 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10312 ;; If the shift count is a constant, we need never emit more than one
10313 ;; shift pair, instead using moves and sign extension for counts greater
10316 (define_expand "ashlti3"
10317 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10318 (ashift:TI (match_operand:TI 1 "register_operand" "")
10319 (match_operand:QI 2 "nonmemory_operand" "")))
10320 (clobber (reg:CC FLAGS_REG))])]
10323 if (! immediate_operand (operands[2], QImode))
10325 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10328 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10332 (define_insn "ashlti3_1"
10333 [(set (match_operand:TI 0 "register_operand" "=r")
10334 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10335 (match_operand:QI 2 "register_operand" "c")))
10336 (clobber (match_scratch:DI 3 "=&r"))
10337 (clobber (reg:CC FLAGS_REG))]
10340 [(set_attr "type" "multi")])
10342 (define_insn "*ashlti3_2"
10343 [(set (match_operand:TI 0 "register_operand" "=r")
10344 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10345 (match_operand:QI 2 "immediate_operand" "O")))
10346 (clobber (reg:CC FLAGS_REG))]
10349 [(set_attr "type" "multi")])
10352 [(set (match_operand:TI 0 "register_operand" "")
10353 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10354 (match_operand:QI 2 "register_operand" "")))
10355 (clobber (match_scratch:DI 3 ""))
10356 (clobber (reg:CC FLAGS_REG))]
10357 "TARGET_64BIT && reload_completed"
10359 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10362 [(set (match_operand:TI 0 "register_operand" "")
10363 (ashift:TI (match_operand:TI 1 "register_operand" "")
10364 (match_operand:QI 2 "immediate_operand" "")))
10365 (clobber (reg:CC FLAGS_REG))]
10366 "TARGET_64BIT && reload_completed"
10368 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10370 (define_insn "x86_64_shld"
10371 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10372 (ior:DI (ashift:DI (match_dup 0)
10373 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10374 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10375 (minus:QI (const_int 64) (match_dup 2)))))
10376 (clobber (reg:CC FLAGS_REG))]
10379 shld{q}\t{%2, %1, %0|%0, %1, %2}
10380 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10381 [(set_attr "type" "ishift")
10382 (set_attr "prefix_0f" "1")
10383 (set_attr "mode" "DI")
10384 (set_attr "athlon_decode" "vector")
10385 (set_attr "amdfam10_decode" "vector")])
10387 (define_expand "x86_64_shift_adj"
10388 [(set (reg:CCZ FLAGS_REG)
10389 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10392 (set (match_operand:DI 0 "register_operand" "")
10393 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10394 (match_operand:DI 1 "register_operand" "")
10397 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10398 (match_operand:DI 3 "register_operand" "r")
10403 (define_expand "ashldi3"
10404 [(set (match_operand:DI 0 "shiftdi_operand" "")
10405 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10406 (match_operand:QI 2 "nonmemory_operand" "")))]
10408 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10410 (define_insn "*ashldi3_1_rex64"
10411 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10412 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10413 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10414 (clobber (reg:CC FLAGS_REG))]
10415 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10417 switch (get_attr_type (insn))
10420 gcc_assert (operands[2] == const1_rtx);
10421 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10422 return "add{q}\t%0, %0";
10425 gcc_assert (CONST_INT_P (operands[2]));
10426 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10427 operands[1] = gen_rtx_MULT (DImode, operands[1],
10428 GEN_INT (1 << INTVAL (operands[2])));
10429 return "lea{q}\t{%a1, %0|%0, %a1}";
10432 if (REG_P (operands[2]))
10433 return "sal{q}\t{%b2, %0|%0, %b2}";
10434 else if (operands[2] == const1_rtx
10435 && (TARGET_SHIFT1 || optimize_size))
10436 return "sal{q}\t%0";
10438 return "sal{q}\t{%2, %0|%0, %2}";
10441 [(set (attr "type")
10442 (cond [(eq_attr "alternative" "1")
10443 (const_string "lea")
10444 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10446 (match_operand 0 "register_operand" ""))
10447 (match_operand 2 "const1_operand" ""))
10448 (const_string "alu")
10450 (const_string "ishift")))
10451 (set_attr "mode" "DI")])
10453 ;; Convert lea to the lea pattern to avoid flags dependency.
10455 [(set (match_operand:DI 0 "register_operand" "")
10456 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10457 (match_operand:QI 2 "immediate_operand" "")))
10458 (clobber (reg:CC FLAGS_REG))]
10459 "TARGET_64BIT && reload_completed
10460 && true_regnum (operands[0]) != true_regnum (operands[1])"
10461 [(set (match_dup 0)
10462 (mult:DI (match_dup 1)
10464 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10466 ;; This pattern can't accept a variable shift count, since shifts by
10467 ;; zero don't affect the flags. We assume that shifts by constant
10468 ;; zero are optimized away.
10469 (define_insn "*ashldi3_cmp_rex64"
10470 [(set (reg FLAGS_REG)
10472 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10473 (match_operand:QI 2 "immediate_operand" "e"))
10475 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10476 (ashift:DI (match_dup 1) (match_dup 2)))]
10477 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10478 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10480 || !TARGET_PARTIAL_FLAG_REG_STALL
10481 || (operands[2] == const1_rtx
10483 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10485 switch (get_attr_type (insn))
10488 gcc_assert (operands[2] == const1_rtx);
10489 return "add{q}\t%0, %0";
10492 if (REG_P (operands[2]))
10493 return "sal{q}\t{%b2, %0|%0, %b2}";
10494 else if (operands[2] == const1_rtx
10495 && (TARGET_SHIFT1 || optimize_size))
10496 return "sal{q}\t%0";
10498 return "sal{q}\t{%2, %0|%0, %2}";
10501 [(set (attr "type")
10502 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10504 (match_operand 0 "register_operand" ""))
10505 (match_operand 2 "const1_operand" ""))
10506 (const_string "alu")
10508 (const_string "ishift")))
10509 (set_attr "mode" "DI")])
10511 (define_insn "*ashldi3_cconly_rex64"
10512 [(set (reg FLAGS_REG)
10514 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10515 (match_operand:QI 2 "immediate_operand" "e"))
10517 (clobber (match_scratch:DI 0 "=r"))]
10518 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10519 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10521 || !TARGET_PARTIAL_FLAG_REG_STALL
10522 || (operands[2] == const1_rtx
10524 || TARGET_DOUBLE_WITH_ADD)))"
10526 switch (get_attr_type (insn))
10529 gcc_assert (operands[2] == const1_rtx);
10530 return "add{q}\t%0, %0";
10533 if (REG_P (operands[2]))
10534 return "sal{q}\t{%b2, %0|%0, %b2}";
10535 else if (operands[2] == const1_rtx
10536 && (TARGET_SHIFT1 || optimize_size))
10537 return "sal{q}\t%0";
10539 return "sal{q}\t{%2, %0|%0, %2}";
10542 [(set (attr "type")
10543 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10545 (match_operand 0 "register_operand" ""))
10546 (match_operand 2 "const1_operand" ""))
10547 (const_string "alu")
10549 (const_string "ishift")))
10550 (set_attr "mode" "DI")])
10552 (define_insn "*ashldi3_1"
10553 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10554 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10555 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10556 (clobber (reg:CC FLAGS_REG))]
10559 [(set_attr "type" "multi")])
10561 ;; By default we don't ask for a scratch register, because when DImode
10562 ;; values are manipulated, registers are already at a premium. But if
10563 ;; we have one handy, we won't turn it away.
10565 [(match_scratch:SI 3 "r")
10566 (parallel [(set (match_operand:DI 0 "register_operand" "")
10567 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10568 (match_operand:QI 2 "nonmemory_operand" "")))
10569 (clobber (reg:CC FLAGS_REG))])
10571 "!TARGET_64BIT && TARGET_CMOVE"
10573 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10576 [(set (match_operand:DI 0 "register_operand" "")
10577 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10578 (match_operand:QI 2 "nonmemory_operand" "")))
10579 (clobber (reg:CC FLAGS_REG))]
10580 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10581 ? flow2_completed : reload_completed)"
10583 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10585 (define_insn "x86_shld_1"
10586 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10587 (ior:SI (ashift:SI (match_dup 0)
10588 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10589 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10590 (minus:QI (const_int 32) (match_dup 2)))))
10591 (clobber (reg:CC FLAGS_REG))]
10594 shld{l}\t{%2, %1, %0|%0, %1, %2}
10595 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10596 [(set_attr "type" "ishift")
10597 (set_attr "prefix_0f" "1")
10598 (set_attr "mode" "SI")
10599 (set_attr "pent_pair" "np")
10600 (set_attr "athlon_decode" "vector")
10601 (set_attr "amdfam10_decode" "vector")])
10603 (define_expand "x86_shift_adj_1"
10604 [(set (reg:CCZ FLAGS_REG)
10605 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10608 (set (match_operand:SI 0 "register_operand" "")
10609 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10610 (match_operand:SI 1 "register_operand" "")
10613 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10614 (match_operand:SI 3 "register_operand" "r")
10619 (define_expand "x86_shift_adj_2"
10620 [(use (match_operand:SI 0 "register_operand" ""))
10621 (use (match_operand:SI 1 "register_operand" ""))
10622 (use (match_operand:QI 2 "register_operand" ""))]
10625 rtx label = gen_label_rtx ();
10628 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10630 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10631 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10632 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10633 gen_rtx_LABEL_REF (VOIDmode, label),
10635 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10636 JUMP_LABEL (tmp) = label;
10638 emit_move_insn (operands[0], operands[1]);
10639 ix86_expand_clear (operands[1]);
10641 emit_label (label);
10642 LABEL_NUSES (label) = 1;
10647 (define_expand "ashlsi3"
10648 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10649 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10650 (match_operand:QI 2 "nonmemory_operand" "")))
10651 (clobber (reg:CC FLAGS_REG))]
10653 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10655 (define_insn "*ashlsi3_1"
10656 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10657 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10658 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10659 (clobber (reg:CC FLAGS_REG))]
10660 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10662 switch (get_attr_type (insn))
10665 gcc_assert (operands[2] == const1_rtx);
10666 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10667 return "add{l}\t%0, %0";
10673 if (REG_P (operands[2]))
10674 return "sal{l}\t{%b2, %0|%0, %b2}";
10675 else if (operands[2] == const1_rtx
10676 && (TARGET_SHIFT1 || optimize_size))
10677 return "sal{l}\t%0";
10679 return "sal{l}\t{%2, %0|%0, %2}";
10682 [(set (attr "type")
10683 (cond [(eq_attr "alternative" "1")
10684 (const_string "lea")
10685 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10687 (match_operand 0 "register_operand" ""))
10688 (match_operand 2 "const1_operand" ""))
10689 (const_string "alu")
10691 (const_string "ishift")))
10692 (set_attr "mode" "SI")])
10694 ;; Convert lea to the lea pattern to avoid flags dependency.
10696 [(set (match_operand 0 "register_operand" "")
10697 (ashift (match_operand 1 "index_register_operand" "")
10698 (match_operand:QI 2 "const_int_operand" "")))
10699 (clobber (reg:CC FLAGS_REG))]
10701 && true_regnum (operands[0]) != true_regnum (operands[1])
10702 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10706 enum machine_mode mode = GET_MODE (operands[0]);
10708 if (GET_MODE_SIZE (mode) < 4)
10709 operands[0] = gen_lowpart (SImode, operands[0]);
10711 operands[1] = gen_lowpart (Pmode, operands[1]);
10712 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10714 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10715 if (Pmode != SImode)
10716 pat = gen_rtx_SUBREG (SImode, pat, 0);
10717 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10721 ;; Rare case of shifting RSP is handled by generating move and shift
10723 [(set (match_operand 0 "register_operand" "")
10724 (ashift (match_operand 1 "register_operand" "")
10725 (match_operand:QI 2 "const_int_operand" "")))
10726 (clobber (reg:CC FLAGS_REG))]
10728 && true_regnum (operands[0]) != true_regnum (operands[1])"
10732 emit_move_insn (operands[0], operands[1]);
10733 pat = gen_rtx_SET (VOIDmode, operands[0],
10734 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10735 operands[0], operands[2]));
10736 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10737 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10741 (define_insn "*ashlsi3_1_zext"
10742 [(set (match_operand:DI 0 "register_operand" "=r,r")
10743 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10744 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10745 (clobber (reg:CC FLAGS_REG))]
10746 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10748 switch (get_attr_type (insn))
10751 gcc_assert (operands[2] == const1_rtx);
10752 return "add{l}\t%k0, %k0";
10758 if (REG_P (operands[2]))
10759 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10760 else if (operands[2] == const1_rtx
10761 && (TARGET_SHIFT1 || optimize_size))
10762 return "sal{l}\t%k0";
10764 return "sal{l}\t{%2, %k0|%k0, %2}";
10767 [(set (attr "type")
10768 (cond [(eq_attr "alternative" "1")
10769 (const_string "lea")
10770 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10772 (match_operand 2 "const1_operand" ""))
10773 (const_string "alu")
10775 (const_string "ishift")))
10776 (set_attr "mode" "SI")])
10778 ;; Convert lea to the lea pattern to avoid flags dependency.
10780 [(set (match_operand:DI 0 "register_operand" "")
10781 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10782 (match_operand:QI 2 "const_int_operand" ""))))
10783 (clobber (reg:CC FLAGS_REG))]
10784 "TARGET_64BIT && reload_completed
10785 && true_regnum (operands[0]) != true_regnum (operands[1])"
10786 [(set (match_dup 0) (zero_extend:DI
10787 (subreg:SI (mult:SI (match_dup 1)
10788 (match_dup 2)) 0)))]
10790 operands[1] = gen_lowpart (Pmode, operands[1]);
10791 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10794 ;; This pattern can't accept a variable shift count, since shifts by
10795 ;; zero don't affect the flags. We assume that shifts by constant
10796 ;; zero are optimized away.
10797 (define_insn "*ashlsi3_cmp"
10798 [(set (reg FLAGS_REG)
10800 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10801 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10803 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10804 (ashift:SI (match_dup 1) (match_dup 2)))]
10805 "ix86_match_ccmode (insn, CCGOCmode)
10806 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10808 || !TARGET_PARTIAL_FLAG_REG_STALL
10809 || (operands[2] == const1_rtx
10811 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10813 switch (get_attr_type (insn))
10816 gcc_assert (operands[2] == const1_rtx);
10817 return "add{l}\t%0, %0";
10820 if (REG_P (operands[2]))
10821 return "sal{l}\t{%b2, %0|%0, %b2}";
10822 else if (operands[2] == const1_rtx
10823 && (TARGET_SHIFT1 || optimize_size))
10824 return "sal{l}\t%0";
10826 return "sal{l}\t{%2, %0|%0, %2}";
10829 [(set (attr "type")
10830 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10832 (match_operand 0 "register_operand" ""))
10833 (match_operand 2 "const1_operand" ""))
10834 (const_string "alu")
10836 (const_string "ishift")))
10837 (set_attr "mode" "SI")])
10839 (define_insn "*ashlsi3_cconly"
10840 [(set (reg FLAGS_REG)
10842 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10843 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10845 (clobber (match_scratch:SI 0 "=r"))]
10846 "ix86_match_ccmode (insn, CCGOCmode)
10847 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10849 || !TARGET_PARTIAL_FLAG_REG_STALL
10850 || (operands[2] == const1_rtx
10852 || TARGET_DOUBLE_WITH_ADD)))"
10854 switch (get_attr_type (insn))
10857 gcc_assert (operands[2] == const1_rtx);
10858 return "add{l}\t%0, %0";
10861 if (REG_P (operands[2]))
10862 return "sal{l}\t{%b2, %0|%0, %b2}";
10863 else if (operands[2] == const1_rtx
10864 && (TARGET_SHIFT1 || optimize_size))
10865 return "sal{l}\t%0";
10867 return "sal{l}\t{%2, %0|%0, %2}";
10870 [(set (attr "type")
10871 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10873 (match_operand 0 "register_operand" ""))
10874 (match_operand 2 "const1_operand" ""))
10875 (const_string "alu")
10877 (const_string "ishift")))
10878 (set_attr "mode" "SI")])
10880 (define_insn "*ashlsi3_cmp_zext"
10881 [(set (reg FLAGS_REG)
10883 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10884 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10886 (set (match_operand:DI 0 "register_operand" "=r")
10887 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10888 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10889 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10891 || !TARGET_PARTIAL_FLAG_REG_STALL
10892 || (operands[2] == const1_rtx
10894 || TARGET_DOUBLE_WITH_ADD)))"
10896 switch (get_attr_type (insn))
10899 gcc_assert (operands[2] == const1_rtx);
10900 return "add{l}\t%k0, %k0";
10903 if (REG_P (operands[2]))
10904 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10905 else if (operands[2] == const1_rtx
10906 && (TARGET_SHIFT1 || optimize_size))
10907 return "sal{l}\t%k0";
10909 return "sal{l}\t{%2, %k0|%k0, %2}";
10912 [(set (attr "type")
10913 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10915 (match_operand 2 "const1_operand" ""))
10916 (const_string "alu")
10918 (const_string "ishift")))
10919 (set_attr "mode" "SI")])
10921 (define_expand "ashlhi3"
10922 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10923 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10924 (match_operand:QI 2 "nonmemory_operand" "")))
10925 (clobber (reg:CC FLAGS_REG))]
10926 "TARGET_HIMODE_MATH"
10927 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10929 (define_insn "*ashlhi3_1_lea"
10930 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10931 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10932 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10933 (clobber (reg:CC FLAGS_REG))]
10934 "!TARGET_PARTIAL_REG_STALL
10935 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10937 switch (get_attr_type (insn))
10942 gcc_assert (operands[2] == const1_rtx);
10943 return "add{w}\t%0, %0";
10946 if (REG_P (operands[2]))
10947 return "sal{w}\t{%b2, %0|%0, %b2}";
10948 else if (operands[2] == const1_rtx
10949 && (TARGET_SHIFT1 || optimize_size))
10950 return "sal{w}\t%0";
10952 return "sal{w}\t{%2, %0|%0, %2}";
10955 [(set (attr "type")
10956 (cond [(eq_attr "alternative" "1")
10957 (const_string "lea")
10958 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10960 (match_operand 0 "register_operand" ""))
10961 (match_operand 2 "const1_operand" ""))
10962 (const_string "alu")
10964 (const_string "ishift")))
10965 (set_attr "mode" "HI,SI")])
10967 (define_insn "*ashlhi3_1"
10968 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10969 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10970 (match_operand:QI 2 "nonmemory_operand" "cI")))
10971 (clobber (reg:CC FLAGS_REG))]
10972 "TARGET_PARTIAL_REG_STALL
10973 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10975 switch (get_attr_type (insn))
10978 gcc_assert (operands[2] == const1_rtx);
10979 return "add{w}\t%0, %0";
10982 if (REG_P (operands[2]))
10983 return "sal{w}\t{%b2, %0|%0, %b2}";
10984 else if (operands[2] == const1_rtx
10985 && (TARGET_SHIFT1 || optimize_size))
10986 return "sal{w}\t%0";
10988 return "sal{w}\t{%2, %0|%0, %2}";
10991 [(set (attr "type")
10992 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10994 (match_operand 0 "register_operand" ""))
10995 (match_operand 2 "const1_operand" ""))
10996 (const_string "alu")
10998 (const_string "ishift")))
10999 (set_attr "mode" "HI")])
11001 ;; This pattern can't accept a variable shift count, since shifts by
11002 ;; zero don't affect the flags. We assume that shifts by constant
11003 ;; zero are optimized away.
11004 (define_insn "*ashlhi3_cmp"
11005 [(set (reg FLAGS_REG)
11007 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11008 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11010 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11011 (ashift:HI (match_dup 1) (match_dup 2)))]
11012 "ix86_match_ccmode (insn, CCGOCmode)
11013 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11015 || !TARGET_PARTIAL_FLAG_REG_STALL
11016 || (operands[2] == const1_rtx
11018 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11020 switch (get_attr_type (insn))
11023 gcc_assert (operands[2] == const1_rtx);
11024 return "add{w}\t%0, %0";
11027 if (REG_P (operands[2]))
11028 return "sal{w}\t{%b2, %0|%0, %b2}";
11029 else if (operands[2] == const1_rtx
11030 && (TARGET_SHIFT1 || optimize_size))
11031 return "sal{w}\t%0";
11033 return "sal{w}\t{%2, %0|%0, %2}";
11036 [(set (attr "type")
11037 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11039 (match_operand 0 "register_operand" ""))
11040 (match_operand 2 "const1_operand" ""))
11041 (const_string "alu")
11043 (const_string "ishift")))
11044 (set_attr "mode" "HI")])
11046 (define_insn "*ashlhi3_cconly"
11047 [(set (reg FLAGS_REG)
11049 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11050 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11052 (clobber (match_scratch:HI 0 "=r"))]
11053 "ix86_match_ccmode (insn, CCGOCmode)
11054 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11056 || !TARGET_PARTIAL_FLAG_REG_STALL
11057 || (operands[2] == const1_rtx
11059 || TARGET_DOUBLE_WITH_ADD)))"
11061 switch (get_attr_type (insn))
11064 gcc_assert (operands[2] == const1_rtx);
11065 return "add{w}\t%0, %0";
11068 if (REG_P (operands[2]))
11069 return "sal{w}\t{%b2, %0|%0, %b2}";
11070 else if (operands[2] == const1_rtx
11071 && (TARGET_SHIFT1 || optimize_size))
11072 return "sal{w}\t%0";
11074 return "sal{w}\t{%2, %0|%0, %2}";
11077 [(set (attr "type")
11078 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11080 (match_operand 0 "register_operand" ""))
11081 (match_operand 2 "const1_operand" ""))
11082 (const_string "alu")
11084 (const_string "ishift")))
11085 (set_attr "mode" "HI")])
11087 (define_expand "ashlqi3"
11088 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11089 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11090 (match_operand:QI 2 "nonmemory_operand" "")))
11091 (clobber (reg:CC FLAGS_REG))]
11092 "TARGET_QIMODE_MATH"
11093 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11095 ;; %%% Potential partial reg stall on alternative 2. What to do?
11097 (define_insn "*ashlqi3_1_lea"
11098 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11099 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11100 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11101 (clobber (reg:CC FLAGS_REG))]
11102 "!TARGET_PARTIAL_REG_STALL
11103 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11105 switch (get_attr_type (insn))
11110 gcc_assert (operands[2] == const1_rtx);
11111 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11112 return "add{l}\t%k0, %k0";
11114 return "add{b}\t%0, %0";
11117 if (REG_P (operands[2]))
11119 if (get_attr_mode (insn) == MODE_SI)
11120 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11122 return "sal{b}\t{%b2, %0|%0, %b2}";
11124 else if (operands[2] == const1_rtx
11125 && (TARGET_SHIFT1 || optimize_size))
11127 if (get_attr_mode (insn) == MODE_SI)
11128 return "sal{l}\t%0";
11130 return "sal{b}\t%0";
11134 if (get_attr_mode (insn) == MODE_SI)
11135 return "sal{l}\t{%2, %k0|%k0, %2}";
11137 return "sal{b}\t{%2, %0|%0, %2}";
11141 [(set (attr "type")
11142 (cond [(eq_attr "alternative" "2")
11143 (const_string "lea")
11144 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11146 (match_operand 0 "register_operand" ""))
11147 (match_operand 2 "const1_operand" ""))
11148 (const_string "alu")
11150 (const_string "ishift")))
11151 (set_attr "mode" "QI,SI,SI")])
11153 (define_insn "*ashlqi3_1"
11154 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11155 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11156 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11157 (clobber (reg:CC FLAGS_REG))]
11158 "TARGET_PARTIAL_REG_STALL
11159 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11161 switch (get_attr_type (insn))
11164 gcc_assert (operands[2] == const1_rtx);
11165 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11166 return "add{l}\t%k0, %k0";
11168 return "add{b}\t%0, %0";
11171 if (REG_P (operands[2]))
11173 if (get_attr_mode (insn) == MODE_SI)
11174 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11176 return "sal{b}\t{%b2, %0|%0, %b2}";
11178 else if (operands[2] == const1_rtx
11179 && (TARGET_SHIFT1 || optimize_size))
11181 if (get_attr_mode (insn) == MODE_SI)
11182 return "sal{l}\t%0";
11184 return "sal{b}\t%0";
11188 if (get_attr_mode (insn) == MODE_SI)
11189 return "sal{l}\t{%2, %k0|%k0, %2}";
11191 return "sal{b}\t{%2, %0|%0, %2}";
11195 [(set (attr "type")
11196 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11198 (match_operand 0 "register_operand" ""))
11199 (match_operand 2 "const1_operand" ""))
11200 (const_string "alu")
11202 (const_string "ishift")))
11203 (set_attr "mode" "QI,SI")])
11205 ;; This pattern can't accept a variable shift count, since shifts by
11206 ;; zero don't affect the flags. We assume that shifts by constant
11207 ;; zero are optimized away.
11208 (define_insn "*ashlqi3_cmp"
11209 [(set (reg FLAGS_REG)
11211 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11212 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11214 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11215 (ashift:QI (match_dup 1) (match_dup 2)))]
11216 "ix86_match_ccmode (insn, CCGOCmode)
11217 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11219 || !TARGET_PARTIAL_FLAG_REG_STALL
11220 || (operands[2] == const1_rtx
11222 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11224 switch (get_attr_type (insn))
11227 gcc_assert (operands[2] == const1_rtx);
11228 return "add{b}\t%0, %0";
11231 if (REG_P (operands[2]))
11232 return "sal{b}\t{%b2, %0|%0, %b2}";
11233 else if (operands[2] == const1_rtx
11234 && (TARGET_SHIFT1 || optimize_size))
11235 return "sal{b}\t%0";
11237 return "sal{b}\t{%2, %0|%0, %2}";
11240 [(set (attr "type")
11241 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11243 (match_operand 0 "register_operand" ""))
11244 (match_operand 2 "const1_operand" ""))
11245 (const_string "alu")
11247 (const_string "ishift")))
11248 (set_attr "mode" "QI")])
11250 (define_insn "*ashlqi3_cconly"
11251 [(set (reg FLAGS_REG)
11253 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11254 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11256 (clobber (match_scratch:QI 0 "=q"))]
11257 "ix86_match_ccmode (insn, CCGOCmode)
11258 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11260 || !TARGET_PARTIAL_FLAG_REG_STALL
11261 || (operands[2] == const1_rtx
11263 || TARGET_DOUBLE_WITH_ADD)))"
11265 switch (get_attr_type (insn))
11268 gcc_assert (operands[2] == const1_rtx);
11269 return "add{b}\t%0, %0";
11272 if (REG_P (operands[2]))
11273 return "sal{b}\t{%b2, %0|%0, %b2}";
11274 else if (operands[2] == const1_rtx
11275 && (TARGET_SHIFT1 || optimize_size))
11276 return "sal{b}\t%0";
11278 return "sal{b}\t{%2, %0|%0, %2}";
11281 [(set (attr "type")
11282 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11284 (match_operand 0 "register_operand" ""))
11285 (match_operand 2 "const1_operand" ""))
11286 (const_string "alu")
11288 (const_string "ishift")))
11289 (set_attr "mode" "QI")])
11291 ;; See comment above `ashldi3' about how this works.
11293 (define_expand "ashrti3"
11294 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11295 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11296 (match_operand:QI 2 "nonmemory_operand" "")))
11297 (clobber (reg:CC FLAGS_REG))])]
11300 if (! immediate_operand (operands[2], QImode))
11302 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11305 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11309 (define_insn "ashrti3_1"
11310 [(set (match_operand:TI 0 "register_operand" "=r")
11311 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11312 (match_operand:QI 2 "register_operand" "c")))
11313 (clobber (match_scratch:DI 3 "=&r"))
11314 (clobber (reg:CC FLAGS_REG))]
11317 [(set_attr "type" "multi")])
11319 (define_insn "*ashrti3_2"
11320 [(set (match_operand:TI 0 "register_operand" "=r")
11321 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11322 (match_operand:QI 2 "immediate_operand" "O")))
11323 (clobber (reg:CC FLAGS_REG))]
11326 [(set_attr "type" "multi")])
11329 [(set (match_operand:TI 0 "register_operand" "")
11330 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11331 (match_operand:QI 2 "register_operand" "")))
11332 (clobber (match_scratch:DI 3 ""))
11333 (clobber (reg:CC FLAGS_REG))]
11334 "TARGET_64BIT && reload_completed"
11336 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11339 [(set (match_operand:TI 0 "register_operand" "")
11340 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11341 (match_operand:QI 2 "immediate_operand" "")))
11342 (clobber (reg:CC FLAGS_REG))]
11343 "TARGET_64BIT && reload_completed"
11345 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11347 (define_insn "x86_64_shrd"
11348 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11349 (ior:DI (ashiftrt:DI (match_dup 0)
11350 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11351 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11352 (minus:QI (const_int 64) (match_dup 2)))))
11353 (clobber (reg:CC FLAGS_REG))]
11356 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11357 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11358 [(set_attr "type" "ishift")
11359 (set_attr "prefix_0f" "1")
11360 (set_attr "mode" "DI")
11361 (set_attr "athlon_decode" "vector")
11362 (set_attr "amdfam10_decode" "vector")])
11364 (define_expand "ashrdi3"
11365 [(set (match_operand:DI 0 "shiftdi_operand" "")
11366 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11367 (match_operand:QI 2 "nonmemory_operand" "")))]
11369 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11371 (define_insn "*ashrdi3_63_rex64"
11372 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11373 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11374 (match_operand:DI 2 "const_int_operand" "i,i")))
11375 (clobber (reg:CC FLAGS_REG))]
11376 "TARGET_64BIT && INTVAL (operands[2]) == 63
11377 && (TARGET_USE_CLTD || optimize_size)
11378 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11381 sar{q}\t{%2, %0|%0, %2}"
11382 [(set_attr "type" "imovx,ishift")
11383 (set_attr "prefix_0f" "0,*")
11384 (set_attr "length_immediate" "0,*")
11385 (set_attr "modrm" "0,1")
11386 (set_attr "mode" "DI")])
11388 (define_insn "*ashrdi3_1_one_bit_rex64"
11389 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11390 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11391 (match_operand:QI 2 "const1_operand" "")))
11392 (clobber (reg:CC FLAGS_REG))]
11393 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11394 && (TARGET_SHIFT1 || optimize_size)"
11396 [(set_attr "type" "ishift")
11397 (set (attr "length")
11398 (if_then_else (match_operand:DI 0 "register_operand" "")
11400 (const_string "*")))])
11402 (define_insn "*ashrdi3_1_rex64"
11403 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11404 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11405 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11406 (clobber (reg:CC FLAGS_REG))]
11407 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11409 sar{q}\t{%2, %0|%0, %2}
11410 sar{q}\t{%b2, %0|%0, %b2}"
11411 [(set_attr "type" "ishift")
11412 (set_attr "mode" "DI")])
11414 ;; This pattern can't accept a variable shift count, since shifts by
11415 ;; zero don't affect the flags. We assume that shifts by constant
11416 ;; zero are optimized away.
11417 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11418 [(set (reg FLAGS_REG)
11420 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11421 (match_operand:QI 2 "const1_operand" ""))
11423 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11424 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11425 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11426 && (TARGET_SHIFT1 || optimize_size)
11427 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11429 [(set_attr "type" "ishift")
11430 (set (attr "length")
11431 (if_then_else (match_operand:DI 0 "register_operand" "")
11433 (const_string "*")))])
11435 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11436 [(set (reg FLAGS_REG)
11438 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11439 (match_operand:QI 2 "const1_operand" ""))
11441 (clobber (match_scratch:DI 0 "=r"))]
11442 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11443 && (TARGET_SHIFT1 || optimize_size)
11444 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11446 [(set_attr "type" "ishift")
11447 (set_attr "length" "2")])
11449 ;; This pattern can't accept a variable shift count, since shifts by
11450 ;; zero don't affect the flags. We assume that shifts by constant
11451 ;; zero are optimized away.
11452 (define_insn "*ashrdi3_cmp_rex64"
11453 [(set (reg FLAGS_REG)
11455 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11456 (match_operand:QI 2 "const_int_operand" "n"))
11458 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11459 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11460 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11461 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11463 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11464 "sar{q}\t{%2, %0|%0, %2}"
11465 [(set_attr "type" "ishift")
11466 (set_attr "mode" "DI")])
11468 (define_insn "*ashrdi3_cconly_rex64"
11469 [(set (reg FLAGS_REG)
11471 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11472 (match_operand:QI 2 "const_int_operand" "n"))
11474 (clobber (match_scratch:DI 0 "=r"))]
11475 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11476 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11478 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11479 "sar{q}\t{%2, %0|%0, %2}"
11480 [(set_attr "type" "ishift")
11481 (set_attr "mode" "DI")])
11483 (define_insn "*ashrdi3_1"
11484 [(set (match_operand:DI 0 "register_operand" "=r")
11485 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11486 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11487 (clobber (reg:CC FLAGS_REG))]
11490 [(set_attr "type" "multi")])
11492 ;; By default we don't ask for a scratch register, because when DImode
11493 ;; values are manipulated, registers are already at a premium. But if
11494 ;; we have one handy, we won't turn it away.
11496 [(match_scratch:SI 3 "r")
11497 (parallel [(set (match_operand:DI 0 "register_operand" "")
11498 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11499 (match_operand:QI 2 "nonmemory_operand" "")))
11500 (clobber (reg:CC FLAGS_REG))])
11502 "!TARGET_64BIT && TARGET_CMOVE"
11504 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11507 [(set (match_operand:DI 0 "register_operand" "")
11508 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11509 (match_operand:QI 2 "nonmemory_operand" "")))
11510 (clobber (reg:CC FLAGS_REG))]
11511 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11512 ? flow2_completed : reload_completed)"
11514 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11516 (define_insn "x86_shrd_1"
11517 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11518 (ior:SI (ashiftrt:SI (match_dup 0)
11519 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11520 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11521 (minus:QI (const_int 32) (match_dup 2)))))
11522 (clobber (reg:CC FLAGS_REG))]
11525 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11526 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11527 [(set_attr "type" "ishift")
11528 (set_attr "prefix_0f" "1")
11529 (set_attr "pent_pair" "np")
11530 (set_attr "mode" "SI")])
11532 (define_expand "x86_shift_adj_3"
11533 [(use (match_operand:SI 0 "register_operand" ""))
11534 (use (match_operand:SI 1 "register_operand" ""))
11535 (use (match_operand:QI 2 "register_operand" ""))]
11538 rtx label = gen_label_rtx ();
11541 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11543 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11544 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11545 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11546 gen_rtx_LABEL_REF (VOIDmode, label),
11548 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11549 JUMP_LABEL (tmp) = label;
11551 emit_move_insn (operands[0], operands[1]);
11552 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11554 emit_label (label);
11555 LABEL_NUSES (label) = 1;
11560 (define_insn "ashrsi3_31"
11561 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11562 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11563 (match_operand:SI 2 "const_int_operand" "i,i")))
11564 (clobber (reg:CC FLAGS_REG))]
11565 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11566 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11569 sar{l}\t{%2, %0|%0, %2}"
11570 [(set_attr "type" "imovx,ishift")
11571 (set_attr "prefix_0f" "0,*")
11572 (set_attr "length_immediate" "0,*")
11573 (set_attr "modrm" "0,1")
11574 (set_attr "mode" "SI")])
11576 (define_insn "*ashrsi3_31_zext"
11577 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11578 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11579 (match_operand:SI 2 "const_int_operand" "i,i"))))
11580 (clobber (reg:CC FLAGS_REG))]
11581 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11582 && INTVAL (operands[2]) == 31
11583 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11586 sar{l}\t{%2, %k0|%k0, %2}"
11587 [(set_attr "type" "imovx,ishift")
11588 (set_attr "prefix_0f" "0,*")
11589 (set_attr "length_immediate" "0,*")
11590 (set_attr "modrm" "0,1")
11591 (set_attr "mode" "SI")])
11593 (define_expand "ashrsi3"
11594 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11595 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11596 (match_operand:QI 2 "nonmemory_operand" "")))
11597 (clobber (reg:CC FLAGS_REG))]
11599 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11601 (define_insn "*ashrsi3_1_one_bit"
11602 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11603 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11604 (match_operand:QI 2 "const1_operand" "")))
11605 (clobber (reg:CC FLAGS_REG))]
11606 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11607 && (TARGET_SHIFT1 || optimize_size)"
11609 [(set_attr "type" "ishift")
11610 (set (attr "length")
11611 (if_then_else (match_operand:SI 0 "register_operand" "")
11613 (const_string "*")))])
11615 (define_insn "*ashrsi3_1_one_bit_zext"
11616 [(set (match_operand:DI 0 "register_operand" "=r")
11617 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11618 (match_operand:QI 2 "const1_operand" ""))))
11619 (clobber (reg:CC FLAGS_REG))]
11620 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11621 && (TARGET_SHIFT1 || optimize_size)"
11623 [(set_attr "type" "ishift")
11624 (set_attr "length" "2")])
11626 (define_insn "*ashrsi3_1"
11627 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11628 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11629 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11630 (clobber (reg:CC FLAGS_REG))]
11631 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11633 sar{l}\t{%2, %0|%0, %2}
11634 sar{l}\t{%b2, %0|%0, %b2}"
11635 [(set_attr "type" "ishift")
11636 (set_attr "mode" "SI")])
11638 (define_insn "*ashrsi3_1_zext"
11639 [(set (match_operand:DI 0 "register_operand" "=r,r")
11640 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11641 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11642 (clobber (reg:CC FLAGS_REG))]
11643 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11645 sar{l}\t{%2, %k0|%k0, %2}
11646 sar{l}\t{%b2, %k0|%k0, %b2}"
11647 [(set_attr "type" "ishift")
11648 (set_attr "mode" "SI")])
11650 ;; This pattern can't accept a variable shift count, since shifts by
11651 ;; zero don't affect the flags. We assume that shifts by constant
11652 ;; zero are optimized away.
11653 (define_insn "*ashrsi3_one_bit_cmp"
11654 [(set (reg FLAGS_REG)
11656 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11657 (match_operand:QI 2 "const1_operand" ""))
11659 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11660 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11661 "ix86_match_ccmode (insn, CCGOCmode)
11662 && (TARGET_SHIFT1 || optimize_size)
11663 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11665 [(set_attr "type" "ishift")
11666 (set (attr "length")
11667 (if_then_else (match_operand:SI 0 "register_operand" "")
11669 (const_string "*")))])
11671 (define_insn "*ashrsi3_one_bit_cconly"
11672 [(set (reg FLAGS_REG)
11674 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11675 (match_operand:QI 2 "const1_operand" ""))
11677 (clobber (match_scratch:SI 0 "=r"))]
11678 "ix86_match_ccmode (insn, CCGOCmode)
11679 && (TARGET_SHIFT1 || optimize_size)
11680 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11682 [(set_attr "type" "ishift")
11683 (set_attr "length" "2")])
11685 (define_insn "*ashrsi3_one_bit_cmp_zext"
11686 [(set (reg FLAGS_REG)
11688 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11689 (match_operand:QI 2 "const1_operand" ""))
11691 (set (match_operand:DI 0 "register_operand" "=r")
11692 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11693 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11694 && (TARGET_SHIFT1 || optimize_size)
11695 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11697 [(set_attr "type" "ishift")
11698 (set_attr "length" "2")])
11700 ;; This pattern can't accept a variable shift count, since shifts by
11701 ;; zero don't affect the flags. We assume that shifts by constant
11702 ;; zero are optimized away.
11703 (define_insn "*ashrsi3_cmp"
11704 [(set (reg FLAGS_REG)
11706 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11707 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11709 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11710 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11711 "ix86_match_ccmode (insn, CCGOCmode)
11712 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11714 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11715 "sar{l}\t{%2, %0|%0, %2}"
11716 [(set_attr "type" "ishift")
11717 (set_attr "mode" "SI")])
11719 (define_insn "*ashrsi3_cconly"
11720 [(set (reg FLAGS_REG)
11722 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11723 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11725 (clobber (match_scratch:SI 0 "=r"))]
11726 "ix86_match_ccmode (insn, CCGOCmode)
11727 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11729 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11730 "sar{l}\t{%2, %0|%0, %2}"
11731 [(set_attr "type" "ishift")
11732 (set_attr "mode" "SI")])
11734 (define_insn "*ashrsi3_cmp_zext"
11735 [(set (reg FLAGS_REG)
11737 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11738 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11740 (set (match_operand:DI 0 "register_operand" "=r")
11741 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11742 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11743 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11745 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11746 "sar{l}\t{%2, %k0|%k0, %2}"
11747 [(set_attr "type" "ishift")
11748 (set_attr "mode" "SI")])
11750 (define_expand "ashrhi3"
11751 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11752 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11753 (match_operand:QI 2 "nonmemory_operand" "")))
11754 (clobber (reg:CC FLAGS_REG))]
11755 "TARGET_HIMODE_MATH"
11756 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11758 (define_insn "*ashrhi3_1_one_bit"
11759 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11760 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11761 (match_operand:QI 2 "const1_operand" "")))
11762 (clobber (reg:CC FLAGS_REG))]
11763 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11764 && (TARGET_SHIFT1 || optimize_size)"
11766 [(set_attr "type" "ishift")
11767 (set (attr "length")
11768 (if_then_else (match_operand 0 "register_operand" "")
11770 (const_string "*")))])
11772 (define_insn "*ashrhi3_1"
11773 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11774 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11775 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11776 (clobber (reg:CC FLAGS_REG))]
11777 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11779 sar{w}\t{%2, %0|%0, %2}
11780 sar{w}\t{%b2, %0|%0, %b2}"
11781 [(set_attr "type" "ishift")
11782 (set_attr "mode" "HI")])
11784 ;; This pattern can't accept a variable shift count, since shifts by
11785 ;; zero don't affect the flags. We assume that shifts by constant
11786 ;; zero are optimized away.
11787 (define_insn "*ashrhi3_one_bit_cmp"
11788 [(set (reg FLAGS_REG)
11790 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11791 (match_operand:QI 2 "const1_operand" ""))
11793 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11794 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11795 "ix86_match_ccmode (insn, CCGOCmode)
11796 && (TARGET_SHIFT1 || optimize_size)
11797 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11799 [(set_attr "type" "ishift")
11800 (set (attr "length")
11801 (if_then_else (match_operand 0 "register_operand" "")
11803 (const_string "*")))])
11805 (define_insn "*ashrhi3_one_bit_cconly"
11806 [(set (reg FLAGS_REG)
11808 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11809 (match_operand:QI 2 "const1_operand" ""))
11811 (clobber (match_scratch:HI 0 "=r"))]
11812 "ix86_match_ccmode (insn, CCGOCmode)
11813 && (TARGET_SHIFT1 || optimize_size)
11814 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11816 [(set_attr "type" "ishift")
11817 (set_attr "length" "2")])
11819 ;; This pattern can't accept a variable shift count, since shifts by
11820 ;; zero don't affect the flags. We assume that shifts by constant
11821 ;; zero are optimized away.
11822 (define_insn "*ashrhi3_cmp"
11823 [(set (reg FLAGS_REG)
11825 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11826 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11828 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11829 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11830 "ix86_match_ccmode (insn, CCGOCmode)
11831 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11833 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11834 "sar{w}\t{%2, %0|%0, %2}"
11835 [(set_attr "type" "ishift")
11836 (set_attr "mode" "HI")])
11838 (define_insn "*ashrhi3_cconly"
11839 [(set (reg FLAGS_REG)
11841 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11842 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11844 (clobber (match_scratch:HI 0 "=r"))]
11845 "ix86_match_ccmode (insn, CCGOCmode)
11846 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11848 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11849 "sar{w}\t{%2, %0|%0, %2}"
11850 [(set_attr "type" "ishift")
11851 (set_attr "mode" "HI")])
11853 (define_expand "ashrqi3"
11854 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11855 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11856 (match_operand:QI 2 "nonmemory_operand" "")))
11857 (clobber (reg:CC FLAGS_REG))]
11858 "TARGET_QIMODE_MATH"
11859 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11861 (define_insn "*ashrqi3_1_one_bit"
11862 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11863 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11864 (match_operand:QI 2 "const1_operand" "")))
11865 (clobber (reg:CC FLAGS_REG))]
11866 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11867 && (TARGET_SHIFT1 || optimize_size)"
11869 [(set_attr "type" "ishift")
11870 (set (attr "length")
11871 (if_then_else (match_operand 0 "register_operand" "")
11873 (const_string "*")))])
11875 (define_insn "*ashrqi3_1_one_bit_slp"
11876 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11877 (ashiftrt:QI (match_dup 0)
11878 (match_operand:QI 1 "const1_operand" "")))
11879 (clobber (reg:CC FLAGS_REG))]
11880 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11881 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11882 && (TARGET_SHIFT1 || optimize_size)"
11884 [(set_attr "type" "ishift1")
11885 (set (attr "length")
11886 (if_then_else (match_operand 0 "register_operand" "")
11888 (const_string "*")))])
11890 (define_insn "*ashrqi3_1"
11891 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11892 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11893 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11894 (clobber (reg:CC FLAGS_REG))]
11895 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11897 sar{b}\t{%2, %0|%0, %2}
11898 sar{b}\t{%b2, %0|%0, %b2}"
11899 [(set_attr "type" "ishift")
11900 (set_attr "mode" "QI")])
11902 (define_insn "*ashrqi3_1_slp"
11903 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11904 (ashiftrt:QI (match_dup 0)
11905 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11906 (clobber (reg:CC FLAGS_REG))]
11907 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11908 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11910 sar{b}\t{%1, %0|%0, %1}
11911 sar{b}\t{%b1, %0|%0, %b1}"
11912 [(set_attr "type" "ishift1")
11913 (set_attr "mode" "QI")])
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 "*ashrqi3_one_bit_cmp"
11919 [(set (reg FLAGS_REG)
11921 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11922 (match_operand:QI 2 "const1_operand" "I"))
11924 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11925 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11926 "ix86_match_ccmode (insn, CCGOCmode)
11927 && (TARGET_SHIFT1 || optimize_size)
11928 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11930 [(set_attr "type" "ishift")
11931 (set (attr "length")
11932 (if_then_else (match_operand 0 "register_operand" "")
11934 (const_string "*")))])
11936 (define_insn "*ashrqi3_one_bit_cconly"
11937 [(set (reg FLAGS_REG)
11939 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11940 (match_operand:QI 2 "const1_operand" "I"))
11942 (clobber (match_scratch:QI 0 "=q"))]
11943 "ix86_match_ccmode (insn, CCGOCmode)
11944 && (TARGET_SHIFT1 || optimize_size)
11945 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11947 [(set_attr "type" "ishift")
11948 (set_attr "length" "2")])
11950 ;; This pattern can't accept a variable shift count, since shifts by
11951 ;; zero don't affect the flags. We assume that shifts by constant
11952 ;; zero are optimized away.
11953 (define_insn "*ashrqi3_cmp"
11954 [(set (reg FLAGS_REG)
11956 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11957 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11959 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11960 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11961 "ix86_match_ccmode (insn, CCGOCmode)
11962 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11964 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11965 "sar{b}\t{%2, %0|%0, %2}"
11966 [(set_attr "type" "ishift")
11967 (set_attr "mode" "QI")])
11969 (define_insn "*ashrqi3_cconly"
11970 [(set (reg FLAGS_REG)
11972 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11973 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11975 (clobber (match_scratch:QI 0 "=q"))]
11976 "ix86_match_ccmode (insn, CCGOCmode)
11977 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11979 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11980 "sar{b}\t{%2, %0|%0, %2}"
11981 [(set_attr "type" "ishift")
11982 (set_attr "mode" "QI")])
11985 ;; Logical shift instructions
11987 ;; See comment above `ashldi3' about how this works.
11989 (define_expand "lshrti3"
11990 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11991 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11992 (match_operand:QI 2 "nonmemory_operand" "")))
11993 (clobber (reg:CC FLAGS_REG))])]
11996 if (! immediate_operand (operands[2], QImode))
11998 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12001 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12005 (define_insn "lshrti3_1"
12006 [(set (match_operand:TI 0 "register_operand" "=r")
12007 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12008 (match_operand:QI 2 "register_operand" "c")))
12009 (clobber (match_scratch:DI 3 "=&r"))
12010 (clobber (reg:CC FLAGS_REG))]
12013 [(set_attr "type" "multi")])
12015 (define_insn "*lshrti3_2"
12016 [(set (match_operand:TI 0 "register_operand" "=r")
12017 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12018 (match_operand:QI 2 "immediate_operand" "O")))
12019 (clobber (reg:CC FLAGS_REG))]
12022 [(set_attr "type" "multi")])
12025 [(set (match_operand:TI 0 "register_operand" "")
12026 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12027 (match_operand:QI 2 "register_operand" "")))
12028 (clobber (match_scratch:DI 3 ""))
12029 (clobber (reg:CC FLAGS_REG))]
12030 "TARGET_64BIT && reload_completed"
12032 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12035 [(set (match_operand:TI 0 "register_operand" "")
12036 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12037 (match_operand:QI 2 "immediate_operand" "")))
12038 (clobber (reg:CC FLAGS_REG))]
12039 "TARGET_64BIT && reload_completed"
12041 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12043 (define_expand "lshrdi3"
12044 [(set (match_operand:DI 0 "shiftdi_operand" "")
12045 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12046 (match_operand:QI 2 "nonmemory_operand" "")))]
12048 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12050 (define_insn "*lshrdi3_1_one_bit_rex64"
12051 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12052 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12053 (match_operand:QI 2 "const1_operand" "")))
12054 (clobber (reg:CC FLAGS_REG))]
12055 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12056 && (TARGET_SHIFT1 || optimize_size)"
12058 [(set_attr "type" "ishift")
12059 (set (attr "length")
12060 (if_then_else (match_operand:DI 0 "register_operand" "")
12062 (const_string "*")))])
12064 (define_insn "*lshrdi3_1_rex64"
12065 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12066 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12067 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12068 (clobber (reg:CC FLAGS_REG))]
12069 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12071 shr{q}\t{%2, %0|%0, %2}
12072 shr{q}\t{%b2, %0|%0, %b2}"
12073 [(set_attr "type" "ishift")
12074 (set_attr "mode" "DI")])
12076 ;; This pattern can't accept a variable shift count, since shifts by
12077 ;; zero don't affect the flags. We assume that shifts by constant
12078 ;; zero are optimized away.
12079 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12080 [(set (reg FLAGS_REG)
12082 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12083 (match_operand:QI 2 "const1_operand" ""))
12085 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12086 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12087 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12088 && (TARGET_SHIFT1 || optimize_size)
12089 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12091 [(set_attr "type" "ishift")
12092 (set (attr "length")
12093 (if_then_else (match_operand:DI 0 "register_operand" "")
12095 (const_string "*")))])
12097 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12098 [(set (reg FLAGS_REG)
12100 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12101 (match_operand:QI 2 "const1_operand" ""))
12103 (clobber (match_scratch:DI 0 "=r"))]
12104 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12105 && (TARGET_SHIFT1 || optimize_size)
12106 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12108 [(set_attr "type" "ishift")
12109 (set_attr "length" "2")])
12111 ;; This pattern can't accept a variable shift count, since shifts by
12112 ;; zero don't affect the flags. We assume that shifts by constant
12113 ;; zero are optimized away.
12114 (define_insn "*lshrdi3_cmp_rex64"
12115 [(set (reg FLAGS_REG)
12117 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12118 (match_operand:QI 2 "const_int_operand" "e"))
12120 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12121 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12122 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12123 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12125 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12126 "shr{q}\t{%2, %0|%0, %2}"
12127 [(set_attr "type" "ishift")
12128 (set_attr "mode" "DI")])
12130 (define_insn "*lshrdi3_cconly_rex64"
12131 [(set (reg FLAGS_REG)
12133 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12134 (match_operand:QI 2 "const_int_operand" "e"))
12136 (clobber (match_scratch:DI 0 "=r"))]
12137 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12138 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12140 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12141 "shr{q}\t{%2, %0|%0, %2}"
12142 [(set_attr "type" "ishift")
12143 (set_attr "mode" "DI")])
12145 (define_insn "*lshrdi3_1"
12146 [(set (match_operand:DI 0 "register_operand" "=r")
12147 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12148 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12149 (clobber (reg:CC FLAGS_REG))]
12152 [(set_attr "type" "multi")])
12154 ;; By default we don't ask for a scratch register, because when DImode
12155 ;; values are manipulated, registers are already at a premium. But if
12156 ;; we have one handy, we won't turn it away.
12158 [(match_scratch:SI 3 "r")
12159 (parallel [(set (match_operand:DI 0 "register_operand" "")
12160 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12161 (match_operand:QI 2 "nonmemory_operand" "")))
12162 (clobber (reg:CC FLAGS_REG))])
12164 "!TARGET_64BIT && TARGET_CMOVE"
12166 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12169 [(set (match_operand:DI 0 "register_operand" "")
12170 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12171 (match_operand:QI 2 "nonmemory_operand" "")))
12172 (clobber (reg:CC FLAGS_REG))]
12173 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12174 ? flow2_completed : reload_completed)"
12176 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12178 (define_expand "lshrsi3"
12179 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12180 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12181 (match_operand:QI 2 "nonmemory_operand" "")))
12182 (clobber (reg:CC FLAGS_REG))]
12184 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12186 (define_insn "*lshrsi3_1_one_bit"
12187 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12188 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12189 (match_operand:QI 2 "const1_operand" "")))
12190 (clobber (reg:CC FLAGS_REG))]
12191 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12192 && (TARGET_SHIFT1 || optimize_size)"
12194 [(set_attr "type" "ishift")
12195 (set (attr "length")
12196 (if_then_else (match_operand:SI 0 "register_operand" "")
12198 (const_string "*")))])
12200 (define_insn "*lshrsi3_1_one_bit_zext"
12201 [(set (match_operand:DI 0 "register_operand" "=r")
12202 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12203 (match_operand:QI 2 "const1_operand" "")))
12204 (clobber (reg:CC FLAGS_REG))]
12205 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12206 && (TARGET_SHIFT1 || optimize_size)"
12208 [(set_attr "type" "ishift")
12209 (set_attr "length" "2")])
12211 (define_insn "*lshrsi3_1"
12212 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12213 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12214 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12215 (clobber (reg:CC FLAGS_REG))]
12216 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12218 shr{l}\t{%2, %0|%0, %2}
12219 shr{l}\t{%b2, %0|%0, %b2}"
12220 [(set_attr "type" "ishift")
12221 (set_attr "mode" "SI")])
12223 (define_insn "*lshrsi3_1_zext"
12224 [(set (match_operand:DI 0 "register_operand" "=r,r")
12226 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12227 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12228 (clobber (reg:CC FLAGS_REG))]
12229 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12231 shr{l}\t{%2, %k0|%k0, %2}
12232 shr{l}\t{%b2, %k0|%k0, %b2}"
12233 [(set_attr "type" "ishift")
12234 (set_attr "mode" "SI")])
12236 ;; This pattern can't accept a variable shift count, since shifts by
12237 ;; zero don't affect the flags. We assume that shifts by constant
12238 ;; zero are optimized away.
12239 (define_insn "*lshrsi3_one_bit_cmp"
12240 [(set (reg FLAGS_REG)
12242 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12243 (match_operand:QI 2 "const1_operand" ""))
12245 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12246 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12247 "ix86_match_ccmode (insn, CCGOCmode)
12248 && (TARGET_SHIFT1 || optimize_size)
12249 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12251 [(set_attr "type" "ishift")
12252 (set (attr "length")
12253 (if_then_else (match_operand:SI 0 "register_operand" "")
12255 (const_string "*")))])
12257 (define_insn "*lshrsi3_one_bit_cconly"
12258 [(set (reg FLAGS_REG)
12260 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12261 (match_operand:QI 2 "const1_operand" ""))
12263 (clobber (match_scratch:SI 0 "=r"))]
12264 "ix86_match_ccmode (insn, CCGOCmode)
12265 && (TARGET_SHIFT1 || optimize_size)
12266 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12268 [(set_attr "type" "ishift")
12269 (set_attr "length" "2")])
12271 (define_insn "*lshrsi3_cmp_one_bit_zext"
12272 [(set (reg FLAGS_REG)
12274 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12275 (match_operand:QI 2 "const1_operand" ""))
12277 (set (match_operand:DI 0 "register_operand" "=r")
12278 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12279 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12280 && (TARGET_SHIFT1 || optimize_size)
12281 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12283 [(set_attr "type" "ishift")
12284 (set_attr "length" "2")])
12286 ;; This pattern can't accept a variable shift count, since shifts by
12287 ;; zero don't affect the flags. We assume that shifts by constant
12288 ;; zero are optimized away.
12289 (define_insn "*lshrsi3_cmp"
12290 [(set (reg FLAGS_REG)
12292 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12293 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12295 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12296 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12297 "ix86_match_ccmode (insn, CCGOCmode)
12298 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12300 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12301 "shr{l}\t{%2, %0|%0, %2}"
12302 [(set_attr "type" "ishift")
12303 (set_attr "mode" "SI")])
12305 (define_insn "*lshrsi3_cconly"
12306 [(set (reg FLAGS_REG)
12308 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12309 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12311 (clobber (match_scratch:SI 0 "=r"))]
12312 "ix86_match_ccmode (insn, CCGOCmode)
12313 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12315 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12316 "shr{l}\t{%2, %0|%0, %2}"
12317 [(set_attr "type" "ishift")
12318 (set_attr "mode" "SI")])
12320 (define_insn "*lshrsi3_cmp_zext"
12321 [(set (reg FLAGS_REG)
12323 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12324 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12326 (set (match_operand:DI 0 "register_operand" "=r")
12327 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12328 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12329 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12331 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12332 "shr{l}\t{%2, %k0|%k0, %2}"
12333 [(set_attr "type" "ishift")
12334 (set_attr "mode" "SI")])
12336 (define_expand "lshrhi3"
12337 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12338 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12339 (match_operand:QI 2 "nonmemory_operand" "")))
12340 (clobber (reg:CC FLAGS_REG))]
12341 "TARGET_HIMODE_MATH"
12342 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12344 (define_insn "*lshrhi3_1_one_bit"
12345 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12346 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12347 (match_operand:QI 2 "const1_operand" "")))
12348 (clobber (reg:CC FLAGS_REG))]
12349 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12350 && (TARGET_SHIFT1 || optimize_size)"
12352 [(set_attr "type" "ishift")
12353 (set (attr "length")
12354 (if_then_else (match_operand 0 "register_operand" "")
12356 (const_string "*")))])
12358 (define_insn "*lshrhi3_1"
12359 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12360 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12361 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12362 (clobber (reg:CC FLAGS_REG))]
12363 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12365 shr{w}\t{%2, %0|%0, %2}
12366 shr{w}\t{%b2, %0|%0, %b2}"
12367 [(set_attr "type" "ishift")
12368 (set_attr "mode" "HI")])
12370 ;; This pattern can't accept a variable shift count, since shifts by
12371 ;; zero don't affect the flags. We assume that shifts by constant
12372 ;; zero are optimized away.
12373 (define_insn "*lshrhi3_one_bit_cmp"
12374 [(set (reg FLAGS_REG)
12376 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12377 (match_operand:QI 2 "const1_operand" ""))
12379 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12380 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12381 "ix86_match_ccmode (insn, CCGOCmode)
12382 && (TARGET_SHIFT1 || optimize_size)
12383 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12385 [(set_attr "type" "ishift")
12386 (set (attr "length")
12387 (if_then_else (match_operand:SI 0 "register_operand" "")
12389 (const_string "*")))])
12391 (define_insn "*lshrhi3_one_bit_cconly"
12392 [(set (reg FLAGS_REG)
12394 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12395 (match_operand:QI 2 "const1_operand" ""))
12397 (clobber (match_scratch:HI 0 "=r"))]
12398 "ix86_match_ccmode (insn, CCGOCmode)
12399 && (TARGET_SHIFT1 || optimize_size)
12400 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12402 [(set_attr "type" "ishift")
12403 (set_attr "length" "2")])
12405 ;; This pattern can't accept a variable shift count, since shifts by
12406 ;; zero don't affect the flags. We assume that shifts by constant
12407 ;; zero are optimized away.
12408 (define_insn "*lshrhi3_cmp"
12409 [(set (reg FLAGS_REG)
12411 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12412 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12414 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12415 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12416 "ix86_match_ccmode (insn, CCGOCmode)
12417 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12419 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12420 "shr{w}\t{%2, %0|%0, %2}"
12421 [(set_attr "type" "ishift")
12422 (set_attr "mode" "HI")])
12424 (define_insn "*lshrhi3_cconly"
12425 [(set (reg FLAGS_REG)
12427 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12428 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12430 (clobber (match_scratch:HI 0 "=r"))]
12431 "ix86_match_ccmode (insn, CCGOCmode)
12432 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12434 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12435 "shr{w}\t{%2, %0|%0, %2}"
12436 [(set_attr "type" "ishift")
12437 (set_attr "mode" "HI")])
12439 (define_expand "lshrqi3"
12440 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12441 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12442 (match_operand:QI 2 "nonmemory_operand" "")))
12443 (clobber (reg:CC FLAGS_REG))]
12444 "TARGET_QIMODE_MATH"
12445 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12447 (define_insn "*lshrqi3_1_one_bit"
12448 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12449 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12450 (match_operand:QI 2 "const1_operand" "")))
12451 (clobber (reg:CC FLAGS_REG))]
12452 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12453 && (TARGET_SHIFT1 || optimize_size)"
12455 [(set_attr "type" "ishift")
12456 (set (attr "length")
12457 (if_then_else (match_operand 0 "register_operand" "")
12459 (const_string "*")))])
12461 (define_insn "*lshrqi3_1_one_bit_slp"
12462 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12463 (lshiftrt:QI (match_dup 0)
12464 (match_operand:QI 1 "const1_operand" "")))
12465 (clobber (reg:CC FLAGS_REG))]
12466 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12467 && (TARGET_SHIFT1 || optimize_size)"
12469 [(set_attr "type" "ishift1")
12470 (set (attr "length")
12471 (if_then_else (match_operand 0 "register_operand" "")
12473 (const_string "*")))])
12475 (define_insn "*lshrqi3_1"
12476 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12477 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12478 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12479 (clobber (reg:CC FLAGS_REG))]
12480 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12482 shr{b}\t{%2, %0|%0, %2}
12483 shr{b}\t{%b2, %0|%0, %b2}"
12484 [(set_attr "type" "ishift")
12485 (set_attr "mode" "QI")])
12487 (define_insn "*lshrqi3_1_slp"
12488 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12489 (lshiftrt:QI (match_dup 0)
12490 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12491 (clobber (reg:CC FLAGS_REG))]
12492 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12493 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12495 shr{b}\t{%1, %0|%0, %1}
12496 shr{b}\t{%b1, %0|%0, %b1}"
12497 [(set_attr "type" "ishift1")
12498 (set_attr "mode" "QI")])
12500 ;; This pattern can't accept a variable shift count, since shifts by
12501 ;; zero don't affect the flags. We assume that shifts by constant
12502 ;; zero are optimized away.
12503 (define_insn "*lshrqi2_one_bit_cmp"
12504 [(set (reg FLAGS_REG)
12506 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12507 (match_operand:QI 2 "const1_operand" ""))
12509 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12510 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12511 "ix86_match_ccmode (insn, CCGOCmode)
12512 && (TARGET_SHIFT1 || optimize_size)
12513 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12515 [(set_attr "type" "ishift")
12516 (set (attr "length")
12517 (if_then_else (match_operand:SI 0 "register_operand" "")
12519 (const_string "*")))])
12521 (define_insn "*lshrqi2_one_bit_cconly"
12522 [(set (reg FLAGS_REG)
12524 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12525 (match_operand:QI 2 "const1_operand" ""))
12527 (clobber (match_scratch:QI 0 "=q"))]
12528 "ix86_match_ccmode (insn, CCGOCmode)
12529 && (TARGET_SHIFT1 || optimize_size)
12530 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12532 [(set_attr "type" "ishift")
12533 (set_attr "length" "2")])
12535 ;; This pattern can't accept a variable shift count, since shifts by
12536 ;; zero don't affect the flags. We assume that shifts by constant
12537 ;; zero are optimized away.
12538 (define_insn "*lshrqi2_cmp"
12539 [(set (reg FLAGS_REG)
12541 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12542 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12544 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12545 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12546 "ix86_match_ccmode (insn, CCGOCmode)
12547 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12549 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12550 "shr{b}\t{%2, %0|%0, %2}"
12551 [(set_attr "type" "ishift")
12552 (set_attr "mode" "QI")])
12554 (define_insn "*lshrqi2_cconly"
12555 [(set (reg FLAGS_REG)
12557 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12558 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12560 (clobber (match_scratch:QI 0 "=q"))]
12561 "ix86_match_ccmode (insn, CCGOCmode)
12562 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12564 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12565 "shr{b}\t{%2, %0|%0, %2}"
12566 [(set_attr "type" "ishift")
12567 (set_attr "mode" "QI")])
12569 ;; Rotate instructions
12571 (define_expand "rotldi3"
12572 [(set (match_operand:DI 0 "shiftdi_operand" "")
12573 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12574 (match_operand:QI 2 "nonmemory_operand" "")))
12575 (clobber (reg:CC FLAGS_REG))]
12580 ix86_expand_binary_operator (ROTATE, DImode, operands);
12583 if (!const_1_to_31_operand (operands[2], VOIDmode))
12585 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12589 ;; Implement rotation using two double-precision shift instructions
12590 ;; and a scratch register.
12591 (define_insn_and_split "ix86_rotldi3"
12592 [(set (match_operand:DI 0 "register_operand" "=r")
12593 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12594 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12595 (clobber (reg:CC FLAGS_REG))
12596 (clobber (match_scratch:SI 3 "=&r"))]
12599 "&& reload_completed"
12600 [(set (match_dup 3) (match_dup 4))
12602 [(set (match_dup 4)
12603 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12604 (lshiftrt:SI (match_dup 5)
12605 (minus:QI (const_int 32) (match_dup 2)))))
12606 (clobber (reg:CC FLAGS_REG))])
12608 [(set (match_dup 5)
12609 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12610 (lshiftrt:SI (match_dup 3)
12611 (minus:QI (const_int 32) (match_dup 2)))))
12612 (clobber (reg:CC FLAGS_REG))])]
12613 "split_di (operands, 1, operands + 4, operands + 5);")
12615 (define_insn "*rotlsi3_1_one_bit_rex64"
12616 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12617 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12618 (match_operand:QI 2 "const1_operand" "")))
12619 (clobber (reg:CC FLAGS_REG))]
12620 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12621 && (TARGET_SHIFT1 || optimize_size)"
12623 [(set_attr "type" "rotate")
12624 (set (attr "length")
12625 (if_then_else (match_operand:DI 0 "register_operand" "")
12627 (const_string "*")))])
12629 (define_insn "*rotldi3_1_rex64"
12630 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12631 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12632 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12633 (clobber (reg:CC FLAGS_REG))]
12634 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12636 rol{q}\t{%2, %0|%0, %2}
12637 rol{q}\t{%b2, %0|%0, %b2}"
12638 [(set_attr "type" "rotate")
12639 (set_attr "mode" "DI")])
12641 (define_expand "rotlsi3"
12642 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12643 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12644 (match_operand:QI 2 "nonmemory_operand" "")))
12645 (clobber (reg:CC FLAGS_REG))]
12647 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12649 (define_insn "*rotlsi3_1_one_bit"
12650 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12651 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12652 (match_operand:QI 2 "const1_operand" "")))
12653 (clobber (reg:CC FLAGS_REG))]
12654 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12655 && (TARGET_SHIFT1 || optimize_size)"
12657 [(set_attr "type" "rotate")
12658 (set (attr "length")
12659 (if_then_else (match_operand:SI 0 "register_operand" "")
12661 (const_string "*")))])
12663 (define_insn "*rotlsi3_1_one_bit_zext"
12664 [(set (match_operand:DI 0 "register_operand" "=r")
12666 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12667 (match_operand:QI 2 "const1_operand" ""))))
12668 (clobber (reg:CC FLAGS_REG))]
12669 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12670 && (TARGET_SHIFT1 || optimize_size)"
12672 [(set_attr "type" "rotate")
12673 (set_attr "length" "2")])
12675 (define_insn "*rotlsi3_1"
12676 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12677 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12678 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12679 (clobber (reg:CC FLAGS_REG))]
12680 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12682 rol{l}\t{%2, %0|%0, %2}
12683 rol{l}\t{%b2, %0|%0, %b2}"
12684 [(set_attr "type" "rotate")
12685 (set_attr "mode" "SI")])
12687 (define_insn "*rotlsi3_1_zext"
12688 [(set (match_operand:DI 0 "register_operand" "=r,r")
12690 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12691 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12692 (clobber (reg:CC FLAGS_REG))]
12693 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12695 rol{l}\t{%2, %k0|%k0, %2}
12696 rol{l}\t{%b2, %k0|%k0, %b2}"
12697 [(set_attr "type" "rotate")
12698 (set_attr "mode" "SI")])
12700 (define_expand "rotlhi3"
12701 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12702 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12703 (match_operand:QI 2 "nonmemory_operand" "")))
12704 (clobber (reg:CC FLAGS_REG))]
12705 "TARGET_HIMODE_MATH"
12706 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12708 (define_insn "*rotlhi3_1_one_bit"
12709 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12710 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12711 (match_operand:QI 2 "const1_operand" "")))
12712 (clobber (reg:CC FLAGS_REG))]
12713 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12714 && (TARGET_SHIFT1 || optimize_size)"
12716 [(set_attr "type" "rotate")
12717 (set (attr "length")
12718 (if_then_else (match_operand 0 "register_operand" "")
12720 (const_string "*")))])
12722 (define_insn "*rotlhi3_1"
12723 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12724 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12725 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12726 (clobber (reg:CC FLAGS_REG))]
12727 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12729 rol{w}\t{%2, %0|%0, %2}
12730 rol{w}\t{%b2, %0|%0, %b2}"
12731 [(set_attr "type" "rotate")
12732 (set_attr "mode" "HI")])
12735 [(set (match_operand:HI 0 "register_operand" "")
12736 (rotate:HI (match_dup 0) (const_int 8)))
12737 (clobber (reg:CC FLAGS_REG))]
12739 [(parallel [(set (strict_low_part (match_dup 0))
12740 (bswap:HI (match_dup 0)))
12741 (clobber (reg:CC FLAGS_REG))])]
12744 (define_expand "rotlqi3"
12745 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12746 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12747 (match_operand:QI 2 "nonmemory_operand" "")))
12748 (clobber (reg:CC FLAGS_REG))]
12749 "TARGET_QIMODE_MATH"
12750 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12752 (define_insn "*rotlqi3_1_one_bit_slp"
12753 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12754 (rotate:QI (match_dup 0)
12755 (match_operand:QI 1 "const1_operand" "")))
12756 (clobber (reg:CC FLAGS_REG))]
12757 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12758 && (TARGET_SHIFT1 || optimize_size)"
12760 [(set_attr "type" "rotate1")
12761 (set (attr "length")
12762 (if_then_else (match_operand 0 "register_operand" "")
12764 (const_string "*")))])
12766 (define_insn "*rotlqi3_1_one_bit"
12767 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12768 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12769 (match_operand:QI 2 "const1_operand" "")))
12770 (clobber (reg:CC FLAGS_REG))]
12771 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12772 && (TARGET_SHIFT1 || optimize_size)"
12774 [(set_attr "type" "rotate")
12775 (set (attr "length")
12776 (if_then_else (match_operand 0 "register_operand" "")
12778 (const_string "*")))])
12780 (define_insn "*rotlqi3_1_slp"
12781 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12782 (rotate:QI (match_dup 0)
12783 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12784 (clobber (reg:CC FLAGS_REG))]
12785 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12786 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12788 rol{b}\t{%1, %0|%0, %1}
12789 rol{b}\t{%b1, %0|%0, %b1}"
12790 [(set_attr "type" "rotate1")
12791 (set_attr "mode" "QI")])
12793 (define_insn "*rotlqi3_1"
12794 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12795 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12796 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12797 (clobber (reg:CC FLAGS_REG))]
12798 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12800 rol{b}\t{%2, %0|%0, %2}
12801 rol{b}\t{%b2, %0|%0, %b2}"
12802 [(set_attr "type" "rotate")
12803 (set_attr "mode" "QI")])
12805 (define_expand "rotrdi3"
12806 [(set (match_operand:DI 0 "shiftdi_operand" "")
12807 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12808 (match_operand:QI 2 "nonmemory_operand" "")))
12809 (clobber (reg:CC FLAGS_REG))]
12814 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12817 if (!const_1_to_31_operand (operands[2], VOIDmode))
12819 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12823 ;; Implement rotation using two double-precision shift instructions
12824 ;; and a scratch register.
12825 (define_insn_and_split "ix86_rotrdi3"
12826 [(set (match_operand:DI 0 "register_operand" "=r")
12827 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12828 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12829 (clobber (reg:CC FLAGS_REG))
12830 (clobber (match_scratch:SI 3 "=&r"))]
12833 "&& reload_completed"
12834 [(set (match_dup 3) (match_dup 4))
12836 [(set (match_dup 4)
12837 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12838 (ashift:SI (match_dup 5)
12839 (minus:QI (const_int 32) (match_dup 2)))))
12840 (clobber (reg:CC FLAGS_REG))])
12842 [(set (match_dup 5)
12843 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12844 (ashift:SI (match_dup 3)
12845 (minus:QI (const_int 32) (match_dup 2)))))
12846 (clobber (reg:CC FLAGS_REG))])]
12847 "split_di (operands, 1, operands + 4, operands + 5);")
12849 (define_insn "*rotrdi3_1_one_bit_rex64"
12850 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12851 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12852 (match_operand:QI 2 "const1_operand" "")))
12853 (clobber (reg:CC FLAGS_REG))]
12854 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12855 && (TARGET_SHIFT1 || optimize_size)"
12857 [(set_attr "type" "rotate")
12858 (set (attr "length")
12859 (if_then_else (match_operand:DI 0 "register_operand" "")
12861 (const_string "*")))])
12863 (define_insn "*rotrdi3_1_rex64"
12864 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12865 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12866 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12867 (clobber (reg:CC FLAGS_REG))]
12868 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12870 ror{q}\t{%2, %0|%0, %2}
12871 ror{q}\t{%b2, %0|%0, %b2}"
12872 [(set_attr "type" "rotate")
12873 (set_attr "mode" "DI")])
12875 (define_expand "rotrsi3"
12876 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12877 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12878 (match_operand:QI 2 "nonmemory_operand" "")))
12879 (clobber (reg:CC FLAGS_REG))]
12881 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12883 (define_insn "*rotrsi3_1_one_bit"
12884 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12885 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12886 (match_operand:QI 2 "const1_operand" "")))
12887 (clobber (reg:CC FLAGS_REG))]
12888 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12889 && (TARGET_SHIFT1 || optimize_size)"
12891 [(set_attr "type" "rotate")
12892 (set (attr "length")
12893 (if_then_else (match_operand:SI 0 "register_operand" "")
12895 (const_string "*")))])
12897 (define_insn "*rotrsi3_1_one_bit_zext"
12898 [(set (match_operand:DI 0 "register_operand" "=r")
12900 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12901 (match_operand:QI 2 "const1_operand" ""))))
12902 (clobber (reg:CC FLAGS_REG))]
12903 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12904 && (TARGET_SHIFT1 || optimize_size)"
12906 [(set_attr "type" "rotate")
12907 (set (attr "length")
12908 (if_then_else (match_operand:SI 0 "register_operand" "")
12910 (const_string "*")))])
12912 (define_insn "*rotrsi3_1"
12913 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12914 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12915 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12916 (clobber (reg:CC FLAGS_REG))]
12917 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12919 ror{l}\t{%2, %0|%0, %2}
12920 ror{l}\t{%b2, %0|%0, %b2}"
12921 [(set_attr "type" "rotate")
12922 (set_attr "mode" "SI")])
12924 (define_insn "*rotrsi3_1_zext"
12925 [(set (match_operand:DI 0 "register_operand" "=r,r")
12927 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12928 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12929 (clobber (reg:CC FLAGS_REG))]
12930 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12932 ror{l}\t{%2, %k0|%k0, %2}
12933 ror{l}\t{%b2, %k0|%k0, %b2}"
12934 [(set_attr "type" "rotate")
12935 (set_attr "mode" "SI")])
12937 (define_expand "rotrhi3"
12938 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12939 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12940 (match_operand:QI 2 "nonmemory_operand" "")))
12941 (clobber (reg:CC FLAGS_REG))]
12942 "TARGET_HIMODE_MATH"
12943 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12945 (define_insn "*rotrhi3_one_bit"
12946 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12947 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12948 (match_operand:QI 2 "const1_operand" "")))
12949 (clobber (reg:CC FLAGS_REG))]
12950 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12951 && (TARGET_SHIFT1 || optimize_size)"
12953 [(set_attr "type" "rotate")
12954 (set (attr "length")
12955 (if_then_else (match_operand 0 "register_operand" "")
12957 (const_string "*")))])
12959 (define_insn "*rotrhi3_1"
12960 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12961 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12962 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12963 (clobber (reg:CC FLAGS_REG))]
12964 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12966 ror{w}\t{%2, %0|%0, %2}
12967 ror{w}\t{%b2, %0|%0, %b2}"
12968 [(set_attr "type" "rotate")
12969 (set_attr "mode" "HI")])
12972 [(set (match_operand:HI 0 "register_operand" "")
12973 (rotatert:HI (match_dup 0) (const_int 8)))
12974 (clobber (reg:CC FLAGS_REG))]
12976 [(parallel [(set (strict_low_part (match_dup 0))
12977 (bswap:HI (match_dup 0)))
12978 (clobber (reg:CC FLAGS_REG))])]
12981 (define_expand "rotrqi3"
12982 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12983 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12984 (match_operand:QI 2 "nonmemory_operand" "")))
12985 (clobber (reg:CC FLAGS_REG))]
12986 "TARGET_QIMODE_MATH"
12987 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12989 (define_insn "*rotrqi3_1_one_bit"
12990 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12991 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12992 (match_operand:QI 2 "const1_operand" "")))
12993 (clobber (reg:CC FLAGS_REG))]
12994 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12995 && (TARGET_SHIFT1 || optimize_size)"
12997 [(set_attr "type" "rotate")
12998 (set (attr "length")
12999 (if_then_else (match_operand 0 "register_operand" "")
13001 (const_string "*")))])
13003 (define_insn "*rotrqi3_1_one_bit_slp"
13004 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13005 (rotatert:QI (match_dup 0)
13006 (match_operand:QI 1 "const1_operand" "")))
13007 (clobber (reg:CC FLAGS_REG))]
13008 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13009 && (TARGET_SHIFT1 || optimize_size)"
13011 [(set_attr "type" "rotate1")
13012 (set (attr "length")
13013 (if_then_else (match_operand 0 "register_operand" "")
13015 (const_string "*")))])
13017 (define_insn "*rotrqi3_1"
13018 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13019 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13020 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13021 (clobber (reg:CC FLAGS_REG))]
13022 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13024 ror{b}\t{%2, %0|%0, %2}
13025 ror{b}\t{%b2, %0|%0, %b2}"
13026 [(set_attr "type" "rotate")
13027 (set_attr "mode" "QI")])
13029 (define_insn "*rotrqi3_1_slp"
13030 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13031 (rotatert:QI (match_dup 0)
13032 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13033 (clobber (reg:CC FLAGS_REG))]
13034 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13035 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13037 ror{b}\t{%1, %0|%0, %1}
13038 ror{b}\t{%b1, %0|%0, %b1}"
13039 [(set_attr "type" "rotate1")
13040 (set_attr "mode" "QI")])
13042 ;; Bit set / bit test instructions
13044 (define_expand "extv"
13045 [(set (match_operand:SI 0 "register_operand" "")
13046 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13047 (match_operand:SI 2 "const8_operand" "")
13048 (match_operand:SI 3 "const8_operand" "")))]
13051 /* Handle extractions from %ah et al. */
13052 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13055 /* From mips.md: extract_bit_field doesn't verify that our source
13056 matches the predicate, so check it again here. */
13057 if (! ext_register_operand (operands[1], VOIDmode))
13061 (define_expand "extzv"
13062 [(set (match_operand:SI 0 "register_operand" "")
13063 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13064 (match_operand:SI 2 "const8_operand" "")
13065 (match_operand:SI 3 "const8_operand" "")))]
13068 /* Handle extractions from %ah et al. */
13069 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13072 /* From mips.md: extract_bit_field doesn't verify that our source
13073 matches the predicate, so check it again here. */
13074 if (! ext_register_operand (operands[1], VOIDmode))
13078 (define_expand "insv"
13079 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13080 (match_operand 1 "const8_operand" "")
13081 (match_operand 2 "const8_operand" ""))
13082 (match_operand 3 "register_operand" ""))]
13085 /* Handle insertions to %ah et al. */
13086 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13089 /* From mips.md: insert_bit_field doesn't verify that our source
13090 matches the predicate, so check it again here. */
13091 if (! ext_register_operand (operands[0], VOIDmode))
13095 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13097 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13102 ;; %%% bts, btr, btc, bt.
13103 ;; In general these instructions are *slow* when applied to memory,
13104 ;; since they enforce atomic operation. When applied to registers,
13105 ;; it depends on the cpu implementation. They're never faster than
13106 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13107 ;; no point. But in 64-bit, we can't hold the relevant immediates
13108 ;; within the instruction itself, so operating on bits in the high
13109 ;; 32-bits of a register becomes easier.
13111 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13112 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13113 ;; negdf respectively, so they can never be disabled entirely.
13115 (define_insn "*btsq"
13116 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13118 (match_operand:DI 1 "const_0_to_63_operand" ""))
13120 (clobber (reg:CC FLAGS_REG))]
13121 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13123 [(set_attr "type" "alu1")])
13125 (define_insn "*btrq"
13126 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13128 (match_operand:DI 1 "const_0_to_63_operand" ""))
13130 (clobber (reg:CC FLAGS_REG))]
13131 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13133 [(set_attr "type" "alu1")])
13135 (define_insn "*btcq"
13136 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13138 (match_operand:DI 1 "const_0_to_63_operand" ""))
13139 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13140 (clobber (reg:CC FLAGS_REG))]
13141 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13143 [(set_attr "type" "alu1")])
13145 ;; Allow Nocona to avoid these instructions if a register is available.
13148 [(match_scratch:DI 2 "r")
13149 (parallel [(set (zero_extract:DI
13150 (match_operand:DI 0 "register_operand" "")
13152 (match_operand:DI 1 "const_0_to_63_operand" ""))
13154 (clobber (reg:CC FLAGS_REG))])]
13155 "TARGET_64BIT && !TARGET_USE_BT"
13158 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13161 if (HOST_BITS_PER_WIDE_INT >= 64)
13162 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13163 else if (i < HOST_BITS_PER_WIDE_INT)
13164 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13166 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13168 op1 = immed_double_const (lo, hi, DImode);
13171 emit_move_insn (operands[2], op1);
13175 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13180 [(match_scratch:DI 2 "r")
13181 (parallel [(set (zero_extract:DI
13182 (match_operand:DI 0 "register_operand" "")
13184 (match_operand:DI 1 "const_0_to_63_operand" ""))
13186 (clobber (reg:CC FLAGS_REG))])]
13187 "TARGET_64BIT && !TARGET_USE_BT"
13190 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13193 if (HOST_BITS_PER_WIDE_INT >= 64)
13194 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13195 else if (i < HOST_BITS_PER_WIDE_INT)
13196 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13198 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13200 op1 = immed_double_const (~lo, ~hi, DImode);
13203 emit_move_insn (operands[2], op1);
13207 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13212 [(match_scratch:DI 2 "r")
13213 (parallel [(set (zero_extract:DI
13214 (match_operand:DI 0 "register_operand" "")
13216 (match_operand:DI 1 "const_0_to_63_operand" ""))
13217 (not:DI (zero_extract:DI
13218 (match_dup 0) (const_int 1) (match_dup 1))))
13219 (clobber (reg:CC FLAGS_REG))])]
13220 "TARGET_64BIT && !TARGET_USE_BT"
13223 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13226 if (HOST_BITS_PER_WIDE_INT >= 64)
13227 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13228 else if (i < HOST_BITS_PER_WIDE_INT)
13229 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13231 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13233 op1 = immed_double_const (lo, hi, DImode);
13236 emit_move_insn (operands[2], op1);
13240 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13244 ;; Store-flag instructions.
13246 ;; For all sCOND expanders, also expand the compare or test insn that
13247 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13249 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13250 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13251 ;; way, which can later delete the movzx if only QImode is needed.
13253 (define_expand "seq"
13254 [(set (match_operand:QI 0 "register_operand" "")
13255 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13259 (define_expand "sne"
13260 [(set (match_operand:QI 0 "register_operand" "")
13261 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13263 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13265 (define_expand "sgt"
13266 [(set (match_operand:QI 0 "register_operand" "")
13267 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13269 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13271 (define_expand "sgtu"
13272 [(set (match_operand:QI 0 "register_operand" "")
13273 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13275 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13277 (define_expand "slt"
13278 [(set (match_operand:QI 0 "register_operand" "")
13279 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13281 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13283 (define_expand "sltu"
13284 [(set (match_operand:QI 0 "register_operand" "")
13285 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13287 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13289 (define_expand "sge"
13290 [(set (match_operand:QI 0 "register_operand" "")
13291 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13293 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13295 (define_expand "sgeu"
13296 [(set (match_operand:QI 0 "register_operand" "")
13297 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13299 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13301 (define_expand "sle"
13302 [(set (match_operand:QI 0 "register_operand" "")
13303 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13305 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13307 (define_expand "sleu"
13308 [(set (match_operand:QI 0 "register_operand" "")
13309 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13311 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13313 (define_expand "sunordered"
13314 [(set (match_operand:QI 0 "register_operand" "")
13315 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13316 "TARGET_80387 || TARGET_SSE"
13317 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13319 (define_expand "sordered"
13320 [(set (match_operand:QI 0 "register_operand" "")
13321 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13323 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13325 (define_expand "suneq"
13326 [(set (match_operand:QI 0 "register_operand" "")
13327 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13328 "TARGET_80387 || TARGET_SSE"
13329 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13331 (define_expand "sunge"
13332 [(set (match_operand:QI 0 "register_operand" "")
13333 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13334 "TARGET_80387 || TARGET_SSE"
13335 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13337 (define_expand "sungt"
13338 [(set (match_operand:QI 0 "register_operand" "")
13339 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13340 "TARGET_80387 || TARGET_SSE"
13341 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13343 (define_expand "sunle"
13344 [(set (match_operand:QI 0 "register_operand" "")
13345 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13346 "TARGET_80387 || TARGET_SSE"
13347 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13349 (define_expand "sunlt"
13350 [(set (match_operand:QI 0 "register_operand" "")
13351 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13352 "TARGET_80387 || TARGET_SSE"
13353 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13355 (define_expand "sltgt"
13356 [(set (match_operand:QI 0 "register_operand" "")
13357 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13358 "TARGET_80387 || TARGET_SSE"
13359 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13361 (define_insn "*setcc_1"
13362 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13363 (match_operator:QI 1 "ix86_comparison_operator"
13364 [(reg FLAGS_REG) (const_int 0)]))]
13367 [(set_attr "type" "setcc")
13368 (set_attr "mode" "QI")])
13370 (define_insn "*setcc_2"
13371 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13372 (match_operator:QI 1 "ix86_comparison_operator"
13373 [(reg FLAGS_REG) (const_int 0)]))]
13376 [(set_attr "type" "setcc")
13377 (set_attr "mode" "QI")])
13379 ;; In general it is not safe to assume too much about CCmode registers,
13380 ;; so simplify-rtx stops when it sees a second one. Under certain
13381 ;; conditions this is safe on x86, so help combine not create
13388 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13389 (ne:QI (match_operator 1 "ix86_comparison_operator"
13390 [(reg FLAGS_REG) (const_int 0)])
13393 [(set (match_dup 0) (match_dup 1))]
13395 PUT_MODE (operands[1], QImode);
13399 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13400 (ne:QI (match_operator 1 "ix86_comparison_operator"
13401 [(reg FLAGS_REG) (const_int 0)])
13404 [(set (match_dup 0) (match_dup 1))]
13406 PUT_MODE (operands[1], QImode);
13410 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13411 (eq:QI (match_operator 1 "ix86_comparison_operator"
13412 [(reg FLAGS_REG) (const_int 0)])
13415 [(set (match_dup 0) (match_dup 1))]
13417 rtx new_op1 = copy_rtx (operands[1]);
13418 operands[1] = new_op1;
13419 PUT_MODE (new_op1, QImode);
13420 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13421 GET_MODE (XEXP (new_op1, 0))));
13423 /* Make sure that (a) the CCmode we have for the flags is strong
13424 enough for the reversed compare or (b) we have a valid FP compare. */
13425 if (! ix86_comparison_operator (new_op1, VOIDmode))
13430 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13431 (eq:QI (match_operator 1 "ix86_comparison_operator"
13432 [(reg FLAGS_REG) (const_int 0)])
13435 [(set (match_dup 0) (match_dup 1))]
13437 rtx new_op1 = copy_rtx (operands[1]);
13438 operands[1] = new_op1;
13439 PUT_MODE (new_op1, QImode);
13440 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13441 GET_MODE (XEXP (new_op1, 0))));
13443 /* Make sure that (a) the CCmode we have for the flags is strong
13444 enough for the reversed compare or (b) we have a valid FP compare. */
13445 if (! ix86_comparison_operator (new_op1, VOIDmode))
13449 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13450 ;; subsequent logical operations are used to imitate conditional moves.
13451 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13454 (define_insn "*sse_setccsf"
13455 [(set (match_operand:SF 0 "register_operand" "=x")
13456 (match_operator:SF 1 "sse_comparison_operator"
13457 [(match_operand:SF 2 "register_operand" "0")
13458 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13460 "cmp%D1ss\t{%3, %0|%0, %3}"
13461 [(set_attr "type" "ssecmp")
13462 (set_attr "mode" "SF")])
13464 (define_insn "*sse_setccdf"
13465 [(set (match_operand:DF 0 "register_operand" "=x")
13466 (match_operator:DF 1 "sse_comparison_operator"
13467 [(match_operand:DF 2 "register_operand" "0")
13468 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13470 "cmp%D1sd\t{%3, %0|%0, %3}"
13471 [(set_attr "type" "ssecmp")
13472 (set_attr "mode" "DF")])
13474 ;; Basic conditional jump instructions.
13475 ;; We ignore the overflow flag for signed branch instructions.
13477 ;; For all bCOND expanders, also expand the compare or test insn that
13478 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13480 (define_expand "beq"
13482 (if_then_else (match_dup 1)
13483 (label_ref (match_operand 0 "" ""))
13486 "ix86_expand_branch (EQ, operands[0]); DONE;")
13488 (define_expand "bne"
13490 (if_then_else (match_dup 1)
13491 (label_ref (match_operand 0 "" ""))
13494 "ix86_expand_branch (NE, operands[0]); DONE;")
13496 (define_expand "bgt"
13498 (if_then_else (match_dup 1)
13499 (label_ref (match_operand 0 "" ""))
13502 "ix86_expand_branch (GT, operands[0]); DONE;")
13504 (define_expand "bgtu"
13506 (if_then_else (match_dup 1)
13507 (label_ref (match_operand 0 "" ""))
13510 "ix86_expand_branch (GTU, operands[0]); DONE;")
13512 (define_expand "blt"
13514 (if_then_else (match_dup 1)
13515 (label_ref (match_operand 0 "" ""))
13518 "ix86_expand_branch (LT, operands[0]); DONE;")
13520 (define_expand "bltu"
13522 (if_then_else (match_dup 1)
13523 (label_ref (match_operand 0 "" ""))
13526 "ix86_expand_branch (LTU, operands[0]); DONE;")
13528 (define_expand "bge"
13530 (if_then_else (match_dup 1)
13531 (label_ref (match_operand 0 "" ""))
13534 "ix86_expand_branch (GE, operands[0]); DONE;")
13536 (define_expand "bgeu"
13538 (if_then_else (match_dup 1)
13539 (label_ref (match_operand 0 "" ""))
13542 "ix86_expand_branch (GEU, operands[0]); DONE;")
13544 (define_expand "ble"
13546 (if_then_else (match_dup 1)
13547 (label_ref (match_operand 0 "" ""))
13550 "ix86_expand_branch (LE, operands[0]); DONE;")
13552 (define_expand "bleu"
13554 (if_then_else (match_dup 1)
13555 (label_ref (match_operand 0 "" ""))
13558 "ix86_expand_branch (LEU, operands[0]); DONE;")
13560 (define_expand "bunordered"
13562 (if_then_else (match_dup 1)
13563 (label_ref (match_operand 0 "" ""))
13565 "TARGET_80387 || TARGET_SSE_MATH"
13566 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13568 (define_expand "bordered"
13570 (if_then_else (match_dup 1)
13571 (label_ref (match_operand 0 "" ""))
13573 "TARGET_80387 || TARGET_SSE_MATH"
13574 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13576 (define_expand "buneq"
13578 (if_then_else (match_dup 1)
13579 (label_ref (match_operand 0 "" ""))
13581 "TARGET_80387 || TARGET_SSE_MATH"
13582 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13584 (define_expand "bunge"
13586 (if_then_else (match_dup 1)
13587 (label_ref (match_operand 0 "" ""))
13589 "TARGET_80387 || TARGET_SSE_MATH"
13590 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13592 (define_expand "bungt"
13594 (if_then_else (match_dup 1)
13595 (label_ref (match_operand 0 "" ""))
13597 "TARGET_80387 || TARGET_SSE_MATH"
13598 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13600 (define_expand "bunle"
13602 (if_then_else (match_dup 1)
13603 (label_ref (match_operand 0 "" ""))
13605 "TARGET_80387 || TARGET_SSE_MATH"
13606 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13608 (define_expand "bunlt"
13610 (if_then_else (match_dup 1)
13611 (label_ref (match_operand 0 "" ""))
13613 "TARGET_80387 || TARGET_SSE_MATH"
13614 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13616 (define_expand "bltgt"
13618 (if_then_else (match_dup 1)
13619 (label_ref (match_operand 0 "" ""))
13621 "TARGET_80387 || TARGET_SSE_MATH"
13622 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13624 (define_insn "*jcc_1"
13626 (if_then_else (match_operator 1 "ix86_comparison_operator"
13627 [(reg FLAGS_REG) (const_int 0)])
13628 (label_ref (match_operand 0 "" ""))
13632 [(set_attr "type" "ibr")
13633 (set_attr "modrm" "0")
13634 (set (attr "length")
13635 (if_then_else (and (ge (minus (match_dup 0) (pc))
13637 (lt (minus (match_dup 0) (pc))
13642 (define_insn "*jcc_2"
13644 (if_then_else (match_operator 1 "ix86_comparison_operator"
13645 [(reg FLAGS_REG) (const_int 0)])
13647 (label_ref (match_operand 0 "" ""))))]
13650 [(set_attr "type" "ibr")
13651 (set_attr "modrm" "0")
13652 (set (attr "length")
13653 (if_then_else (and (ge (minus (match_dup 0) (pc))
13655 (lt (minus (match_dup 0) (pc))
13660 ;; In general it is not safe to assume too much about CCmode registers,
13661 ;; so simplify-rtx stops when it sees a second one. Under certain
13662 ;; conditions this is safe on x86, so help combine not create
13670 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13671 [(reg FLAGS_REG) (const_int 0)])
13673 (label_ref (match_operand 1 "" ""))
13677 (if_then_else (match_dup 0)
13678 (label_ref (match_dup 1))
13681 PUT_MODE (operands[0], VOIDmode);
13686 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13687 [(reg FLAGS_REG) (const_int 0)])
13689 (label_ref (match_operand 1 "" ""))
13693 (if_then_else (match_dup 0)
13694 (label_ref (match_dup 1))
13697 rtx new_op0 = copy_rtx (operands[0]);
13698 operands[0] = new_op0;
13699 PUT_MODE (new_op0, VOIDmode);
13700 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13701 GET_MODE (XEXP (new_op0, 0))));
13703 /* Make sure that (a) the CCmode we have for the flags is strong
13704 enough for the reversed compare or (b) we have a valid FP compare. */
13705 if (! ix86_comparison_operator (new_op0, VOIDmode))
13709 ;; Define combination compare-and-branch fp compare instructions to use
13710 ;; during early optimization. Splitting the operation apart early makes
13711 ;; for bad code when we want to reverse the operation.
13713 (define_insn "*fp_jcc_1_mixed"
13715 (if_then_else (match_operator 0 "comparison_operator"
13716 [(match_operand 1 "register_operand" "f,x")
13717 (match_operand 2 "nonimmediate_operand" "f,xm")])
13718 (label_ref (match_operand 3 "" ""))
13720 (clobber (reg:CCFP FPSR_REG))
13721 (clobber (reg:CCFP FLAGS_REG))]
13722 "TARGET_MIX_SSE_I387
13723 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13724 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13725 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13728 (define_insn "*fp_jcc_1_sse"
13730 (if_then_else (match_operator 0 "comparison_operator"
13731 [(match_operand 1 "register_operand" "x")
13732 (match_operand 2 "nonimmediate_operand" "xm")])
13733 (label_ref (match_operand 3 "" ""))
13735 (clobber (reg:CCFP FPSR_REG))
13736 (clobber (reg:CCFP FLAGS_REG))]
13738 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13739 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13740 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13743 (define_insn "*fp_jcc_1_387"
13745 (if_then_else (match_operator 0 "comparison_operator"
13746 [(match_operand 1 "register_operand" "f")
13747 (match_operand 2 "register_operand" "f")])
13748 (label_ref (match_operand 3 "" ""))
13750 (clobber (reg:CCFP FPSR_REG))
13751 (clobber (reg:CCFP FLAGS_REG))]
13752 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13754 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13755 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13758 (define_insn "*fp_jcc_2_mixed"
13760 (if_then_else (match_operator 0 "comparison_operator"
13761 [(match_operand 1 "register_operand" "f,x")
13762 (match_operand 2 "nonimmediate_operand" "f,xm")])
13764 (label_ref (match_operand 3 "" ""))))
13765 (clobber (reg:CCFP FPSR_REG))
13766 (clobber (reg:CCFP FLAGS_REG))]
13767 "TARGET_MIX_SSE_I387
13768 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13769 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13770 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13773 (define_insn "*fp_jcc_2_sse"
13775 (if_then_else (match_operator 0 "comparison_operator"
13776 [(match_operand 1 "register_operand" "x")
13777 (match_operand 2 "nonimmediate_operand" "xm")])
13779 (label_ref (match_operand 3 "" ""))))
13780 (clobber (reg:CCFP FPSR_REG))
13781 (clobber (reg:CCFP FLAGS_REG))]
13783 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13784 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13785 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13788 (define_insn "*fp_jcc_2_387"
13790 (if_then_else (match_operator 0 "comparison_operator"
13791 [(match_operand 1 "register_operand" "f")
13792 (match_operand 2 "register_operand" "f")])
13794 (label_ref (match_operand 3 "" ""))))
13795 (clobber (reg:CCFP FPSR_REG))
13796 (clobber (reg:CCFP FLAGS_REG))]
13797 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13799 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13800 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13803 (define_insn "*fp_jcc_3_387"
13805 (if_then_else (match_operator 0 "comparison_operator"
13806 [(match_operand 1 "register_operand" "f")
13807 (match_operand 2 "nonimmediate_operand" "fm")])
13808 (label_ref (match_operand 3 "" ""))
13810 (clobber (reg:CCFP FPSR_REG))
13811 (clobber (reg:CCFP FLAGS_REG))
13812 (clobber (match_scratch:HI 4 "=a"))]
13814 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13815 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13816 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13817 && SELECT_CC_MODE (GET_CODE (operands[0]),
13818 operands[1], operands[2]) == CCFPmode
13819 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13822 (define_insn "*fp_jcc_4_387"
13824 (if_then_else (match_operator 0 "comparison_operator"
13825 [(match_operand 1 "register_operand" "f")
13826 (match_operand 2 "nonimmediate_operand" "fm")])
13828 (label_ref (match_operand 3 "" ""))))
13829 (clobber (reg:CCFP FPSR_REG))
13830 (clobber (reg:CCFP FLAGS_REG))
13831 (clobber (match_scratch:HI 4 "=a"))]
13833 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13834 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13835 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13836 && SELECT_CC_MODE (GET_CODE (operands[0]),
13837 operands[1], operands[2]) == CCFPmode
13838 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13841 (define_insn "*fp_jcc_5_387"
13843 (if_then_else (match_operator 0 "comparison_operator"
13844 [(match_operand 1 "register_operand" "f")
13845 (match_operand 2 "register_operand" "f")])
13846 (label_ref (match_operand 3 "" ""))
13848 (clobber (reg:CCFP FPSR_REG))
13849 (clobber (reg:CCFP FLAGS_REG))
13850 (clobber (match_scratch:HI 4 "=a"))]
13851 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13852 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13853 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13856 (define_insn "*fp_jcc_6_387"
13858 (if_then_else (match_operator 0 "comparison_operator"
13859 [(match_operand 1 "register_operand" "f")
13860 (match_operand 2 "register_operand" "f")])
13862 (label_ref (match_operand 3 "" ""))))
13863 (clobber (reg:CCFP FPSR_REG))
13864 (clobber (reg:CCFP FLAGS_REG))
13865 (clobber (match_scratch:HI 4 "=a"))]
13866 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13867 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13868 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13871 (define_insn "*fp_jcc_7_387"
13873 (if_then_else (match_operator 0 "comparison_operator"
13874 [(match_operand 1 "register_operand" "f")
13875 (match_operand 2 "const0_operand" "X")])
13876 (label_ref (match_operand 3 "" ""))
13878 (clobber (reg:CCFP FPSR_REG))
13879 (clobber (reg:CCFP FLAGS_REG))
13880 (clobber (match_scratch:HI 4 "=a"))]
13881 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13882 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13883 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13884 && SELECT_CC_MODE (GET_CODE (operands[0]),
13885 operands[1], operands[2]) == CCFPmode
13886 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13889 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13890 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13891 ;; with a precedence over other operators and is always put in the first
13892 ;; place. Swap condition and operands to match ficom instruction.
13894 (define_insn "*fp_jcc_8<mode>_387"
13896 (if_then_else (match_operator 0 "comparison_operator"
13897 [(match_operator 1 "float_operator"
13898 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13899 (match_operand 3 "register_operand" "f,f")])
13900 (label_ref (match_operand 4 "" ""))
13902 (clobber (reg:CCFP FPSR_REG))
13903 (clobber (reg:CCFP FLAGS_REG))
13904 (clobber (match_scratch:HI 5 "=a,a"))]
13905 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13906 && TARGET_USE_<MODE>MODE_FIOP
13907 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13908 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13909 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13910 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13915 (if_then_else (match_operator 0 "comparison_operator"
13916 [(match_operand 1 "register_operand" "")
13917 (match_operand 2 "nonimmediate_operand" "")])
13918 (match_operand 3 "" "")
13919 (match_operand 4 "" "")))
13920 (clobber (reg:CCFP FPSR_REG))
13921 (clobber (reg:CCFP FLAGS_REG))]
13925 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13926 operands[3], operands[4], NULL_RTX, NULL_RTX);
13932 (if_then_else (match_operator 0 "comparison_operator"
13933 [(match_operand 1 "register_operand" "")
13934 (match_operand 2 "general_operand" "")])
13935 (match_operand 3 "" "")
13936 (match_operand 4 "" "")))
13937 (clobber (reg:CCFP FPSR_REG))
13938 (clobber (reg:CCFP FLAGS_REG))
13939 (clobber (match_scratch:HI 5 "=a"))]
13943 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13944 operands[3], operands[4], operands[5], NULL_RTX);
13950 (if_then_else (match_operator 0 "comparison_operator"
13951 [(match_operator 1 "float_operator"
13952 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13953 (match_operand 3 "register_operand" "")])
13954 (match_operand 4 "" "")
13955 (match_operand 5 "" "")))
13956 (clobber (reg:CCFP FPSR_REG))
13957 (clobber (reg:CCFP FLAGS_REG))
13958 (clobber (match_scratch:HI 6 "=a"))]
13962 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13963 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13964 operands[3], operands[7],
13965 operands[4], operands[5], operands[6], NULL_RTX);
13969 ;; %%% Kill this when reload knows how to do it.
13972 (if_then_else (match_operator 0 "comparison_operator"
13973 [(match_operator 1 "float_operator"
13974 [(match_operand:X87MODEI12 2 "register_operand" "")])
13975 (match_operand 3 "register_operand" "")])
13976 (match_operand 4 "" "")
13977 (match_operand 5 "" "")))
13978 (clobber (reg:CCFP FPSR_REG))
13979 (clobber (reg:CCFP FLAGS_REG))
13980 (clobber (match_scratch:HI 6 "=a"))]
13984 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13985 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13986 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13987 operands[3], operands[7],
13988 operands[4], operands[5], operands[6], operands[2]);
13992 ;; Unconditional and other jump instructions
13994 (define_insn "jump"
13996 (label_ref (match_operand 0 "" "")))]
13999 [(set_attr "type" "ibr")
14000 (set (attr "length")
14001 (if_then_else (and (ge (minus (match_dup 0) (pc))
14003 (lt (minus (match_dup 0) (pc))
14007 (set_attr "modrm" "0")])
14009 (define_expand "indirect_jump"
14010 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14014 (define_insn "*indirect_jump"
14015 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14018 [(set_attr "type" "ibr")
14019 (set_attr "length_immediate" "0")])
14021 (define_insn "*indirect_jump_rtx64"
14022 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14025 [(set_attr "type" "ibr")
14026 (set_attr "length_immediate" "0")])
14028 (define_expand "tablejump"
14029 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14030 (use (label_ref (match_operand 1 "" "")))])]
14033 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14034 relative. Convert the relative address to an absolute address. */
14038 enum rtx_code code;
14040 /* We can't use @GOTOFF for text labels on VxWorks;
14041 see gotoff_operand. */
14042 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14046 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14048 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14052 op1 = pic_offset_table_rtx;
14057 op0 = pic_offset_table_rtx;
14061 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14066 (define_insn "*tablejump_1"
14067 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14068 (use (label_ref (match_operand 1 "" "")))]
14071 [(set_attr "type" "ibr")
14072 (set_attr "length_immediate" "0")])
14074 (define_insn "*tablejump_1_rtx64"
14075 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14076 (use (label_ref (match_operand 1 "" "")))]
14079 [(set_attr "type" "ibr")
14080 (set_attr "length_immediate" "0")])
14082 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14085 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14086 (set (match_operand:QI 1 "register_operand" "")
14087 (match_operator:QI 2 "ix86_comparison_operator"
14088 [(reg FLAGS_REG) (const_int 0)]))
14089 (set (match_operand 3 "q_regs_operand" "")
14090 (zero_extend (match_dup 1)))]
14091 "(peep2_reg_dead_p (3, operands[1])
14092 || operands_match_p (operands[1], operands[3]))
14093 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14094 [(set (match_dup 4) (match_dup 0))
14095 (set (strict_low_part (match_dup 5))
14098 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14099 operands[5] = gen_lowpart (QImode, operands[3]);
14100 ix86_expand_clear (operands[3]);
14103 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14106 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14107 (set (match_operand:QI 1 "register_operand" "")
14108 (match_operator:QI 2 "ix86_comparison_operator"
14109 [(reg FLAGS_REG) (const_int 0)]))
14110 (parallel [(set (match_operand 3 "q_regs_operand" "")
14111 (zero_extend (match_dup 1)))
14112 (clobber (reg:CC FLAGS_REG))])]
14113 "(peep2_reg_dead_p (3, operands[1])
14114 || operands_match_p (operands[1], operands[3]))
14115 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14116 [(set (match_dup 4) (match_dup 0))
14117 (set (strict_low_part (match_dup 5))
14120 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14121 operands[5] = gen_lowpart (QImode, operands[3]);
14122 ix86_expand_clear (operands[3]);
14125 ;; Call instructions.
14127 ;; The predicates normally associated with named expanders are not properly
14128 ;; checked for calls. This is a bug in the generic code, but it isn't that
14129 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14131 ;; Call subroutine returning no value.
14133 (define_expand "call_pop"
14134 [(parallel [(call (match_operand:QI 0 "" "")
14135 (match_operand:SI 1 "" ""))
14136 (set (reg:SI SP_REG)
14137 (plus:SI (reg:SI SP_REG)
14138 (match_operand:SI 3 "" "")))])]
14141 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14145 (define_insn "*call_pop_0"
14146 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14147 (match_operand:SI 1 "" ""))
14148 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14149 (match_operand:SI 2 "immediate_operand" "")))]
14152 if (SIBLING_CALL_P (insn))
14155 return "call\t%P0";
14157 [(set_attr "type" "call")])
14159 (define_insn "*call_pop_1"
14160 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14161 (match_operand:SI 1 "" ""))
14162 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14163 (match_operand:SI 2 "immediate_operand" "i")))]
14166 if (constant_call_address_operand (operands[0], Pmode))
14168 if (SIBLING_CALL_P (insn))
14171 return "call\t%P0";
14173 if (SIBLING_CALL_P (insn))
14176 return "call\t%A0";
14178 [(set_attr "type" "call")])
14180 (define_expand "call"
14181 [(call (match_operand:QI 0 "" "")
14182 (match_operand 1 "" ""))
14183 (use (match_operand 2 "" ""))]
14186 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14190 (define_expand "sibcall"
14191 [(call (match_operand:QI 0 "" "")
14192 (match_operand 1 "" ""))
14193 (use (match_operand 2 "" ""))]
14196 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14200 (define_insn "*call_0"
14201 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14202 (match_operand 1 "" ""))]
14205 if (SIBLING_CALL_P (insn))
14208 return "call\t%P0";
14210 [(set_attr "type" "call")])
14212 (define_insn "*call_1"
14213 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14214 (match_operand 1 "" ""))]
14215 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14217 if (constant_call_address_operand (operands[0], Pmode))
14218 return "call\t%P0";
14219 return "call\t%A0";
14221 [(set_attr "type" "call")])
14223 (define_insn "*sibcall_1"
14224 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14225 (match_operand 1 "" ""))]
14226 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14228 if (constant_call_address_operand (operands[0], Pmode))
14232 [(set_attr "type" "call")])
14234 (define_insn "*call_1_rex64"
14235 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14236 (match_operand 1 "" ""))]
14237 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14238 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14240 if (constant_call_address_operand (operands[0], Pmode))
14241 return "call\t%P0";
14242 return "call\t%A0";
14244 [(set_attr "type" "call")])
14246 (define_insn "*call_1_rex64_large"
14247 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14248 (match_operand 1 "" ""))]
14249 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14251 [(set_attr "type" "call")])
14253 (define_insn "*sibcall_1_rex64"
14254 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14255 (match_operand 1 "" ""))]
14256 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14258 [(set_attr "type" "call")])
14260 (define_insn "*sibcall_1_rex64_v"
14261 [(call (mem:QI (reg:DI R11_REG))
14262 (match_operand 0 "" ""))]
14263 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14265 [(set_attr "type" "call")])
14268 ;; Call subroutine, returning value in operand 0
14270 (define_expand "call_value_pop"
14271 [(parallel [(set (match_operand 0 "" "")
14272 (call (match_operand:QI 1 "" "")
14273 (match_operand:SI 2 "" "")))
14274 (set (reg:SI SP_REG)
14275 (plus:SI (reg:SI SP_REG)
14276 (match_operand:SI 4 "" "")))])]
14279 ix86_expand_call (operands[0], operands[1], operands[2],
14280 operands[3], operands[4], 0);
14284 (define_expand "call_value"
14285 [(set (match_operand 0 "" "")
14286 (call (match_operand:QI 1 "" "")
14287 (match_operand:SI 2 "" "")))
14288 (use (match_operand:SI 3 "" ""))]
14289 ;; Operand 2 not used on the i386.
14292 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14296 (define_expand "sibcall_value"
14297 [(set (match_operand 0 "" "")
14298 (call (match_operand:QI 1 "" "")
14299 (match_operand:SI 2 "" "")))
14300 (use (match_operand:SI 3 "" ""))]
14301 ;; Operand 2 not used on the i386.
14304 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14308 ;; Call subroutine returning any type.
14310 (define_expand "untyped_call"
14311 [(parallel [(call (match_operand 0 "" "")
14313 (match_operand 1 "" "")
14314 (match_operand 2 "" "")])]
14319 /* In order to give reg-stack an easier job in validating two
14320 coprocessor registers as containing a possible return value,
14321 simply pretend the untyped call returns a complex long double
14324 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14325 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14326 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14329 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14331 rtx set = XVECEXP (operands[2], 0, i);
14332 emit_move_insn (SET_DEST (set), SET_SRC (set));
14335 /* The optimizer does not know that the call sets the function value
14336 registers we stored in the result block. We avoid problems by
14337 claiming that all hard registers are used and clobbered at this
14339 emit_insn (gen_blockage (const0_rtx));
14344 ;; Prologue and epilogue instructions
14346 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14347 ;; all of memory. This blocks insns from being moved across this point.
14349 (define_insn "blockage"
14350 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14353 [(set_attr "length" "0")])
14355 ;; Insn emitted into the body of a function to return from a function.
14356 ;; This is only done if the function's epilogue is known to be simple.
14357 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14359 (define_expand "return"
14361 "ix86_can_use_return_insn_p ()"
14363 if (current_function_pops_args)
14365 rtx popc = GEN_INT (current_function_pops_args);
14366 emit_jump_insn (gen_return_pop_internal (popc));
14371 (define_insn "return_internal"
14375 [(set_attr "length" "1")
14376 (set_attr "length_immediate" "0")
14377 (set_attr "modrm" "0")])
14379 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14380 ;; instruction Athlon and K8 have.
14382 (define_insn "return_internal_long"
14384 (unspec [(const_int 0)] UNSPEC_REP)]
14387 [(set_attr "length" "1")
14388 (set_attr "length_immediate" "0")
14389 (set_attr "prefix_rep" "1")
14390 (set_attr "modrm" "0")])
14392 (define_insn "return_pop_internal"
14394 (use (match_operand:SI 0 "const_int_operand" ""))]
14397 [(set_attr "length" "3")
14398 (set_attr "length_immediate" "2")
14399 (set_attr "modrm" "0")])
14401 (define_insn "return_indirect_internal"
14403 (use (match_operand:SI 0 "register_operand" "r"))]
14406 [(set_attr "type" "ibr")
14407 (set_attr "length_immediate" "0")])
14413 [(set_attr "length" "1")
14414 (set_attr "length_immediate" "0")
14415 (set_attr "modrm" "0")])
14417 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14418 ;; branch prediction penalty for the third jump in a 16-byte
14421 (define_insn "align"
14422 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14425 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14426 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14428 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14429 The align insn is used to avoid 3 jump instructions in the row to improve
14430 branch prediction and the benefits hardly outweigh the cost of extra 8
14431 nops on the average inserted by full alignment pseudo operation. */
14435 [(set_attr "length" "16")])
14437 (define_expand "prologue"
14440 "ix86_expand_prologue (); DONE;")
14442 (define_insn "set_got"
14443 [(set (match_operand:SI 0 "register_operand" "=r")
14444 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14445 (clobber (reg:CC FLAGS_REG))]
14447 { return output_set_got (operands[0], NULL_RTX); }
14448 [(set_attr "type" "multi")
14449 (set_attr "length" "12")])
14451 (define_insn "set_got_labelled"
14452 [(set (match_operand:SI 0 "register_operand" "=r")
14453 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14455 (clobber (reg:CC FLAGS_REG))]
14457 { return output_set_got (operands[0], operands[1]); }
14458 [(set_attr "type" "multi")
14459 (set_attr "length" "12")])
14461 (define_insn "set_got_rex64"
14462 [(set (match_operand:DI 0 "register_operand" "=r")
14463 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14465 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14466 [(set_attr "type" "lea")
14467 (set_attr "length" "6")])
14469 (define_insn "set_rip_rex64"
14470 [(set (match_operand:DI 0 "register_operand" "=r")
14471 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14473 "lea{q}\t%l1(%%rip), %0"
14474 [(set_attr "type" "lea")
14475 (set_attr "length" "6")])
14477 (define_insn "set_got_offset_rex64"
14478 [(set (match_operand:DI 0 "register_operand" "=r")
14479 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14481 "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
14482 [(set_attr "type" "imov")
14483 (set_attr "length" "11")])
14485 (define_expand "epilogue"
14488 "ix86_expand_epilogue (1); DONE;")
14490 (define_expand "sibcall_epilogue"
14493 "ix86_expand_epilogue (0); DONE;")
14495 (define_expand "eh_return"
14496 [(use (match_operand 0 "register_operand" ""))]
14499 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14501 /* Tricky bit: we write the address of the handler to which we will
14502 be returning into someone else's stack frame, one word below the
14503 stack address we wish to restore. */
14504 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14505 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14506 tmp = gen_rtx_MEM (Pmode, tmp);
14507 emit_move_insn (tmp, ra);
14509 if (Pmode == SImode)
14510 emit_jump_insn (gen_eh_return_si (sa));
14512 emit_jump_insn (gen_eh_return_di (sa));
14517 (define_insn_and_split "eh_return_si"
14519 (unspec [(match_operand:SI 0 "register_operand" "c")]
14520 UNSPEC_EH_RETURN))]
14525 "ix86_expand_epilogue (2); DONE;")
14527 (define_insn_and_split "eh_return_di"
14529 (unspec [(match_operand:DI 0 "register_operand" "c")]
14530 UNSPEC_EH_RETURN))]
14535 "ix86_expand_epilogue (2); DONE;")
14537 (define_insn "leave"
14538 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14539 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14540 (clobber (mem:BLK (scratch)))]
14543 [(set_attr "type" "leave")])
14545 (define_insn "leave_rex64"
14546 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14547 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14548 (clobber (mem:BLK (scratch)))]
14551 [(set_attr "type" "leave")])
14553 (define_expand "ffssi2"
14555 [(set (match_operand:SI 0 "register_operand" "")
14556 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14557 (clobber (match_scratch:SI 2 ""))
14558 (clobber (reg:CC FLAGS_REG))])]
14562 (define_insn_and_split "*ffs_cmove"
14563 [(set (match_operand:SI 0 "register_operand" "=r")
14564 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14565 (clobber (match_scratch:SI 2 "=&r"))
14566 (clobber (reg:CC FLAGS_REG))]
14569 "&& reload_completed"
14570 [(set (match_dup 2) (const_int -1))
14571 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14572 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14573 (set (match_dup 0) (if_then_else:SI
14574 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14577 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14578 (clobber (reg:CC FLAGS_REG))])]
14581 (define_insn_and_split "*ffs_no_cmove"
14582 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14583 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14584 (clobber (match_scratch:SI 2 "=&q"))
14585 (clobber (reg:CC FLAGS_REG))]
14589 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14590 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14591 (set (strict_low_part (match_dup 3))
14592 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14593 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14594 (clobber (reg:CC FLAGS_REG))])
14595 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14596 (clobber (reg:CC FLAGS_REG))])
14597 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14598 (clobber (reg:CC FLAGS_REG))])]
14600 operands[3] = gen_lowpart (QImode, operands[2]);
14601 ix86_expand_clear (operands[2]);
14604 (define_insn "*ffssi_1"
14605 [(set (reg:CCZ FLAGS_REG)
14606 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14608 (set (match_operand:SI 0 "register_operand" "=r")
14609 (ctz:SI (match_dup 1)))]
14611 "bsf{l}\t{%1, %0|%0, %1}"
14612 [(set_attr "prefix_0f" "1")])
14614 (define_expand "ffsdi2"
14616 [(set (match_operand:DI 0 "register_operand" "")
14617 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14618 (clobber (match_scratch:DI 2 ""))
14619 (clobber (reg:CC FLAGS_REG))])]
14620 "TARGET_64BIT && TARGET_CMOVE"
14623 (define_insn_and_split "*ffs_rex64"
14624 [(set (match_operand:DI 0 "register_operand" "=r")
14625 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14626 (clobber (match_scratch:DI 2 "=&r"))
14627 (clobber (reg:CC FLAGS_REG))]
14628 "TARGET_64BIT && TARGET_CMOVE"
14630 "&& reload_completed"
14631 [(set (match_dup 2) (const_int -1))
14632 (parallel [(set (reg:CCZ FLAGS_REG)
14633 (compare:CCZ (match_dup 1) (const_int 0)))
14634 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14635 (set (match_dup 0) (if_then_else:DI
14636 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14639 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14640 (clobber (reg:CC FLAGS_REG))])]
14643 (define_insn "*ffsdi_1"
14644 [(set (reg:CCZ FLAGS_REG)
14645 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14647 (set (match_operand:DI 0 "register_operand" "=r")
14648 (ctz:DI (match_dup 1)))]
14650 "bsf{q}\t{%1, %0|%0, %1}"
14651 [(set_attr "prefix_0f" "1")])
14653 (define_insn "ctzsi2"
14654 [(set (match_operand:SI 0 "register_operand" "=r")
14655 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14656 (clobber (reg:CC FLAGS_REG))]
14658 "bsf{l}\t{%1, %0|%0, %1}"
14659 [(set_attr "prefix_0f" "1")])
14661 (define_insn "ctzdi2"
14662 [(set (match_operand:DI 0 "register_operand" "=r")
14663 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14664 (clobber (reg:CC FLAGS_REG))]
14666 "bsf{q}\t{%1, %0|%0, %1}"
14667 [(set_attr "prefix_0f" "1")])
14669 (define_expand "clzsi2"
14671 [(set (match_operand:SI 0 "register_operand" "")
14672 (minus:SI (const_int 31)
14673 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14674 (clobber (reg:CC FLAGS_REG))])
14676 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14677 (clobber (reg:CC FLAGS_REG))])]
14682 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14687 (define_insn "clzsi2_abm"
14688 [(set (match_operand:SI 0 "register_operand" "=r")
14689 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14690 (clobber (reg:CC FLAGS_REG))]
14692 "lzcnt{l}\t{%1, %0|%0, %1}"
14693 [(set_attr "prefix_rep" "1")
14694 (set_attr "type" "bitmanip")
14695 (set_attr "mode" "SI")])
14697 (define_insn "*bsr"
14698 [(set (match_operand:SI 0 "register_operand" "=r")
14699 (minus:SI (const_int 31)
14700 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14701 (clobber (reg:CC FLAGS_REG))]
14703 "bsr{l}\t{%1, %0|%0, %1}"
14704 [(set_attr "prefix_0f" "1")
14705 (set_attr "mode" "SI")])
14707 (define_insn "popcountsi2"
14708 [(set (match_operand:SI 0 "register_operand" "=r")
14709 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14710 (clobber (reg:CC FLAGS_REG))]
14712 "popcnt{l}\t{%1, %0|%0, %1}"
14713 [(set_attr "prefix_rep" "1")
14714 (set_attr "type" "bitmanip")
14715 (set_attr "mode" "SI")])
14717 (define_insn "*popcountsi2_cmp"
14718 [(set (reg FLAGS_REG)
14720 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14722 (set (match_operand:SI 0 "register_operand" "=r")
14723 (popcount:SI (match_dup 1)))]
14724 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14725 "popcnt{l}\t{%1, %0|%0, %1}"
14726 [(set_attr "prefix_rep" "1")
14727 (set_attr "type" "bitmanip")
14728 (set_attr "mode" "SI")])
14730 (define_insn "*popcountsi2_cmp_zext"
14731 [(set (reg FLAGS_REG)
14733 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14735 (set (match_operand:DI 0 "register_operand" "=r")
14736 (zero_extend:DI(popcount:SI (match_dup 1))))]
14737 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14738 "popcnt{l}\t{%1, %0|%0, %1}"
14739 [(set_attr "prefix_rep" "1")
14740 (set_attr "type" "bitmanip")
14741 (set_attr "mode" "SI")])
14743 (define_expand "bswapsi2"
14744 [(set (match_operand:SI 0 "register_operand" "")
14745 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14750 rtx x = operands[0];
14752 emit_move_insn (x, operands[1]);
14753 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14754 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14755 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14760 (define_insn "*bswapsi_1"
14761 [(set (match_operand:SI 0 "register_operand" "=r")
14762 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14765 [(set_attr "prefix_0f" "1")
14766 (set_attr "length" "2")])
14768 (define_insn "*bswaphi_lowpart_1"
14769 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14770 (bswap:HI (match_dup 0)))
14771 (clobber (reg:CC FLAGS_REG))]
14772 "TARGET_USE_XCHGB || optimize_size"
14774 xchg{b}\t{%h0, %b0|%b0, %h0}
14775 rol{w}\t{$8, %0|%0, 8}"
14776 [(set_attr "length" "2,4")
14777 (set_attr "mode" "QI,HI")])
14779 (define_insn "bswaphi_lowpart"
14780 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14781 (bswap:HI (match_dup 0)))
14782 (clobber (reg:CC FLAGS_REG))]
14784 "rol{w}\t{$8, %0|%0, 8}"
14785 [(set_attr "length" "4")
14786 (set_attr "mode" "HI")])
14788 (define_insn "bswapdi2"
14789 [(set (match_operand:DI 0 "register_operand" "=r")
14790 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14793 [(set_attr "prefix_0f" "1")
14794 (set_attr "length" "3")])
14796 (define_expand "clzdi2"
14798 [(set (match_operand:DI 0 "register_operand" "")
14799 (minus:DI (const_int 63)
14800 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14801 (clobber (reg:CC FLAGS_REG))])
14803 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14804 (clobber (reg:CC FLAGS_REG))])]
14809 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14814 (define_insn "clzdi2_abm"
14815 [(set (match_operand:DI 0 "register_operand" "=r")
14816 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14817 (clobber (reg:CC FLAGS_REG))]
14818 "TARGET_64BIT && TARGET_ABM"
14819 "lzcnt{q}\t{%1, %0|%0, %1}"
14820 [(set_attr "prefix_rep" "1")
14821 (set_attr "type" "bitmanip")
14822 (set_attr "mode" "DI")])
14824 (define_insn "*bsr_rex64"
14825 [(set (match_operand:DI 0 "register_operand" "=r")
14826 (minus:DI (const_int 63)
14827 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14828 (clobber (reg:CC FLAGS_REG))]
14830 "bsr{q}\t{%1, %0|%0, %1}"
14831 [(set_attr "prefix_0f" "1")
14832 (set_attr "mode" "DI")])
14834 (define_insn "popcountdi2"
14835 [(set (match_operand:DI 0 "register_operand" "=r")
14836 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14837 (clobber (reg:CC FLAGS_REG))]
14838 "TARGET_64BIT && TARGET_POPCNT"
14839 "popcnt{q}\t{%1, %0|%0, %1}"
14840 [(set_attr "prefix_rep" "1")
14841 (set_attr "type" "bitmanip")
14842 (set_attr "mode" "DI")])
14844 (define_insn "*popcountdi2_cmp"
14845 [(set (reg FLAGS_REG)
14847 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14849 (set (match_operand:DI 0 "register_operand" "=r")
14850 (popcount:DI (match_dup 1)))]
14851 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14852 "popcnt{q}\t{%1, %0|%0, %1}"
14853 [(set_attr "prefix_rep" "1")
14854 (set_attr "type" "bitmanip")
14855 (set_attr "mode" "DI")])
14857 (define_expand "clzhi2"
14859 [(set (match_operand:HI 0 "register_operand" "")
14860 (minus:HI (const_int 15)
14861 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14862 (clobber (reg:CC FLAGS_REG))])
14864 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14865 (clobber (reg:CC FLAGS_REG))])]
14870 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14875 (define_insn "clzhi2_abm"
14876 [(set (match_operand:HI 0 "register_operand" "=r")
14877 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14878 (clobber (reg:CC FLAGS_REG))]
14880 "lzcnt{w}\t{%1, %0|%0, %1}"
14881 [(set_attr "prefix_rep" "1")
14882 (set_attr "type" "bitmanip")
14883 (set_attr "mode" "HI")])
14885 (define_insn "*bsrhi"
14886 [(set (match_operand:HI 0 "register_operand" "=r")
14887 (minus:HI (const_int 15)
14888 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14889 (clobber (reg:CC FLAGS_REG))]
14891 "bsr{w}\t{%1, %0|%0, %1}"
14892 [(set_attr "prefix_0f" "1")
14893 (set_attr "mode" "HI")])
14895 (define_insn "popcounthi2"
14896 [(set (match_operand:HI 0 "register_operand" "=r")
14897 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14898 (clobber (reg:CC FLAGS_REG))]
14900 "popcnt{w}\t{%1, %0|%0, %1}"
14901 [(set_attr "prefix_rep" "1")
14902 (set_attr "type" "bitmanip")
14903 (set_attr "mode" "HI")])
14905 (define_insn "*popcounthi2_cmp"
14906 [(set (reg FLAGS_REG)
14908 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14910 (set (match_operand:HI 0 "register_operand" "=r")
14911 (popcount:HI (match_dup 1)))]
14912 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14913 "popcnt{w}\t{%1, %0|%0, %1}"
14914 [(set_attr "prefix_rep" "1")
14915 (set_attr "type" "bitmanip")
14916 (set_attr "mode" "HI")])
14918 (define_expand "paritydi2"
14919 [(set (match_operand:DI 0 "register_operand" "")
14920 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
14923 rtx scratch = gen_reg_rtx (QImode);
14926 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14927 NULL_RTX, operands[1]));
14929 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14930 gen_rtx_REG (CCmode, FLAGS_REG),
14932 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14935 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14938 rtx tmp = gen_reg_rtx (SImode);
14940 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14941 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14946 (define_insn_and_split "paritydi2_cmp"
14947 [(set (reg:CC FLAGS_REG)
14948 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
14949 (clobber (match_scratch:DI 0 "=r,X"))
14950 (clobber (match_scratch:SI 1 "=r,r"))
14951 (clobber (match_scratch:HI 2 "=Q,Q"))]
14954 "&& reload_completed"
14956 [(set (match_dup 1)
14957 (xor:SI (match_dup 1) (match_dup 4)))
14958 (clobber (reg:CC FLAGS_REG))])
14960 [(set (reg:CC FLAGS_REG)
14961 (parity:CC (match_dup 1)))
14962 (clobber (match_dup 1))
14963 (clobber (match_dup 2))])]
14965 operands[4] = gen_lowpart (SImode, operands[3]);
14967 if (MEM_P (operands[3]))
14968 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
14969 else if (! TARGET_64BIT)
14970 operands[1] = gen_highpart (SImode, operands[3]);
14973 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14974 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14978 (define_expand "paritysi2"
14979 [(set (match_operand:SI 0 "register_operand" "")
14980 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
14983 rtx scratch = gen_reg_rtx (QImode);
14986 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14988 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14989 gen_rtx_REG (CCmode, FLAGS_REG),
14991 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14993 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14997 (define_insn_and_split "paritysi2_cmp"
14998 [(set (reg:CC FLAGS_REG)
14999 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15000 (clobber (match_scratch:SI 0 "=r,X"))
15001 (clobber (match_scratch:HI 1 "=Q,Q"))]
15004 "&& reload_completed"
15006 [(set (match_dup 1)
15007 (xor:HI (match_dup 1) (match_dup 3)))
15008 (clobber (reg:CC FLAGS_REG))])
15010 [(set (reg:CC FLAGS_REG)
15011 (parity:CC (match_dup 1)))
15012 (clobber (match_dup 1))])]
15014 operands[3] = gen_lowpart (HImode, operands[2]);
15016 if (MEM_P (operands[2]))
15017 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15020 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15021 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15025 (define_insn "*parityhi2_cmp"
15026 [(set (reg:CC FLAGS_REG)
15027 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15028 (clobber (match_scratch:HI 0 "=Q"))]
15030 "xor{b}\t{%h0, %b0|%b0, %h0}"
15031 [(set_attr "length" "2")
15032 (set_attr "mode" "HI")])
15034 (define_insn "*parityqi2_cmp"
15035 [(set (reg:CC FLAGS_REG)
15036 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15039 [(set_attr "length" "2")
15040 (set_attr "mode" "QI")])
15042 ;; Thread-local storage patterns for ELF.
15044 ;; Note that these code sequences must appear exactly as shown
15045 ;; in order to allow linker relaxation.
15047 (define_insn "*tls_global_dynamic_32_gnu"
15048 [(set (match_operand:SI 0 "register_operand" "=a")
15049 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15050 (match_operand:SI 2 "tls_symbolic_operand" "")
15051 (match_operand:SI 3 "call_insn_operand" "")]
15053 (clobber (match_scratch:SI 4 "=d"))
15054 (clobber (match_scratch:SI 5 "=c"))
15055 (clobber (reg:CC FLAGS_REG))]
15056 "!TARGET_64BIT && TARGET_GNU_TLS"
15057 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15058 [(set_attr "type" "multi")
15059 (set_attr "length" "12")])
15061 (define_insn "*tls_global_dynamic_32_sun"
15062 [(set (match_operand:SI 0 "register_operand" "=a")
15063 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15064 (match_operand:SI 2 "tls_symbolic_operand" "")
15065 (match_operand:SI 3 "call_insn_operand" "")]
15067 (clobber (match_scratch:SI 4 "=d"))
15068 (clobber (match_scratch:SI 5 "=c"))
15069 (clobber (reg:CC FLAGS_REG))]
15070 "!TARGET_64BIT && TARGET_SUN_TLS"
15071 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15072 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15073 [(set_attr "type" "multi")
15074 (set_attr "length" "14")])
15076 (define_expand "tls_global_dynamic_32"
15077 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15080 (match_operand:SI 1 "tls_symbolic_operand" "")
15083 (clobber (match_scratch:SI 4 ""))
15084 (clobber (match_scratch:SI 5 ""))
15085 (clobber (reg:CC FLAGS_REG))])]
15089 operands[2] = pic_offset_table_rtx;
15092 operands[2] = gen_reg_rtx (Pmode);
15093 emit_insn (gen_set_got (operands[2]));
15095 if (TARGET_GNU2_TLS)
15097 emit_insn (gen_tls_dynamic_gnu2_32
15098 (operands[0], operands[1], operands[2]));
15101 operands[3] = ix86_tls_get_addr ();
15104 (define_insn "*tls_global_dynamic_64"
15105 [(set (match_operand:DI 0 "register_operand" "=a")
15106 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15107 (match_operand:DI 3 "" "")))
15108 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15111 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15112 [(set_attr "type" "multi")
15113 (set_attr "length" "16")])
15115 (define_expand "tls_global_dynamic_64"
15116 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15117 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15118 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15122 if (TARGET_GNU2_TLS)
15124 emit_insn (gen_tls_dynamic_gnu2_64
15125 (operands[0], operands[1]));
15128 operands[2] = ix86_tls_get_addr ();
15131 (define_insn "*tls_local_dynamic_base_32_gnu"
15132 [(set (match_operand:SI 0 "register_operand" "=a")
15133 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15134 (match_operand:SI 2 "call_insn_operand" "")]
15135 UNSPEC_TLS_LD_BASE))
15136 (clobber (match_scratch:SI 3 "=d"))
15137 (clobber (match_scratch:SI 4 "=c"))
15138 (clobber (reg:CC FLAGS_REG))]
15139 "!TARGET_64BIT && TARGET_GNU_TLS"
15140 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15141 [(set_attr "type" "multi")
15142 (set_attr "length" "11")])
15144 (define_insn "*tls_local_dynamic_base_32_sun"
15145 [(set (match_operand:SI 0 "register_operand" "=a")
15146 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15147 (match_operand:SI 2 "call_insn_operand" "")]
15148 UNSPEC_TLS_LD_BASE))
15149 (clobber (match_scratch:SI 3 "=d"))
15150 (clobber (match_scratch:SI 4 "=c"))
15151 (clobber (reg:CC FLAGS_REG))]
15152 "!TARGET_64BIT && TARGET_SUN_TLS"
15153 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15154 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15155 [(set_attr "type" "multi")
15156 (set_attr "length" "13")])
15158 (define_expand "tls_local_dynamic_base_32"
15159 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15160 (unspec:SI [(match_dup 1) (match_dup 2)]
15161 UNSPEC_TLS_LD_BASE))
15162 (clobber (match_scratch:SI 3 ""))
15163 (clobber (match_scratch:SI 4 ""))
15164 (clobber (reg:CC FLAGS_REG))])]
15168 operands[1] = pic_offset_table_rtx;
15171 operands[1] = gen_reg_rtx (Pmode);
15172 emit_insn (gen_set_got (operands[1]));
15174 if (TARGET_GNU2_TLS)
15176 emit_insn (gen_tls_dynamic_gnu2_32
15177 (operands[0], ix86_tls_module_base (), operands[1]));
15180 operands[2] = ix86_tls_get_addr ();
15183 (define_insn "*tls_local_dynamic_base_64"
15184 [(set (match_operand:DI 0 "register_operand" "=a")
15185 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15186 (match_operand:DI 2 "" "")))
15187 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15189 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15190 [(set_attr "type" "multi")
15191 (set_attr "length" "12")])
15193 (define_expand "tls_local_dynamic_base_64"
15194 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15195 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15196 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15199 if (TARGET_GNU2_TLS)
15201 emit_insn (gen_tls_dynamic_gnu2_64
15202 (operands[0], ix86_tls_module_base ()));
15205 operands[1] = ix86_tls_get_addr ();
15208 ;; Local dynamic of a single variable is a lose. Show combine how
15209 ;; to convert that back to global dynamic.
15211 (define_insn_and_split "*tls_local_dynamic_32_once"
15212 [(set (match_operand:SI 0 "register_operand" "=a")
15213 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15214 (match_operand:SI 2 "call_insn_operand" "")]
15215 UNSPEC_TLS_LD_BASE)
15216 (const:SI (unspec:SI
15217 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15219 (clobber (match_scratch:SI 4 "=d"))
15220 (clobber (match_scratch:SI 5 "=c"))
15221 (clobber (reg:CC FLAGS_REG))]
15225 [(parallel [(set (match_dup 0)
15226 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15228 (clobber (match_dup 4))
15229 (clobber (match_dup 5))
15230 (clobber (reg:CC FLAGS_REG))])]
15233 ;; Load and add the thread base pointer from %gs:0.
15235 (define_insn "*load_tp_si"
15236 [(set (match_operand:SI 0 "register_operand" "=r")
15237 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15239 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15240 [(set_attr "type" "imov")
15241 (set_attr "modrm" "0")
15242 (set_attr "length" "7")
15243 (set_attr "memory" "load")
15244 (set_attr "imm_disp" "false")])
15246 (define_insn "*add_tp_si"
15247 [(set (match_operand:SI 0 "register_operand" "=r")
15248 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15249 (match_operand:SI 1 "register_operand" "0")))
15250 (clobber (reg:CC FLAGS_REG))]
15252 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15253 [(set_attr "type" "alu")
15254 (set_attr "modrm" "0")
15255 (set_attr "length" "7")
15256 (set_attr "memory" "load")
15257 (set_attr "imm_disp" "false")])
15259 (define_insn "*load_tp_di"
15260 [(set (match_operand:DI 0 "register_operand" "=r")
15261 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15263 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15264 [(set_attr "type" "imov")
15265 (set_attr "modrm" "0")
15266 (set_attr "length" "7")
15267 (set_attr "memory" "load")
15268 (set_attr "imm_disp" "false")])
15270 (define_insn "*add_tp_di"
15271 [(set (match_operand:DI 0 "register_operand" "=r")
15272 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15273 (match_operand:DI 1 "register_operand" "0")))
15274 (clobber (reg:CC FLAGS_REG))]
15276 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15277 [(set_attr "type" "alu")
15278 (set_attr "modrm" "0")
15279 (set_attr "length" "7")
15280 (set_attr "memory" "load")
15281 (set_attr "imm_disp" "false")])
15283 ;; GNU2 TLS patterns can be split.
15285 (define_expand "tls_dynamic_gnu2_32"
15286 [(set (match_dup 3)
15287 (plus:SI (match_operand:SI 2 "register_operand" "")
15289 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15292 [(set (match_operand:SI 0 "register_operand" "")
15293 (unspec:SI [(match_dup 1) (match_dup 3)
15294 (match_dup 2) (reg:SI SP_REG)]
15296 (clobber (reg:CC FLAGS_REG))])]
15297 "!TARGET_64BIT && TARGET_GNU2_TLS"
15299 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15300 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15303 (define_insn "*tls_dynamic_lea_32"
15304 [(set (match_operand:SI 0 "register_operand" "=r")
15305 (plus:SI (match_operand:SI 1 "register_operand" "b")
15307 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15308 UNSPEC_TLSDESC))))]
15309 "!TARGET_64BIT && TARGET_GNU2_TLS"
15310 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15311 [(set_attr "type" "lea")
15312 (set_attr "mode" "SI")
15313 (set_attr "length" "6")
15314 (set_attr "length_address" "4")])
15316 (define_insn "*tls_dynamic_call_32"
15317 [(set (match_operand:SI 0 "register_operand" "=a")
15318 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15319 (match_operand:SI 2 "register_operand" "0")
15320 ;; we have to make sure %ebx still points to the GOT
15321 (match_operand:SI 3 "register_operand" "b")
15324 (clobber (reg:CC FLAGS_REG))]
15325 "!TARGET_64BIT && TARGET_GNU2_TLS"
15326 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15327 [(set_attr "type" "call")
15328 (set_attr "length" "2")
15329 (set_attr "length_address" "0")])
15331 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15332 [(set (match_operand:SI 0 "register_operand" "=&a")
15334 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15335 (match_operand:SI 4 "" "")
15336 (match_operand:SI 2 "register_operand" "b")
15339 (const:SI (unspec:SI
15340 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15342 (clobber (reg:CC FLAGS_REG))]
15343 "!TARGET_64BIT && TARGET_GNU2_TLS"
15346 [(set (match_dup 0) (match_dup 5))]
15348 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15349 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15352 (define_expand "tls_dynamic_gnu2_64"
15353 [(set (match_dup 2)
15354 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15357 [(set (match_operand:DI 0 "register_operand" "")
15358 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15360 (clobber (reg:CC FLAGS_REG))])]
15361 "TARGET_64BIT && TARGET_GNU2_TLS"
15363 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15364 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15367 (define_insn "*tls_dynamic_lea_64"
15368 [(set (match_operand:DI 0 "register_operand" "=r")
15369 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15371 "TARGET_64BIT && TARGET_GNU2_TLS"
15372 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15373 [(set_attr "type" "lea")
15374 (set_attr "mode" "DI")
15375 (set_attr "length" "7")
15376 (set_attr "length_address" "4")])
15378 (define_insn "*tls_dynamic_call_64"
15379 [(set (match_operand:DI 0 "register_operand" "=a")
15380 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15381 (match_operand:DI 2 "register_operand" "0")
15384 (clobber (reg:CC FLAGS_REG))]
15385 "TARGET_64BIT && TARGET_GNU2_TLS"
15386 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15387 [(set_attr "type" "call")
15388 (set_attr "length" "2")
15389 (set_attr "length_address" "0")])
15391 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15392 [(set (match_operand:DI 0 "register_operand" "=&a")
15394 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15395 (match_operand:DI 3 "" "")
15398 (const:DI (unspec:DI
15399 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15401 (clobber (reg:CC FLAGS_REG))]
15402 "TARGET_64BIT && TARGET_GNU2_TLS"
15405 [(set (match_dup 0) (match_dup 4))]
15407 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15408 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15413 ;; These patterns match the binary 387 instructions for addM3, subM3,
15414 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15415 ;; SFmode. The first is the normal insn, the second the same insn but
15416 ;; with one operand a conversion, and the third the same insn but with
15417 ;; the other operand a conversion. The conversion may be SFmode or
15418 ;; SImode if the target mode DFmode, but only SImode if the target mode
15421 ;; Gcc is slightly more smart about handling normal two address instructions
15422 ;; so use special patterns for add and mull.
15424 (define_insn "*fop_sf_comm_mixed"
15425 [(set (match_operand:SF 0 "register_operand" "=f,x")
15426 (match_operator:SF 3 "binary_fp_operator"
15427 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15428 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15429 "TARGET_MIX_SSE_I387
15430 && COMMUTATIVE_ARITH_P (operands[3])
15431 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15432 "* return output_387_binary_op (insn, operands);"
15433 [(set (attr "type")
15434 (if_then_else (eq_attr "alternative" "1")
15435 (if_then_else (match_operand:SF 3 "mult_operator" "")
15436 (const_string "ssemul")
15437 (const_string "sseadd"))
15438 (if_then_else (match_operand:SF 3 "mult_operator" "")
15439 (const_string "fmul")
15440 (const_string "fop"))))
15441 (set_attr "mode" "SF")])
15443 (define_insn "*fop_sf_comm_sse"
15444 [(set (match_operand:SF 0 "register_operand" "=x")
15445 (match_operator:SF 3 "binary_fp_operator"
15446 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15447 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15449 && COMMUTATIVE_ARITH_P (operands[3])
15450 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15451 "* return output_387_binary_op (insn, operands);"
15452 [(set (attr "type")
15453 (if_then_else (match_operand:SF 3 "mult_operator" "")
15454 (const_string "ssemul")
15455 (const_string "sseadd")))
15456 (set_attr "mode" "SF")])
15458 (define_insn "*fop_sf_comm_i387"
15459 [(set (match_operand:SF 0 "register_operand" "=f")
15460 (match_operator:SF 3 "binary_fp_operator"
15461 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15462 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15464 && COMMUTATIVE_ARITH_P (operands[3])
15465 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15466 "* return output_387_binary_op (insn, operands);"
15467 [(set (attr "type")
15468 (if_then_else (match_operand:SF 3 "mult_operator" "")
15469 (const_string "fmul")
15470 (const_string "fop")))
15471 (set_attr "mode" "SF")])
15473 (define_insn "*fop_sf_1_mixed"
15474 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15475 (match_operator:SF 3 "binary_fp_operator"
15476 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15477 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15478 "TARGET_MIX_SSE_I387
15479 && !COMMUTATIVE_ARITH_P (operands[3])
15480 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15481 "* return output_387_binary_op (insn, operands);"
15482 [(set (attr "type")
15483 (cond [(and (eq_attr "alternative" "2")
15484 (match_operand:SF 3 "mult_operator" ""))
15485 (const_string "ssemul")
15486 (and (eq_attr "alternative" "2")
15487 (match_operand:SF 3 "div_operator" ""))
15488 (const_string "ssediv")
15489 (eq_attr "alternative" "2")
15490 (const_string "sseadd")
15491 (match_operand:SF 3 "mult_operator" "")
15492 (const_string "fmul")
15493 (match_operand:SF 3 "div_operator" "")
15494 (const_string "fdiv")
15496 (const_string "fop")))
15497 (set_attr "mode" "SF")])
15499 (define_insn "*fop_sf_1_sse"
15500 [(set (match_operand:SF 0 "register_operand" "=x")
15501 (match_operator:SF 3 "binary_fp_operator"
15502 [(match_operand:SF 1 "register_operand" "0")
15503 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15505 && !COMMUTATIVE_ARITH_P (operands[3])"
15506 "* return output_387_binary_op (insn, operands);"
15507 [(set (attr "type")
15508 (cond [(match_operand:SF 3 "mult_operator" "")
15509 (const_string "ssemul")
15510 (match_operand:SF 3 "div_operator" "")
15511 (const_string "ssediv")
15513 (const_string "sseadd")))
15514 (set_attr "mode" "SF")])
15516 ;; This pattern is not fully shadowed by the pattern above.
15517 (define_insn "*fop_sf_1_i387"
15518 [(set (match_operand:SF 0 "register_operand" "=f,f")
15519 (match_operator:SF 3 "binary_fp_operator"
15520 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15521 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15522 "TARGET_80387 && !TARGET_SSE_MATH
15523 && !COMMUTATIVE_ARITH_P (operands[3])
15524 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15525 "* return output_387_binary_op (insn, operands);"
15526 [(set (attr "type")
15527 (cond [(match_operand:SF 3 "mult_operator" "")
15528 (const_string "fmul")
15529 (match_operand:SF 3 "div_operator" "")
15530 (const_string "fdiv")
15532 (const_string "fop")))
15533 (set_attr "mode" "SF")])
15535 ;; ??? Add SSE splitters for these!
15536 (define_insn "*fop_sf_2<mode>_i387"
15537 [(set (match_operand:SF 0 "register_operand" "=f,f")
15538 (match_operator:SF 3 "binary_fp_operator"
15539 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15540 (match_operand:SF 2 "register_operand" "0,0")]))]
15541 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15542 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15543 [(set (attr "type")
15544 (cond [(match_operand:SF 3 "mult_operator" "")
15545 (const_string "fmul")
15546 (match_operand:SF 3 "div_operator" "")
15547 (const_string "fdiv")
15549 (const_string "fop")))
15550 (set_attr "fp_int_src" "true")
15551 (set_attr "mode" "<MODE>")])
15553 (define_insn "*fop_sf_3<mode>_i387"
15554 [(set (match_operand:SF 0 "register_operand" "=f,f")
15555 (match_operator:SF 3 "binary_fp_operator"
15556 [(match_operand:SF 1 "register_operand" "0,0")
15557 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15558 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15559 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15560 [(set (attr "type")
15561 (cond [(match_operand:SF 3 "mult_operator" "")
15562 (const_string "fmul")
15563 (match_operand:SF 3 "div_operator" "")
15564 (const_string "fdiv")
15566 (const_string "fop")))
15567 (set_attr "fp_int_src" "true")
15568 (set_attr "mode" "<MODE>")])
15570 (define_insn "*fop_df_comm_mixed"
15571 [(set (match_operand:DF 0 "register_operand" "=f,x")
15572 (match_operator:DF 3 "binary_fp_operator"
15573 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15574 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15575 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15576 && COMMUTATIVE_ARITH_P (operands[3])
15577 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15578 "* return output_387_binary_op (insn, operands);"
15579 [(set (attr "type")
15580 (if_then_else (eq_attr "alternative" "1")
15581 (if_then_else (match_operand:DF 3 "mult_operator" "")
15582 (const_string "ssemul")
15583 (const_string "sseadd"))
15584 (if_then_else (match_operand:DF 3 "mult_operator" "")
15585 (const_string "fmul")
15586 (const_string "fop"))))
15587 (set_attr "mode" "DF")])
15589 (define_insn "*fop_df_comm_sse"
15590 [(set (match_operand:DF 0 "register_operand" "=x")
15591 (match_operator:DF 3 "binary_fp_operator"
15592 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15593 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15594 "TARGET_SSE2 && TARGET_SSE_MATH
15595 && COMMUTATIVE_ARITH_P (operands[3])
15596 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15597 "* return output_387_binary_op (insn, operands);"
15598 [(set (attr "type")
15599 (if_then_else (match_operand:DF 3 "mult_operator" "")
15600 (const_string "ssemul")
15601 (const_string "sseadd")))
15602 (set_attr "mode" "DF")])
15604 (define_insn "*fop_df_comm_i387"
15605 [(set (match_operand:DF 0 "register_operand" "=f")
15606 (match_operator:DF 3 "binary_fp_operator"
15607 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15608 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15610 && COMMUTATIVE_ARITH_P (operands[3])
15611 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15612 "* return output_387_binary_op (insn, operands);"
15613 [(set (attr "type")
15614 (if_then_else (match_operand:DF 3 "mult_operator" "")
15615 (const_string "fmul")
15616 (const_string "fop")))
15617 (set_attr "mode" "DF")])
15619 (define_insn "*fop_df_1_mixed"
15620 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15621 (match_operator:DF 3 "binary_fp_operator"
15622 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15623 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15624 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15625 && !COMMUTATIVE_ARITH_P (operands[3])
15626 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15627 "* return output_387_binary_op (insn, operands);"
15628 [(set (attr "type")
15629 (cond [(and (eq_attr "alternative" "2")
15630 (match_operand:DF 3 "mult_operator" ""))
15631 (const_string "ssemul")
15632 (and (eq_attr "alternative" "2")
15633 (match_operand:DF 3 "div_operator" ""))
15634 (const_string "ssediv")
15635 (eq_attr "alternative" "2")
15636 (const_string "sseadd")
15637 (match_operand:DF 3 "mult_operator" "")
15638 (const_string "fmul")
15639 (match_operand:DF 3 "div_operator" "")
15640 (const_string "fdiv")
15642 (const_string "fop")))
15643 (set_attr "mode" "DF")])
15645 (define_insn "*fop_df_1_sse"
15646 [(set (match_operand:DF 0 "register_operand" "=x")
15647 (match_operator:DF 3 "binary_fp_operator"
15648 [(match_operand:DF 1 "register_operand" "0")
15649 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15650 "TARGET_SSE2 && TARGET_SSE_MATH
15651 && !COMMUTATIVE_ARITH_P (operands[3])"
15652 "* return output_387_binary_op (insn, operands);"
15653 [(set_attr "mode" "DF")
15655 (cond [(match_operand:DF 3 "mult_operator" "")
15656 (const_string "ssemul")
15657 (match_operand:DF 3 "div_operator" "")
15658 (const_string "ssediv")
15660 (const_string "sseadd")))])
15662 ;; This pattern is not fully shadowed by the pattern above.
15663 (define_insn "*fop_df_1_i387"
15664 [(set (match_operand:DF 0 "register_operand" "=f,f")
15665 (match_operator:DF 3 "binary_fp_operator"
15666 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15667 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15668 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15669 && !COMMUTATIVE_ARITH_P (operands[3])
15670 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15671 "* return output_387_binary_op (insn, operands);"
15672 [(set (attr "type")
15673 (cond [(match_operand:DF 3 "mult_operator" "")
15674 (const_string "fmul")
15675 (match_operand:DF 3 "div_operator" "")
15676 (const_string "fdiv")
15678 (const_string "fop")))
15679 (set_attr "mode" "DF")])
15681 ;; ??? Add SSE splitters for these!
15682 (define_insn "*fop_df_2<mode>_i387"
15683 [(set (match_operand:DF 0 "register_operand" "=f,f")
15684 (match_operator:DF 3 "binary_fp_operator"
15685 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15686 (match_operand:DF 2 "register_operand" "0,0")]))]
15687 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15688 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15689 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15690 [(set (attr "type")
15691 (cond [(match_operand:DF 3 "mult_operator" "")
15692 (const_string "fmul")
15693 (match_operand:DF 3 "div_operator" "")
15694 (const_string "fdiv")
15696 (const_string "fop")))
15697 (set_attr "fp_int_src" "true")
15698 (set_attr "mode" "<MODE>")])
15700 (define_insn "*fop_df_3<mode>_i387"
15701 [(set (match_operand:DF 0 "register_operand" "=f,f")
15702 (match_operator:DF 3 "binary_fp_operator"
15703 [(match_operand:DF 1 "register_operand" "0,0")
15704 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15705 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15706 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15707 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15708 [(set (attr "type")
15709 (cond [(match_operand:DF 3 "mult_operator" "")
15710 (const_string "fmul")
15711 (match_operand:DF 3 "div_operator" "")
15712 (const_string "fdiv")
15714 (const_string "fop")))
15715 (set_attr "fp_int_src" "true")
15716 (set_attr "mode" "<MODE>")])
15718 (define_insn "*fop_df_4_i387"
15719 [(set (match_operand:DF 0 "register_operand" "=f,f")
15720 (match_operator:DF 3 "binary_fp_operator"
15721 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15722 (match_operand:DF 2 "register_operand" "0,f")]))]
15723 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15724 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15725 "* return output_387_binary_op (insn, operands);"
15726 [(set (attr "type")
15727 (cond [(match_operand:DF 3 "mult_operator" "")
15728 (const_string "fmul")
15729 (match_operand:DF 3 "div_operator" "")
15730 (const_string "fdiv")
15732 (const_string "fop")))
15733 (set_attr "mode" "SF")])
15735 (define_insn "*fop_df_5_i387"
15736 [(set (match_operand:DF 0 "register_operand" "=f,f")
15737 (match_operator:DF 3 "binary_fp_operator"
15738 [(match_operand:DF 1 "register_operand" "0,f")
15740 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15741 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15742 "* return output_387_binary_op (insn, operands);"
15743 [(set (attr "type")
15744 (cond [(match_operand:DF 3 "mult_operator" "")
15745 (const_string "fmul")
15746 (match_operand:DF 3 "div_operator" "")
15747 (const_string "fdiv")
15749 (const_string "fop")))
15750 (set_attr "mode" "SF")])
15752 (define_insn "*fop_df_6_i387"
15753 [(set (match_operand:DF 0 "register_operand" "=f,f")
15754 (match_operator:DF 3 "binary_fp_operator"
15756 (match_operand:SF 1 "register_operand" "0,f"))
15758 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15759 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15760 "* return output_387_binary_op (insn, operands);"
15761 [(set (attr "type")
15762 (cond [(match_operand:DF 3 "mult_operator" "")
15763 (const_string "fmul")
15764 (match_operand:DF 3 "div_operator" "")
15765 (const_string "fdiv")
15767 (const_string "fop")))
15768 (set_attr "mode" "SF")])
15770 (define_insn "*fop_xf_comm_i387"
15771 [(set (match_operand:XF 0 "register_operand" "=f")
15772 (match_operator:XF 3 "binary_fp_operator"
15773 [(match_operand:XF 1 "register_operand" "%0")
15774 (match_operand:XF 2 "register_operand" "f")]))]
15776 && COMMUTATIVE_ARITH_P (operands[3])"
15777 "* return output_387_binary_op (insn, operands);"
15778 [(set (attr "type")
15779 (if_then_else (match_operand:XF 3 "mult_operator" "")
15780 (const_string "fmul")
15781 (const_string "fop")))
15782 (set_attr "mode" "XF")])
15784 (define_insn "*fop_xf_1_i387"
15785 [(set (match_operand:XF 0 "register_operand" "=f,f")
15786 (match_operator:XF 3 "binary_fp_operator"
15787 [(match_operand:XF 1 "register_operand" "0,f")
15788 (match_operand:XF 2 "register_operand" "f,0")]))]
15790 && !COMMUTATIVE_ARITH_P (operands[3])"
15791 "* return output_387_binary_op (insn, operands);"
15792 [(set (attr "type")
15793 (cond [(match_operand:XF 3 "mult_operator" "")
15794 (const_string "fmul")
15795 (match_operand:XF 3 "div_operator" "")
15796 (const_string "fdiv")
15798 (const_string "fop")))
15799 (set_attr "mode" "XF")])
15801 (define_insn "*fop_xf_2<mode>_i387"
15802 [(set (match_operand:XF 0 "register_operand" "=f,f")
15803 (match_operator:XF 3 "binary_fp_operator"
15804 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15805 (match_operand:XF 2 "register_operand" "0,0")]))]
15806 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15807 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15808 [(set (attr "type")
15809 (cond [(match_operand:XF 3 "mult_operator" "")
15810 (const_string "fmul")
15811 (match_operand:XF 3 "div_operator" "")
15812 (const_string "fdiv")
15814 (const_string "fop")))
15815 (set_attr "fp_int_src" "true")
15816 (set_attr "mode" "<MODE>")])
15818 (define_insn "*fop_xf_3<mode>_i387"
15819 [(set (match_operand:XF 0 "register_operand" "=f,f")
15820 (match_operator:XF 3 "binary_fp_operator"
15821 [(match_operand:XF 1 "register_operand" "0,0")
15822 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15823 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15824 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15825 [(set (attr "type")
15826 (cond [(match_operand:XF 3 "mult_operator" "")
15827 (const_string "fmul")
15828 (match_operand:XF 3 "div_operator" "")
15829 (const_string "fdiv")
15831 (const_string "fop")))
15832 (set_attr "fp_int_src" "true")
15833 (set_attr "mode" "<MODE>")])
15835 (define_insn "*fop_xf_4_i387"
15836 [(set (match_operand:XF 0 "register_operand" "=f,f")
15837 (match_operator:XF 3 "binary_fp_operator"
15839 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15840 (match_operand:XF 2 "register_operand" "0,f")]))]
15842 "* return output_387_binary_op (insn, operands);"
15843 [(set (attr "type")
15844 (cond [(match_operand:XF 3 "mult_operator" "")
15845 (const_string "fmul")
15846 (match_operand:XF 3 "div_operator" "")
15847 (const_string "fdiv")
15849 (const_string "fop")))
15850 (set_attr "mode" "SF")])
15852 (define_insn "*fop_xf_5_i387"
15853 [(set (match_operand:XF 0 "register_operand" "=f,f")
15854 (match_operator:XF 3 "binary_fp_operator"
15855 [(match_operand:XF 1 "register_operand" "0,f")
15857 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15859 "* return output_387_binary_op (insn, operands);"
15860 [(set (attr "type")
15861 (cond [(match_operand:XF 3 "mult_operator" "")
15862 (const_string "fmul")
15863 (match_operand:XF 3 "div_operator" "")
15864 (const_string "fdiv")
15866 (const_string "fop")))
15867 (set_attr "mode" "SF")])
15869 (define_insn "*fop_xf_6_i387"
15870 [(set (match_operand:XF 0 "register_operand" "=f,f")
15871 (match_operator:XF 3 "binary_fp_operator"
15873 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15875 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15877 "* return output_387_binary_op (insn, operands);"
15878 [(set (attr "type")
15879 (cond [(match_operand:XF 3 "mult_operator" "")
15880 (const_string "fmul")
15881 (match_operand:XF 3 "div_operator" "")
15882 (const_string "fdiv")
15884 (const_string "fop")))
15885 (set_attr "mode" "SF")])
15888 [(set (match_operand 0 "register_operand" "")
15889 (match_operator 3 "binary_fp_operator"
15890 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15891 (match_operand 2 "register_operand" "")]))]
15893 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
15896 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15897 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15898 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15899 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15900 GET_MODE (operands[3]),
15903 ix86_free_from_memory (GET_MODE (operands[1]));
15908 [(set (match_operand 0 "register_operand" "")
15909 (match_operator 3 "binary_fp_operator"
15910 [(match_operand 1 "register_operand" "")
15911 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15913 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
15916 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15917 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15918 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15919 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15920 GET_MODE (operands[3]),
15923 ix86_free_from_memory (GET_MODE (operands[2]));
15927 ;; FPU special functions.
15929 ;; This pattern implements a no-op XFmode truncation for
15930 ;; all fancy i386 XFmode math functions.
15932 (define_insn "truncxf<mode>2_i387_noop_unspec"
15933 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15934 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15935 UNSPEC_TRUNC_NOOP))]
15936 "TARGET_USE_FANCY_MATH_387"
15937 "* return output_387_reg_move (insn, operands);"
15938 [(set_attr "type" "fmov")
15939 (set_attr "mode" "<MODE>")])
15941 (define_insn "sqrtxf2"
15942 [(set (match_operand:XF 0 "register_operand" "=f")
15943 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15944 "TARGET_USE_FANCY_MATH_387"
15946 [(set_attr "type" "fpspc")
15947 (set_attr "mode" "XF")
15948 (set_attr "athlon_decode" "direct")
15949 (set_attr "amdfam10_decode" "direct")])
15951 (define_insn "sqrt_extend<mode>xf2_i387"
15952 [(set (match_operand:XF 0 "register_operand" "=f")
15955 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15956 "TARGET_USE_FANCY_MATH_387"
15958 [(set_attr "type" "fpspc")
15959 (set_attr "mode" "XF")
15960 (set_attr "athlon_decode" "direct")
15961 (set_attr "amdfam10_decode" "direct")])
15963 (define_insn "*sqrt<mode>2_sse"
15964 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15966 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15967 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15968 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15969 [(set_attr "type" "sse")
15970 (set_attr "mode" "<MODE>")
15971 (set_attr "athlon_decode" "*")
15972 (set_attr "amdfam10_decode" "*")])
15974 (define_expand "sqrt<mode>2"
15975 [(set (match_operand:X87MODEF12 0 "register_operand" "")
15977 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15978 "TARGET_USE_FANCY_MATH_387
15979 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15981 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15983 rtx op0 = gen_reg_rtx (XFmode);
15984 rtx op1 = force_reg (<MODE>mode, operands[1]);
15986 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15987 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15992 (define_insn "fpremxf4_i387"
15993 [(set (match_operand:XF 0 "register_operand" "=f")
15994 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15995 (match_operand:XF 3 "register_operand" "1")]
15997 (set (match_operand:XF 1 "register_operand" "=u")
15998 (unspec:XF [(match_dup 2) (match_dup 3)]
16000 (set (reg:CCFP FPSR_REG)
16001 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16003 "TARGET_USE_FANCY_MATH_387"
16005 [(set_attr "type" "fpspc")
16006 (set_attr "mode" "XF")])
16008 (define_expand "fmodxf3"
16009 [(use (match_operand:XF 0 "register_operand" ""))
16010 (use (match_operand:XF 1 "register_operand" ""))
16011 (use (match_operand:XF 2 "register_operand" ""))]
16012 "TARGET_USE_FANCY_MATH_387"
16014 rtx label = gen_label_rtx ();
16016 emit_label (label);
16018 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16019 operands[1], operands[2]));
16020 ix86_emit_fp_unordered_jump (label);
16021 LABEL_NUSES (label) = 1;
16023 emit_move_insn (operands[0], operands[1]);
16027 (define_expand "fmod<mode>3"
16028 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16029 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16030 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16031 "TARGET_USE_FANCY_MATH_387"
16033 rtx label = gen_label_rtx ();
16035 rtx op1 = gen_reg_rtx (XFmode);
16036 rtx op2 = gen_reg_rtx (XFmode);
16038 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16039 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16041 emit_label (label);
16042 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16043 ix86_emit_fp_unordered_jump (label);
16044 LABEL_NUSES (label) = 1;
16046 /* Truncate the result properly for strict SSE math. */
16047 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16048 && !TARGET_MIX_SSE_I387)
16049 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16051 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16056 (define_insn "fprem1xf4_i387"
16057 [(set (match_operand:XF 0 "register_operand" "=f")
16058 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16059 (match_operand:XF 3 "register_operand" "1")]
16061 (set (match_operand:XF 1 "register_operand" "=u")
16062 (unspec:XF [(match_dup 2) (match_dup 3)]
16064 (set (reg:CCFP FPSR_REG)
16065 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16067 "TARGET_USE_FANCY_MATH_387"
16069 [(set_attr "type" "fpspc")
16070 (set_attr "mode" "XF")])
16072 (define_expand "remainderxf3"
16073 [(use (match_operand:XF 0 "register_operand" ""))
16074 (use (match_operand:XF 1 "register_operand" ""))
16075 (use (match_operand:XF 2 "register_operand" ""))]
16076 "TARGET_USE_FANCY_MATH_387"
16078 rtx label = gen_label_rtx ();
16080 emit_label (label);
16082 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16083 operands[1], operands[2]));
16084 ix86_emit_fp_unordered_jump (label);
16085 LABEL_NUSES (label) = 1;
16087 emit_move_insn (operands[0], operands[1]);
16091 (define_expand "remainder<mode>3"
16092 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16093 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16094 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16095 "TARGET_USE_FANCY_MATH_387"
16097 rtx label = gen_label_rtx ();
16099 rtx op1 = gen_reg_rtx (XFmode);
16100 rtx op2 = gen_reg_rtx (XFmode);
16102 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16103 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16105 emit_label (label);
16107 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16108 ix86_emit_fp_unordered_jump (label);
16109 LABEL_NUSES (label) = 1;
16111 /* Truncate the result properly for strict SSE math. */
16112 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16113 && !TARGET_MIX_SSE_I387)
16114 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16116 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16121 (define_insn "*sinxf2_i387"
16122 [(set (match_operand:XF 0 "register_operand" "=f")
16123 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16124 "TARGET_USE_FANCY_MATH_387
16125 && flag_unsafe_math_optimizations"
16127 [(set_attr "type" "fpspc")
16128 (set_attr "mode" "XF")])
16130 (define_insn "*sin_extend<mode>xf2_i387"
16131 [(set (match_operand:XF 0 "register_operand" "=f")
16132 (unspec:XF [(float_extend:XF
16133 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16135 "TARGET_USE_FANCY_MATH_387
16136 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16137 || TARGET_MIX_SSE_I387)
16138 && flag_unsafe_math_optimizations"
16140 [(set_attr "type" "fpspc")
16141 (set_attr "mode" "XF")])
16143 (define_insn "*cosxf2_i387"
16144 [(set (match_operand:XF 0 "register_operand" "=f")
16145 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16146 "TARGET_USE_FANCY_MATH_387
16147 && flag_unsafe_math_optimizations"
16149 [(set_attr "type" "fpspc")
16150 (set_attr "mode" "XF")])
16152 (define_insn "*cos_extend<mode>xf2_i387"
16153 [(set (match_operand:XF 0 "register_operand" "=f")
16154 (unspec:XF [(float_extend:XF
16155 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16157 "TARGET_USE_FANCY_MATH_387
16158 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16159 || TARGET_MIX_SSE_I387)
16160 && flag_unsafe_math_optimizations"
16162 [(set_attr "type" "fpspc")
16163 (set_attr "mode" "XF")])
16165 ;; When sincos pattern is defined, sin and cos builtin functions will be
16166 ;; expanded to sincos pattern with one of its outputs left unused.
16167 ;; CSE pass will figure out if two sincos patterns can be combined,
16168 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16169 ;; depending on the unused output.
16171 (define_insn "sincosxf3"
16172 [(set (match_operand:XF 0 "register_operand" "=f")
16173 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16174 UNSPEC_SINCOS_COS))
16175 (set (match_operand:XF 1 "register_operand" "=u")
16176 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16177 "TARGET_USE_FANCY_MATH_387
16178 && flag_unsafe_math_optimizations"
16180 [(set_attr "type" "fpspc")
16181 (set_attr "mode" "XF")])
16184 [(set (match_operand:XF 0 "register_operand" "")
16185 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16186 UNSPEC_SINCOS_COS))
16187 (set (match_operand:XF 1 "register_operand" "")
16188 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16189 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16190 && !reload_completed && !reload_in_progress"
16191 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16195 [(set (match_operand:XF 0 "register_operand" "")
16196 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16197 UNSPEC_SINCOS_COS))
16198 (set (match_operand:XF 1 "register_operand" "")
16199 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16200 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16201 && !reload_completed && !reload_in_progress"
16202 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16205 (define_insn "sincos_extend<mode>xf3_i387"
16206 [(set (match_operand:XF 0 "register_operand" "=f")
16207 (unspec:XF [(float_extend:XF
16208 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16209 UNSPEC_SINCOS_COS))
16210 (set (match_operand:XF 1 "register_operand" "=u")
16211 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16212 "TARGET_USE_FANCY_MATH_387
16213 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16214 || TARGET_MIX_SSE_I387)
16215 && flag_unsafe_math_optimizations"
16217 [(set_attr "type" "fpspc")
16218 (set_attr "mode" "XF")])
16221 [(set (match_operand:XF 0 "register_operand" "")
16222 (unspec:XF [(float_extend:XF
16223 (match_operand:X87MODEF12 2 "register_operand" ""))]
16224 UNSPEC_SINCOS_COS))
16225 (set (match_operand:XF 1 "register_operand" "")
16226 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16227 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16228 && !reload_completed && !reload_in_progress"
16229 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16233 [(set (match_operand:XF 0 "register_operand" "")
16234 (unspec:XF [(float_extend:XF
16235 (match_operand:X87MODEF12 2 "register_operand" ""))]
16236 UNSPEC_SINCOS_COS))
16237 (set (match_operand:XF 1 "register_operand" "")
16238 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16239 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16240 && !reload_completed && !reload_in_progress"
16241 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16244 (define_expand "sincos<mode>3"
16245 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16246 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16247 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16248 "TARGET_USE_FANCY_MATH_387
16249 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16250 || TARGET_MIX_SSE_I387)
16251 && flag_unsafe_math_optimizations"
16253 rtx op0 = gen_reg_rtx (XFmode);
16254 rtx op1 = gen_reg_rtx (XFmode);
16256 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16257 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16258 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16262 (define_insn "fptanxf4_i387"
16263 [(set (match_operand:XF 0 "register_operand" "=f")
16264 (match_operand:XF 3 "const_double_operand" "F"))
16265 (set (match_operand:XF 1 "register_operand" "=u")
16266 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16268 "TARGET_USE_FANCY_MATH_387
16269 && flag_unsafe_math_optimizations
16270 && standard_80387_constant_p (operands[3]) == 2"
16272 [(set_attr "type" "fpspc")
16273 (set_attr "mode" "XF")])
16275 (define_insn "fptan_extend<mode>xf4_i387"
16276 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16277 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16278 (set (match_operand:XF 1 "register_operand" "=u")
16279 (unspec:XF [(float_extend:XF
16280 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16282 "TARGET_USE_FANCY_MATH_387
16283 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16284 || TARGET_MIX_SSE_I387)
16285 && flag_unsafe_math_optimizations
16286 && standard_80387_constant_p (operands[3]) == 2"
16288 [(set_attr "type" "fpspc")
16289 (set_attr "mode" "XF")])
16291 (define_expand "tanxf2"
16292 [(use (match_operand:XF 0 "register_operand" ""))
16293 (use (match_operand:XF 1 "register_operand" ""))]
16294 "TARGET_USE_FANCY_MATH_387
16295 && flag_unsafe_math_optimizations"
16297 rtx one = gen_reg_rtx (XFmode);
16298 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16300 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16304 (define_expand "tan<mode>2"
16305 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16306 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16307 "TARGET_USE_FANCY_MATH_387
16308 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16309 || TARGET_MIX_SSE_I387)
16310 && flag_unsafe_math_optimizations"
16312 rtx op0 = gen_reg_rtx (XFmode);
16314 rtx one = gen_reg_rtx (<MODE>mode);
16315 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16317 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16318 operands[1], op2));
16319 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16323 (define_insn "*fpatanxf3_i387"
16324 [(set (match_operand:XF 0 "register_operand" "=f")
16325 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16326 (match_operand:XF 2 "register_operand" "u")]
16328 (clobber (match_scratch:XF 3 "=2"))]
16329 "TARGET_USE_FANCY_MATH_387
16330 && flag_unsafe_math_optimizations"
16332 [(set_attr "type" "fpspc")
16333 (set_attr "mode" "XF")])
16335 (define_insn "fpatan_extend<mode>xf3_i387"
16336 [(set (match_operand:XF 0 "register_operand" "=f")
16337 (unspec:XF [(float_extend:XF
16338 (match_operand:X87MODEF12 1 "register_operand" "0"))
16340 (match_operand:X87MODEF12 2 "register_operand" "u"))]
16342 (clobber (match_scratch:XF 3 "=2"))]
16343 "TARGET_USE_FANCY_MATH_387
16344 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16345 || TARGET_MIX_SSE_I387)
16346 && flag_unsafe_math_optimizations"
16348 [(set_attr "type" "fpspc")
16349 (set_attr "mode" "XF")])
16351 (define_expand "atan2xf3"
16352 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16353 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16354 (match_operand:XF 1 "register_operand" "")]
16356 (clobber (match_scratch:XF 3 ""))])]
16357 "TARGET_USE_FANCY_MATH_387
16358 && flag_unsafe_math_optimizations"
16361 (define_expand "atan2<mode>3"
16362 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16363 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16364 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16365 "TARGET_USE_FANCY_MATH_387
16366 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16367 || TARGET_MIX_SSE_I387)
16368 && flag_unsafe_math_optimizations"
16370 rtx op0 = gen_reg_rtx (XFmode);
16372 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16373 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16377 (define_expand "atanxf2"
16378 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16379 (unspec:XF [(match_dup 2)
16380 (match_operand:XF 1 "register_operand" "")]
16382 (clobber (match_scratch:XF 3 ""))])]
16383 "TARGET_USE_FANCY_MATH_387
16384 && flag_unsafe_math_optimizations"
16386 operands[2] = gen_reg_rtx (XFmode);
16387 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16390 (define_expand "atan<mode>2"
16391 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16392 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16393 "TARGET_USE_FANCY_MATH_387
16394 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16395 || TARGET_MIX_SSE_I387)
16396 && flag_unsafe_math_optimizations"
16398 rtx op0 = gen_reg_rtx (XFmode);
16400 rtx op2 = gen_reg_rtx (<MODE>mode);
16401 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16403 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16404 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16408 (define_expand "asinxf2"
16409 [(set (match_dup 2)
16410 (mult:XF (match_operand:XF 1 "register_operand" "")
16412 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16413 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16414 (parallel [(set (match_operand:XF 0 "register_operand" "")
16415 (unspec:XF [(match_dup 5) (match_dup 1)]
16417 (clobber (match_scratch:XF 6 ""))])]
16418 "TARGET_USE_FANCY_MATH_387
16419 && flag_unsafe_math_optimizations && !optimize_size"
16423 for (i = 2; i < 6; i++)
16424 operands[i] = gen_reg_rtx (XFmode);
16426 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16429 (define_expand "asin<mode>2"
16430 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16431 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16432 "TARGET_USE_FANCY_MATH_387
16433 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16434 || TARGET_MIX_SSE_I387)
16435 && flag_unsafe_math_optimizations && !optimize_size"
16437 rtx op0 = gen_reg_rtx (XFmode);
16438 rtx op1 = gen_reg_rtx (XFmode);
16440 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16441 emit_insn (gen_asinxf2 (op0, op1));
16442 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16446 (define_expand "acosxf2"
16447 [(set (match_dup 2)
16448 (mult:XF (match_operand:XF 1 "register_operand" "")
16450 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16451 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16452 (parallel [(set (match_operand:XF 0 "register_operand" "")
16453 (unspec:XF [(match_dup 1) (match_dup 5)]
16455 (clobber (match_scratch:XF 6 ""))])]
16456 "TARGET_USE_FANCY_MATH_387
16457 && flag_unsafe_math_optimizations && !optimize_size"
16461 for (i = 2; i < 6; i++)
16462 operands[i] = gen_reg_rtx (XFmode);
16464 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16467 (define_expand "acos<mode>2"
16468 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16469 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16470 "TARGET_USE_FANCY_MATH_387
16471 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16472 || TARGET_MIX_SSE_I387)
16473 && flag_unsafe_math_optimizations && !optimize_size"
16475 rtx op0 = gen_reg_rtx (XFmode);
16476 rtx op1 = gen_reg_rtx (XFmode);
16478 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16479 emit_insn (gen_acosxf2 (op0, op1));
16480 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16484 (define_insn "fyl2xxf3_i387"
16485 [(set (match_operand:XF 0 "register_operand" "=f")
16486 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16487 (match_operand:XF 2 "register_operand" "u")]
16489 (clobber (match_scratch:XF 3 "=2"))]
16490 "TARGET_USE_FANCY_MATH_387
16491 && flag_unsafe_math_optimizations"
16493 [(set_attr "type" "fpspc")
16494 (set_attr "mode" "XF")])
16496 (define_insn "fyl2x_extend<mode>xf3_i387"
16497 [(set (match_operand:XF 0 "register_operand" "=f")
16498 (unspec:XF [(float_extend:XF
16499 (match_operand:X87MODEF12 1 "register_operand" "0"))
16500 (match_operand:XF 2 "register_operand" "u")]
16502 (clobber (match_scratch:XF 3 "=2"))]
16503 "TARGET_USE_FANCY_MATH_387
16504 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16505 || TARGET_MIX_SSE_I387)
16506 && flag_unsafe_math_optimizations"
16508 [(set_attr "type" "fpspc")
16509 (set_attr "mode" "XF")])
16511 (define_expand "logxf2"
16512 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16513 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16514 (match_dup 2)] UNSPEC_FYL2X))
16515 (clobber (match_scratch:XF 3 ""))])]
16516 "TARGET_USE_FANCY_MATH_387
16517 && flag_unsafe_math_optimizations"
16519 operands[2] = gen_reg_rtx (XFmode);
16520 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16523 (define_expand "log<mode>2"
16524 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16525 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16526 "TARGET_USE_FANCY_MATH_387
16527 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16528 || TARGET_MIX_SSE_I387)
16529 && flag_unsafe_math_optimizations"
16531 rtx op0 = gen_reg_rtx (XFmode);
16533 rtx op2 = gen_reg_rtx (XFmode);
16534 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16536 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16537 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16541 (define_expand "log10xf2"
16542 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16543 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16544 (match_dup 2)] UNSPEC_FYL2X))
16545 (clobber (match_scratch:XF 3 ""))])]
16546 "TARGET_USE_FANCY_MATH_387
16547 && flag_unsafe_math_optimizations"
16549 operands[2] = gen_reg_rtx (XFmode);
16550 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16553 (define_expand "log10<mode>2"
16554 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16555 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16556 "TARGET_USE_FANCY_MATH_387
16557 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16558 || TARGET_MIX_SSE_I387)
16559 && flag_unsafe_math_optimizations"
16561 rtx op0 = gen_reg_rtx (XFmode);
16563 rtx op2 = gen_reg_rtx (XFmode);
16564 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16566 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16567 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16571 (define_expand "log2xf2"
16572 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16573 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16574 (match_dup 2)] UNSPEC_FYL2X))
16575 (clobber (match_scratch:XF 3 ""))])]
16576 "TARGET_USE_FANCY_MATH_387
16577 && flag_unsafe_math_optimizations"
16579 operands[2] = gen_reg_rtx (XFmode);
16580 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16583 (define_expand "log2<mode>2"
16584 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16585 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16586 "TARGET_USE_FANCY_MATH_387
16587 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16588 || TARGET_MIX_SSE_I387)
16589 && flag_unsafe_math_optimizations"
16591 rtx op0 = gen_reg_rtx (XFmode);
16593 rtx op2 = gen_reg_rtx (XFmode);
16594 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16596 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16597 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16601 (define_insn "fyl2xp1xf3_i387"
16602 [(set (match_operand:XF 0 "register_operand" "=f")
16603 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16604 (match_operand:XF 2 "register_operand" "u")]
16606 (clobber (match_scratch:XF 3 "=2"))]
16607 "TARGET_USE_FANCY_MATH_387
16608 && flag_unsafe_math_optimizations"
16610 [(set_attr "type" "fpspc")
16611 (set_attr "mode" "XF")])
16613 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16614 [(set (match_operand:XF 0 "register_operand" "=f")
16615 (unspec:XF [(float_extend:XF
16616 (match_operand:X87MODEF12 1 "register_operand" "0"))
16617 (match_operand:XF 2 "register_operand" "u")]
16619 (clobber (match_scratch:XF 3 "=2"))]
16620 "TARGET_USE_FANCY_MATH_387
16621 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16622 || TARGET_MIX_SSE_I387)
16623 && flag_unsafe_math_optimizations"
16625 [(set_attr "type" "fpspc")
16626 (set_attr "mode" "XF")])
16628 (define_expand "log1pxf2"
16629 [(use (match_operand:XF 0 "register_operand" ""))
16630 (use (match_operand:XF 1 "register_operand" ""))]
16631 "TARGET_USE_FANCY_MATH_387
16632 && flag_unsafe_math_optimizations && !optimize_size"
16634 ix86_emit_i387_log1p (operands[0], operands[1]);
16638 (define_expand "log1p<mode>2"
16639 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16640 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16641 "TARGET_USE_FANCY_MATH_387
16642 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16643 || TARGET_MIX_SSE_I387)
16644 && flag_unsafe_math_optimizations && !optimize_size"
16646 rtx op0 = gen_reg_rtx (XFmode);
16648 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16650 ix86_emit_i387_log1p (op0, operands[1]);
16651 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16655 (define_insn "fxtractxf3_i387"
16656 [(set (match_operand:XF 0 "register_operand" "=f")
16657 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16658 UNSPEC_XTRACT_FRACT))
16659 (set (match_operand:XF 1 "register_operand" "=u")
16660 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16661 "TARGET_USE_FANCY_MATH_387
16662 && flag_unsafe_math_optimizations"
16664 [(set_attr "type" "fpspc")
16665 (set_attr "mode" "XF")])
16667 (define_insn "fxtract_extend<mode>xf3_i387"
16668 [(set (match_operand:XF 0 "register_operand" "=f")
16669 (unspec:XF [(float_extend:XF
16670 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16671 UNSPEC_XTRACT_FRACT))
16672 (set (match_operand:XF 1 "register_operand" "=u")
16673 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16674 "TARGET_USE_FANCY_MATH_387
16675 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16676 || TARGET_MIX_SSE_I387)
16677 && flag_unsafe_math_optimizations"
16679 [(set_attr "type" "fpspc")
16680 (set_attr "mode" "XF")])
16682 (define_expand "logbxf2"
16683 [(parallel [(set (match_dup 2)
16684 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16685 UNSPEC_XTRACT_FRACT))
16686 (set (match_operand:XF 0 "register_operand" "")
16687 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16688 "TARGET_USE_FANCY_MATH_387
16689 && flag_unsafe_math_optimizations"
16691 operands[2] = gen_reg_rtx (XFmode);
16694 (define_expand "logb<mode>2"
16695 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16696 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16697 "TARGET_USE_FANCY_MATH_387
16698 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16699 || TARGET_MIX_SSE_I387)
16700 && flag_unsafe_math_optimizations"
16702 rtx op0 = gen_reg_rtx (XFmode);
16703 rtx op1 = gen_reg_rtx (XFmode);
16705 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16706 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16710 (define_expand "ilogbxf2"
16711 [(use (match_operand:SI 0 "register_operand" ""))
16712 (use (match_operand:XF 1 "register_operand" ""))]
16713 "TARGET_USE_FANCY_MATH_387
16714 && flag_unsafe_math_optimizations && !optimize_size"
16716 rtx op0 = gen_reg_rtx (XFmode);
16717 rtx op1 = gen_reg_rtx (XFmode);
16719 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16720 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16724 (define_expand "ilogb<mode>2"
16725 [(use (match_operand:SI 0 "register_operand" ""))
16726 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16727 "TARGET_USE_FANCY_MATH_387
16728 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16729 || TARGET_MIX_SSE_I387)
16730 && flag_unsafe_math_optimizations && !optimize_size"
16732 rtx op0 = gen_reg_rtx (XFmode);
16733 rtx op1 = gen_reg_rtx (XFmode);
16735 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16736 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16740 (define_insn "*f2xm1xf2_i387"
16741 [(set (match_operand:XF 0 "register_operand" "=f")
16742 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16744 "TARGET_USE_FANCY_MATH_387
16745 && flag_unsafe_math_optimizations"
16747 [(set_attr "type" "fpspc")
16748 (set_attr "mode" "XF")])
16750 (define_insn "*fscalexf4_i387"
16751 [(set (match_operand:XF 0 "register_operand" "=f")
16752 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16753 (match_operand:XF 3 "register_operand" "1")]
16754 UNSPEC_FSCALE_FRACT))
16755 (set (match_operand:XF 1 "register_operand" "=u")
16756 (unspec:XF [(match_dup 2) (match_dup 3)]
16757 UNSPEC_FSCALE_EXP))]
16758 "TARGET_USE_FANCY_MATH_387
16759 && flag_unsafe_math_optimizations"
16761 [(set_attr "type" "fpspc")
16762 (set_attr "mode" "XF")])
16764 (define_expand "expNcorexf3"
16765 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16766 (match_operand:XF 2 "register_operand" "")))
16767 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16768 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16769 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16770 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16771 (parallel [(set (match_operand:XF 0 "register_operand" "")
16772 (unspec:XF [(match_dup 8) (match_dup 4)]
16773 UNSPEC_FSCALE_FRACT))
16775 (unspec:XF [(match_dup 8) (match_dup 4)]
16776 UNSPEC_FSCALE_EXP))])]
16777 "TARGET_USE_FANCY_MATH_387
16778 && flag_unsafe_math_optimizations && !optimize_size"
16782 for (i = 3; i < 10; i++)
16783 operands[i] = gen_reg_rtx (XFmode);
16785 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16788 (define_expand "expxf2"
16789 [(use (match_operand:XF 0 "register_operand" ""))
16790 (use (match_operand:XF 1 "register_operand" ""))]
16791 "TARGET_USE_FANCY_MATH_387
16792 && flag_unsafe_math_optimizations && !optimize_size"
16794 rtx op2 = gen_reg_rtx (XFmode);
16795 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16797 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16801 (define_expand "exp<mode>2"
16802 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16803 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16804 "TARGET_USE_FANCY_MATH_387
16805 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16806 || TARGET_MIX_SSE_I387)
16807 && flag_unsafe_math_optimizations && !optimize_size"
16809 rtx op0 = gen_reg_rtx (XFmode);
16810 rtx op1 = gen_reg_rtx (XFmode);
16812 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16813 emit_insn (gen_expxf2 (op0, op1));
16814 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16818 (define_expand "exp10xf2"
16819 [(use (match_operand:XF 0 "register_operand" ""))
16820 (use (match_operand:XF 1 "register_operand" ""))]
16821 "TARGET_USE_FANCY_MATH_387
16822 && flag_unsafe_math_optimizations && !optimize_size"
16824 rtx op2 = gen_reg_rtx (XFmode);
16825 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16827 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16831 (define_expand "exp10<mode>2"
16832 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16833 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16834 "TARGET_USE_FANCY_MATH_387
16835 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16836 || TARGET_MIX_SSE_I387)
16837 && flag_unsafe_math_optimizations && !optimize_size"
16839 rtx op0 = gen_reg_rtx (XFmode);
16840 rtx op1 = gen_reg_rtx (XFmode);
16842 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16843 emit_insn (gen_exp10xf2 (op0, op1));
16844 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16848 (define_expand "exp2xf2"
16849 [(use (match_operand:XF 0 "register_operand" ""))
16850 (use (match_operand:XF 1 "register_operand" ""))]
16851 "TARGET_USE_FANCY_MATH_387
16852 && flag_unsafe_math_optimizations && !optimize_size"
16854 rtx op2 = gen_reg_rtx (XFmode);
16855 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16857 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16861 (define_expand "exp2<mode>2"
16862 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16863 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16864 "TARGET_USE_FANCY_MATH_387
16865 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16866 || TARGET_MIX_SSE_I387)
16867 && flag_unsafe_math_optimizations && !optimize_size"
16869 rtx op0 = gen_reg_rtx (XFmode);
16870 rtx op1 = gen_reg_rtx (XFmode);
16872 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16873 emit_insn (gen_exp2xf2 (op0, op1));
16874 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16878 (define_expand "expm1xf2"
16879 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16881 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16882 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16883 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16884 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16885 (parallel [(set (match_dup 7)
16886 (unspec:XF [(match_dup 6) (match_dup 4)]
16887 UNSPEC_FSCALE_FRACT))
16889 (unspec:XF [(match_dup 6) (match_dup 4)]
16890 UNSPEC_FSCALE_EXP))])
16891 (parallel [(set (match_dup 10)
16892 (unspec:XF [(match_dup 9) (match_dup 8)]
16893 UNSPEC_FSCALE_FRACT))
16894 (set (match_dup 11)
16895 (unspec:XF [(match_dup 9) (match_dup 8)]
16896 UNSPEC_FSCALE_EXP))])
16897 (set (match_dup 12) (minus:XF (match_dup 10)
16898 (float_extend:XF (match_dup 13))))
16899 (set (match_operand:XF 0 "register_operand" "")
16900 (plus:XF (match_dup 12) (match_dup 7)))]
16901 "TARGET_USE_FANCY_MATH_387
16902 && flag_unsafe_math_optimizations && !optimize_size"
16906 for (i = 2; i < 13; i++)
16907 operands[i] = gen_reg_rtx (XFmode);
16910 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16912 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16915 (define_expand "expm1<mode>2"
16916 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16917 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16918 "TARGET_USE_FANCY_MATH_387
16919 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16920 || TARGET_MIX_SSE_I387)
16921 && flag_unsafe_math_optimizations && !optimize_size"
16923 rtx op0 = gen_reg_rtx (XFmode);
16924 rtx op1 = gen_reg_rtx (XFmode);
16926 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16927 emit_insn (gen_expm1xf2 (op0, op1));
16928 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16932 (define_expand "ldexpxf3"
16933 [(set (match_dup 3)
16934 (float:XF (match_operand:SI 2 "register_operand" "")))
16935 (parallel [(set (match_operand:XF 0 " register_operand" "")
16936 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16938 UNSPEC_FSCALE_FRACT))
16940 (unspec:XF [(match_dup 1) (match_dup 3)]
16941 UNSPEC_FSCALE_EXP))])]
16942 "TARGET_USE_FANCY_MATH_387
16943 && flag_unsafe_math_optimizations && !optimize_size"
16945 operands[3] = gen_reg_rtx (XFmode);
16946 operands[4] = gen_reg_rtx (XFmode);
16949 (define_expand "ldexp<mode>3"
16950 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16951 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16952 (use (match_operand:SI 2 "register_operand" ""))]
16953 "TARGET_USE_FANCY_MATH_387
16954 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16955 || TARGET_MIX_SSE_I387)
16956 && flag_unsafe_math_optimizations && !optimize_size"
16958 rtx op0 = gen_reg_rtx (XFmode);
16959 rtx op1 = gen_reg_rtx (XFmode);
16961 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16962 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16963 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16967 (define_expand "scalbxf3"
16968 [(parallel [(set (match_operand:XF 0 " register_operand" "")
16969 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16970 (match_operand:XF 2 "register_operand" "")]
16971 UNSPEC_FSCALE_FRACT))
16973 (unspec:XF [(match_dup 1) (match_dup 2)]
16974 UNSPEC_FSCALE_EXP))])]
16975 "TARGET_USE_FANCY_MATH_387
16976 && flag_unsafe_math_optimizations && !optimize_size"
16978 operands[3] = gen_reg_rtx (XFmode);
16981 (define_expand "scalb<mode>3"
16982 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16983 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16984 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16985 "TARGET_USE_FANCY_MATH_387
16986 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16987 || TARGET_MIX_SSE_I387)
16988 && flag_unsafe_math_optimizations && !optimize_size"
16990 rtx op0 = gen_reg_rtx (XFmode);
16991 rtx op1 = gen_reg_rtx (XFmode);
16992 rtx op2 = gen_reg_rtx (XFmode);
16994 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16995 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16996 emit_insn (gen_scalbxf3 (op0, op1, op2));
16997 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17002 (define_insn "rintxf2"
17003 [(set (match_operand:XF 0 "register_operand" "=f")
17004 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17006 "TARGET_USE_FANCY_MATH_387
17007 && flag_unsafe_math_optimizations"
17009 [(set_attr "type" "fpspc")
17010 (set_attr "mode" "XF")])
17012 (define_expand "rint<mode>2"
17013 [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17014 (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17015 "(TARGET_USE_FANCY_MATH_387
17016 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17017 || TARGET_MIX_SSE_I387)
17018 && flag_unsafe_math_optimizations)
17019 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17020 && !flag_trapping_math
17021 && !optimize_size)"
17023 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17024 && !flag_trapping_math
17026 ix86_expand_rint (operand0, operand1);
17029 rtx op0 = gen_reg_rtx (XFmode);
17030 rtx op1 = gen_reg_rtx (XFmode);
17032 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17033 emit_insn (gen_rintxf2 (op0, op1));
17035 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17040 (define_expand "round<mode>2"
17041 [(match_operand:SSEMODEF 0 "register_operand" "")
17042 (match_operand:SSEMODEF 1 "nonimmediate_operand" "")]
17043 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17044 && !flag_trapping_math && !flag_rounding_math
17047 if ((<MODE>mode != DFmode) || TARGET_64BIT)
17048 ix86_expand_round (operand0, operand1);
17050 ix86_expand_rounddf_32 (operand0, operand1);
17054 (define_insn_and_split "*fistdi2_1"
17055 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17056 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17058 "TARGET_USE_FANCY_MATH_387
17059 && !(reload_completed || reload_in_progress)"
17064 if (memory_operand (operands[0], VOIDmode))
17065 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17068 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17069 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17074 [(set_attr "type" "fpspc")
17075 (set_attr "mode" "DI")])
17077 (define_insn "fistdi2"
17078 [(set (match_operand:DI 0 "memory_operand" "=m")
17079 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17081 (clobber (match_scratch:XF 2 "=&1f"))]
17082 "TARGET_USE_FANCY_MATH_387"
17083 "* return output_fix_trunc (insn, operands, 0);"
17084 [(set_attr "type" "fpspc")
17085 (set_attr "mode" "DI")])
17087 (define_insn "fistdi2_with_temp"
17088 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17089 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17091 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17092 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17093 "TARGET_USE_FANCY_MATH_387"
17095 [(set_attr "type" "fpspc")
17096 (set_attr "mode" "DI")])
17099 [(set (match_operand:DI 0 "register_operand" "")
17100 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17102 (clobber (match_operand:DI 2 "memory_operand" ""))
17103 (clobber (match_scratch 3 ""))]
17105 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17106 (clobber (match_dup 3))])
17107 (set (match_dup 0) (match_dup 2))]
17111 [(set (match_operand:DI 0 "memory_operand" "")
17112 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17114 (clobber (match_operand:DI 2 "memory_operand" ""))
17115 (clobber (match_scratch 3 ""))]
17117 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17118 (clobber (match_dup 3))])]
17121 (define_insn_and_split "*fist<mode>2_1"
17122 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17123 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17125 "TARGET_USE_FANCY_MATH_387
17126 && !(reload_completed || reload_in_progress)"
17131 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17132 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17136 [(set_attr "type" "fpspc")
17137 (set_attr "mode" "<MODE>")])
17139 (define_insn "fist<mode>2"
17140 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17141 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17143 "TARGET_USE_FANCY_MATH_387"
17144 "* return output_fix_trunc (insn, operands, 0);"
17145 [(set_attr "type" "fpspc")
17146 (set_attr "mode" "<MODE>")])
17148 (define_insn "fist<mode>2_with_temp"
17149 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17150 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17152 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17153 "TARGET_USE_FANCY_MATH_387"
17155 [(set_attr "type" "fpspc")
17156 (set_attr "mode" "<MODE>")])
17159 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17160 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17162 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17164 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17165 (set (match_dup 0) (match_dup 2))]
17169 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17170 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17172 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17174 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17177 (define_expand "lrintxf<mode>2"
17178 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17179 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17181 "TARGET_USE_FANCY_MATH_387"
17184 (define_expand "lrint<SSEMODEF:mode><SSEMODEI24:mode>2"
17185 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17186 (unspec:SSEMODEI24 [(match_operand:SSEMODEF 1 "register_operand" "")]
17187 UNSPEC_FIX_NOTRUNC))]
17188 "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17189 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17192 (define_expand "lround<SSEMODEF:mode><SSEMODEI24:mode>2"
17193 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17194 (match_operand:SSEMODEF 1 "register_operand" "")]
17195 "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17196 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17197 && !flag_trapping_math && !flag_rounding_math
17200 ix86_expand_lround (operand0, operand1);
17204 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17205 (define_insn_and_split "frndintxf2_floor"
17206 [(set (match_operand:XF 0 "register_operand" "=f")
17207 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17208 UNSPEC_FRNDINT_FLOOR))
17209 (clobber (reg:CC FLAGS_REG))]
17210 "TARGET_USE_FANCY_MATH_387
17211 && flag_unsafe_math_optimizations
17212 && !(reload_completed || reload_in_progress)"
17217 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17219 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17220 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17222 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17223 operands[2], operands[3]));
17226 [(set_attr "type" "frndint")
17227 (set_attr "i387_cw" "floor")
17228 (set_attr "mode" "XF")])
17230 (define_insn "frndintxf2_floor_i387"
17231 [(set (match_operand:XF 0 "register_operand" "=f")
17232 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17233 UNSPEC_FRNDINT_FLOOR))
17234 (use (match_operand:HI 2 "memory_operand" "m"))
17235 (use (match_operand:HI 3 "memory_operand" "m"))]
17236 "TARGET_USE_FANCY_MATH_387
17237 && flag_unsafe_math_optimizations"
17238 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17239 [(set_attr "type" "frndint")
17240 (set_attr "i387_cw" "floor")
17241 (set_attr "mode" "XF")])
17243 (define_expand "floorxf2"
17244 [(use (match_operand:XF 0 "register_operand" ""))
17245 (use (match_operand:XF 1 "register_operand" ""))]
17246 "TARGET_USE_FANCY_MATH_387
17247 && flag_unsafe_math_optimizations && !optimize_size"
17249 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17253 (define_expand "floordf2"
17254 [(use (match_operand:DF 0 "register_operand" ""))
17255 (use (match_operand:DF 1 "register_operand" ""))]
17256 "((TARGET_USE_FANCY_MATH_387
17257 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17258 && flag_unsafe_math_optimizations)
17259 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17260 && !flag_trapping_math))
17263 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17264 && !flag_trapping_math)
17267 ix86_expand_floorceil (operand0, operand1, true);
17269 ix86_expand_floorceildf_32 (operand0, operand1, true);
17273 rtx op0 = gen_reg_rtx (XFmode);
17274 rtx op1 = gen_reg_rtx (XFmode);
17276 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17277 emit_insn (gen_frndintxf2_floor (op0, op1));
17279 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17284 (define_expand "floorsf2"
17285 [(use (match_operand:SF 0 "register_operand" ""))
17286 (use (match_operand:SF 1 "register_operand" ""))]
17287 "((TARGET_USE_FANCY_MATH_387
17288 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17289 && flag_unsafe_math_optimizations)
17290 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17291 && !flag_trapping_math))
17294 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17295 && !flag_trapping_math)
17296 ix86_expand_floorceil (operand0, operand1, true);
17299 rtx op0 = gen_reg_rtx (XFmode);
17300 rtx op1 = gen_reg_rtx (XFmode);
17302 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17303 emit_insn (gen_frndintxf2_floor (op0, op1));
17305 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17310 (define_insn_and_split "*fist<mode>2_floor_1"
17311 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17312 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17313 UNSPEC_FIST_FLOOR))
17314 (clobber (reg:CC FLAGS_REG))]
17315 "TARGET_USE_FANCY_MATH_387
17316 && flag_unsafe_math_optimizations
17317 && !(reload_completed || reload_in_progress)"
17322 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17324 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17325 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17326 if (memory_operand (operands[0], VOIDmode))
17327 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17328 operands[2], operands[3]));
17331 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17332 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17333 operands[2], operands[3],
17338 [(set_attr "type" "fistp")
17339 (set_attr "i387_cw" "floor")
17340 (set_attr "mode" "<MODE>")])
17342 (define_insn "fistdi2_floor"
17343 [(set (match_operand:DI 0 "memory_operand" "=m")
17344 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17345 UNSPEC_FIST_FLOOR))
17346 (use (match_operand:HI 2 "memory_operand" "m"))
17347 (use (match_operand:HI 3 "memory_operand" "m"))
17348 (clobber (match_scratch:XF 4 "=&1f"))]
17349 "TARGET_USE_FANCY_MATH_387
17350 && flag_unsafe_math_optimizations"
17351 "* return output_fix_trunc (insn, operands, 0);"
17352 [(set_attr "type" "fistp")
17353 (set_attr "i387_cw" "floor")
17354 (set_attr "mode" "DI")])
17356 (define_insn "fistdi2_floor_with_temp"
17357 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17358 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17359 UNSPEC_FIST_FLOOR))
17360 (use (match_operand:HI 2 "memory_operand" "m,m"))
17361 (use (match_operand:HI 3 "memory_operand" "m,m"))
17362 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17363 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17364 "TARGET_USE_FANCY_MATH_387
17365 && flag_unsafe_math_optimizations"
17367 [(set_attr "type" "fistp")
17368 (set_attr "i387_cw" "floor")
17369 (set_attr "mode" "DI")])
17372 [(set (match_operand:DI 0 "register_operand" "")
17373 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17374 UNSPEC_FIST_FLOOR))
17375 (use (match_operand:HI 2 "memory_operand" ""))
17376 (use (match_operand:HI 3 "memory_operand" ""))
17377 (clobber (match_operand:DI 4 "memory_operand" ""))
17378 (clobber (match_scratch 5 ""))]
17380 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17381 (use (match_dup 2))
17382 (use (match_dup 3))
17383 (clobber (match_dup 5))])
17384 (set (match_dup 0) (match_dup 4))]
17388 [(set (match_operand:DI 0 "memory_operand" "")
17389 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17390 UNSPEC_FIST_FLOOR))
17391 (use (match_operand:HI 2 "memory_operand" ""))
17392 (use (match_operand:HI 3 "memory_operand" ""))
17393 (clobber (match_operand:DI 4 "memory_operand" ""))
17394 (clobber (match_scratch 5 ""))]
17396 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17397 (use (match_dup 2))
17398 (use (match_dup 3))
17399 (clobber (match_dup 5))])]
17402 (define_insn "fist<mode>2_floor"
17403 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17404 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17405 UNSPEC_FIST_FLOOR))
17406 (use (match_operand:HI 2 "memory_operand" "m"))
17407 (use (match_operand:HI 3 "memory_operand" "m"))]
17408 "TARGET_USE_FANCY_MATH_387
17409 && flag_unsafe_math_optimizations"
17410 "* return output_fix_trunc (insn, operands, 0);"
17411 [(set_attr "type" "fistp")
17412 (set_attr "i387_cw" "floor")
17413 (set_attr "mode" "<MODE>")])
17415 (define_insn "fist<mode>2_floor_with_temp"
17416 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17417 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17418 UNSPEC_FIST_FLOOR))
17419 (use (match_operand:HI 2 "memory_operand" "m,m"))
17420 (use (match_operand:HI 3 "memory_operand" "m,m"))
17421 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17422 "TARGET_USE_FANCY_MATH_387
17423 && flag_unsafe_math_optimizations"
17425 [(set_attr "type" "fistp")
17426 (set_attr "i387_cw" "floor")
17427 (set_attr "mode" "<MODE>")])
17430 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17431 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17432 UNSPEC_FIST_FLOOR))
17433 (use (match_operand:HI 2 "memory_operand" ""))
17434 (use (match_operand:HI 3 "memory_operand" ""))
17435 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17437 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17438 UNSPEC_FIST_FLOOR))
17439 (use (match_dup 2))
17440 (use (match_dup 3))])
17441 (set (match_dup 0) (match_dup 4))]
17445 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17446 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17447 UNSPEC_FIST_FLOOR))
17448 (use (match_operand:HI 2 "memory_operand" ""))
17449 (use (match_operand:HI 3 "memory_operand" ""))
17450 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17452 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17453 UNSPEC_FIST_FLOOR))
17454 (use (match_dup 2))
17455 (use (match_dup 3))])]
17458 (define_expand "lfloorxf<mode>2"
17459 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17460 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17461 UNSPEC_FIST_FLOOR))
17462 (clobber (reg:CC FLAGS_REG))])]
17463 "TARGET_USE_FANCY_MATH_387
17464 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17465 && flag_unsafe_math_optimizations"
17468 (define_expand "lfloor<mode>di2"
17469 [(match_operand:DI 0 "nonimmediate_operand" "")
17470 (match_operand:SSEMODEF 1 "register_operand" "")]
17471 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17472 && !flag_trapping_math
17475 ix86_expand_lfloorceil (operand0, operand1, true);
17479 (define_expand "lfloor<mode>si2"
17480 [(match_operand:SI 0 "nonimmediate_operand" "")
17481 (match_operand:SSEMODEF 1 "register_operand" "")]
17482 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17483 && !flag_trapping_math
17484 && (!optimize_size || !TARGET_64BIT)"
17486 ix86_expand_lfloorceil (operand0, operand1, true);
17490 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17491 (define_insn_and_split "frndintxf2_ceil"
17492 [(set (match_operand:XF 0 "register_operand" "=f")
17493 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17494 UNSPEC_FRNDINT_CEIL))
17495 (clobber (reg:CC FLAGS_REG))]
17496 "TARGET_USE_FANCY_MATH_387
17497 && flag_unsafe_math_optimizations
17498 && !(reload_completed || reload_in_progress)"
17503 ix86_optimize_mode_switching[I387_CEIL] = 1;
17505 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17506 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17508 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17509 operands[2], operands[3]));
17512 [(set_attr "type" "frndint")
17513 (set_attr "i387_cw" "ceil")
17514 (set_attr "mode" "XF")])
17516 (define_insn "frndintxf2_ceil_i387"
17517 [(set (match_operand:XF 0 "register_operand" "=f")
17518 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17519 UNSPEC_FRNDINT_CEIL))
17520 (use (match_operand:HI 2 "memory_operand" "m"))
17521 (use (match_operand:HI 3 "memory_operand" "m"))]
17522 "TARGET_USE_FANCY_MATH_387
17523 && flag_unsafe_math_optimizations"
17524 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17525 [(set_attr "type" "frndint")
17526 (set_attr "i387_cw" "ceil")
17527 (set_attr "mode" "XF")])
17529 (define_expand "ceilxf2"
17530 [(use (match_operand:XF 0 "register_operand" ""))
17531 (use (match_operand:XF 1 "register_operand" ""))]
17532 "TARGET_USE_FANCY_MATH_387
17533 && flag_unsafe_math_optimizations && !optimize_size"
17535 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17539 (define_expand "ceildf2"
17540 [(use (match_operand:DF 0 "register_operand" ""))
17541 (use (match_operand:DF 1 "register_operand" ""))]
17542 "((TARGET_USE_FANCY_MATH_387
17543 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17544 && flag_unsafe_math_optimizations)
17545 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17546 && !flag_trapping_math))
17549 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17550 && !flag_trapping_math)
17553 ix86_expand_floorceil (operand0, operand1, false);
17555 ix86_expand_floorceildf_32 (operand0, operand1, false);
17559 rtx op0 = gen_reg_rtx (XFmode);
17560 rtx op1 = gen_reg_rtx (XFmode);
17562 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17563 emit_insn (gen_frndintxf2_ceil (op0, op1));
17565 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17570 (define_expand "ceilsf2"
17571 [(use (match_operand:SF 0 "register_operand" ""))
17572 (use (match_operand:SF 1 "register_operand" ""))]
17573 "((TARGET_USE_FANCY_MATH_387
17574 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17575 && flag_unsafe_math_optimizations)
17576 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17577 && !flag_trapping_math))
17580 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17581 && !flag_trapping_math)
17582 ix86_expand_floorceil (operand0, operand1, false);
17585 rtx op0 = gen_reg_rtx (XFmode);
17586 rtx op1 = gen_reg_rtx (XFmode);
17588 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17589 emit_insn (gen_frndintxf2_ceil (op0, op1));
17591 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17596 (define_insn_and_split "*fist<mode>2_ceil_1"
17597 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17598 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17600 (clobber (reg:CC FLAGS_REG))]
17601 "TARGET_USE_FANCY_MATH_387
17602 && flag_unsafe_math_optimizations
17603 && !(reload_completed || reload_in_progress)"
17608 ix86_optimize_mode_switching[I387_CEIL] = 1;
17610 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17611 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17612 if (memory_operand (operands[0], VOIDmode))
17613 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17614 operands[2], operands[3]));
17617 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17618 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17619 operands[2], operands[3],
17624 [(set_attr "type" "fistp")
17625 (set_attr "i387_cw" "ceil")
17626 (set_attr "mode" "<MODE>")])
17628 (define_insn "fistdi2_ceil"
17629 [(set (match_operand:DI 0 "memory_operand" "=m")
17630 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17632 (use (match_operand:HI 2 "memory_operand" "m"))
17633 (use (match_operand:HI 3 "memory_operand" "m"))
17634 (clobber (match_scratch:XF 4 "=&1f"))]
17635 "TARGET_USE_FANCY_MATH_387
17636 && flag_unsafe_math_optimizations"
17637 "* return output_fix_trunc (insn, operands, 0);"
17638 [(set_attr "type" "fistp")
17639 (set_attr "i387_cw" "ceil")
17640 (set_attr "mode" "DI")])
17642 (define_insn "fistdi2_ceil_with_temp"
17643 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17644 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17646 (use (match_operand:HI 2 "memory_operand" "m,m"))
17647 (use (match_operand:HI 3 "memory_operand" "m,m"))
17648 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17649 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17650 "TARGET_USE_FANCY_MATH_387
17651 && flag_unsafe_math_optimizations"
17653 [(set_attr "type" "fistp")
17654 (set_attr "i387_cw" "ceil")
17655 (set_attr "mode" "DI")])
17658 [(set (match_operand:DI 0 "register_operand" "")
17659 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17661 (use (match_operand:HI 2 "memory_operand" ""))
17662 (use (match_operand:HI 3 "memory_operand" ""))
17663 (clobber (match_operand:DI 4 "memory_operand" ""))
17664 (clobber (match_scratch 5 ""))]
17666 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17667 (use (match_dup 2))
17668 (use (match_dup 3))
17669 (clobber (match_dup 5))])
17670 (set (match_dup 0) (match_dup 4))]
17674 [(set (match_operand:DI 0 "memory_operand" "")
17675 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17677 (use (match_operand:HI 2 "memory_operand" ""))
17678 (use (match_operand:HI 3 "memory_operand" ""))
17679 (clobber (match_operand:DI 4 "memory_operand" ""))
17680 (clobber (match_scratch 5 ""))]
17682 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17683 (use (match_dup 2))
17684 (use (match_dup 3))
17685 (clobber (match_dup 5))])]
17688 (define_insn "fist<mode>2_ceil"
17689 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17690 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17692 (use (match_operand:HI 2 "memory_operand" "m"))
17693 (use (match_operand:HI 3 "memory_operand" "m"))]
17694 "TARGET_USE_FANCY_MATH_387
17695 && flag_unsafe_math_optimizations"
17696 "* return output_fix_trunc (insn, operands, 0);"
17697 [(set_attr "type" "fistp")
17698 (set_attr "i387_cw" "ceil")
17699 (set_attr "mode" "<MODE>")])
17701 (define_insn "fist<mode>2_ceil_with_temp"
17702 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17703 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17705 (use (match_operand:HI 2 "memory_operand" "m,m"))
17706 (use (match_operand:HI 3 "memory_operand" "m,m"))
17707 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17708 "TARGET_USE_FANCY_MATH_387
17709 && flag_unsafe_math_optimizations"
17711 [(set_attr "type" "fistp")
17712 (set_attr "i387_cw" "ceil")
17713 (set_attr "mode" "<MODE>")])
17716 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17717 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17719 (use (match_operand:HI 2 "memory_operand" ""))
17720 (use (match_operand:HI 3 "memory_operand" ""))
17721 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17723 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17725 (use (match_dup 2))
17726 (use (match_dup 3))])
17727 (set (match_dup 0) (match_dup 4))]
17731 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17732 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17734 (use (match_operand:HI 2 "memory_operand" ""))
17735 (use (match_operand:HI 3 "memory_operand" ""))
17736 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17738 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17740 (use (match_dup 2))
17741 (use (match_dup 3))])]
17744 (define_expand "lceilxf<mode>2"
17745 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17746 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17748 (clobber (reg:CC FLAGS_REG))])]
17749 "TARGET_USE_FANCY_MATH_387
17750 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17751 && flag_unsafe_math_optimizations"
17754 (define_expand "lceil<mode>di2"
17755 [(match_operand:DI 0 "nonimmediate_operand" "")
17756 (match_operand:SSEMODEF 1 "register_operand" "")]
17757 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17758 && !flag_trapping_math"
17760 ix86_expand_lfloorceil (operand0, operand1, false);
17764 (define_expand "lceil<mode>si2"
17765 [(match_operand:SI 0 "nonimmediate_operand" "")
17766 (match_operand:SSEMODEF 1 "register_operand" "")]
17767 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17768 && !flag_trapping_math"
17770 ix86_expand_lfloorceil (operand0, operand1, false);
17774 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17775 (define_insn_and_split "frndintxf2_trunc"
17776 [(set (match_operand:XF 0 "register_operand" "=f")
17777 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17778 UNSPEC_FRNDINT_TRUNC))
17779 (clobber (reg:CC FLAGS_REG))]
17780 "TARGET_USE_FANCY_MATH_387
17781 && flag_unsafe_math_optimizations
17782 && !(reload_completed || reload_in_progress)"
17787 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17789 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17790 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17792 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17793 operands[2], operands[3]));
17796 [(set_attr "type" "frndint")
17797 (set_attr "i387_cw" "trunc")
17798 (set_attr "mode" "XF")])
17800 (define_insn "frndintxf2_trunc_i387"
17801 [(set (match_operand:XF 0 "register_operand" "=f")
17802 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17803 UNSPEC_FRNDINT_TRUNC))
17804 (use (match_operand:HI 2 "memory_operand" "m"))
17805 (use (match_operand:HI 3 "memory_operand" "m"))]
17806 "TARGET_USE_FANCY_MATH_387
17807 && flag_unsafe_math_optimizations"
17808 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17809 [(set_attr "type" "frndint")
17810 (set_attr "i387_cw" "trunc")
17811 (set_attr "mode" "XF")])
17813 (define_expand "btruncxf2"
17814 [(use (match_operand:XF 0 "register_operand" ""))
17815 (use (match_operand:XF 1 "register_operand" ""))]
17816 "TARGET_USE_FANCY_MATH_387
17817 && flag_unsafe_math_optimizations && !optimize_size"
17819 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17823 (define_expand "btruncdf2"
17824 [(use (match_operand:DF 0 "register_operand" ""))
17825 (use (match_operand:DF 1 "register_operand" ""))]
17826 "((TARGET_USE_FANCY_MATH_387
17827 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17828 && flag_unsafe_math_optimizations)
17829 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17830 && !flag_trapping_math))
17833 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17834 && !flag_trapping_math)
17837 ix86_expand_trunc (operand0, operand1);
17839 ix86_expand_truncdf_32 (operand0, operand1);
17843 rtx op0 = gen_reg_rtx (XFmode);
17844 rtx op1 = gen_reg_rtx (XFmode);
17846 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17847 emit_insn (gen_frndintxf2_trunc (op0, op1));
17849 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17854 (define_expand "btruncsf2"
17855 [(use (match_operand:SF 0 "register_operand" ""))
17856 (use (match_operand:SF 1 "register_operand" ""))]
17857 "((TARGET_USE_FANCY_MATH_387
17858 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17859 && flag_unsafe_math_optimizations)
17860 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17861 && !flag_trapping_math))
17864 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17865 && !flag_trapping_math)
17866 ix86_expand_trunc (operand0, operand1);
17869 rtx op0 = gen_reg_rtx (XFmode);
17870 rtx op1 = gen_reg_rtx (XFmode);
17872 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17873 emit_insn (gen_frndintxf2_trunc (op0, op1));
17875 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17880 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17881 (define_insn_and_split "frndintxf2_mask_pm"
17882 [(set (match_operand:XF 0 "register_operand" "=f")
17883 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17884 UNSPEC_FRNDINT_MASK_PM))
17885 (clobber (reg:CC FLAGS_REG))]
17886 "TARGET_USE_FANCY_MATH_387
17887 && flag_unsafe_math_optimizations
17888 && !(reload_completed || reload_in_progress)"
17893 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17895 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17896 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17898 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17899 operands[2], operands[3]));
17902 [(set_attr "type" "frndint")
17903 (set_attr "i387_cw" "mask_pm")
17904 (set_attr "mode" "XF")])
17906 (define_insn "frndintxf2_mask_pm_i387"
17907 [(set (match_operand:XF 0 "register_operand" "=f")
17908 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17909 UNSPEC_FRNDINT_MASK_PM))
17910 (use (match_operand:HI 2 "memory_operand" "m"))
17911 (use (match_operand:HI 3 "memory_operand" "m"))]
17912 "TARGET_USE_FANCY_MATH_387
17913 && flag_unsafe_math_optimizations"
17914 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17915 [(set_attr "type" "frndint")
17916 (set_attr "i387_cw" "mask_pm")
17917 (set_attr "mode" "XF")])
17919 (define_expand "nearbyintxf2"
17920 [(use (match_operand:XF 0 "register_operand" ""))
17921 (use (match_operand:XF 1 "register_operand" ""))]
17922 "TARGET_USE_FANCY_MATH_387
17923 && flag_unsafe_math_optimizations"
17925 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17930 (define_expand "nearbyintdf2"
17931 [(use (match_operand:DF 0 "register_operand" ""))
17932 (use (match_operand:DF 1 "register_operand" ""))]
17933 "TARGET_USE_FANCY_MATH_387
17934 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17935 && flag_unsafe_math_optimizations"
17937 rtx op0 = gen_reg_rtx (XFmode);
17938 rtx op1 = gen_reg_rtx (XFmode);
17940 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17941 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17943 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17947 (define_expand "nearbyintsf2"
17948 [(use (match_operand:SF 0 "register_operand" ""))
17949 (use (match_operand:SF 1 "register_operand" ""))]
17950 "TARGET_USE_FANCY_MATH_387
17951 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17952 && flag_unsafe_math_optimizations"
17954 rtx op0 = gen_reg_rtx (XFmode);
17955 rtx op1 = gen_reg_rtx (XFmode);
17957 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17958 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17960 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17964 (define_insn "fxam<mode>2_i387"
17965 [(set (match_operand:HI 0 "register_operand" "=a")
17967 [(match_operand:X87MODEF 1 "register_operand" "f")]
17969 "TARGET_USE_FANCY_MATH_387"
17970 "fxam\n\tfnstsw\t%0"
17971 [(set_attr "type" "multi")
17972 (set_attr "unit" "i387")
17973 (set_attr "mode" "<MODE>")])
17975 (define_expand "isinf<mode>2"
17976 [(use (match_operand:SI 0 "register_operand" ""))
17977 (use (match_operand:X87MODEF 1 "register_operand" ""))]
17978 "TARGET_USE_FANCY_MATH_387
17979 && TARGET_C99_FUNCTIONS
17980 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17981 || TARGET_MIX_SSE_I387)"
17983 rtx mask = GEN_INT (0x45);
17984 rtx val = GEN_INT (0x05);
17988 rtx scratch = gen_reg_rtx (HImode);
17989 rtx res = gen_reg_rtx (QImode);
17991 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17992 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17993 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17994 cond = gen_rtx_fmt_ee (EQ, QImode,
17995 gen_rtx_REG (CCmode, FLAGS_REG),
17997 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17998 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18003 ;; Block operation instructions
18005 (define_expand "movmemsi"
18006 [(use (match_operand:BLK 0 "memory_operand" ""))
18007 (use (match_operand:BLK 1 "memory_operand" ""))
18008 (use (match_operand:SI 2 "nonmemory_operand" ""))
18009 (use (match_operand:SI 3 "const_int_operand" ""))
18010 (use (match_operand:SI 4 "const_int_operand" ""))
18011 (use (match_operand:SI 5 "const_int_operand" ""))]
18014 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18015 operands[4], operands[5]))
18021 (define_expand "movmemdi"
18022 [(use (match_operand:BLK 0 "memory_operand" ""))
18023 (use (match_operand:BLK 1 "memory_operand" ""))
18024 (use (match_operand:DI 2 "nonmemory_operand" ""))
18025 (use (match_operand:DI 3 "const_int_operand" ""))
18026 (use (match_operand:SI 4 "const_int_operand" ""))
18027 (use (match_operand:SI 5 "const_int_operand" ""))]
18030 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18031 operands[4], operands[5]))
18037 ;; Most CPUs don't like single string operations
18038 ;; Handle this case here to simplify previous expander.
18040 (define_expand "strmov"
18041 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18042 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18043 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18044 (clobber (reg:CC FLAGS_REG))])
18045 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18046 (clobber (reg:CC FLAGS_REG))])]
18049 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18051 /* If .md ever supports :P for Pmode, these can be directly
18052 in the pattern above. */
18053 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18054 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18056 if (TARGET_SINGLE_STRINGOP || optimize_size)
18058 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18059 operands[2], operands[3],
18060 operands[5], operands[6]));
18064 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18067 (define_expand "strmov_singleop"
18068 [(parallel [(set (match_operand 1 "memory_operand" "")
18069 (match_operand 3 "memory_operand" ""))
18070 (set (match_operand 0 "register_operand" "")
18071 (match_operand 4 "" ""))
18072 (set (match_operand 2 "register_operand" "")
18073 (match_operand 5 "" ""))])]
18074 "TARGET_SINGLE_STRINGOP || optimize_size"
18077 (define_insn "*strmovdi_rex_1"
18078 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18079 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18080 (set (match_operand:DI 0 "register_operand" "=D")
18081 (plus:DI (match_dup 2)
18083 (set (match_operand:DI 1 "register_operand" "=S")
18084 (plus:DI (match_dup 3)
18086 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18088 [(set_attr "type" "str")
18089 (set_attr "mode" "DI")
18090 (set_attr "memory" "both")])
18092 (define_insn "*strmovsi_1"
18093 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18094 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18095 (set (match_operand:SI 0 "register_operand" "=D")
18096 (plus:SI (match_dup 2)
18098 (set (match_operand:SI 1 "register_operand" "=S")
18099 (plus:SI (match_dup 3)
18101 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18103 [(set_attr "type" "str")
18104 (set_attr "mode" "SI")
18105 (set_attr "memory" "both")])
18107 (define_insn "*strmovsi_rex_1"
18108 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18109 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18110 (set (match_operand:DI 0 "register_operand" "=D")
18111 (plus:DI (match_dup 2)
18113 (set (match_operand:DI 1 "register_operand" "=S")
18114 (plus:DI (match_dup 3)
18116 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18118 [(set_attr "type" "str")
18119 (set_attr "mode" "SI")
18120 (set_attr "memory" "both")])
18122 (define_insn "*strmovhi_1"
18123 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18124 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18125 (set (match_operand:SI 0 "register_operand" "=D")
18126 (plus:SI (match_dup 2)
18128 (set (match_operand:SI 1 "register_operand" "=S")
18129 (plus:SI (match_dup 3)
18131 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18133 [(set_attr "type" "str")
18134 (set_attr "memory" "both")
18135 (set_attr "mode" "HI")])
18137 (define_insn "*strmovhi_rex_1"
18138 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18139 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18140 (set (match_operand:DI 0 "register_operand" "=D")
18141 (plus:DI (match_dup 2)
18143 (set (match_operand:DI 1 "register_operand" "=S")
18144 (plus:DI (match_dup 3)
18146 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18148 [(set_attr "type" "str")
18149 (set_attr "memory" "both")
18150 (set_attr "mode" "HI")])
18152 (define_insn "*strmovqi_1"
18153 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18154 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18155 (set (match_operand:SI 0 "register_operand" "=D")
18156 (plus:SI (match_dup 2)
18158 (set (match_operand:SI 1 "register_operand" "=S")
18159 (plus:SI (match_dup 3)
18161 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18163 [(set_attr "type" "str")
18164 (set_attr "memory" "both")
18165 (set_attr "mode" "QI")])
18167 (define_insn "*strmovqi_rex_1"
18168 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18169 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18170 (set (match_operand:DI 0 "register_operand" "=D")
18171 (plus:DI (match_dup 2)
18173 (set (match_operand:DI 1 "register_operand" "=S")
18174 (plus:DI (match_dup 3)
18176 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18178 [(set_attr "type" "str")
18179 (set_attr "memory" "both")
18180 (set_attr "mode" "QI")])
18182 (define_expand "rep_mov"
18183 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18184 (set (match_operand 0 "register_operand" "")
18185 (match_operand 5 "" ""))
18186 (set (match_operand 2 "register_operand" "")
18187 (match_operand 6 "" ""))
18188 (set (match_operand 1 "memory_operand" "")
18189 (match_operand 3 "memory_operand" ""))
18190 (use (match_dup 4))])]
18194 (define_insn "*rep_movdi_rex64"
18195 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18196 (set (match_operand:DI 0 "register_operand" "=D")
18197 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18199 (match_operand:DI 3 "register_operand" "0")))
18200 (set (match_operand:DI 1 "register_operand" "=S")
18201 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18202 (match_operand:DI 4 "register_operand" "1")))
18203 (set (mem:BLK (match_dup 3))
18204 (mem:BLK (match_dup 4)))
18205 (use (match_dup 5))]
18207 "{rep\;movsq|rep movsq}"
18208 [(set_attr "type" "str")
18209 (set_attr "prefix_rep" "1")
18210 (set_attr "memory" "both")
18211 (set_attr "mode" "DI")])
18213 (define_insn "*rep_movsi"
18214 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18215 (set (match_operand:SI 0 "register_operand" "=D")
18216 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18218 (match_operand:SI 3 "register_operand" "0")))
18219 (set (match_operand:SI 1 "register_operand" "=S")
18220 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18221 (match_operand:SI 4 "register_operand" "1")))
18222 (set (mem:BLK (match_dup 3))
18223 (mem:BLK (match_dup 4)))
18224 (use (match_dup 5))]
18226 "{rep\;movsl|rep movsd}"
18227 [(set_attr "type" "str")
18228 (set_attr "prefix_rep" "1")
18229 (set_attr "memory" "both")
18230 (set_attr "mode" "SI")])
18232 (define_insn "*rep_movsi_rex64"
18233 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18234 (set (match_operand:DI 0 "register_operand" "=D")
18235 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18237 (match_operand:DI 3 "register_operand" "0")))
18238 (set (match_operand:DI 1 "register_operand" "=S")
18239 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18240 (match_operand:DI 4 "register_operand" "1")))
18241 (set (mem:BLK (match_dup 3))
18242 (mem:BLK (match_dup 4)))
18243 (use (match_dup 5))]
18245 "{rep\;movsl|rep movsd}"
18246 [(set_attr "type" "str")
18247 (set_attr "prefix_rep" "1")
18248 (set_attr "memory" "both")
18249 (set_attr "mode" "SI")])
18251 (define_insn "*rep_movqi"
18252 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18253 (set (match_operand:SI 0 "register_operand" "=D")
18254 (plus:SI (match_operand:SI 3 "register_operand" "0")
18255 (match_operand:SI 5 "register_operand" "2")))
18256 (set (match_operand:SI 1 "register_operand" "=S")
18257 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18258 (set (mem:BLK (match_dup 3))
18259 (mem:BLK (match_dup 4)))
18260 (use (match_dup 5))]
18262 "{rep\;movsb|rep movsb}"
18263 [(set_attr "type" "str")
18264 (set_attr "prefix_rep" "1")
18265 (set_attr "memory" "both")
18266 (set_attr "mode" "SI")])
18268 (define_insn "*rep_movqi_rex64"
18269 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18270 (set (match_operand:DI 0 "register_operand" "=D")
18271 (plus:DI (match_operand:DI 3 "register_operand" "0")
18272 (match_operand:DI 5 "register_operand" "2")))
18273 (set (match_operand:DI 1 "register_operand" "=S")
18274 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18275 (set (mem:BLK (match_dup 3))
18276 (mem:BLK (match_dup 4)))
18277 (use (match_dup 5))]
18279 "{rep\;movsb|rep movsb}"
18280 [(set_attr "type" "str")
18281 (set_attr "prefix_rep" "1")
18282 (set_attr "memory" "both")
18283 (set_attr "mode" "SI")])
18285 (define_expand "setmemsi"
18286 [(use (match_operand:BLK 0 "memory_operand" ""))
18287 (use (match_operand:SI 1 "nonmemory_operand" ""))
18288 (use (match_operand 2 "const_int_operand" ""))
18289 (use (match_operand 3 "const_int_operand" ""))
18290 (use (match_operand:SI 4 "const_int_operand" ""))
18291 (use (match_operand:SI 5 "const_int_operand" ""))]
18294 if (ix86_expand_setmem (operands[0], operands[1],
18295 operands[2], operands[3],
18296 operands[4], operands[5]))
18302 (define_expand "setmemdi"
18303 [(use (match_operand:BLK 0 "memory_operand" ""))
18304 (use (match_operand:DI 1 "nonmemory_operand" ""))
18305 (use (match_operand 2 "const_int_operand" ""))
18306 (use (match_operand 3 "const_int_operand" ""))
18307 (use (match_operand 4 "const_int_operand" ""))
18308 (use (match_operand 5 "const_int_operand" ""))]
18311 if (ix86_expand_setmem (operands[0], operands[1],
18312 operands[2], operands[3],
18313 operands[4], operands[5]))
18319 ;; Most CPUs don't like single string operations
18320 ;; Handle this case here to simplify previous expander.
18322 (define_expand "strset"
18323 [(set (match_operand 1 "memory_operand" "")
18324 (match_operand 2 "register_operand" ""))
18325 (parallel [(set (match_operand 0 "register_operand" "")
18327 (clobber (reg:CC FLAGS_REG))])]
18330 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18331 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18333 /* If .md ever supports :P for Pmode, this can be directly
18334 in the pattern above. */
18335 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18336 GEN_INT (GET_MODE_SIZE (GET_MODE
18338 if (TARGET_SINGLE_STRINGOP || optimize_size)
18340 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18346 (define_expand "strset_singleop"
18347 [(parallel [(set (match_operand 1 "memory_operand" "")
18348 (match_operand 2 "register_operand" ""))
18349 (set (match_operand 0 "register_operand" "")
18350 (match_operand 3 "" ""))])]
18351 "TARGET_SINGLE_STRINGOP || optimize_size"
18354 (define_insn "*strsetdi_rex_1"
18355 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18356 (match_operand:DI 2 "register_operand" "a"))
18357 (set (match_operand:DI 0 "register_operand" "=D")
18358 (plus:DI (match_dup 1)
18360 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18362 [(set_attr "type" "str")
18363 (set_attr "memory" "store")
18364 (set_attr "mode" "DI")])
18366 (define_insn "*strsetsi_1"
18367 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18368 (match_operand:SI 2 "register_operand" "a"))
18369 (set (match_operand:SI 0 "register_operand" "=D")
18370 (plus:SI (match_dup 1)
18372 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18374 [(set_attr "type" "str")
18375 (set_attr "memory" "store")
18376 (set_attr "mode" "SI")])
18378 (define_insn "*strsetsi_rex_1"
18379 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18380 (match_operand:SI 2 "register_operand" "a"))
18381 (set (match_operand:DI 0 "register_operand" "=D")
18382 (plus:DI (match_dup 1)
18384 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18386 [(set_attr "type" "str")
18387 (set_attr "memory" "store")
18388 (set_attr "mode" "SI")])
18390 (define_insn "*strsethi_1"
18391 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18392 (match_operand:HI 2 "register_operand" "a"))
18393 (set (match_operand:SI 0 "register_operand" "=D")
18394 (plus:SI (match_dup 1)
18396 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18398 [(set_attr "type" "str")
18399 (set_attr "memory" "store")
18400 (set_attr "mode" "HI")])
18402 (define_insn "*strsethi_rex_1"
18403 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18404 (match_operand:HI 2 "register_operand" "a"))
18405 (set (match_operand:DI 0 "register_operand" "=D")
18406 (plus:DI (match_dup 1)
18408 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18410 [(set_attr "type" "str")
18411 (set_attr "memory" "store")
18412 (set_attr "mode" "HI")])
18414 (define_insn "*strsetqi_1"
18415 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18416 (match_operand:QI 2 "register_operand" "a"))
18417 (set (match_operand:SI 0 "register_operand" "=D")
18418 (plus:SI (match_dup 1)
18420 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18422 [(set_attr "type" "str")
18423 (set_attr "memory" "store")
18424 (set_attr "mode" "QI")])
18426 (define_insn "*strsetqi_rex_1"
18427 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18428 (match_operand:QI 2 "register_operand" "a"))
18429 (set (match_operand:DI 0 "register_operand" "=D")
18430 (plus:DI (match_dup 1)
18432 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18434 [(set_attr "type" "str")
18435 (set_attr "memory" "store")
18436 (set_attr "mode" "QI")])
18438 (define_expand "rep_stos"
18439 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18440 (set (match_operand 0 "register_operand" "")
18441 (match_operand 4 "" ""))
18442 (set (match_operand 2 "memory_operand" "") (const_int 0))
18443 (use (match_operand 3 "register_operand" ""))
18444 (use (match_dup 1))])]
18448 (define_insn "*rep_stosdi_rex64"
18449 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18450 (set (match_operand:DI 0 "register_operand" "=D")
18451 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18453 (match_operand:DI 3 "register_operand" "0")))
18454 (set (mem:BLK (match_dup 3))
18456 (use (match_operand:DI 2 "register_operand" "a"))
18457 (use (match_dup 4))]
18459 "{rep\;stosq|rep stosq}"
18460 [(set_attr "type" "str")
18461 (set_attr "prefix_rep" "1")
18462 (set_attr "memory" "store")
18463 (set_attr "mode" "DI")])
18465 (define_insn "*rep_stossi"
18466 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18467 (set (match_operand:SI 0 "register_operand" "=D")
18468 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18470 (match_operand:SI 3 "register_operand" "0")))
18471 (set (mem:BLK (match_dup 3))
18473 (use (match_operand:SI 2 "register_operand" "a"))
18474 (use (match_dup 4))]
18476 "{rep\;stosl|rep stosd}"
18477 [(set_attr "type" "str")
18478 (set_attr "prefix_rep" "1")
18479 (set_attr "memory" "store")
18480 (set_attr "mode" "SI")])
18482 (define_insn "*rep_stossi_rex64"
18483 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18484 (set (match_operand:DI 0 "register_operand" "=D")
18485 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18487 (match_operand:DI 3 "register_operand" "0")))
18488 (set (mem:BLK (match_dup 3))
18490 (use (match_operand:SI 2 "register_operand" "a"))
18491 (use (match_dup 4))]
18493 "{rep\;stosl|rep stosd}"
18494 [(set_attr "type" "str")
18495 (set_attr "prefix_rep" "1")
18496 (set_attr "memory" "store")
18497 (set_attr "mode" "SI")])
18499 (define_insn "*rep_stosqi"
18500 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18501 (set (match_operand:SI 0 "register_operand" "=D")
18502 (plus:SI (match_operand:SI 3 "register_operand" "0")
18503 (match_operand:SI 4 "register_operand" "1")))
18504 (set (mem:BLK (match_dup 3))
18506 (use (match_operand:QI 2 "register_operand" "a"))
18507 (use (match_dup 4))]
18509 "{rep\;stosb|rep stosb}"
18510 [(set_attr "type" "str")
18511 (set_attr "prefix_rep" "1")
18512 (set_attr "memory" "store")
18513 (set_attr "mode" "QI")])
18515 (define_insn "*rep_stosqi_rex64"
18516 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18517 (set (match_operand:DI 0 "register_operand" "=D")
18518 (plus:DI (match_operand:DI 3 "register_operand" "0")
18519 (match_operand:DI 4 "register_operand" "1")))
18520 (set (mem:BLK (match_dup 3))
18522 (use (match_operand:QI 2 "register_operand" "a"))
18523 (use (match_dup 4))]
18525 "{rep\;stosb|rep stosb}"
18526 [(set_attr "type" "str")
18527 (set_attr "prefix_rep" "1")
18528 (set_attr "memory" "store")
18529 (set_attr "mode" "QI")])
18531 (define_expand "cmpstrnsi"
18532 [(set (match_operand:SI 0 "register_operand" "")
18533 (compare:SI (match_operand:BLK 1 "general_operand" "")
18534 (match_operand:BLK 2 "general_operand" "")))
18535 (use (match_operand 3 "general_operand" ""))
18536 (use (match_operand 4 "immediate_operand" ""))]
18537 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18539 rtx addr1, addr2, out, outlow, count, countreg, align;
18541 /* Can't use this if the user has appropriated esi or edi. */
18542 if (global_regs[4] || global_regs[5])
18547 out = gen_reg_rtx (SImode);
18549 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18550 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18551 if (addr1 != XEXP (operands[1], 0))
18552 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18553 if (addr2 != XEXP (operands[2], 0))
18554 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18556 count = operands[3];
18557 countreg = ix86_zero_extend_to_Pmode (count);
18559 /* %%% Iff we are testing strict equality, we can use known alignment
18560 to good advantage. This may be possible with combine, particularly
18561 once cc0 is dead. */
18562 align = operands[4];
18564 if (CONST_INT_P (count))
18566 if (INTVAL (count) == 0)
18568 emit_move_insn (operands[0], const0_rtx);
18571 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18572 operands[1], operands[2]));
18577 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18579 emit_insn (gen_cmpsi_1 (countreg, countreg));
18580 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18581 operands[1], operands[2]));
18584 outlow = gen_lowpart (QImode, out);
18585 emit_insn (gen_cmpintqi (outlow));
18586 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18588 if (operands[0] != out)
18589 emit_move_insn (operands[0], out);
18594 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18596 (define_expand "cmpintqi"
18597 [(set (match_dup 1)
18598 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18600 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18601 (parallel [(set (match_operand:QI 0 "register_operand" "")
18602 (minus:QI (match_dup 1)
18604 (clobber (reg:CC FLAGS_REG))])]
18606 "operands[1] = gen_reg_rtx (QImode);
18607 operands[2] = gen_reg_rtx (QImode);")
18609 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18610 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18612 (define_expand "cmpstrnqi_nz_1"
18613 [(parallel [(set (reg:CC FLAGS_REG)
18614 (compare:CC (match_operand 4 "memory_operand" "")
18615 (match_operand 5 "memory_operand" "")))
18616 (use (match_operand 2 "register_operand" ""))
18617 (use (match_operand:SI 3 "immediate_operand" ""))
18618 (clobber (match_operand 0 "register_operand" ""))
18619 (clobber (match_operand 1 "register_operand" ""))
18620 (clobber (match_dup 2))])]
18624 (define_insn "*cmpstrnqi_nz_1"
18625 [(set (reg:CC FLAGS_REG)
18626 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18627 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18628 (use (match_operand:SI 6 "register_operand" "2"))
18629 (use (match_operand:SI 3 "immediate_operand" "i"))
18630 (clobber (match_operand:SI 0 "register_operand" "=S"))
18631 (clobber (match_operand:SI 1 "register_operand" "=D"))
18632 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18635 [(set_attr "type" "str")
18636 (set_attr "mode" "QI")
18637 (set_attr "prefix_rep" "1")])
18639 (define_insn "*cmpstrnqi_nz_rex_1"
18640 [(set (reg:CC FLAGS_REG)
18641 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18642 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18643 (use (match_operand:DI 6 "register_operand" "2"))
18644 (use (match_operand:SI 3 "immediate_operand" "i"))
18645 (clobber (match_operand:DI 0 "register_operand" "=S"))
18646 (clobber (match_operand:DI 1 "register_operand" "=D"))
18647 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18650 [(set_attr "type" "str")
18651 (set_attr "mode" "QI")
18652 (set_attr "prefix_rep" "1")])
18654 ;; The same, but the count is not known to not be zero.
18656 (define_expand "cmpstrnqi_1"
18657 [(parallel [(set (reg:CC FLAGS_REG)
18658 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18660 (compare:CC (match_operand 4 "memory_operand" "")
18661 (match_operand 5 "memory_operand" ""))
18663 (use (match_operand:SI 3 "immediate_operand" ""))
18664 (use (reg:CC FLAGS_REG))
18665 (clobber (match_operand 0 "register_operand" ""))
18666 (clobber (match_operand 1 "register_operand" ""))
18667 (clobber (match_dup 2))])]
18671 (define_insn "*cmpstrnqi_1"
18672 [(set (reg:CC FLAGS_REG)
18673 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18675 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18676 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18678 (use (match_operand:SI 3 "immediate_operand" "i"))
18679 (use (reg:CC FLAGS_REG))
18680 (clobber (match_operand:SI 0 "register_operand" "=S"))
18681 (clobber (match_operand:SI 1 "register_operand" "=D"))
18682 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18685 [(set_attr "type" "str")
18686 (set_attr "mode" "QI")
18687 (set_attr "prefix_rep" "1")])
18689 (define_insn "*cmpstrnqi_rex_1"
18690 [(set (reg:CC FLAGS_REG)
18691 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18693 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18694 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18696 (use (match_operand:SI 3 "immediate_operand" "i"))
18697 (use (reg:CC FLAGS_REG))
18698 (clobber (match_operand:DI 0 "register_operand" "=S"))
18699 (clobber (match_operand:DI 1 "register_operand" "=D"))
18700 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18703 [(set_attr "type" "str")
18704 (set_attr "mode" "QI")
18705 (set_attr "prefix_rep" "1")])
18707 (define_expand "strlensi"
18708 [(set (match_operand:SI 0 "register_operand" "")
18709 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18710 (match_operand:QI 2 "immediate_operand" "")
18711 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18714 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18720 (define_expand "strlendi"
18721 [(set (match_operand:DI 0 "register_operand" "")
18722 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18723 (match_operand:QI 2 "immediate_operand" "")
18724 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18727 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18733 (define_expand "strlenqi_1"
18734 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18735 (clobber (match_operand 1 "register_operand" ""))
18736 (clobber (reg:CC FLAGS_REG))])]
18740 (define_insn "*strlenqi_1"
18741 [(set (match_operand:SI 0 "register_operand" "=&c")
18742 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18743 (match_operand:QI 2 "register_operand" "a")
18744 (match_operand:SI 3 "immediate_operand" "i")
18745 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18746 (clobber (match_operand:SI 1 "register_operand" "=D"))
18747 (clobber (reg:CC FLAGS_REG))]
18750 [(set_attr "type" "str")
18751 (set_attr "mode" "QI")
18752 (set_attr "prefix_rep" "1")])
18754 (define_insn "*strlenqi_rex_1"
18755 [(set (match_operand:DI 0 "register_operand" "=&c")
18756 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18757 (match_operand:QI 2 "register_operand" "a")
18758 (match_operand:DI 3 "immediate_operand" "i")
18759 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18760 (clobber (match_operand:DI 1 "register_operand" "=D"))
18761 (clobber (reg:CC FLAGS_REG))]
18764 [(set_attr "type" "str")
18765 (set_attr "mode" "QI")
18766 (set_attr "prefix_rep" "1")])
18768 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18769 ;; handled in combine, but it is not currently up to the task.
18770 ;; When used for their truth value, the cmpstrn* expanders generate
18779 ;; The intermediate three instructions are unnecessary.
18781 ;; This one handles cmpstrn*_nz_1...
18784 (set (reg:CC FLAGS_REG)
18785 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18786 (mem:BLK (match_operand 5 "register_operand" ""))))
18787 (use (match_operand 6 "register_operand" ""))
18788 (use (match_operand:SI 3 "immediate_operand" ""))
18789 (clobber (match_operand 0 "register_operand" ""))
18790 (clobber (match_operand 1 "register_operand" ""))
18791 (clobber (match_operand 2 "register_operand" ""))])
18792 (set (match_operand:QI 7 "register_operand" "")
18793 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18794 (set (match_operand:QI 8 "register_operand" "")
18795 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18796 (set (reg FLAGS_REG)
18797 (compare (match_dup 7) (match_dup 8)))
18799 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18801 (set (reg:CC FLAGS_REG)
18802 (compare:CC (mem:BLK (match_dup 4))
18803 (mem:BLK (match_dup 5))))
18804 (use (match_dup 6))
18805 (use (match_dup 3))
18806 (clobber (match_dup 0))
18807 (clobber (match_dup 1))
18808 (clobber (match_dup 2))])]
18811 ;; ...and this one handles cmpstrn*_1.
18814 (set (reg:CC FLAGS_REG)
18815 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18817 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18818 (mem:BLK (match_operand 5 "register_operand" "")))
18820 (use (match_operand:SI 3 "immediate_operand" ""))
18821 (use (reg:CC FLAGS_REG))
18822 (clobber (match_operand 0 "register_operand" ""))
18823 (clobber (match_operand 1 "register_operand" ""))
18824 (clobber (match_operand 2 "register_operand" ""))])
18825 (set (match_operand:QI 7 "register_operand" "")
18826 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18827 (set (match_operand:QI 8 "register_operand" "")
18828 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18829 (set (reg FLAGS_REG)
18830 (compare (match_dup 7) (match_dup 8)))
18832 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18834 (set (reg:CC FLAGS_REG)
18835 (if_then_else:CC (ne (match_dup 6)
18837 (compare:CC (mem:BLK (match_dup 4))
18838 (mem:BLK (match_dup 5)))
18840 (use (match_dup 3))
18841 (use (reg:CC FLAGS_REG))
18842 (clobber (match_dup 0))
18843 (clobber (match_dup 1))
18844 (clobber (match_dup 2))])]
18849 ;; Conditional move instructions.
18851 (define_expand "movdicc"
18852 [(set (match_operand:DI 0 "register_operand" "")
18853 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18854 (match_operand:DI 2 "general_operand" "")
18855 (match_operand:DI 3 "general_operand" "")))]
18857 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18859 (define_insn "x86_movdicc_0_m1_rex64"
18860 [(set (match_operand:DI 0 "register_operand" "=r")
18861 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18864 (clobber (reg:CC FLAGS_REG))]
18867 ; Since we don't have the proper number of operands for an alu insn,
18868 ; fill in all the blanks.
18869 [(set_attr "type" "alu")
18870 (set_attr "pent_pair" "pu")
18871 (set_attr "memory" "none")
18872 (set_attr "imm_disp" "false")
18873 (set_attr "mode" "DI")
18874 (set_attr "length_immediate" "0")])
18876 (define_insn "*movdicc_c_rex64"
18877 [(set (match_operand:DI 0 "register_operand" "=r,r")
18878 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18879 [(reg FLAGS_REG) (const_int 0)])
18880 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18881 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18882 "TARGET_64BIT && TARGET_CMOVE
18883 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18885 cmov%O2%C1\t{%2, %0|%0, %2}
18886 cmov%O2%c1\t{%3, %0|%0, %3}"
18887 [(set_attr "type" "icmov")
18888 (set_attr "mode" "DI")])
18890 (define_expand "movsicc"
18891 [(set (match_operand:SI 0 "register_operand" "")
18892 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18893 (match_operand:SI 2 "general_operand" "")
18894 (match_operand:SI 3 "general_operand" "")))]
18896 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18898 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18899 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18900 ;; So just document what we're doing explicitly.
18902 (define_insn "x86_movsicc_0_m1"
18903 [(set (match_operand:SI 0 "register_operand" "=r")
18904 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18907 (clobber (reg:CC FLAGS_REG))]
18910 ; Since we don't have the proper number of operands for an alu insn,
18911 ; fill in all the blanks.
18912 [(set_attr "type" "alu")
18913 (set_attr "pent_pair" "pu")
18914 (set_attr "memory" "none")
18915 (set_attr "imm_disp" "false")
18916 (set_attr "mode" "SI")
18917 (set_attr "length_immediate" "0")])
18919 (define_insn "*movsicc_noc"
18920 [(set (match_operand:SI 0 "register_operand" "=r,r")
18921 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18922 [(reg FLAGS_REG) (const_int 0)])
18923 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18924 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18926 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18928 cmov%O2%C1\t{%2, %0|%0, %2}
18929 cmov%O2%c1\t{%3, %0|%0, %3}"
18930 [(set_attr "type" "icmov")
18931 (set_attr "mode" "SI")])
18933 (define_expand "movhicc"
18934 [(set (match_operand:HI 0 "register_operand" "")
18935 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18936 (match_operand:HI 2 "general_operand" "")
18937 (match_operand:HI 3 "general_operand" "")))]
18938 "TARGET_HIMODE_MATH"
18939 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18941 (define_insn "*movhicc_noc"
18942 [(set (match_operand:HI 0 "register_operand" "=r,r")
18943 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18944 [(reg FLAGS_REG) (const_int 0)])
18945 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18946 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18948 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18950 cmov%O2%C1\t{%2, %0|%0, %2}
18951 cmov%O2%c1\t{%3, %0|%0, %3}"
18952 [(set_attr "type" "icmov")
18953 (set_attr "mode" "HI")])
18955 (define_expand "movqicc"
18956 [(set (match_operand:QI 0 "register_operand" "")
18957 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18958 (match_operand:QI 2 "general_operand" "")
18959 (match_operand:QI 3 "general_operand" "")))]
18960 "TARGET_QIMODE_MATH"
18961 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18963 (define_insn_and_split "*movqicc_noc"
18964 [(set (match_operand:QI 0 "register_operand" "=r,r")
18965 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18966 [(match_operand 4 "flags_reg_operand" "")
18968 (match_operand:QI 2 "register_operand" "r,0")
18969 (match_operand:QI 3 "register_operand" "0,r")))]
18970 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18972 "&& reload_completed"
18973 [(set (match_dup 0)
18974 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18977 "operands[0] = gen_lowpart (SImode, operands[0]);
18978 operands[2] = gen_lowpart (SImode, operands[2]);
18979 operands[3] = gen_lowpart (SImode, operands[3]);"
18980 [(set_attr "type" "icmov")
18981 (set_attr "mode" "SI")])
18983 (define_expand "movsfcc"
18984 [(set (match_operand:SF 0 "register_operand" "")
18985 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18986 (match_operand:SF 2 "register_operand" "")
18987 (match_operand:SF 3 "register_operand" "")))]
18988 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18989 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18991 (define_insn "*movsfcc_1_387"
18992 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18993 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18994 [(reg FLAGS_REG) (const_int 0)])
18995 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18996 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18997 "TARGET_80387 && TARGET_CMOVE
18998 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19000 fcmov%F1\t{%2, %0|%0, %2}
19001 fcmov%f1\t{%3, %0|%0, %3}
19002 cmov%O2%C1\t{%2, %0|%0, %2}
19003 cmov%O2%c1\t{%3, %0|%0, %3}"
19004 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19005 (set_attr "mode" "SF,SF,SI,SI")])
19007 (define_expand "movdfcc"
19008 [(set (match_operand:DF 0 "register_operand" "")
19009 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19010 (match_operand:DF 2 "register_operand" "")
19011 (match_operand:DF 3 "register_operand" "")))]
19012 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19013 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19015 (define_insn "*movdfcc_1"
19016 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19017 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19018 [(reg FLAGS_REG) (const_int 0)])
19019 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19020 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19021 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19022 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19024 fcmov%F1\t{%2, %0|%0, %2}
19025 fcmov%f1\t{%3, %0|%0, %3}
19028 [(set_attr "type" "fcmov,fcmov,multi,multi")
19029 (set_attr "mode" "DF")])
19031 (define_insn "*movdfcc_1_rex64"
19032 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19033 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19034 [(reg FLAGS_REG) (const_int 0)])
19035 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19036 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19037 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19038 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19040 fcmov%F1\t{%2, %0|%0, %2}
19041 fcmov%f1\t{%3, %0|%0, %3}
19042 cmov%O2%C1\t{%2, %0|%0, %2}
19043 cmov%O2%c1\t{%3, %0|%0, %3}"
19044 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19045 (set_attr "mode" "DF")])
19048 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19049 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19050 [(match_operand 4 "flags_reg_operand" "")
19052 (match_operand:DF 2 "nonimmediate_operand" "")
19053 (match_operand:DF 3 "nonimmediate_operand" "")))]
19054 "!TARGET_64BIT && reload_completed"
19055 [(set (match_dup 2)
19056 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19060 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19063 "split_di (operands+2, 1, operands+5, operands+6);
19064 split_di (operands+3, 1, operands+7, operands+8);
19065 split_di (operands, 1, operands+2, operands+3);")
19067 (define_expand "movxfcc"
19068 [(set (match_operand:XF 0 "register_operand" "")
19069 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19070 (match_operand:XF 2 "register_operand" "")
19071 (match_operand:XF 3 "register_operand" "")))]
19072 "TARGET_80387 && TARGET_CMOVE"
19073 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19075 (define_insn "*movxfcc_1"
19076 [(set (match_operand:XF 0 "register_operand" "=f,f")
19077 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19078 [(reg FLAGS_REG) (const_int 0)])
19079 (match_operand:XF 2 "register_operand" "f,0")
19080 (match_operand:XF 3 "register_operand" "0,f")))]
19081 "TARGET_80387 && TARGET_CMOVE"
19083 fcmov%F1\t{%2, %0|%0, %2}
19084 fcmov%f1\t{%3, %0|%0, %3}"
19085 [(set_attr "type" "fcmov")
19086 (set_attr "mode" "XF")])
19088 ;; These versions of the min/max patterns are intentionally ignorant of
19089 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19090 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19091 ;; are undefined in this condition, we're certain this is correct.
19093 (define_insn "sminsf3"
19094 [(set (match_operand:SF 0 "register_operand" "=x")
19095 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19096 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19098 "minss\t{%2, %0|%0, %2}"
19099 [(set_attr "type" "sseadd")
19100 (set_attr "mode" "SF")])
19102 (define_insn "smaxsf3"
19103 [(set (match_operand:SF 0 "register_operand" "=x")
19104 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19105 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19107 "maxss\t{%2, %0|%0, %2}"
19108 [(set_attr "type" "sseadd")
19109 (set_attr "mode" "SF")])
19111 (define_insn "smindf3"
19112 [(set (match_operand:DF 0 "register_operand" "=x")
19113 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19114 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19115 "TARGET_SSE2 && TARGET_SSE_MATH"
19116 "minsd\t{%2, %0|%0, %2}"
19117 [(set_attr "type" "sseadd")
19118 (set_attr "mode" "DF")])
19120 (define_insn "smaxdf3"
19121 [(set (match_operand:DF 0 "register_operand" "=x")
19122 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19123 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19124 "TARGET_SSE2 && TARGET_SSE_MATH"
19125 "maxsd\t{%2, %0|%0, %2}"
19126 [(set_attr "type" "sseadd")
19127 (set_attr "mode" "DF")])
19129 ;; These versions of the min/max patterns implement exactly the operations
19130 ;; min = (op1 < op2 ? op1 : op2)
19131 ;; max = (!(op1 < op2) ? op1 : op2)
19132 ;; Their operands are not commutative, and thus they may be used in the
19133 ;; presence of -0.0 and NaN.
19135 (define_insn "*ieee_sminsf3"
19136 [(set (match_operand:SF 0 "register_operand" "=x")
19137 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19138 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19141 "minss\t{%2, %0|%0, %2}"
19142 [(set_attr "type" "sseadd")
19143 (set_attr "mode" "SF")])
19145 (define_insn "*ieee_smaxsf3"
19146 [(set (match_operand:SF 0 "register_operand" "=x")
19147 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19148 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19151 "maxss\t{%2, %0|%0, %2}"
19152 [(set_attr "type" "sseadd")
19153 (set_attr "mode" "SF")])
19155 (define_insn "*ieee_smindf3"
19156 [(set (match_operand:DF 0 "register_operand" "=x")
19157 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19158 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19160 "TARGET_SSE2 && TARGET_SSE_MATH"
19161 "minsd\t{%2, %0|%0, %2}"
19162 [(set_attr "type" "sseadd")
19163 (set_attr "mode" "DF")])
19165 (define_insn "*ieee_smaxdf3"
19166 [(set (match_operand:DF 0 "register_operand" "=x")
19167 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19168 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19170 "TARGET_SSE2 && TARGET_SSE_MATH"
19171 "maxsd\t{%2, %0|%0, %2}"
19172 [(set_attr "type" "sseadd")
19173 (set_attr "mode" "DF")])
19175 ;; Make two stack loads independent:
19177 ;; fld %st(0) -> fld bb
19178 ;; fmul bb fmul %st(1), %st
19180 ;; Actually we only match the last two instructions for simplicity.
19182 [(set (match_operand 0 "fp_register_operand" "")
19183 (match_operand 1 "fp_register_operand" ""))
19185 (match_operator 2 "binary_fp_operator"
19187 (match_operand 3 "memory_operand" "")]))]
19188 "REGNO (operands[0]) != REGNO (operands[1])"
19189 [(set (match_dup 0) (match_dup 3))
19190 (set (match_dup 0) (match_dup 4))]
19192 ;; The % modifier is not operational anymore in peephole2's, so we have to
19193 ;; swap the operands manually in the case of addition and multiplication.
19194 "if (COMMUTATIVE_ARITH_P (operands[2]))
19195 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19196 operands[0], operands[1]);
19198 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19199 operands[1], operands[0]);")
19201 ;; Conditional addition patterns
19202 (define_expand "addqicc"
19203 [(match_operand:QI 0 "register_operand" "")
19204 (match_operand 1 "comparison_operator" "")
19205 (match_operand:QI 2 "register_operand" "")
19206 (match_operand:QI 3 "const_int_operand" "")]
19208 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19210 (define_expand "addhicc"
19211 [(match_operand:HI 0 "register_operand" "")
19212 (match_operand 1 "comparison_operator" "")
19213 (match_operand:HI 2 "register_operand" "")
19214 (match_operand:HI 3 "const_int_operand" "")]
19216 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19218 (define_expand "addsicc"
19219 [(match_operand:SI 0 "register_operand" "")
19220 (match_operand 1 "comparison_operator" "")
19221 (match_operand:SI 2 "register_operand" "")
19222 (match_operand:SI 3 "const_int_operand" "")]
19224 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19226 (define_expand "adddicc"
19227 [(match_operand:DI 0 "register_operand" "")
19228 (match_operand 1 "comparison_operator" "")
19229 (match_operand:DI 2 "register_operand" "")
19230 (match_operand:DI 3 "const_int_operand" "")]
19232 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19235 ;; Misc patterns (?)
19237 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19238 ;; Otherwise there will be nothing to keep
19240 ;; [(set (reg ebp) (reg esp))]
19241 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19242 ;; (clobber (eflags)]
19243 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19245 ;; in proper program order.
19246 (define_insn "pro_epilogue_adjust_stack_1"
19247 [(set (match_operand:SI 0 "register_operand" "=r,r")
19248 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19249 (match_operand:SI 2 "immediate_operand" "i,i")))
19250 (clobber (reg:CC FLAGS_REG))
19251 (clobber (mem:BLK (scratch)))]
19254 switch (get_attr_type (insn))
19257 return "mov{l}\t{%1, %0|%0, %1}";
19260 if (CONST_INT_P (operands[2])
19261 && (INTVAL (operands[2]) == 128
19262 || (INTVAL (operands[2]) < 0
19263 && INTVAL (operands[2]) != -128)))
19265 operands[2] = GEN_INT (-INTVAL (operands[2]));
19266 return "sub{l}\t{%2, %0|%0, %2}";
19268 return "add{l}\t{%2, %0|%0, %2}";
19271 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19272 return "lea{l}\t{%a2, %0|%0, %a2}";
19275 gcc_unreachable ();
19278 [(set (attr "type")
19279 (cond [(eq_attr "alternative" "0")
19280 (const_string "alu")
19281 (match_operand:SI 2 "const0_operand" "")
19282 (const_string "imov")
19284 (const_string "lea")))
19285 (set_attr "mode" "SI")])
19287 (define_insn "pro_epilogue_adjust_stack_rex64"
19288 [(set (match_operand:DI 0 "register_operand" "=r,r")
19289 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19290 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19291 (clobber (reg:CC FLAGS_REG))
19292 (clobber (mem:BLK (scratch)))]
19295 switch (get_attr_type (insn))
19298 return "mov{q}\t{%1, %0|%0, %1}";
19301 if (CONST_INT_P (operands[2])
19302 /* Avoid overflows. */
19303 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19304 && (INTVAL (operands[2]) == 128
19305 || (INTVAL (operands[2]) < 0
19306 && INTVAL (operands[2]) != -128)))
19308 operands[2] = GEN_INT (-INTVAL (operands[2]));
19309 return "sub{q}\t{%2, %0|%0, %2}";
19311 return "add{q}\t{%2, %0|%0, %2}";
19314 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19315 return "lea{q}\t{%a2, %0|%0, %a2}";
19318 gcc_unreachable ();
19321 [(set (attr "type")
19322 (cond [(eq_attr "alternative" "0")
19323 (const_string "alu")
19324 (match_operand:DI 2 "const0_operand" "")
19325 (const_string "imov")
19327 (const_string "lea")))
19328 (set_attr "mode" "DI")])
19330 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19331 [(set (match_operand:DI 0 "register_operand" "=r,r")
19332 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19333 (match_operand:DI 3 "immediate_operand" "i,i")))
19334 (use (match_operand:DI 2 "register_operand" "r,r"))
19335 (clobber (reg:CC FLAGS_REG))
19336 (clobber (mem:BLK (scratch)))]
19339 switch (get_attr_type (insn))
19342 return "add{q}\t{%2, %0|%0, %2}";
19345 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19346 return "lea{q}\t{%a2, %0|%0, %a2}";
19349 gcc_unreachable ();
19352 [(set_attr "type" "alu,lea")
19353 (set_attr "mode" "DI")])
19355 (define_insn "allocate_stack_worker_32"
19356 [(set (match_operand:SI 0 "register_operand" "+a")
19357 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19358 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19359 (clobber (reg:CC FLAGS_REG))]
19360 "!TARGET_64BIT && TARGET_STACK_PROBE"
19362 [(set_attr "type" "multi")
19363 (set_attr "length" "5")])
19365 (define_insn "allocate_stack_worker_64"
19366 [(set (match_operand:DI 0 "register_operand" "=a")
19367 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19368 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19369 (clobber (reg:DI R10_REG))
19370 (clobber (reg:DI R11_REG))
19371 (clobber (reg:CC FLAGS_REG))]
19372 "TARGET_64BIT && TARGET_STACK_PROBE"
19374 [(set_attr "type" "multi")
19375 (set_attr "length" "5")])
19377 (define_expand "allocate_stack"
19378 [(match_operand 0 "register_operand" "")
19379 (match_operand 1 "general_operand" "")]
19380 "TARGET_STACK_PROBE"
19384 #ifndef CHECK_STACK_LIMIT
19385 #define CHECK_STACK_LIMIT 0
19388 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19389 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19391 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19392 stack_pointer_rtx, 0, OPTAB_DIRECT);
19393 if (x != stack_pointer_rtx)
19394 emit_move_insn (stack_pointer_rtx, x);
19398 x = copy_to_mode_reg (Pmode, operands[1]);
19400 x = gen_allocate_stack_worker_64 (x);
19402 x = gen_allocate_stack_worker_32 (x);
19406 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19410 (define_expand "builtin_setjmp_receiver"
19411 [(label_ref (match_operand 0 "" ""))]
19412 "!TARGET_64BIT && flag_pic"
19417 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19418 rtx label_rtx = gen_label_rtx ();
19419 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19420 xops[0] = xops[1] = picreg;
19421 xops[2] = gen_rtx_CONST (SImode,
19422 gen_rtx_MINUS (SImode,
19423 gen_rtx_LABEL_REF (SImode, label_rtx),
19424 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19425 ix86_expand_binary_operator (MINUS, SImode, xops);
19428 emit_insn (gen_set_got (pic_offset_table_rtx));
19432 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19435 [(set (match_operand 0 "register_operand" "")
19436 (match_operator 3 "promotable_binary_operator"
19437 [(match_operand 1 "register_operand" "")
19438 (match_operand 2 "aligned_operand" "")]))
19439 (clobber (reg:CC FLAGS_REG))]
19440 "! TARGET_PARTIAL_REG_STALL && reload_completed
19441 && ((GET_MODE (operands[0]) == HImode
19442 && ((!optimize_size && !TARGET_FAST_PREFIX)
19443 /* ??? next two lines just !satisfies_constraint_K (...) */
19444 || !CONST_INT_P (operands[2])
19445 || satisfies_constraint_K (operands[2])))
19446 || (GET_MODE (operands[0]) == QImode
19447 && (TARGET_PROMOTE_QImode || optimize_size)))"
19448 [(parallel [(set (match_dup 0)
19449 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19450 (clobber (reg:CC FLAGS_REG))])]
19451 "operands[0] = gen_lowpart (SImode, operands[0]);
19452 operands[1] = gen_lowpart (SImode, operands[1]);
19453 if (GET_CODE (operands[3]) != ASHIFT)
19454 operands[2] = gen_lowpart (SImode, operands[2]);
19455 PUT_MODE (operands[3], SImode);")
19457 ; Promote the QImode tests, as i386 has encoding of the AND
19458 ; instruction with 32-bit sign-extended immediate and thus the
19459 ; instruction size is unchanged, except in the %eax case for
19460 ; which it is increased by one byte, hence the ! optimize_size.
19462 [(set (match_operand 0 "flags_reg_operand" "")
19463 (match_operator 2 "compare_operator"
19464 [(and (match_operand 3 "aligned_operand" "")
19465 (match_operand 4 "const_int_operand" ""))
19467 (set (match_operand 1 "register_operand" "")
19468 (and (match_dup 3) (match_dup 4)))]
19469 "! TARGET_PARTIAL_REG_STALL && reload_completed
19470 /* Ensure that the operand will remain sign-extended immediate. */
19471 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19473 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19474 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19475 [(parallel [(set (match_dup 0)
19476 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19479 (and:SI (match_dup 3) (match_dup 4)))])]
19482 = gen_int_mode (INTVAL (operands[4])
19483 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19484 operands[1] = gen_lowpart (SImode, operands[1]);
19485 operands[3] = gen_lowpart (SImode, operands[3]);
19488 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19489 ; the TEST instruction with 32-bit sign-extended immediate and thus
19490 ; the instruction size would at least double, which is not what we
19491 ; want even with ! optimize_size.
19493 [(set (match_operand 0 "flags_reg_operand" "")
19494 (match_operator 1 "compare_operator"
19495 [(and (match_operand:HI 2 "aligned_operand" "")
19496 (match_operand:HI 3 "const_int_operand" ""))
19498 "! TARGET_PARTIAL_REG_STALL && reload_completed
19499 /* Ensure that the operand will remain sign-extended immediate. */
19500 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19501 && ! TARGET_FAST_PREFIX
19502 && ! optimize_size"
19503 [(set (match_dup 0)
19504 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19508 = gen_int_mode (INTVAL (operands[3])
19509 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19510 operands[2] = gen_lowpart (SImode, operands[2]);
19514 [(set (match_operand 0 "register_operand" "")
19515 (neg (match_operand 1 "register_operand" "")))
19516 (clobber (reg:CC FLAGS_REG))]
19517 "! TARGET_PARTIAL_REG_STALL && reload_completed
19518 && (GET_MODE (operands[0]) == HImode
19519 || (GET_MODE (operands[0]) == QImode
19520 && (TARGET_PROMOTE_QImode || optimize_size)))"
19521 [(parallel [(set (match_dup 0)
19522 (neg:SI (match_dup 1)))
19523 (clobber (reg:CC FLAGS_REG))])]
19524 "operands[0] = gen_lowpart (SImode, operands[0]);
19525 operands[1] = gen_lowpart (SImode, operands[1]);")
19528 [(set (match_operand 0 "register_operand" "")
19529 (not (match_operand 1 "register_operand" "")))]
19530 "! TARGET_PARTIAL_REG_STALL && reload_completed
19531 && (GET_MODE (operands[0]) == HImode
19532 || (GET_MODE (operands[0]) == QImode
19533 && (TARGET_PROMOTE_QImode || optimize_size)))"
19534 [(set (match_dup 0)
19535 (not:SI (match_dup 1)))]
19536 "operands[0] = gen_lowpart (SImode, operands[0]);
19537 operands[1] = gen_lowpart (SImode, operands[1]);")
19540 [(set (match_operand 0 "register_operand" "")
19541 (if_then_else (match_operator 1 "comparison_operator"
19542 [(reg FLAGS_REG) (const_int 0)])
19543 (match_operand 2 "register_operand" "")
19544 (match_operand 3 "register_operand" "")))]
19545 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19546 && (GET_MODE (operands[0]) == HImode
19547 || (GET_MODE (operands[0]) == QImode
19548 && (TARGET_PROMOTE_QImode || optimize_size)))"
19549 [(set (match_dup 0)
19550 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19551 "operands[0] = gen_lowpart (SImode, operands[0]);
19552 operands[2] = gen_lowpart (SImode, operands[2]);
19553 operands[3] = gen_lowpart (SImode, operands[3]);")
19556 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19557 ;; transform a complex memory operation into two memory to register operations.
19559 ;; Don't push memory operands
19561 [(set (match_operand:SI 0 "push_operand" "")
19562 (match_operand:SI 1 "memory_operand" ""))
19563 (match_scratch:SI 2 "r")]
19564 "!optimize_size && !TARGET_PUSH_MEMORY
19565 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19566 [(set (match_dup 2) (match_dup 1))
19567 (set (match_dup 0) (match_dup 2))]
19571 [(set (match_operand:DI 0 "push_operand" "")
19572 (match_operand:DI 1 "memory_operand" ""))
19573 (match_scratch:DI 2 "r")]
19574 "!optimize_size && !TARGET_PUSH_MEMORY
19575 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19576 [(set (match_dup 2) (match_dup 1))
19577 (set (match_dup 0) (match_dup 2))]
19580 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19583 [(set (match_operand:SF 0 "push_operand" "")
19584 (match_operand:SF 1 "memory_operand" ""))
19585 (match_scratch:SF 2 "r")]
19586 "!optimize_size && !TARGET_PUSH_MEMORY
19587 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19588 [(set (match_dup 2) (match_dup 1))
19589 (set (match_dup 0) (match_dup 2))]
19593 [(set (match_operand:HI 0 "push_operand" "")
19594 (match_operand:HI 1 "memory_operand" ""))
19595 (match_scratch:HI 2 "r")]
19596 "!optimize_size && !TARGET_PUSH_MEMORY
19597 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19598 [(set (match_dup 2) (match_dup 1))
19599 (set (match_dup 0) (match_dup 2))]
19603 [(set (match_operand:QI 0 "push_operand" "")
19604 (match_operand:QI 1 "memory_operand" ""))
19605 (match_scratch:QI 2 "q")]
19606 "!optimize_size && !TARGET_PUSH_MEMORY
19607 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19608 [(set (match_dup 2) (match_dup 1))
19609 (set (match_dup 0) (match_dup 2))]
19612 ;; Don't move an immediate directly to memory when the instruction
19615 [(match_scratch:SI 1 "r")
19616 (set (match_operand:SI 0 "memory_operand" "")
19619 && ! TARGET_USE_MOV0
19620 && TARGET_SPLIT_LONG_MOVES
19621 && get_attr_length (insn) >= ix86_cost->large_insn
19622 && peep2_regno_dead_p (0, FLAGS_REG)"
19623 [(parallel [(set (match_dup 1) (const_int 0))
19624 (clobber (reg:CC FLAGS_REG))])
19625 (set (match_dup 0) (match_dup 1))]
19629 [(match_scratch:HI 1 "r")
19630 (set (match_operand:HI 0 "memory_operand" "")
19633 && ! TARGET_USE_MOV0
19634 && TARGET_SPLIT_LONG_MOVES
19635 && get_attr_length (insn) >= ix86_cost->large_insn
19636 && peep2_regno_dead_p (0, FLAGS_REG)"
19637 [(parallel [(set (match_dup 2) (const_int 0))
19638 (clobber (reg:CC FLAGS_REG))])
19639 (set (match_dup 0) (match_dup 1))]
19640 "operands[2] = gen_lowpart (SImode, operands[1]);")
19643 [(match_scratch:QI 1 "q")
19644 (set (match_operand:QI 0 "memory_operand" "")
19647 && ! TARGET_USE_MOV0
19648 && TARGET_SPLIT_LONG_MOVES
19649 && get_attr_length (insn) >= ix86_cost->large_insn
19650 && peep2_regno_dead_p (0, FLAGS_REG)"
19651 [(parallel [(set (match_dup 2) (const_int 0))
19652 (clobber (reg:CC FLAGS_REG))])
19653 (set (match_dup 0) (match_dup 1))]
19654 "operands[2] = gen_lowpart (SImode, operands[1]);")
19657 [(match_scratch:SI 2 "r")
19658 (set (match_operand:SI 0 "memory_operand" "")
19659 (match_operand:SI 1 "immediate_operand" ""))]
19661 && get_attr_length (insn) >= ix86_cost->large_insn
19662 && TARGET_SPLIT_LONG_MOVES"
19663 [(set (match_dup 2) (match_dup 1))
19664 (set (match_dup 0) (match_dup 2))]
19668 [(match_scratch:HI 2 "r")
19669 (set (match_operand:HI 0 "memory_operand" "")
19670 (match_operand:HI 1 "immediate_operand" ""))]
19671 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19672 && TARGET_SPLIT_LONG_MOVES"
19673 [(set (match_dup 2) (match_dup 1))
19674 (set (match_dup 0) (match_dup 2))]
19678 [(match_scratch:QI 2 "q")
19679 (set (match_operand:QI 0 "memory_operand" "")
19680 (match_operand:QI 1 "immediate_operand" ""))]
19681 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19682 && TARGET_SPLIT_LONG_MOVES"
19683 [(set (match_dup 2) (match_dup 1))
19684 (set (match_dup 0) (match_dup 2))]
19687 ;; Don't compare memory with zero, load and use a test instead.
19689 [(set (match_operand 0 "flags_reg_operand" "")
19690 (match_operator 1 "compare_operator"
19691 [(match_operand:SI 2 "memory_operand" "")
19693 (match_scratch:SI 3 "r")]
19694 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19695 [(set (match_dup 3) (match_dup 2))
19696 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19699 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19700 ;; Don't split NOTs with a displacement operand, because resulting XOR
19701 ;; will not be pairable anyway.
19703 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19704 ;; represented using a modRM byte. The XOR replacement is long decoded,
19705 ;; so this split helps here as well.
19707 ;; Note: Can't do this as a regular split because we can't get proper
19708 ;; lifetime information then.
19711 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19712 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19714 && peep2_regno_dead_p (0, FLAGS_REG)
19715 && ((TARGET_NOT_UNPAIRABLE
19716 && (!MEM_P (operands[0])
19717 || !memory_displacement_operand (operands[0], SImode)))
19718 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))"
19719 [(parallel [(set (match_dup 0)
19720 (xor:SI (match_dup 1) (const_int -1)))
19721 (clobber (reg:CC FLAGS_REG))])]
19725 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19726 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19728 && peep2_regno_dead_p (0, FLAGS_REG)
19729 && ((TARGET_NOT_UNPAIRABLE
19730 && (!MEM_P (operands[0])
19731 || !memory_displacement_operand (operands[0], HImode)))
19732 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))"
19733 [(parallel [(set (match_dup 0)
19734 (xor:HI (match_dup 1) (const_int -1)))
19735 (clobber (reg:CC FLAGS_REG))])]
19739 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19740 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19742 && peep2_regno_dead_p (0, FLAGS_REG)
19743 && ((TARGET_NOT_UNPAIRABLE
19744 && (!MEM_P (operands[0])
19745 || !memory_displacement_operand (operands[0], QImode)))
19746 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))"
19747 [(parallel [(set (match_dup 0)
19748 (xor:QI (match_dup 1) (const_int -1)))
19749 (clobber (reg:CC FLAGS_REG))])]
19752 ;; Non pairable "test imm, reg" instructions can be translated to
19753 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19754 ;; byte opcode instead of two, have a short form for byte operands),
19755 ;; so do it for other CPUs as well. Given that the value was dead,
19756 ;; this should not create any new dependencies. Pass on the sub-word
19757 ;; versions if we're concerned about partial register stalls.
19760 [(set (match_operand 0 "flags_reg_operand" "")
19761 (match_operator 1 "compare_operator"
19762 [(and:SI (match_operand:SI 2 "register_operand" "")
19763 (match_operand:SI 3 "immediate_operand" ""))
19765 "ix86_match_ccmode (insn, CCNOmode)
19766 && (true_regnum (operands[2]) != 0
19767 || satisfies_constraint_K (operands[3]))
19768 && peep2_reg_dead_p (1, operands[2])"
19770 [(set (match_dup 0)
19771 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19774 (and:SI (match_dup 2) (match_dup 3)))])]
19777 ;; We don't need to handle HImode case, because it will be promoted to SImode
19778 ;; on ! TARGET_PARTIAL_REG_STALL
19781 [(set (match_operand 0 "flags_reg_operand" "")
19782 (match_operator 1 "compare_operator"
19783 [(and:QI (match_operand:QI 2 "register_operand" "")
19784 (match_operand:QI 3 "immediate_operand" ""))
19786 "! TARGET_PARTIAL_REG_STALL
19787 && ix86_match_ccmode (insn, CCNOmode)
19788 && true_regnum (operands[2]) != 0
19789 && peep2_reg_dead_p (1, operands[2])"
19791 [(set (match_dup 0)
19792 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19795 (and:QI (match_dup 2) (match_dup 3)))])]
19799 [(set (match_operand 0 "flags_reg_operand" "")
19800 (match_operator 1 "compare_operator"
19803 (match_operand 2 "ext_register_operand" "")
19806 (match_operand 3 "const_int_operand" ""))
19808 "! TARGET_PARTIAL_REG_STALL
19809 && ix86_match_ccmode (insn, CCNOmode)
19810 && true_regnum (operands[2]) != 0
19811 && peep2_reg_dead_p (1, operands[2])"
19812 [(parallel [(set (match_dup 0)
19821 (set (zero_extract:SI (match_dup 2)
19832 ;; Don't do logical operations with memory inputs.
19834 [(match_scratch:SI 2 "r")
19835 (parallel [(set (match_operand:SI 0 "register_operand" "")
19836 (match_operator:SI 3 "arith_or_logical_operator"
19838 (match_operand:SI 1 "memory_operand" "")]))
19839 (clobber (reg:CC FLAGS_REG))])]
19840 "! optimize_size && ! TARGET_READ_MODIFY"
19841 [(set (match_dup 2) (match_dup 1))
19842 (parallel [(set (match_dup 0)
19843 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19844 (clobber (reg:CC FLAGS_REG))])]
19848 [(match_scratch:SI 2 "r")
19849 (parallel [(set (match_operand:SI 0 "register_operand" "")
19850 (match_operator:SI 3 "arith_or_logical_operator"
19851 [(match_operand:SI 1 "memory_operand" "")
19853 (clobber (reg:CC FLAGS_REG))])]
19854 "! optimize_size && ! TARGET_READ_MODIFY"
19855 [(set (match_dup 2) (match_dup 1))
19856 (parallel [(set (match_dup 0)
19857 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19858 (clobber (reg:CC FLAGS_REG))])]
19861 ; Don't do logical operations with memory outputs
19863 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19864 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19865 ; the same decoder scheduling characteristics as the original.
19868 [(match_scratch:SI 2 "r")
19869 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19870 (match_operator:SI 3 "arith_or_logical_operator"
19872 (match_operand:SI 1 "nonmemory_operand" "")]))
19873 (clobber (reg:CC FLAGS_REG))])]
19874 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19875 [(set (match_dup 2) (match_dup 0))
19876 (parallel [(set (match_dup 2)
19877 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19878 (clobber (reg:CC FLAGS_REG))])
19879 (set (match_dup 0) (match_dup 2))]
19883 [(match_scratch:SI 2 "r")
19884 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19885 (match_operator:SI 3 "arith_or_logical_operator"
19886 [(match_operand:SI 1 "nonmemory_operand" "")
19888 (clobber (reg:CC FLAGS_REG))])]
19889 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19890 [(set (match_dup 2) (match_dup 0))
19891 (parallel [(set (match_dup 2)
19892 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19893 (clobber (reg:CC FLAGS_REG))])
19894 (set (match_dup 0) (match_dup 2))]
19897 ;; Attempt to always use XOR for zeroing registers.
19899 [(set (match_operand 0 "register_operand" "")
19900 (match_operand 1 "const0_operand" ""))]
19901 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19902 && (! TARGET_USE_MOV0 || optimize_size)
19903 && GENERAL_REG_P (operands[0])
19904 && peep2_regno_dead_p (0, FLAGS_REG)"
19905 [(parallel [(set (match_dup 0) (const_int 0))
19906 (clobber (reg:CC FLAGS_REG))])]
19908 operands[0] = gen_lowpart (word_mode, operands[0]);
19912 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19914 "(GET_MODE (operands[0]) == QImode
19915 || GET_MODE (operands[0]) == HImode)
19916 && (! TARGET_USE_MOV0 || optimize_size)
19917 && peep2_regno_dead_p (0, FLAGS_REG)"
19918 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19919 (clobber (reg:CC FLAGS_REG))])])
19921 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19923 [(set (match_operand 0 "register_operand" "")
19925 "(GET_MODE (operands[0]) == HImode
19926 || GET_MODE (operands[0]) == SImode
19927 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19928 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
19929 && peep2_regno_dead_p (0, FLAGS_REG)"
19930 [(parallel [(set (match_dup 0) (const_int -1))
19931 (clobber (reg:CC FLAGS_REG))])]
19932 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19935 ;; Attempt to convert simple leas to adds. These can be created by
19938 [(set (match_operand:SI 0 "register_operand" "")
19939 (plus:SI (match_dup 0)
19940 (match_operand:SI 1 "nonmemory_operand" "")))]
19941 "peep2_regno_dead_p (0, FLAGS_REG)"
19942 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19943 (clobber (reg:CC FLAGS_REG))])]
19947 [(set (match_operand:SI 0 "register_operand" "")
19948 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19949 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19950 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19951 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19952 (clobber (reg:CC FLAGS_REG))])]
19953 "operands[2] = gen_lowpart (SImode, operands[2]);")
19956 [(set (match_operand:DI 0 "register_operand" "")
19957 (plus:DI (match_dup 0)
19958 (match_operand:DI 1 "x86_64_general_operand" "")))]
19959 "peep2_regno_dead_p (0, FLAGS_REG)"
19960 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19961 (clobber (reg:CC FLAGS_REG))])]
19965 [(set (match_operand:SI 0 "register_operand" "")
19966 (mult:SI (match_dup 0)
19967 (match_operand:SI 1 "const_int_operand" "")))]
19968 "exact_log2 (INTVAL (operands[1])) >= 0
19969 && peep2_regno_dead_p (0, FLAGS_REG)"
19970 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19971 (clobber (reg:CC FLAGS_REG))])]
19972 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19975 [(set (match_operand:DI 0 "register_operand" "")
19976 (mult:DI (match_dup 0)
19977 (match_operand:DI 1 "const_int_operand" "")))]
19978 "exact_log2 (INTVAL (operands[1])) >= 0
19979 && peep2_regno_dead_p (0, FLAGS_REG)"
19980 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19981 (clobber (reg:CC FLAGS_REG))])]
19982 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19985 [(set (match_operand:SI 0 "register_operand" "")
19986 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19987 (match_operand:DI 2 "const_int_operand" "")) 0))]
19988 "exact_log2 (INTVAL (operands[2])) >= 0
19989 && REGNO (operands[0]) == REGNO (operands[1])
19990 && peep2_regno_dead_p (0, FLAGS_REG)"
19991 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19992 (clobber (reg:CC FLAGS_REG))])]
19993 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19995 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19996 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19997 ;; many CPUs it is also faster, since special hardware to avoid esp
19998 ;; dependencies is present.
20000 ;; While some of these conversions may be done using splitters, we use peepholes
20001 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20003 ;; Convert prologue esp subtractions to push.
20004 ;; We need register to push. In order to keep verify_flow_info happy we have
20006 ;; - use scratch and clobber it in order to avoid dependencies
20007 ;; - use already live register
20008 ;; We can't use the second way right now, since there is no reliable way how to
20009 ;; verify that given register is live. First choice will also most likely in
20010 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20011 ;; call clobbered registers are dead. We may want to use base pointer as an
20012 ;; alternative when no register is available later.
20015 [(match_scratch:SI 0 "r")
20016 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20017 (clobber (reg:CC FLAGS_REG))
20018 (clobber (mem:BLK (scratch)))])]
20019 "optimize_size || !TARGET_SUB_ESP_4"
20020 [(clobber (match_dup 0))
20021 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20022 (clobber (mem:BLK (scratch)))])])
20025 [(match_scratch:SI 0 "r")
20026 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20027 (clobber (reg:CC FLAGS_REG))
20028 (clobber (mem:BLK (scratch)))])]
20029 "optimize_size || !TARGET_SUB_ESP_8"
20030 [(clobber (match_dup 0))
20031 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20032 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20033 (clobber (mem:BLK (scratch)))])])
20035 ;; Convert esp subtractions to push.
20037 [(match_scratch:SI 0 "r")
20038 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20039 (clobber (reg:CC FLAGS_REG))])]
20040 "optimize_size || !TARGET_SUB_ESP_4"
20041 [(clobber (match_dup 0))
20042 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20045 [(match_scratch:SI 0 "r")
20046 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20047 (clobber (reg:CC FLAGS_REG))])]
20048 "optimize_size || !TARGET_SUB_ESP_8"
20049 [(clobber (match_dup 0))
20050 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20051 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20053 ;; Convert epilogue deallocator to pop.
20055 [(match_scratch:SI 0 "r")
20056 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20057 (clobber (reg:CC FLAGS_REG))
20058 (clobber (mem:BLK (scratch)))])]
20059 "optimize_size || !TARGET_ADD_ESP_4"
20060 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20061 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20062 (clobber (mem:BLK (scratch)))])]
20065 ;; Two pops case is tricky, since pop causes dependency on destination register.
20066 ;; We use two registers if available.
20068 [(match_scratch:SI 0 "r")
20069 (match_scratch:SI 1 "r")
20070 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20071 (clobber (reg:CC FLAGS_REG))
20072 (clobber (mem:BLK (scratch)))])]
20073 "optimize_size || !TARGET_ADD_ESP_8"
20074 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20075 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20076 (clobber (mem:BLK (scratch)))])
20077 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20078 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20082 [(match_scratch:SI 0 "r")
20083 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20084 (clobber (reg:CC FLAGS_REG))
20085 (clobber (mem:BLK (scratch)))])]
20087 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20088 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20089 (clobber (mem:BLK (scratch)))])
20090 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20091 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20094 ;; Convert esp additions to pop.
20096 [(match_scratch:SI 0 "r")
20097 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20098 (clobber (reg:CC FLAGS_REG))])]
20100 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20101 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20104 ;; Two pops case is tricky, since pop causes dependency on destination register.
20105 ;; We use two registers if available.
20107 [(match_scratch:SI 0 "r")
20108 (match_scratch:SI 1 "r")
20109 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20110 (clobber (reg:CC FLAGS_REG))])]
20112 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20113 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20114 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20115 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20119 [(match_scratch:SI 0 "r")
20120 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20121 (clobber (reg:CC FLAGS_REG))])]
20123 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20124 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20125 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20126 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20129 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20130 ;; required and register dies. Similarly for 128 to plus -128.
20132 [(set (match_operand 0 "flags_reg_operand" "")
20133 (match_operator 1 "compare_operator"
20134 [(match_operand 2 "register_operand" "")
20135 (match_operand 3 "const_int_operand" "")]))]
20136 "(INTVAL (operands[3]) == -1
20137 || INTVAL (operands[3]) == 1
20138 || INTVAL (operands[3]) == 128)
20139 && ix86_match_ccmode (insn, CCGCmode)
20140 && peep2_reg_dead_p (1, operands[2])"
20141 [(parallel [(set (match_dup 0)
20142 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20143 (clobber (match_dup 2))])]
20147 [(match_scratch:DI 0 "r")
20148 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20149 (clobber (reg:CC FLAGS_REG))
20150 (clobber (mem:BLK (scratch)))])]
20151 "optimize_size || !TARGET_SUB_ESP_4"
20152 [(clobber (match_dup 0))
20153 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20154 (clobber (mem:BLK (scratch)))])])
20157 [(match_scratch:DI 0 "r")
20158 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20159 (clobber (reg:CC FLAGS_REG))
20160 (clobber (mem:BLK (scratch)))])]
20161 "optimize_size || !TARGET_SUB_ESP_8"
20162 [(clobber (match_dup 0))
20163 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20164 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20165 (clobber (mem:BLK (scratch)))])])
20167 ;; Convert esp subtractions to push.
20169 [(match_scratch:DI 0 "r")
20170 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20171 (clobber (reg:CC FLAGS_REG))])]
20172 "optimize_size || !TARGET_SUB_ESP_4"
20173 [(clobber (match_dup 0))
20174 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20177 [(match_scratch:DI 0 "r")
20178 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20179 (clobber (reg:CC FLAGS_REG))])]
20180 "optimize_size || !TARGET_SUB_ESP_8"
20181 [(clobber (match_dup 0))
20182 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20183 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20185 ;; Convert epilogue deallocator to pop.
20187 [(match_scratch:DI 0 "r")
20188 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20189 (clobber (reg:CC FLAGS_REG))
20190 (clobber (mem:BLK (scratch)))])]
20191 "optimize_size || !TARGET_ADD_ESP_4"
20192 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20193 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20194 (clobber (mem:BLK (scratch)))])]
20197 ;; Two pops case is tricky, since pop causes dependency on destination register.
20198 ;; We use two registers if available.
20200 [(match_scratch:DI 0 "r")
20201 (match_scratch:DI 1 "r")
20202 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20203 (clobber (reg:CC FLAGS_REG))
20204 (clobber (mem:BLK (scratch)))])]
20205 "optimize_size || !TARGET_ADD_ESP_8"
20206 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20207 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20208 (clobber (mem:BLK (scratch)))])
20209 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20210 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20214 [(match_scratch:DI 0 "r")
20215 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20216 (clobber (reg:CC FLAGS_REG))
20217 (clobber (mem:BLK (scratch)))])]
20219 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20220 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20221 (clobber (mem:BLK (scratch)))])
20222 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20223 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20226 ;; Convert esp additions to pop.
20228 [(match_scratch:DI 0 "r")
20229 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20230 (clobber (reg:CC FLAGS_REG))])]
20232 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20233 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20236 ;; Two pops case is tricky, since pop causes dependency on destination register.
20237 ;; We use two registers if available.
20239 [(match_scratch:DI 0 "r")
20240 (match_scratch:DI 1 "r")
20241 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20242 (clobber (reg:CC FLAGS_REG))])]
20244 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20245 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20246 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20247 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20251 [(match_scratch:DI 0 "r")
20252 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20253 (clobber (reg:CC FLAGS_REG))])]
20255 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20256 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20257 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20258 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20261 ;; Convert imul by three, five and nine into lea
20264 [(set (match_operand:SI 0 "register_operand" "")
20265 (mult:SI (match_operand:SI 1 "register_operand" "")
20266 (match_operand:SI 2 "const_int_operand" "")))
20267 (clobber (reg:CC FLAGS_REG))])]
20268 "INTVAL (operands[2]) == 3
20269 || INTVAL (operands[2]) == 5
20270 || INTVAL (operands[2]) == 9"
20271 [(set (match_dup 0)
20272 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20274 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20278 [(set (match_operand:SI 0 "register_operand" "")
20279 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20280 (match_operand:SI 2 "const_int_operand" "")))
20281 (clobber (reg:CC FLAGS_REG))])]
20283 && (INTVAL (operands[2]) == 3
20284 || INTVAL (operands[2]) == 5
20285 || INTVAL (operands[2]) == 9)"
20286 [(set (match_dup 0) (match_dup 1))
20288 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20290 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20294 [(set (match_operand:DI 0 "register_operand" "")
20295 (mult:DI (match_operand:DI 1 "register_operand" "")
20296 (match_operand:DI 2 "const_int_operand" "")))
20297 (clobber (reg:CC FLAGS_REG))])]
20299 && (INTVAL (operands[2]) == 3
20300 || INTVAL (operands[2]) == 5
20301 || INTVAL (operands[2]) == 9)"
20302 [(set (match_dup 0)
20303 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20305 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20309 [(set (match_operand:DI 0 "register_operand" "")
20310 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20311 (match_operand:DI 2 "const_int_operand" "")))
20312 (clobber (reg:CC FLAGS_REG))])]
20315 && (INTVAL (operands[2]) == 3
20316 || INTVAL (operands[2]) == 5
20317 || INTVAL (operands[2]) == 9)"
20318 [(set (match_dup 0) (match_dup 1))
20320 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20322 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20324 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20325 ;; imul $32bit_imm, reg, reg is direct decoded.
20327 [(match_scratch:DI 3 "r")
20328 (parallel [(set (match_operand:DI 0 "register_operand" "")
20329 (mult:DI (match_operand:DI 1 "memory_operand" "")
20330 (match_operand:DI 2 "immediate_operand" "")))
20331 (clobber (reg:CC FLAGS_REG))])]
20332 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20333 && !satisfies_constraint_K (operands[2])"
20334 [(set (match_dup 3) (match_dup 1))
20335 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20336 (clobber (reg:CC FLAGS_REG))])]
20340 [(match_scratch:SI 3 "r")
20341 (parallel [(set (match_operand:SI 0 "register_operand" "")
20342 (mult:SI (match_operand:SI 1 "memory_operand" "")
20343 (match_operand:SI 2 "immediate_operand" "")))
20344 (clobber (reg:CC FLAGS_REG))])]
20345 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20346 && !satisfies_constraint_K (operands[2])"
20347 [(set (match_dup 3) (match_dup 1))
20348 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20349 (clobber (reg:CC FLAGS_REG))])]
20353 [(match_scratch:SI 3 "r")
20354 (parallel [(set (match_operand:DI 0 "register_operand" "")
20356 (mult:SI (match_operand:SI 1 "memory_operand" "")
20357 (match_operand:SI 2 "immediate_operand" ""))))
20358 (clobber (reg:CC FLAGS_REG))])]
20359 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20360 && !satisfies_constraint_K (operands[2])"
20361 [(set (match_dup 3) (match_dup 1))
20362 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20363 (clobber (reg:CC FLAGS_REG))])]
20366 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20367 ;; Convert it into imul reg, reg
20368 ;; It would be better to force assembler to encode instruction using long
20369 ;; immediate, but there is apparently no way to do so.
20371 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20372 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20373 (match_operand:DI 2 "const_int_operand" "")))
20374 (clobber (reg:CC FLAGS_REG))])
20375 (match_scratch:DI 3 "r")]
20376 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20377 && satisfies_constraint_K (operands[2])"
20378 [(set (match_dup 3) (match_dup 2))
20379 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20380 (clobber (reg:CC FLAGS_REG))])]
20382 if (!rtx_equal_p (operands[0], operands[1]))
20383 emit_move_insn (operands[0], operands[1]);
20387 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20388 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20389 (match_operand:SI 2 "const_int_operand" "")))
20390 (clobber (reg:CC FLAGS_REG))])
20391 (match_scratch:SI 3 "r")]
20392 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20393 && satisfies_constraint_K (operands[2])"
20394 [(set (match_dup 3) (match_dup 2))
20395 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20396 (clobber (reg:CC FLAGS_REG))])]
20398 if (!rtx_equal_p (operands[0], operands[1]))
20399 emit_move_insn (operands[0], operands[1]);
20403 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20404 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20405 (match_operand:HI 2 "immediate_operand" "")))
20406 (clobber (reg:CC FLAGS_REG))])
20407 (match_scratch:HI 3 "r")]
20408 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20409 [(set (match_dup 3) (match_dup 2))
20410 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20411 (clobber (reg:CC FLAGS_REG))])]
20413 if (!rtx_equal_p (operands[0], operands[1]))
20414 emit_move_insn (operands[0], operands[1]);
20417 ;; After splitting up read-modify operations, array accesses with memory
20418 ;; operands might end up in form:
20420 ;; movl 4(%esp), %edx
20422 ;; instead of pre-splitting:
20424 ;; addl 4(%esp), %eax
20426 ;; movl 4(%esp), %edx
20427 ;; leal (%edx,%eax,4), %eax
20430 [(parallel [(set (match_operand 0 "register_operand" "")
20431 (ashift (match_operand 1 "register_operand" "")
20432 (match_operand 2 "const_int_operand" "")))
20433 (clobber (reg:CC FLAGS_REG))])
20434 (set (match_operand 3 "register_operand")
20435 (match_operand 4 "x86_64_general_operand" ""))
20436 (parallel [(set (match_operand 5 "register_operand" "")
20437 (plus (match_operand 6 "register_operand" "")
20438 (match_operand 7 "register_operand" "")))
20439 (clobber (reg:CC FLAGS_REG))])]
20440 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20441 /* Validate MODE for lea. */
20442 && ((!TARGET_PARTIAL_REG_STALL
20443 && (GET_MODE (operands[0]) == QImode
20444 || GET_MODE (operands[0]) == HImode))
20445 || GET_MODE (operands[0]) == SImode
20446 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20447 /* We reorder load and the shift. */
20448 && !rtx_equal_p (operands[1], operands[3])
20449 && !reg_overlap_mentioned_p (operands[0], operands[4])
20450 /* Last PLUS must consist of operand 0 and 3. */
20451 && !rtx_equal_p (operands[0], operands[3])
20452 && (rtx_equal_p (operands[3], operands[6])
20453 || rtx_equal_p (operands[3], operands[7]))
20454 && (rtx_equal_p (operands[0], operands[6])
20455 || rtx_equal_p (operands[0], operands[7]))
20456 /* The intermediate operand 0 must die or be same as output. */
20457 && (rtx_equal_p (operands[0], operands[5])
20458 || peep2_reg_dead_p (3, operands[0]))"
20459 [(set (match_dup 3) (match_dup 4))
20460 (set (match_dup 0) (match_dup 1))]
20462 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20463 int scale = 1 << INTVAL (operands[2]);
20464 rtx index = gen_lowpart (Pmode, operands[1]);
20465 rtx base = gen_lowpart (Pmode, operands[3]);
20466 rtx dest = gen_lowpart (mode, operands[5]);
20468 operands[1] = gen_rtx_PLUS (Pmode, base,
20469 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20471 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20472 operands[0] = dest;
20475 ;; Call-value patterns last so that the wildcard operand does not
20476 ;; disrupt insn-recog's switch tables.
20478 (define_insn "*call_value_pop_0"
20479 [(set (match_operand 0 "" "")
20480 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20481 (match_operand:SI 2 "" "")))
20482 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20483 (match_operand:SI 3 "immediate_operand" "")))]
20486 if (SIBLING_CALL_P (insn))
20489 return "call\t%P1";
20491 [(set_attr "type" "callv")])
20493 (define_insn "*call_value_pop_1"
20494 [(set (match_operand 0 "" "")
20495 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20496 (match_operand:SI 2 "" "")))
20497 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20498 (match_operand:SI 3 "immediate_operand" "i")))]
20501 if (constant_call_address_operand (operands[1], Pmode))
20503 if (SIBLING_CALL_P (insn))
20506 return "call\t%P1";
20508 if (SIBLING_CALL_P (insn))
20511 return "call\t%A1";
20513 [(set_attr "type" "callv")])
20515 (define_insn "*call_value_0"
20516 [(set (match_operand 0 "" "")
20517 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20518 (match_operand:SI 2 "" "")))]
20521 if (SIBLING_CALL_P (insn))
20524 return "call\t%P1";
20526 [(set_attr "type" "callv")])
20528 (define_insn "*call_value_0_rex64"
20529 [(set (match_operand 0 "" "")
20530 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20531 (match_operand:DI 2 "const_int_operand" "")))]
20534 if (SIBLING_CALL_P (insn))
20537 return "call\t%P1";
20539 [(set_attr "type" "callv")])
20541 (define_insn "*call_value_1"
20542 [(set (match_operand 0 "" "")
20543 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20544 (match_operand:SI 2 "" "")))]
20545 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20547 if (constant_call_address_operand (operands[1], Pmode))
20548 return "call\t%P1";
20549 return "call\t%A1";
20551 [(set_attr "type" "callv")])
20553 (define_insn "*sibcall_value_1"
20554 [(set (match_operand 0 "" "")
20555 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20556 (match_operand:SI 2 "" "")))]
20557 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20559 if (constant_call_address_operand (operands[1], Pmode))
20563 [(set_attr "type" "callv")])
20565 (define_insn "*call_value_1_rex64"
20566 [(set (match_operand 0 "" "")
20567 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20568 (match_operand:DI 2 "" "")))]
20569 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20570 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20572 if (constant_call_address_operand (operands[1], Pmode))
20573 return "call\t%P1";
20574 return "call\t%A1";
20576 [(set_attr "type" "callv")])
20578 (define_insn "*call_value_1_rex64_large"
20579 [(set (match_operand 0 "" "")
20580 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20581 (match_operand:DI 2 "" "")))]
20582 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20584 [(set_attr "type" "callv")])
20586 (define_insn "*sibcall_value_1_rex64"
20587 [(set (match_operand 0 "" "")
20588 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20589 (match_operand:DI 2 "" "")))]
20590 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20592 [(set_attr "type" "callv")])
20594 (define_insn "*sibcall_value_1_rex64_v"
20595 [(set (match_operand 0 "" "")
20596 (call (mem:QI (reg:DI R11_REG))
20597 (match_operand:DI 1 "" "")))]
20598 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20600 [(set_attr "type" "callv")])
20602 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20603 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20604 ;; caught for use by garbage collectors and the like. Using an insn that
20605 ;; maps to SIGILL makes it more likely the program will rightfully die.
20606 ;; Keeping with tradition, "6" is in honor of #UD.
20607 (define_insn "trap"
20608 [(trap_if (const_int 1) (const_int 6))]
20610 { return ASM_SHORT "0x0b0f"; }
20611 [(set_attr "length" "2")])
20613 (define_expand "sse_prologue_save"
20614 [(parallel [(set (match_operand:BLK 0 "" "")
20615 (unspec:BLK [(reg:DI 21)
20622 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20623 (use (match_operand:DI 1 "register_operand" ""))
20624 (use (match_operand:DI 2 "immediate_operand" ""))
20625 (use (label_ref:DI (match_operand 3 "" "")))])]
20629 (define_insn "*sse_prologue_save_insn"
20630 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20631 (match_operand:DI 4 "const_int_operand" "n")))
20632 (unspec:BLK [(reg:DI 21)
20639 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20640 (use (match_operand:DI 1 "register_operand" "r"))
20641 (use (match_operand:DI 2 "const_int_operand" "i"))
20642 (use (label_ref:DI (match_operand 3 "" "X")))]
20644 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20645 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20649 operands[0] = gen_rtx_MEM (Pmode,
20650 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20651 output_asm_insn (\"jmp\\t%A1\", operands);
20652 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20654 operands[4] = adjust_address (operands[0], DImode, i*16);
20655 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20656 PUT_MODE (operands[4], TImode);
20657 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20658 output_asm_insn (\"rex\", operands);
20659 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20661 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20662 CODE_LABEL_NUMBER (operands[3]));
20666 [(set_attr "type" "other")
20667 (set_attr "length_immediate" "0")
20668 (set_attr "length_address" "0")
20669 (set_attr "length" "135")
20670 (set_attr "memory" "store")
20671 (set_attr "modrm" "0")
20672 (set_attr "mode" "DI")])
20674 (define_expand "prefetch"
20675 [(prefetch (match_operand 0 "address_operand" "")
20676 (match_operand:SI 1 "const_int_operand" "")
20677 (match_operand:SI 2 "const_int_operand" ""))]
20678 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20680 int rw = INTVAL (operands[1]);
20681 int locality = INTVAL (operands[2]);
20683 gcc_assert (rw == 0 || rw == 1);
20684 gcc_assert (locality >= 0 && locality <= 3);
20685 gcc_assert (GET_MODE (operands[0]) == Pmode
20686 || GET_MODE (operands[0]) == VOIDmode);
20688 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20689 supported by SSE counterpart or the SSE prefetch is not available
20690 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20692 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20693 operands[2] = GEN_INT (3);
20695 operands[1] = const0_rtx;
20698 (define_insn "*prefetch_sse"
20699 [(prefetch (match_operand:SI 0 "address_operand" "p")
20701 (match_operand:SI 1 "const_int_operand" ""))]
20702 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20704 static const char * const patterns[4] = {
20705 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20708 int locality = INTVAL (operands[1]);
20709 gcc_assert (locality >= 0 && locality <= 3);
20711 return patterns[locality];
20713 [(set_attr "type" "sse")
20714 (set_attr "memory" "none")])
20716 (define_insn "*prefetch_sse_rex"
20717 [(prefetch (match_operand:DI 0 "address_operand" "p")
20719 (match_operand:SI 1 "const_int_operand" ""))]
20720 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20722 static const char * const patterns[4] = {
20723 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20726 int locality = INTVAL (operands[1]);
20727 gcc_assert (locality >= 0 && locality <= 3);
20729 return patterns[locality];
20731 [(set_attr "type" "sse")
20732 (set_attr "memory" "none")])
20734 (define_insn "*prefetch_3dnow"
20735 [(prefetch (match_operand:SI 0 "address_operand" "p")
20736 (match_operand:SI 1 "const_int_operand" "n")
20738 "TARGET_3DNOW && !TARGET_64BIT"
20740 if (INTVAL (operands[1]) == 0)
20741 return "prefetch\t%a0";
20743 return "prefetchw\t%a0";
20745 [(set_attr "type" "mmx")
20746 (set_attr "memory" "none")])
20748 (define_insn "*prefetch_3dnow_rex"
20749 [(prefetch (match_operand:DI 0 "address_operand" "p")
20750 (match_operand:SI 1 "const_int_operand" "n")
20752 "TARGET_3DNOW && TARGET_64BIT"
20754 if (INTVAL (operands[1]) == 0)
20755 return "prefetch\t%a0";
20757 return "prefetchw\t%a0";
20759 [(set_attr "type" "mmx")
20760 (set_attr "memory" "none")])
20762 (define_expand "stack_protect_set"
20763 [(match_operand 0 "memory_operand" "")
20764 (match_operand 1 "memory_operand" "")]
20767 #ifdef TARGET_THREAD_SSP_OFFSET
20769 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20770 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20772 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20773 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20776 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20778 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20783 (define_insn "stack_protect_set_si"
20784 [(set (match_operand:SI 0 "memory_operand" "=m")
20785 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20786 (set (match_scratch:SI 2 "=&r") (const_int 0))
20787 (clobber (reg:CC FLAGS_REG))]
20789 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20790 [(set_attr "type" "multi")])
20792 (define_insn "stack_protect_set_di"
20793 [(set (match_operand:DI 0 "memory_operand" "=m")
20794 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20795 (set (match_scratch:DI 2 "=&r") (const_int 0))
20796 (clobber (reg:CC FLAGS_REG))]
20798 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20799 [(set_attr "type" "multi")])
20801 (define_insn "stack_tls_protect_set_si"
20802 [(set (match_operand:SI 0 "memory_operand" "=m")
20803 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20804 (set (match_scratch:SI 2 "=&r") (const_int 0))
20805 (clobber (reg:CC FLAGS_REG))]
20807 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20808 [(set_attr "type" "multi")])
20810 (define_insn "stack_tls_protect_set_di"
20811 [(set (match_operand:DI 0 "memory_operand" "=m")
20812 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20813 (set (match_scratch:DI 2 "=&r") (const_int 0))
20814 (clobber (reg:CC FLAGS_REG))]
20817 /* The kernel uses a different segment register for performance reasons; a
20818 system call would not have to trash the userspace segment register,
20819 which would be expensive */
20820 if (ix86_cmodel != CM_KERNEL)
20821 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20823 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20825 [(set_attr "type" "multi")])
20827 (define_expand "stack_protect_test"
20828 [(match_operand 0 "memory_operand" "")
20829 (match_operand 1 "memory_operand" "")
20830 (match_operand 2 "" "")]
20833 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20834 ix86_compare_op0 = operands[0];
20835 ix86_compare_op1 = operands[1];
20836 ix86_compare_emitted = flags;
20838 #ifdef TARGET_THREAD_SSP_OFFSET
20840 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20841 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20843 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20844 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20847 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20849 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20851 emit_jump_insn (gen_beq (operands[2]));
20855 (define_insn "stack_protect_test_si"
20856 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20857 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20858 (match_operand:SI 2 "memory_operand" "m")]
20860 (clobber (match_scratch:SI 3 "=&r"))]
20862 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20863 [(set_attr "type" "multi")])
20865 (define_insn "stack_protect_test_di"
20866 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20867 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20868 (match_operand:DI 2 "memory_operand" "m")]
20870 (clobber (match_scratch:DI 3 "=&r"))]
20872 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20873 [(set_attr "type" "multi")])
20875 (define_insn "stack_tls_protect_test_si"
20876 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20877 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20878 (match_operand:SI 2 "const_int_operand" "i")]
20879 UNSPEC_SP_TLS_TEST))
20880 (clobber (match_scratch:SI 3 "=r"))]
20882 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20883 [(set_attr "type" "multi")])
20885 (define_insn "stack_tls_protect_test_di"
20886 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20887 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20888 (match_operand:DI 2 "const_int_operand" "i")]
20889 UNSPEC_SP_TLS_TEST))
20890 (clobber (match_scratch:DI 3 "=r"))]
20893 /* The kernel uses a different segment register for performance reasons; a
20894 system call would not have to trash the userspace segment register,
20895 which would be expensive */
20896 if (ix86_cmodel != CM_KERNEL)
20897 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20899 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20901 [(set_attr "type" "multi")])
20903 (define_mode_macro CRC32MODE [QI HI SI])
20904 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
20905 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
20907 (define_insn "sse4_2_crc32<mode>"
20908 [(set (match_operand:SI 0 "register_operand" "=r")
20910 [(match_operand:SI 1 "register_operand" "0")
20911 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
20914 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
20915 [(set_attr "type" "sselog1")
20916 (set_attr "prefix_rep" "1")
20917 (set_attr "prefix_extra" "1")
20918 (set_attr "mode" "SI")])
20920 (define_insn "sse4_2_crc32di"
20921 [(set (match_operand:DI 0 "register_operand" "=r")
20923 [(match_operand:DI 1 "register_operand" "0")
20924 (match_operand:DI 2 "nonimmediate_operand" "rm")]
20926 "TARGET_SSE4_2 && TARGET_64BIT"
20927 "crc32q\t{%2, %0|%0, %2}"
20928 [(set_attr "type" "sselog1")
20929 (set_attr "prefix_rep" "1")
20930 (set_attr "prefix_extra" "1")
20931 (set_attr "mode" "DI")])
20935 (include "sync.md")