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 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;; %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
50 [; Relocation specifiers
63 (UNSPEC_STACK_ALLOC 11)
65 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69 (UNSPEC_SET_GOT_OFFSET 17)
74 (UNSPEC_TLS_LD_BASE 20)
77 ; Other random patterns
86 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
87 (UNSPEC_TRUNC_NOOP 39)
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 40)
98 (UNSPEC_NOP 48) ; prevents combiner cleverness
109 ; Generic math support
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
127 (UNSPEC_FRNDINT_FLOOR 70)
128 (UNSPEC_FRNDINT_CEIL 71)
129 (UNSPEC_FRNDINT_TRUNC 72)
130 (UNSPEC_FRNDINT_MASK_PM 73)
131 (UNSPEC_FIST_FLOOR 74)
132 (UNSPEC_FIST_CEIL 75)
134 ; x87 Double output FP
135 (UNSPEC_SINCOS_COS 80)
136 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
151 (UNSPEC_SP_TLS_SET 102)
152 (UNSPEC_SP_TLS_TEST 103)
162 (UNSPEC_INSERTQI 132)
167 (UNSPEC_INSERTPS 135)
169 (UNSPEC_MOVNTDQA 137)
171 (UNSPEC_PHMINPOSUW 139)
177 (UNSPEC_PCMPESTR 144)
178 (UNSPEC_PCMPISTR 145)
182 [(UNSPECV_BLOCKAGE 0)
183 (UNSPECV_STACK_PROBE 1)
192 (UNSPECV_CMPXCHG_1 10)
193 (UNSPECV_CMPXCHG_2 11)
196 (UNSPECV_PROLOGUE_USE 14)
199 ;; Registers by name.
210 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
213 ;; In C guard expressions, put expressions which may be compile-time
214 ;; constants first. This allows for better optimization. For
215 ;; example, write "TARGET_64BIT && reload_completed", not
216 ;; "reload_completed && TARGET_64BIT".
219 ;; Processor type. This attribute must exactly match the processor_type
220 ;; enumeration in i386.h.
221 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
222 nocona,core2,generic32,generic64,amdfam10"
223 (const (symbol_ref "ix86_tune")))
225 ;; A basic instruction type. Refinements due to arguments to be
226 ;; provided in other attributes.
229 alu,alu1,negnot,imov,imovx,lea,
230 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
231 icmp,test,ibr,setcc,icmov,
232 push,pop,call,callv,leave,
234 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
235 sselog,sselog1,sseiadd,sseishft,sseimul,
236 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
237 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
238 (const_string "other"))
240 ;; Main data type used by the insn
242 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
243 (const_string "unknown"))
245 ;; The CPU unit operations uses.
246 (define_attr "unit" "integer,i387,sse,mmx,unknown"
247 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
248 (const_string "i387")
249 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
250 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
252 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
254 (eq_attr "type" "other")
255 (const_string "unknown")]
256 (const_string "integer")))
258 ;; The (bounding maximum) length of an instruction immediate.
259 (define_attr "length_immediate" ""
260 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
263 (eq_attr "unit" "i387,sse,mmx")
265 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
267 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
268 (eq_attr "type" "imov,test")
269 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
270 (eq_attr "type" "call")
271 (if_then_else (match_operand 0 "constant_call_address_operand" "")
274 (eq_attr "type" "callv")
275 (if_then_else (match_operand 1 "constant_call_address_operand" "")
278 ;; We don't know the size before shorten_branches. Expect
279 ;; the instruction to fit for better scheduling.
280 (eq_attr "type" "ibr")
283 (symbol_ref "/* Update immediate_length and other attributes! */
284 gcc_unreachable (),1")))
286 ;; The (bounding maximum) length of an instruction address.
287 (define_attr "length_address" ""
288 (cond [(eq_attr "type" "str,other,multi,fxch")
290 (and (eq_attr "type" "call")
291 (match_operand 0 "constant_call_address_operand" ""))
293 (and (eq_attr "type" "callv")
294 (match_operand 1 "constant_call_address_operand" ""))
297 (symbol_ref "ix86_attr_length_address_default (insn)")))
299 ;; Set when length prefix is used.
300 (define_attr "prefix_data16" ""
301 (if_then_else (ior (eq_attr "mode" "HI")
302 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
306 ;; Set when string REP prefix is used.
307 (define_attr "prefix_rep" ""
308 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
312 ;; Set when 0f opcode prefix is used.
313 (define_attr "prefix_0f" ""
315 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
316 (eq_attr "unit" "sse,mmx"))
320 ;; Set when REX opcode prefix is used.
321 (define_attr "prefix_rex" ""
322 (cond [(and (eq_attr "mode" "DI")
323 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
325 (and (eq_attr "mode" "QI")
326 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
329 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
335 ;; There are also additional prefixes in SSSE3.
336 (define_attr "prefix_extra" "" (const_int 0))
338 ;; Set when modrm byte is used.
339 (define_attr "modrm" ""
340 (cond [(eq_attr "type" "str,leave")
342 (eq_attr "unit" "i387")
344 (and (eq_attr "type" "incdec")
345 (ior (match_operand:SI 1 "register_operand" "")
346 (match_operand:HI 1 "register_operand" "")))
348 (and (eq_attr "type" "push")
349 (not (match_operand 1 "memory_operand" "")))
351 (and (eq_attr "type" "pop")
352 (not (match_operand 0 "memory_operand" "")))
354 (and (eq_attr "type" "imov")
355 (ior (and (match_operand 0 "register_operand" "")
356 (match_operand 1 "immediate_operand" ""))
357 (ior (and (match_operand 0 "ax_reg_operand" "")
358 (match_operand 1 "memory_displacement_only_operand" ""))
359 (and (match_operand 0 "memory_displacement_only_operand" "")
360 (match_operand 1 "ax_reg_operand" "")))))
362 (and (eq_attr "type" "call")
363 (match_operand 0 "constant_call_address_operand" ""))
365 (and (eq_attr "type" "callv")
366 (match_operand 1 "constant_call_address_operand" ""))
371 ;; The (bounding maximum) length of an instruction in bytes.
372 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
373 ;; Later we may want to split them and compute proper length as for
375 (define_attr "length" ""
376 (cond [(eq_attr "type" "other,multi,fistp,frndint")
378 (eq_attr "type" "fcmp")
380 (eq_attr "unit" "i387")
382 (plus (attr "prefix_data16")
383 (attr "length_address")))]
384 (plus (plus (attr "modrm")
385 (plus (attr "prefix_0f")
386 (plus (attr "prefix_rex")
387 (plus (attr "prefix_extra")
389 (plus (attr "prefix_rep")
390 (plus (attr "prefix_data16")
391 (plus (attr "length_immediate")
392 (attr "length_address")))))))
394 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
395 ;; `store' if there is a simple memory reference therein, or `unknown'
396 ;; if the instruction is complex.
398 (define_attr "memory" "none,load,store,both,unknown"
399 (cond [(eq_attr "type" "other,multi,str")
400 (const_string "unknown")
401 (eq_attr "type" "lea,fcmov,fpspc")
402 (const_string "none")
403 (eq_attr "type" "fistp,leave")
404 (const_string "both")
405 (eq_attr "type" "frndint")
406 (const_string "load")
407 (eq_attr "type" "push")
408 (if_then_else (match_operand 1 "memory_operand" "")
409 (const_string "both")
410 (const_string "store"))
411 (eq_attr "type" "pop")
412 (if_then_else (match_operand 0 "memory_operand" "")
413 (const_string "both")
414 (const_string "load"))
415 (eq_attr "type" "setcc")
416 (if_then_else (match_operand 0 "memory_operand" "")
417 (const_string "store")
418 (const_string "none"))
419 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
420 (if_then_else (ior (match_operand 0 "memory_operand" "")
421 (match_operand 1 "memory_operand" ""))
422 (const_string "load")
423 (const_string "none"))
424 (eq_attr "type" "ibr")
425 (if_then_else (match_operand 0 "memory_operand" "")
426 (const_string "load")
427 (const_string "none"))
428 (eq_attr "type" "call")
429 (if_then_else (match_operand 0 "constant_call_address_operand" "")
430 (const_string "none")
431 (const_string "load"))
432 (eq_attr "type" "callv")
433 (if_then_else (match_operand 1 "constant_call_address_operand" "")
434 (const_string "none")
435 (const_string "load"))
436 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
437 (match_operand 1 "memory_operand" ""))
438 (const_string "both")
439 (and (match_operand 0 "memory_operand" "")
440 (match_operand 1 "memory_operand" ""))
441 (const_string "both")
442 (match_operand 0 "memory_operand" "")
443 (const_string "store")
444 (match_operand 1 "memory_operand" "")
445 (const_string "load")
447 "!alu1,negnot,ishift1,
448 imov,imovx,icmp,test,bitmanip,
450 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
451 mmx,mmxmov,mmxcmp,mmxcvt")
452 (match_operand 2 "memory_operand" ""))
453 (const_string "load")
454 (and (eq_attr "type" "icmov")
455 (match_operand 3 "memory_operand" ""))
456 (const_string "load")
458 (const_string "none")))
460 ;; Indicates if an instruction has both an immediate and a displacement.
462 (define_attr "imm_disp" "false,true,unknown"
463 (cond [(eq_attr "type" "other,multi")
464 (const_string "unknown")
465 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
466 (and (match_operand 0 "memory_displacement_operand" "")
467 (match_operand 1 "immediate_operand" "")))
468 (const_string "true")
469 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
470 (and (match_operand 0 "memory_displacement_operand" "")
471 (match_operand 2 "immediate_operand" "")))
472 (const_string "true")
474 (const_string "false")))
476 ;; Indicates if an FP operation has an integer source.
478 (define_attr "fp_int_src" "false,true"
479 (const_string "false"))
481 ;; Defines rounding mode of an FP operation.
483 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
484 (const_string "any"))
486 ;; Describe a user's asm statement.
487 (define_asm_attributes
488 [(set_attr "length" "128")
489 (set_attr "type" "multi")])
491 (define_code_iterator plusminus [plus minus])
493 ;; Base name for define_insn and insn mnemonic.
494 (define_code_attr addsub [(plus "add") (minus "sub")])
496 ;; Mark commutative operators as such in constraints.
497 (define_code_attr comm [(plus "%") (minus "")])
499 ;; All single word integer modes.
500 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
502 ;; Instruction suffix for integer modes.
503 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
505 ;; Register class for integer modes.
506 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
508 ;; Immediate operand constraint for integer modes.
509 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
511 ;; General operand predicate for integer modes.
512 (define_mode_attr general_operand
513 [(QI "general_operand")
514 (HI "general_operand")
515 (SI "general_operand")
516 (DI "x86_64_general_operand")])
518 ;; SSE and x87 SFmode and DFmode floating point modes
519 (define_mode_iterator MODEF [SF DF])
521 ;; All x87 floating point modes
522 (define_mode_iterator X87MODEF [SF DF XF])
524 ;; All integer modes handled by x87 fisttp operator.
525 (define_mode_iterator X87MODEI [HI SI DI])
527 ;; All integer modes handled by integer x87 operators.
528 (define_mode_iterator X87MODEI12 [HI SI])
530 ;; All integer modes handled by SSE cvtts?2si* operators.
531 (define_mode_iterator SSEMODEI24 [SI DI])
533 ;; SSE asm suffix for floating point modes
534 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
536 ;; SSE vector mode corresponding to a scalar mode
537 (define_mode_attr ssevecmode
538 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
540 ;; Scheduling descriptions
542 (include "pentium.md")
545 (include "athlon.md")
549 ;; Operand and operator predicates and constraints
551 (include "predicates.md")
552 (include "constraints.md")
555 ;; Compare instructions.
557 ;; All compare insns have expanders that save the operands away without
558 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
559 ;; after the cmp) will actually emit the cmpM.
561 (define_expand "cmpti"
562 [(set (reg:CC FLAGS_REG)
563 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
564 (match_operand:TI 1 "x86_64_general_operand" "")))]
567 if (MEM_P (operands[0]) && MEM_P (operands[1]))
568 operands[0] = force_reg (TImode, operands[0]);
569 ix86_compare_op0 = operands[0];
570 ix86_compare_op1 = operands[1];
574 (define_expand "cmpdi"
575 [(set (reg:CC FLAGS_REG)
576 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
577 (match_operand:DI 1 "x86_64_general_operand" "")))]
580 if (MEM_P (operands[0]) && MEM_P (operands[1]))
581 operands[0] = force_reg (DImode, operands[0]);
582 ix86_compare_op0 = operands[0];
583 ix86_compare_op1 = operands[1];
587 (define_expand "cmpsi"
588 [(set (reg:CC FLAGS_REG)
589 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
590 (match_operand:SI 1 "general_operand" "")))]
593 if (MEM_P (operands[0]) && MEM_P (operands[1]))
594 operands[0] = force_reg (SImode, operands[0]);
595 ix86_compare_op0 = operands[0];
596 ix86_compare_op1 = operands[1];
600 (define_expand "cmphi"
601 [(set (reg:CC FLAGS_REG)
602 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
603 (match_operand:HI 1 "general_operand" "")))]
606 if (MEM_P (operands[0]) && MEM_P (operands[1]))
607 operands[0] = force_reg (HImode, operands[0]);
608 ix86_compare_op0 = operands[0];
609 ix86_compare_op1 = operands[1];
613 (define_expand "cmpqi"
614 [(set (reg:CC FLAGS_REG)
615 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
616 (match_operand:QI 1 "general_operand" "")))]
619 if (MEM_P (operands[0]) && MEM_P (operands[1]))
620 operands[0] = force_reg (QImode, operands[0]);
621 ix86_compare_op0 = operands[0];
622 ix86_compare_op1 = operands[1];
626 (define_insn "cmpdi_ccno_1_rex64"
627 [(set (reg FLAGS_REG)
628 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
629 (match_operand:DI 1 "const0_operand" "n,n")))]
630 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
633 cmp{q}\t{%1, %0|%0, %1}"
634 [(set_attr "type" "test,icmp")
635 (set_attr "length_immediate" "0,1")
636 (set_attr "mode" "DI")])
638 (define_insn "*cmpdi_minus_1_rex64"
639 [(set (reg FLAGS_REG)
640 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
641 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
643 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
644 "cmp{q}\t{%1, %0|%0, %1}"
645 [(set_attr "type" "icmp")
646 (set_attr "mode" "DI")])
648 (define_expand "cmpdi_1_rex64"
649 [(set (reg:CC FLAGS_REG)
650 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
651 (match_operand:DI 1 "general_operand" "")))]
655 (define_insn "cmpdi_1_insn_rex64"
656 [(set (reg FLAGS_REG)
657 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
658 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
659 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
660 "cmp{q}\t{%1, %0|%0, %1}"
661 [(set_attr "type" "icmp")
662 (set_attr "mode" "DI")])
665 (define_insn "*cmpsi_ccno_1"
666 [(set (reg FLAGS_REG)
667 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
668 (match_operand:SI 1 "const0_operand" "n,n")))]
669 "ix86_match_ccmode (insn, CCNOmode)"
672 cmp{l}\t{%1, %0|%0, %1}"
673 [(set_attr "type" "test,icmp")
674 (set_attr "length_immediate" "0,1")
675 (set_attr "mode" "SI")])
677 (define_insn "*cmpsi_minus_1"
678 [(set (reg FLAGS_REG)
679 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
680 (match_operand:SI 1 "general_operand" "ri,mr"))
682 "ix86_match_ccmode (insn, CCGOCmode)"
683 "cmp{l}\t{%1, %0|%0, %1}"
684 [(set_attr "type" "icmp")
685 (set_attr "mode" "SI")])
687 (define_expand "cmpsi_1"
688 [(set (reg:CC FLAGS_REG)
689 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
690 (match_operand:SI 1 "general_operand" "")))]
694 (define_insn "*cmpsi_1_insn"
695 [(set (reg FLAGS_REG)
696 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
697 (match_operand:SI 1 "general_operand" "ri,mr")))]
698 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
699 && ix86_match_ccmode (insn, CCmode)"
700 "cmp{l}\t{%1, %0|%0, %1}"
701 [(set_attr "type" "icmp")
702 (set_attr "mode" "SI")])
704 (define_insn "*cmphi_ccno_1"
705 [(set (reg FLAGS_REG)
706 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
707 (match_operand:HI 1 "const0_operand" "n,n")))]
708 "ix86_match_ccmode (insn, CCNOmode)"
711 cmp{w}\t{%1, %0|%0, %1}"
712 [(set_attr "type" "test,icmp")
713 (set_attr "length_immediate" "0,1")
714 (set_attr "mode" "HI")])
716 (define_insn "*cmphi_minus_1"
717 [(set (reg FLAGS_REG)
718 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
719 (match_operand:HI 1 "general_operand" "ri,mr"))
721 "ix86_match_ccmode (insn, CCGOCmode)"
722 "cmp{w}\t{%1, %0|%0, %1}"
723 [(set_attr "type" "icmp")
724 (set_attr "mode" "HI")])
726 (define_insn "*cmphi_1"
727 [(set (reg FLAGS_REG)
728 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
729 (match_operand:HI 1 "general_operand" "ri,mr")))]
730 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
731 && ix86_match_ccmode (insn, CCmode)"
732 "cmp{w}\t{%1, %0|%0, %1}"
733 [(set_attr "type" "icmp")
734 (set_attr "mode" "HI")])
736 (define_insn "*cmpqi_ccno_1"
737 [(set (reg FLAGS_REG)
738 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
739 (match_operand:QI 1 "const0_operand" "n,n")))]
740 "ix86_match_ccmode (insn, CCNOmode)"
743 cmp{b}\t{$0, %0|%0, 0}"
744 [(set_attr "type" "test,icmp")
745 (set_attr "length_immediate" "0,1")
746 (set_attr "mode" "QI")])
748 (define_insn "*cmpqi_1"
749 [(set (reg FLAGS_REG)
750 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
751 (match_operand:QI 1 "general_operand" "qi,mq")))]
752 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
753 && ix86_match_ccmode (insn, CCmode)"
754 "cmp{b}\t{%1, %0|%0, %1}"
755 [(set_attr "type" "icmp")
756 (set_attr "mode" "QI")])
758 (define_insn "*cmpqi_minus_1"
759 [(set (reg FLAGS_REG)
760 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
761 (match_operand:QI 1 "general_operand" "qi,mq"))
763 "ix86_match_ccmode (insn, CCGOCmode)"
764 "cmp{b}\t{%1, %0|%0, %1}"
765 [(set_attr "type" "icmp")
766 (set_attr "mode" "QI")])
768 (define_insn "*cmpqi_ext_1"
769 [(set (reg FLAGS_REG)
771 (match_operand:QI 0 "general_operand" "Qm")
774 (match_operand 1 "ext_register_operand" "Q")
777 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
778 "cmp{b}\t{%h1, %0|%0, %h1}"
779 [(set_attr "type" "icmp")
780 (set_attr "mode" "QI")])
782 (define_insn "*cmpqi_ext_1_rex64"
783 [(set (reg FLAGS_REG)
785 (match_operand:QI 0 "register_operand" "Q")
788 (match_operand 1 "ext_register_operand" "Q")
791 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
792 "cmp{b}\t{%h1, %0|%0, %h1}"
793 [(set_attr "type" "icmp")
794 (set_attr "mode" "QI")])
796 (define_insn "*cmpqi_ext_2"
797 [(set (reg FLAGS_REG)
801 (match_operand 0 "ext_register_operand" "Q")
804 (match_operand:QI 1 "const0_operand" "n")))]
805 "ix86_match_ccmode (insn, CCNOmode)"
807 [(set_attr "type" "test")
808 (set_attr "length_immediate" "0")
809 (set_attr "mode" "QI")])
811 (define_expand "cmpqi_ext_3"
812 [(set (reg:CC FLAGS_REG)
816 (match_operand 0 "ext_register_operand" "")
819 (match_operand:QI 1 "general_operand" "")))]
823 (define_insn "cmpqi_ext_3_insn"
824 [(set (reg FLAGS_REG)
828 (match_operand 0 "ext_register_operand" "Q")
831 (match_operand:QI 1 "general_operand" "Qmn")))]
832 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
833 "cmp{b}\t{%1, %h0|%h0, %1}"
834 [(set_attr "type" "icmp")
835 (set_attr "mode" "QI")])
837 (define_insn "cmpqi_ext_3_insn_rex64"
838 [(set (reg FLAGS_REG)
842 (match_operand 0 "ext_register_operand" "Q")
845 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
846 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
847 "cmp{b}\t{%1, %h0|%h0, %1}"
848 [(set_attr "type" "icmp")
849 (set_attr "mode" "QI")])
851 (define_insn "*cmpqi_ext_4"
852 [(set (reg FLAGS_REG)
856 (match_operand 0 "ext_register_operand" "Q")
861 (match_operand 1 "ext_register_operand" "Q")
864 "ix86_match_ccmode (insn, CCmode)"
865 "cmp{b}\t{%h1, %h0|%h0, %h1}"
866 [(set_attr "type" "icmp")
867 (set_attr "mode" "QI")])
869 ;; These implement float point compares.
870 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
871 ;; which would allow mix and match FP modes on the compares. Which is what
872 ;; the old patterns did, but with many more of them.
874 (define_expand "cmpxf"
875 [(set (reg:CC FLAGS_REG)
876 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
877 (match_operand:XF 1 "nonmemory_operand" "")))]
880 ix86_compare_op0 = operands[0];
881 ix86_compare_op1 = operands[1];
885 (define_expand "cmp<mode>"
886 [(set (reg:CC FLAGS_REG)
887 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
888 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
889 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
891 ix86_compare_op0 = operands[0];
892 ix86_compare_op1 = operands[1];
896 ;; FP compares, step 1:
897 ;; Set the FP condition codes.
899 ;; CCFPmode compare with exceptions
900 ;; CCFPUmode compare with no exceptions
902 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
903 ;; used to manage the reg stack popping would not be preserved.
905 (define_insn "*cmpfp_0"
906 [(set (match_operand:HI 0 "register_operand" "=a")
909 (match_operand 1 "register_operand" "f")
910 (match_operand 2 "const0_operand" "X"))]
912 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
913 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
914 "* return output_fp_compare (insn, operands, 0, 0);"
915 [(set_attr "type" "multi")
916 (set_attr "unit" "i387")
918 (cond [(match_operand:SF 1 "" "")
920 (match_operand:DF 1 "" "")
923 (const_string "XF")))])
925 (define_insn_and_split "*cmpfp_0_cc"
926 [(set (reg:CCFP FLAGS_REG)
928 (match_operand 1 "register_operand" "f")
929 (match_operand 2 "const0_operand" "X")))
930 (clobber (match_operand:HI 0 "register_operand" "=a"))]
931 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
932 && TARGET_SAHF && !TARGET_CMOVE
933 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
935 "&& reload_completed"
938 [(compare:CCFP (match_dup 1)(match_dup 2))]
940 (set (reg:CC FLAGS_REG)
941 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
943 [(set_attr "type" "multi")
944 (set_attr "unit" "i387")
946 (cond [(match_operand:SF 1 "" "")
948 (match_operand:DF 1 "" "")
951 (const_string "XF")))])
953 (define_insn "*cmpfp_xf"
954 [(set (match_operand:HI 0 "register_operand" "=a")
957 (match_operand:XF 1 "register_operand" "f")
958 (match_operand:XF 2 "register_operand" "f"))]
961 "* return output_fp_compare (insn, operands, 0, 0);"
962 [(set_attr "type" "multi")
963 (set_attr "unit" "i387")
964 (set_attr "mode" "XF")])
966 (define_insn_and_split "*cmpfp_xf_cc"
967 [(set (reg:CCFP FLAGS_REG)
969 (match_operand:XF 1 "register_operand" "f")
970 (match_operand:XF 2 "register_operand" "f")))
971 (clobber (match_operand:HI 0 "register_operand" "=a"))]
973 && TARGET_SAHF && !TARGET_CMOVE"
975 "&& reload_completed"
978 [(compare:CCFP (match_dup 1)(match_dup 2))]
980 (set (reg:CC FLAGS_REG)
981 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
983 [(set_attr "type" "multi")
984 (set_attr "unit" "i387")
985 (set_attr "mode" "XF")])
987 (define_insn "*cmpfp_<mode>"
988 [(set (match_operand:HI 0 "register_operand" "=a")
991 (match_operand:MODEF 1 "register_operand" "f")
992 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
995 "* return output_fp_compare (insn, operands, 0, 0);"
996 [(set_attr "type" "multi")
997 (set_attr "unit" "i387")
998 (set_attr "mode" "<MODE>")])
1000 (define_insn_and_split "*cmpfp_<mode>_cc"
1001 [(set (reg:CCFP FLAGS_REG)
1003 (match_operand:MODEF 1 "register_operand" "f")
1004 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1005 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1007 && TARGET_SAHF && !TARGET_CMOVE"
1009 "&& reload_completed"
1012 [(compare:CCFP (match_dup 1)(match_dup 2))]
1014 (set (reg:CC FLAGS_REG)
1015 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1017 [(set_attr "type" "multi")
1018 (set_attr "unit" "i387")
1019 (set_attr "mode" "<MODE>")])
1021 (define_insn "*cmpfp_u"
1022 [(set (match_operand:HI 0 "register_operand" "=a")
1025 (match_operand 1 "register_operand" "f")
1026 (match_operand 2 "register_operand" "f"))]
1028 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1029 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1030 "* return output_fp_compare (insn, operands, 0, 1);"
1031 [(set_attr "type" "multi")
1032 (set_attr "unit" "i387")
1034 (cond [(match_operand:SF 1 "" "")
1036 (match_operand:DF 1 "" "")
1039 (const_string "XF")))])
1041 (define_insn_and_split "*cmpfp_u_cc"
1042 [(set (reg:CCFPU FLAGS_REG)
1044 (match_operand 1 "register_operand" "f")
1045 (match_operand 2 "register_operand" "f")))
1046 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1047 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1048 && TARGET_SAHF && !TARGET_CMOVE
1049 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1051 "&& reload_completed"
1054 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1056 (set (reg:CC FLAGS_REG)
1057 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1059 [(set_attr "type" "multi")
1060 (set_attr "unit" "i387")
1062 (cond [(match_operand:SF 1 "" "")
1064 (match_operand:DF 1 "" "")
1067 (const_string "XF")))])
1069 (define_insn "*cmpfp_<mode>"
1070 [(set (match_operand:HI 0 "register_operand" "=a")
1073 (match_operand 1 "register_operand" "f")
1074 (match_operator 3 "float_operator"
1075 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1077 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1078 && TARGET_USE_<MODE>MODE_FIOP
1079 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1080 "* return output_fp_compare (insn, operands, 0, 0);"
1081 [(set_attr "type" "multi")
1082 (set_attr "unit" "i387")
1083 (set_attr "fp_int_src" "true")
1084 (set_attr "mode" "<MODE>")])
1086 (define_insn_and_split "*cmpfp_<mode>_cc"
1087 [(set (reg:CCFP FLAGS_REG)
1089 (match_operand 1 "register_operand" "f")
1090 (match_operator 3 "float_operator"
1091 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1092 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1093 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1094 && TARGET_SAHF && !TARGET_CMOVE
1095 && TARGET_USE_<MODE>MODE_FIOP
1096 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1098 "&& reload_completed"
1103 (match_op_dup 3 [(match_dup 2)]))]
1105 (set (reg:CC FLAGS_REG)
1106 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1108 [(set_attr "type" "multi")
1109 (set_attr "unit" "i387")
1110 (set_attr "fp_int_src" "true")
1111 (set_attr "mode" "<MODE>")])
1113 ;; FP compares, step 2
1114 ;; Move the fpsw to ax.
1116 (define_insn "x86_fnstsw_1"
1117 [(set (match_operand:HI 0 "register_operand" "=a")
1118 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1121 [(set_attr "length" "2")
1122 (set_attr "mode" "SI")
1123 (set_attr "unit" "i387")])
1125 ;; FP compares, step 3
1126 ;; Get ax into flags, general case.
1128 (define_insn "x86_sahf_1"
1129 [(set (reg:CC FLAGS_REG)
1130 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1134 #ifdef HAVE_AS_IX86_SAHF
1137 return ".byte\t0x9e";
1140 [(set_attr "length" "1")
1141 (set_attr "athlon_decode" "vector")
1142 (set_attr "amdfam10_decode" "direct")
1143 (set_attr "mode" "SI")])
1145 ;; Pentium Pro can do steps 1 through 3 in one go.
1146 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1147 (define_insn "*cmpfp_i_mixed"
1148 [(set (reg:CCFP FLAGS_REG)
1149 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1150 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1151 "TARGET_MIX_SSE_I387
1152 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1153 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1154 "* return output_fp_compare (insn, operands, 1, 0);"
1155 [(set_attr "type" "fcmp,ssecomi")
1157 (if_then_else (match_operand:SF 1 "" "")
1159 (const_string "DF")))
1160 (set_attr "athlon_decode" "vector")
1161 (set_attr "amdfam10_decode" "direct")])
1163 (define_insn "*cmpfp_i_sse"
1164 [(set (reg:CCFP FLAGS_REG)
1165 (compare:CCFP (match_operand 0 "register_operand" "x")
1166 (match_operand 1 "nonimmediate_operand" "xm")))]
1168 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1169 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1170 "* return output_fp_compare (insn, operands, 1, 0);"
1171 [(set_attr "type" "ssecomi")
1173 (if_then_else (match_operand:SF 1 "" "")
1175 (const_string "DF")))
1176 (set_attr "athlon_decode" "vector")
1177 (set_attr "amdfam10_decode" "direct")])
1179 (define_insn "*cmpfp_i_i387"
1180 [(set (reg:CCFP FLAGS_REG)
1181 (compare:CCFP (match_operand 0 "register_operand" "f")
1182 (match_operand 1 "register_operand" "f")))]
1183 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1185 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1186 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1187 "* return output_fp_compare (insn, operands, 1, 0);"
1188 [(set_attr "type" "fcmp")
1190 (cond [(match_operand:SF 1 "" "")
1192 (match_operand:DF 1 "" "")
1195 (const_string "XF")))
1196 (set_attr "athlon_decode" "vector")
1197 (set_attr "amdfam10_decode" "direct")])
1199 (define_insn "*cmpfp_iu_mixed"
1200 [(set (reg:CCFPU FLAGS_REG)
1201 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1202 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1203 "TARGET_MIX_SSE_I387
1204 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1205 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1206 "* return output_fp_compare (insn, operands, 1, 1);"
1207 [(set_attr "type" "fcmp,ssecomi")
1209 (if_then_else (match_operand:SF 1 "" "")
1211 (const_string "DF")))
1212 (set_attr "athlon_decode" "vector")
1213 (set_attr "amdfam10_decode" "direct")])
1215 (define_insn "*cmpfp_iu_sse"
1216 [(set (reg:CCFPU FLAGS_REG)
1217 (compare:CCFPU (match_operand 0 "register_operand" "x")
1218 (match_operand 1 "nonimmediate_operand" "xm")))]
1220 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1221 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1222 "* return output_fp_compare (insn, operands, 1, 1);"
1223 [(set_attr "type" "ssecomi")
1225 (if_then_else (match_operand:SF 1 "" "")
1227 (const_string "DF")))
1228 (set_attr "athlon_decode" "vector")
1229 (set_attr "amdfam10_decode" "direct")])
1231 (define_insn "*cmpfp_iu_387"
1232 [(set (reg:CCFPU FLAGS_REG)
1233 (compare:CCFPU (match_operand 0 "register_operand" "f")
1234 (match_operand 1 "register_operand" "f")))]
1235 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1237 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1238 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1239 "* return output_fp_compare (insn, operands, 1, 1);"
1240 [(set_attr "type" "fcmp")
1242 (cond [(match_operand:SF 1 "" "")
1244 (match_operand:DF 1 "" "")
1247 (const_string "XF")))
1248 (set_attr "athlon_decode" "vector")
1249 (set_attr "amdfam10_decode" "direct")])
1251 ;; Move instructions.
1253 ;; General case of fullword move.
1255 (define_expand "movsi"
1256 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1257 (match_operand:SI 1 "general_operand" ""))]
1259 "ix86_expand_move (SImode, operands); DONE;")
1261 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1264 ;; %%% We don't use a post-inc memory reference because x86 is not a
1265 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1266 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1267 ;; targets without our curiosities, and it is just as easy to represent
1268 ;; this differently.
1270 (define_insn "*pushsi2"
1271 [(set (match_operand:SI 0 "push_operand" "=<")
1272 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1275 [(set_attr "type" "push")
1276 (set_attr "mode" "SI")])
1278 ;; For 64BIT abi we always round up to 8 bytes.
1279 (define_insn "*pushsi2_rex64"
1280 [(set (match_operand:SI 0 "push_operand" "=X")
1281 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1284 [(set_attr "type" "push")
1285 (set_attr "mode" "SI")])
1287 (define_insn "*pushsi2_prologue"
1288 [(set (match_operand:SI 0 "push_operand" "=<")
1289 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1290 (clobber (mem:BLK (scratch)))]
1293 [(set_attr "type" "push")
1294 (set_attr "mode" "SI")])
1296 (define_insn "*popsi1_epilogue"
1297 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1298 (mem:SI (reg:SI SP_REG)))
1299 (set (reg:SI SP_REG)
1300 (plus:SI (reg:SI SP_REG) (const_int 4)))
1301 (clobber (mem:BLK (scratch)))]
1304 [(set_attr "type" "pop")
1305 (set_attr "mode" "SI")])
1307 (define_insn "popsi1"
1308 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1309 (mem:SI (reg:SI SP_REG)))
1310 (set (reg:SI SP_REG)
1311 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1314 [(set_attr "type" "pop")
1315 (set_attr "mode" "SI")])
1317 (define_insn "*movsi_xor"
1318 [(set (match_operand:SI 0 "register_operand" "=r")
1319 (match_operand:SI 1 "const0_operand" "i"))
1320 (clobber (reg:CC FLAGS_REG))]
1321 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1323 [(set_attr "type" "alu1")
1324 (set_attr "mode" "SI")
1325 (set_attr "length_immediate" "0")])
1327 (define_insn "*movsi_or"
1328 [(set (match_operand:SI 0 "register_operand" "=r")
1329 (match_operand:SI 1 "immediate_operand" "i"))
1330 (clobber (reg:CC FLAGS_REG))]
1332 && operands[1] == constm1_rtx
1333 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1335 operands[1] = constm1_rtx;
1336 return "or{l}\t{%1, %0|%0, %1}";
1338 [(set_attr "type" "alu1")
1339 (set_attr "mode" "SI")
1340 (set_attr "length_immediate" "1")])
1342 (define_insn "*movsi_1"
1343 [(set (match_operand:SI 0 "nonimmediate_operand"
1344 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1345 (match_operand:SI 1 "general_operand"
1346 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1347 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1349 switch (get_attr_type (insn))
1352 if (get_attr_mode (insn) == MODE_TI)
1353 return "pxor\t%0, %0";
1354 return "xorps\t%0, %0";
1357 switch (get_attr_mode (insn))
1360 return "movdqa\t{%1, %0|%0, %1}";
1362 return "movaps\t{%1, %0|%0, %1}";
1364 return "movd\t{%1, %0|%0, %1}";
1366 return "movss\t{%1, %0|%0, %1}";
1372 return "pxor\t%0, %0";
1375 if (get_attr_mode (insn) == MODE_DI)
1376 return "movq\t{%1, %0|%0, %1}";
1377 return "movd\t{%1, %0|%0, %1}";
1380 return "lea{l}\t{%1, %0|%0, %1}";
1383 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1384 return "mov{l}\t{%1, %0|%0, %1}";
1388 (cond [(eq_attr "alternative" "2")
1389 (const_string "mmxadd")
1390 (eq_attr "alternative" "3,4,5")
1391 (const_string "mmxmov")
1392 (eq_attr "alternative" "6")
1393 (const_string "sselog1")
1394 (eq_attr "alternative" "7,8,9,10,11")
1395 (const_string "ssemov")
1396 (match_operand:DI 1 "pic_32bit_operand" "")
1397 (const_string "lea")
1399 (const_string "imov")))
1401 (cond [(eq_attr "alternative" "2,3")
1403 (eq_attr "alternative" "6,7")
1405 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1406 (const_string "V4SF")
1407 (const_string "TI"))
1408 (and (eq_attr "alternative" "8,9,10,11")
1409 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1412 (const_string "SI")))])
1414 ;; Stores and loads of ax to arbitrary constant address.
1415 ;; We fake an second form of instruction to force reload to load address
1416 ;; into register when rax is not available
1417 (define_insn "*movabssi_1_rex64"
1418 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1419 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1420 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1422 movabs{l}\t{%1, %P0|%P0, %1}
1423 mov{l}\t{%1, %a0|%a0, %1}"
1424 [(set_attr "type" "imov")
1425 (set_attr "modrm" "0,*")
1426 (set_attr "length_address" "8,0")
1427 (set_attr "length_immediate" "0,*")
1428 (set_attr "memory" "store")
1429 (set_attr "mode" "SI")])
1431 (define_insn "*movabssi_2_rex64"
1432 [(set (match_operand:SI 0 "register_operand" "=a,r")
1433 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1434 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1436 movabs{l}\t{%P1, %0|%0, %P1}
1437 mov{l}\t{%a1, %0|%0, %a1}"
1438 [(set_attr "type" "imov")
1439 (set_attr "modrm" "0,*")
1440 (set_attr "length_address" "8,0")
1441 (set_attr "length_immediate" "0")
1442 (set_attr "memory" "load")
1443 (set_attr "mode" "SI")])
1445 (define_insn "*swapsi"
1446 [(set (match_operand:SI 0 "register_operand" "+r")
1447 (match_operand:SI 1 "register_operand" "+r"))
1452 [(set_attr "type" "imov")
1453 (set_attr "mode" "SI")
1454 (set_attr "pent_pair" "np")
1455 (set_attr "athlon_decode" "vector")
1456 (set_attr "amdfam10_decode" "double")])
1458 (define_expand "movhi"
1459 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1460 (match_operand:HI 1 "general_operand" ""))]
1462 "ix86_expand_move (HImode, operands); DONE;")
1464 (define_insn "*pushhi2"
1465 [(set (match_operand:HI 0 "push_operand" "=X")
1466 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1469 [(set_attr "type" "push")
1470 (set_attr "mode" "SI")])
1472 ;; For 64BIT abi we always round up to 8 bytes.
1473 (define_insn "*pushhi2_rex64"
1474 [(set (match_operand:HI 0 "push_operand" "=X")
1475 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1478 [(set_attr "type" "push")
1479 (set_attr "mode" "DI")])
1481 (define_insn "*movhi_1"
1482 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1483 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1484 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1486 switch (get_attr_type (insn))
1489 /* movzwl is faster than movw on p2 due to partial word stalls,
1490 though not as fast as an aligned movl. */
1491 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1493 if (get_attr_mode (insn) == MODE_SI)
1494 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1496 return "mov{w}\t{%1, %0|%0, %1}";
1500 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1501 (const_string "imov")
1502 (and (eq_attr "alternative" "0")
1503 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1505 (eq (symbol_ref "TARGET_HIMODE_MATH")
1507 (const_string "imov")
1508 (and (eq_attr "alternative" "1,2")
1509 (match_operand:HI 1 "aligned_operand" ""))
1510 (const_string "imov")
1511 (and (ne (symbol_ref "TARGET_MOVX")
1513 (eq_attr "alternative" "0,2"))
1514 (const_string "imovx")
1516 (const_string "imov")))
1518 (cond [(eq_attr "type" "imovx")
1520 (and (eq_attr "alternative" "1,2")
1521 (match_operand:HI 1 "aligned_operand" ""))
1523 (and (eq_attr "alternative" "0")
1524 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1526 (eq (symbol_ref "TARGET_HIMODE_MATH")
1530 (const_string "HI")))])
1532 ;; Stores and loads of ax to arbitrary constant address.
1533 ;; We fake an second form of instruction to force reload to load address
1534 ;; into register when rax is not available
1535 (define_insn "*movabshi_1_rex64"
1536 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1537 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1538 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1540 movabs{w}\t{%1, %P0|%P0, %1}
1541 mov{w}\t{%1, %a0|%a0, %1}"
1542 [(set_attr "type" "imov")
1543 (set_attr "modrm" "0,*")
1544 (set_attr "length_address" "8,0")
1545 (set_attr "length_immediate" "0,*")
1546 (set_attr "memory" "store")
1547 (set_attr "mode" "HI")])
1549 (define_insn "*movabshi_2_rex64"
1550 [(set (match_operand:HI 0 "register_operand" "=a,r")
1551 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1552 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1554 movabs{w}\t{%P1, %0|%0, %P1}
1555 mov{w}\t{%a1, %0|%0, %a1}"
1556 [(set_attr "type" "imov")
1557 (set_attr "modrm" "0,*")
1558 (set_attr "length_address" "8,0")
1559 (set_attr "length_immediate" "0")
1560 (set_attr "memory" "load")
1561 (set_attr "mode" "HI")])
1563 (define_insn "*swaphi_1"
1564 [(set (match_operand:HI 0 "register_operand" "+r")
1565 (match_operand:HI 1 "register_operand" "+r"))
1568 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1570 [(set_attr "type" "imov")
1571 (set_attr "mode" "SI")
1572 (set_attr "pent_pair" "np")
1573 (set_attr "athlon_decode" "vector")
1574 (set_attr "amdfam10_decode" "double")])
1576 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1577 (define_insn "*swaphi_2"
1578 [(set (match_operand:HI 0 "register_operand" "+r")
1579 (match_operand:HI 1 "register_operand" "+r"))
1582 "TARGET_PARTIAL_REG_STALL"
1584 [(set_attr "type" "imov")
1585 (set_attr "mode" "HI")
1586 (set_attr "pent_pair" "np")
1587 (set_attr "athlon_decode" "vector")])
1589 (define_expand "movstricthi"
1590 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1591 (match_operand:HI 1 "general_operand" ""))]
1592 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1594 /* Don't generate memory->memory moves, go through a register */
1595 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1596 operands[1] = force_reg (HImode, operands[1]);
1599 (define_insn "*movstricthi_1"
1600 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1601 (match_operand:HI 1 "general_operand" "rn,m"))]
1602 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1603 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1604 "mov{w}\t{%1, %0|%0, %1}"
1605 [(set_attr "type" "imov")
1606 (set_attr "mode" "HI")])
1608 (define_insn "*movstricthi_xor"
1609 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1610 (match_operand:HI 1 "const0_operand" "i"))
1611 (clobber (reg:CC FLAGS_REG))]
1613 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1615 [(set_attr "type" "alu1")
1616 (set_attr "mode" "HI")
1617 (set_attr "length_immediate" "0")])
1619 (define_expand "movqi"
1620 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1621 (match_operand:QI 1 "general_operand" ""))]
1623 "ix86_expand_move (QImode, operands); DONE;")
1625 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1626 ;; "push a byte". But actually we use pushl, which has the effect
1627 ;; of rounding the amount pushed up to a word.
1629 (define_insn "*pushqi2"
1630 [(set (match_operand:QI 0 "push_operand" "=X")
1631 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1634 [(set_attr "type" "push")
1635 (set_attr "mode" "SI")])
1637 ;; For 64BIT abi we always round up to 8 bytes.
1638 (define_insn "*pushqi2_rex64"
1639 [(set (match_operand:QI 0 "push_operand" "=X")
1640 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1643 [(set_attr "type" "push")
1644 (set_attr "mode" "DI")])
1646 ;; Situation is quite tricky about when to choose full sized (SImode) move
1647 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1648 ;; partial register dependency machines (such as AMD Athlon), where QImode
1649 ;; moves issue extra dependency and for partial register stalls machines
1650 ;; that don't use QImode patterns (and QImode move cause stall on the next
1653 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1654 ;; register stall machines with, where we use QImode instructions, since
1655 ;; partial register stall can be caused there. Then we use movzx.
1656 (define_insn "*movqi_1"
1657 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1658 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1659 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1661 switch (get_attr_type (insn))
1664 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1665 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1667 if (get_attr_mode (insn) == MODE_SI)
1668 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1670 return "mov{b}\t{%1, %0|%0, %1}";
1674 (cond [(and (eq_attr "alternative" "5")
1675 (not (match_operand:QI 1 "aligned_operand" "")))
1676 (const_string "imovx")
1677 (ne (symbol_ref "optimize_size") (const_int 0))
1678 (const_string "imov")
1679 (and (eq_attr "alternative" "3")
1680 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1682 (eq (symbol_ref "TARGET_QIMODE_MATH")
1684 (const_string "imov")
1685 (eq_attr "alternative" "3,5")
1686 (const_string "imovx")
1687 (and (ne (symbol_ref "TARGET_MOVX")
1689 (eq_attr "alternative" "2"))
1690 (const_string "imovx")
1692 (const_string "imov")))
1694 (cond [(eq_attr "alternative" "3,4,5")
1696 (eq_attr "alternative" "6")
1698 (eq_attr "type" "imovx")
1700 (and (eq_attr "type" "imov")
1701 (and (eq_attr "alternative" "0,1")
1702 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1704 (and (eq (symbol_ref "optimize_size")
1706 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1709 ;; Avoid partial register stalls when not using QImode arithmetic
1710 (and (eq_attr "type" "imov")
1711 (and (eq_attr "alternative" "0,1")
1712 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1714 (eq (symbol_ref "TARGET_QIMODE_MATH")
1718 (const_string "QI")))])
1720 (define_expand "reload_outqi"
1721 [(parallel [(match_operand:QI 0 "" "=m")
1722 (match_operand:QI 1 "register_operand" "r")
1723 (match_operand:QI 2 "register_operand" "=&q")])]
1727 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1729 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1730 if (! q_regs_operand (op1, QImode))
1732 emit_insn (gen_movqi (op2, op1));
1735 emit_insn (gen_movqi (op0, op1));
1739 (define_insn "*swapqi_1"
1740 [(set (match_operand:QI 0 "register_operand" "+r")
1741 (match_operand:QI 1 "register_operand" "+r"))
1744 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1746 [(set_attr "type" "imov")
1747 (set_attr "mode" "SI")
1748 (set_attr "pent_pair" "np")
1749 (set_attr "athlon_decode" "vector")
1750 (set_attr "amdfam10_decode" "vector")])
1752 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1753 (define_insn "*swapqi_2"
1754 [(set (match_operand:QI 0 "register_operand" "+q")
1755 (match_operand:QI 1 "register_operand" "+q"))
1758 "TARGET_PARTIAL_REG_STALL"
1760 [(set_attr "type" "imov")
1761 (set_attr "mode" "QI")
1762 (set_attr "pent_pair" "np")
1763 (set_attr "athlon_decode" "vector")])
1765 (define_expand "movstrictqi"
1766 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1767 (match_operand:QI 1 "general_operand" ""))]
1768 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1770 /* Don't generate memory->memory moves, go through a register. */
1771 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1772 operands[1] = force_reg (QImode, operands[1]);
1775 (define_insn "*movstrictqi_1"
1776 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1777 (match_operand:QI 1 "general_operand" "*qn,m"))]
1778 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1779 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1780 "mov{b}\t{%1, %0|%0, %1}"
1781 [(set_attr "type" "imov")
1782 (set_attr "mode" "QI")])
1784 (define_insn "*movstrictqi_xor"
1785 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1786 (match_operand:QI 1 "const0_operand" "i"))
1787 (clobber (reg:CC FLAGS_REG))]
1788 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1790 [(set_attr "type" "alu1")
1791 (set_attr "mode" "QI")
1792 (set_attr "length_immediate" "0")])
1794 (define_insn "*movsi_extv_1"
1795 [(set (match_operand:SI 0 "register_operand" "=R")
1796 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1800 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1801 [(set_attr "type" "imovx")
1802 (set_attr "mode" "SI")])
1804 (define_insn "*movhi_extv_1"
1805 [(set (match_operand:HI 0 "register_operand" "=R")
1806 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1810 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1811 [(set_attr "type" "imovx")
1812 (set_attr "mode" "SI")])
1814 (define_insn "*movqi_extv_1"
1815 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1816 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1821 switch (get_attr_type (insn))
1824 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1826 return "mov{b}\t{%h1, %0|%0, %h1}";
1830 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1831 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1832 (ne (symbol_ref "TARGET_MOVX")
1834 (const_string "imovx")
1835 (const_string "imov")))
1837 (if_then_else (eq_attr "type" "imovx")
1839 (const_string "QI")))])
1841 (define_insn "*movqi_extv_1_rex64"
1842 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1843 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1848 switch (get_attr_type (insn))
1851 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1853 return "mov{b}\t{%h1, %0|%0, %h1}";
1857 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1858 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1859 (ne (symbol_ref "TARGET_MOVX")
1861 (const_string "imovx")
1862 (const_string "imov")))
1864 (if_then_else (eq_attr "type" "imovx")
1866 (const_string "QI")))])
1868 ;; Stores and loads of ax to arbitrary constant address.
1869 ;; We fake an second form of instruction to force reload to load address
1870 ;; into register when rax is not available
1871 (define_insn "*movabsqi_1_rex64"
1872 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1873 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1874 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1876 movabs{b}\t{%1, %P0|%P0, %1}
1877 mov{b}\t{%1, %a0|%a0, %1}"
1878 [(set_attr "type" "imov")
1879 (set_attr "modrm" "0,*")
1880 (set_attr "length_address" "8,0")
1881 (set_attr "length_immediate" "0,*")
1882 (set_attr "memory" "store")
1883 (set_attr "mode" "QI")])
1885 (define_insn "*movabsqi_2_rex64"
1886 [(set (match_operand:QI 0 "register_operand" "=a,r")
1887 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1888 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1890 movabs{b}\t{%P1, %0|%0, %P1}
1891 mov{b}\t{%a1, %0|%0, %a1}"
1892 [(set_attr "type" "imov")
1893 (set_attr "modrm" "0,*")
1894 (set_attr "length_address" "8,0")
1895 (set_attr "length_immediate" "0")
1896 (set_attr "memory" "load")
1897 (set_attr "mode" "QI")])
1899 (define_insn "*movdi_extzv_1"
1900 [(set (match_operand:DI 0 "register_operand" "=R")
1901 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1905 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1906 [(set_attr "type" "imovx")
1907 (set_attr "mode" "DI")])
1909 (define_insn "*movsi_extzv_1"
1910 [(set (match_operand:SI 0 "register_operand" "=R")
1911 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1915 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1916 [(set_attr "type" "imovx")
1917 (set_attr "mode" "SI")])
1919 (define_insn "*movqi_extzv_2"
1920 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1921 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1926 switch (get_attr_type (insn))
1929 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1931 return "mov{b}\t{%h1, %0|%0, %h1}";
1935 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1936 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1937 (ne (symbol_ref "TARGET_MOVX")
1939 (const_string "imovx")
1940 (const_string "imov")))
1942 (if_then_else (eq_attr "type" "imovx")
1944 (const_string "QI")))])
1946 (define_insn "*movqi_extzv_2_rex64"
1947 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1948 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1953 switch (get_attr_type (insn))
1956 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1958 return "mov{b}\t{%h1, %0|%0, %h1}";
1962 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1963 (ne (symbol_ref "TARGET_MOVX")
1965 (const_string "imovx")
1966 (const_string "imov")))
1968 (if_then_else (eq_attr "type" "imovx")
1970 (const_string "QI")))])
1972 (define_insn "movsi_insv_1"
1973 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1976 (match_operand:SI 1 "general_operand" "Qmn"))]
1978 "mov{b}\t{%b1, %h0|%h0, %b1}"
1979 [(set_attr "type" "imov")
1980 (set_attr "mode" "QI")])
1982 (define_insn "*movsi_insv_1_rex64"
1983 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1986 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1988 "mov{b}\t{%b1, %h0|%h0, %b1}"
1989 [(set_attr "type" "imov")
1990 (set_attr "mode" "QI")])
1992 (define_insn "movdi_insv_1_rex64"
1993 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1996 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1998 "mov{b}\t{%b1, %h0|%h0, %b1}"
1999 [(set_attr "type" "imov")
2000 (set_attr "mode" "QI")])
2002 (define_insn "*movqi_insv_2"
2003 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2006 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2009 "mov{b}\t{%h1, %h0|%h0, %h1}"
2010 [(set_attr "type" "imov")
2011 (set_attr "mode" "QI")])
2013 (define_expand "movdi"
2014 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2015 (match_operand:DI 1 "general_operand" ""))]
2017 "ix86_expand_move (DImode, operands); DONE;")
2019 (define_insn "*pushdi"
2020 [(set (match_operand:DI 0 "push_operand" "=<")
2021 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2025 (define_insn "*pushdi2_rex64"
2026 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2027 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2032 [(set_attr "type" "push,multi")
2033 (set_attr "mode" "DI")])
2035 ;; Convert impossible pushes of immediate to existing instructions.
2036 ;; First try to get scratch register and go through it. In case this
2037 ;; fails, push sign extended lower part first and then overwrite
2038 ;; upper part by 32bit move.
2040 [(match_scratch:DI 2 "r")
2041 (set (match_operand:DI 0 "push_operand" "")
2042 (match_operand:DI 1 "immediate_operand" ""))]
2043 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2044 && !x86_64_immediate_operand (operands[1], DImode)"
2045 [(set (match_dup 2) (match_dup 1))
2046 (set (match_dup 0) (match_dup 2))]
2049 ;; We need to define this as both peepholer and splitter for case
2050 ;; peephole2 pass is not run.
2051 ;; "&& 1" is needed to keep it from matching the previous pattern.
2053 [(set (match_operand:DI 0 "push_operand" "")
2054 (match_operand:DI 1 "immediate_operand" ""))]
2055 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2056 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2057 [(set (match_dup 0) (match_dup 1))
2058 (set (match_dup 2) (match_dup 3))]
2059 "split_di (operands + 1, 1, operands + 2, operands + 3);
2060 operands[1] = gen_lowpart (DImode, operands[2]);
2061 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2066 [(set (match_operand:DI 0 "push_operand" "")
2067 (match_operand:DI 1 "immediate_operand" ""))]
2068 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2069 ? epilogue_completed : reload_completed)
2070 && !symbolic_operand (operands[1], DImode)
2071 && !x86_64_immediate_operand (operands[1], DImode)"
2072 [(set (match_dup 0) (match_dup 1))
2073 (set (match_dup 2) (match_dup 3))]
2074 "split_di (operands + 1, 1, operands + 2, operands + 3);
2075 operands[1] = gen_lowpart (DImode, operands[2]);
2076 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2080 (define_insn "*pushdi2_prologue_rex64"
2081 [(set (match_operand:DI 0 "push_operand" "=<")
2082 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2083 (clobber (mem:BLK (scratch)))]
2086 [(set_attr "type" "push")
2087 (set_attr "mode" "DI")])
2089 (define_insn "*popdi1_epilogue_rex64"
2090 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2091 (mem:DI (reg:DI SP_REG)))
2092 (set (reg:DI SP_REG)
2093 (plus:DI (reg:DI SP_REG) (const_int 8)))
2094 (clobber (mem:BLK (scratch)))]
2097 [(set_attr "type" "pop")
2098 (set_attr "mode" "DI")])
2100 (define_insn "popdi1"
2101 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2102 (mem:DI (reg:DI SP_REG)))
2103 (set (reg:DI SP_REG)
2104 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2107 [(set_attr "type" "pop")
2108 (set_attr "mode" "DI")])
2110 (define_insn "*movdi_xor_rex64"
2111 [(set (match_operand:DI 0 "register_operand" "=r")
2112 (match_operand:DI 1 "const0_operand" "i"))
2113 (clobber (reg:CC FLAGS_REG))]
2114 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2115 && reload_completed"
2117 [(set_attr "type" "alu1")
2118 (set_attr "mode" "SI")
2119 (set_attr "length_immediate" "0")])
2121 (define_insn "*movdi_or_rex64"
2122 [(set (match_operand:DI 0 "register_operand" "=r")
2123 (match_operand:DI 1 "const_int_operand" "i"))
2124 (clobber (reg:CC FLAGS_REG))]
2125 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2127 && operands[1] == constm1_rtx"
2129 operands[1] = constm1_rtx;
2130 return "or{q}\t{%1, %0|%0, %1}";
2132 [(set_attr "type" "alu1")
2133 (set_attr "mode" "DI")
2134 (set_attr "length_immediate" "1")])
2136 (define_insn "*movdi_2"
2137 [(set (match_operand:DI 0 "nonimmediate_operand"
2138 "=r ,o ,*y,m*y,*y,*Yt,m ,*Yt,*Yt,*x,m ,*x,*x")
2139 (match_operand:DI 1 "general_operand"
2140 "riFo,riF,C ,*y ,m ,C ,*Yt,*Yt,m ,C ,*x,*x,m "))]
2141 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2146 movq\t{%1, %0|%0, %1}
2147 movq\t{%1, %0|%0, %1}
2149 movq\t{%1, %0|%0, %1}
2150 movdqa\t{%1, %0|%0, %1}
2151 movq\t{%1, %0|%0, %1}
2153 movlps\t{%1, %0|%0, %1}
2154 movaps\t{%1, %0|%0, %1}
2155 movlps\t{%1, %0|%0, %1}"
2156 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2157 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2160 [(set (match_operand:DI 0 "push_operand" "")
2161 (match_operand:DI 1 "general_operand" ""))]
2162 "!TARGET_64BIT && reload_completed
2163 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2165 "ix86_split_long_move (operands); DONE;")
2167 ;; %%% This multiword shite has got to go.
2169 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2170 (match_operand:DI 1 "general_operand" ""))]
2171 "!TARGET_64BIT && reload_completed
2172 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2173 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2175 "ix86_split_long_move (operands); DONE;")
2177 (define_insn "*movdi_1_rex64"
2178 [(set (match_operand:DI 0 "nonimmediate_operand"
2179 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2180 (match_operand:DI 1 "general_operand"
2181 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2182 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2184 switch (get_attr_type (insn))
2187 if (SSE_REG_P (operands[0]))
2188 return "movq2dq\t{%1, %0|%0, %1}";
2190 return "movdq2q\t{%1, %0|%0, %1}";
2193 if (get_attr_mode (insn) == MODE_TI)
2194 return "movdqa\t{%1, %0|%0, %1}";
2198 /* Moves from and into integer register is done using movd
2199 opcode with REX prefix. */
2200 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2201 return "movd\t{%1, %0|%0, %1}";
2202 return "movq\t{%1, %0|%0, %1}";
2206 return "pxor\t%0, %0";
2212 return "lea{q}\t{%a1, %0|%0, %a1}";
2215 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2216 if (get_attr_mode (insn) == MODE_SI)
2217 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2218 else if (which_alternative == 2)
2219 return "movabs{q}\t{%1, %0|%0, %1}";
2221 return "mov{q}\t{%1, %0|%0, %1}";
2225 (cond [(eq_attr "alternative" "5")
2226 (const_string "mmxadd")
2227 (eq_attr "alternative" "6,7,8,9,10")
2228 (const_string "mmxmov")
2229 (eq_attr "alternative" "11")
2230 (const_string "sselog1")
2231 (eq_attr "alternative" "12,13,14,15,16")
2232 (const_string "ssemov")
2233 (eq_attr "alternative" "17,18")
2234 (const_string "ssecvt")
2235 (eq_attr "alternative" "4")
2236 (const_string "multi")
2237 (match_operand:DI 1 "pic_32bit_operand" "")
2238 (const_string "lea")
2240 (const_string "imov")))
2241 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2242 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2243 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2245 ;; Stores and loads of ax to arbitrary constant address.
2246 ;; We fake an second form of instruction to force reload to load address
2247 ;; into register when rax is not available
2248 (define_insn "*movabsdi_1_rex64"
2249 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2250 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2251 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2253 movabs{q}\t{%1, %P0|%P0, %1}
2254 mov{q}\t{%1, %a0|%a0, %1}"
2255 [(set_attr "type" "imov")
2256 (set_attr "modrm" "0,*")
2257 (set_attr "length_address" "8,0")
2258 (set_attr "length_immediate" "0,*")
2259 (set_attr "memory" "store")
2260 (set_attr "mode" "DI")])
2262 (define_insn "*movabsdi_2_rex64"
2263 [(set (match_operand:DI 0 "register_operand" "=a,r")
2264 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2265 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2267 movabs{q}\t{%P1, %0|%0, %P1}
2268 mov{q}\t{%a1, %0|%0, %a1}"
2269 [(set_attr "type" "imov")
2270 (set_attr "modrm" "0,*")
2271 (set_attr "length_address" "8,0")
2272 (set_attr "length_immediate" "0")
2273 (set_attr "memory" "load")
2274 (set_attr "mode" "DI")])
2276 ;; Convert impossible stores of immediate to existing instructions.
2277 ;; First try to get scratch register and go through it. In case this
2278 ;; fails, move by 32bit parts.
2280 [(match_scratch:DI 2 "r")
2281 (set (match_operand:DI 0 "memory_operand" "")
2282 (match_operand:DI 1 "immediate_operand" ""))]
2283 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2284 && !x86_64_immediate_operand (operands[1], DImode)"
2285 [(set (match_dup 2) (match_dup 1))
2286 (set (match_dup 0) (match_dup 2))]
2289 ;; We need to define this as both peepholer and splitter for case
2290 ;; peephole2 pass is not run.
2291 ;; "&& 1" is needed to keep it from matching the previous pattern.
2293 [(set (match_operand:DI 0 "memory_operand" "")
2294 (match_operand:DI 1 "immediate_operand" ""))]
2295 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2296 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2297 [(set (match_dup 2) (match_dup 3))
2298 (set (match_dup 4) (match_dup 5))]
2299 "split_di (operands, 2, operands + 2, operands + 4);")
2302 [(set (match_operand:DI 0 "memory_operand" "")
2303 (match_operand:DI 1 "immediate_operand" ""))]
2304 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2305 ? epilogue_completed : reload_completed)
2306 && !symbolic_operand (operands[1], DImode)
2307 && !x86_64_immediate_operand (operands[1], DImode)"
2308 [(set (match_dup 2) (match_dup 3))
2309 (set (match_dup 4) (match_dup 5))]
2310 "split_di (operands, 2, operands + 2, operands + 4);")
2312 (define_insn "*swapdi_rex64"
2313 [(set (match_operand:DI 0 "register_operand" "+r")
2314 (match_operand:DI 1 "register_operand" "+r"))
2319 [(set_attr "type" "imov")
2320 (set_attr "mode" "DI")
2321 (set_attr "pent_pair" "np")
2322 (set_attr "athlon_decode" "vector")
2323 (set_attr "amdfam10_decode" "double")])
2325 (define_expand "movti"
2326 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2327 (match_operand:TI 1 "nonimmediate_operand" ""))]
2328 "TARGET_SSE || TARGET_64BIT"
2331 ix86_expand_move (TImode, operands);
2332 else if (push_operand (operands[0], TImode))
2333 ix86_expand_push (TImode, operands[1]);
2335 ix86_expand_vector_move (TImode, operands);
2339 (define_insn "*movti_internal"
2340 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2341 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2342 "TARGET_SSE && !TARGET_64BIT
2343 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2345 switch (which_alternative)
2348 if (get_attr_mode (insn) == MODE_V4SF)
2349 return "xorps\t%0, %0";
2351 return "pxor\t%0, %0";
2354 if (get_attr_mode (insn) == MODE_V4SF)
2355 return "movaps\t{%1, %0|%0, %1}";
2357 return "movdqa\t{%1, %0|%0, %1}";
2362 [(set_attr "type" "sselog1,ssemov,ssemov")
2364 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2365 (ne (symbol_ref "optimize_size") (const_int 0)))
2366 (const_string "V4SF")
2367 (and (eq_attr "alternative" "2")
2368 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2370 (const_string "V4SF")]
2371 (const_string "TI")))])
2373 (define_insn "*movti_rex64"
2374 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2375 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2377 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2379 switch (which_alternative)
2385 if (get_attr_mode (insn) == MODE_V4SF)
2386 return "xorps\t%0, %0";
2388 return "pxor\t%0, %0";
2391 if (get_attr_mode (insn) == MODE_V4SF)
2392 return "movaps\t{%1, %0|%0, %1}";
2394 return "movdqa\t{%1, %0|%0, %1}";
2399 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2401 (cond [(eq_attr "alternative" "2,3")
2403 (ne (symbol_ref "optimize_size")
2405 (const_string "V4SF")
2406 (const_string "TI"))
2407 (eq_attr "alternative" "4")
2409 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2411 (ne (symbol_ref "optimize_size")
2413 (const_string "V4SF")
2414 (const_string "TI"))]
2415 (const_string "DI")))])
2418 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2419 (match_operand:TI 1 "general_operand" ""))]
2420 "reload_completed && !SSE_REG_P (operands[0])
2421 && !SSE_REG_P (operands[1])"
2423 "ix86_split_long_move (operands); DONE;")
2425 ;; This expands to what emit_move_complex would generate if we didn't
2426 ;; have a movti pattern. Having this avoids problems with reload on
2427 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2428 ;; to have around all the time.
2429 (define_expand "movcdi"
2430 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2431 (match_operand:CDI 1 "general_operand" ""))]
2434 if (push_operand (operands[0], CDImode))
2435 emit_move_complex_push (CDImode, operands[0], operands[1]);
2437 emit_move_complex_parts (operands[0], operands[1]);
2441 (define_expand "movsf"
2442 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2443 (match_operand:SF 1 "general_operand" ""))]
2445 "ix86_expand_move (SFmode, operands); DONE;")
2447 (define_insn "*pushsf"
2448 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2449 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2452 /* Anything else should be already split before reg-stack. */
2453 gcc_assert (which_alternative == 1);
2454 return "push{l}\t%1";
2456 [(set_attr "type" "multi,push,multi")
2457 (set_attr "unit" "i387,*,*")
2458 (set_attr "mode" "SF,SI,SF")])
2460 (define_insn "*pushsf_rex64"
2461 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2462 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2465 /* Anything else should be already split before reg-stack. */
2466 gcc_assert (which_alternative == 1);
2467 return "push{q}\t%q1";
2469 [(set_attr "type" "multi,push,multi")
2470 (set_attr "unit" "i387,*,*")
2471 (set_attr "mode" "SF,DI,SF")])
2474 [(set (match_operand:SF 0 "push_operand" "")
2475 (match_operand:SF 1 "memory_operand" ""))]
2477 && MEM_P (operands[1])
2478 && (operands[2] = find_constant_src (insn))"
2483 ;; %%% Kill this when call knows how to work this out.
2485 [(set (match_operand:SF 0 "push_operand" "")
2486 (match_operand:SF 1 "any_fp_register_operand" ""))]
2488 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2489 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2492 [(set (match_operand:SF 0 "push_operand" "")
2493 (match_operand:SF 1 "any_fp_register_operand" ""))]
2495 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2496 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2498 (define_insn "*movsf_1"
2499 [(set (match_operand:SF 0 "nonimmediate_operand"
2500 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2501 (match_operand:SF 1 "general_operand"
2502 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2503 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2504 && (reload_in_progress || reload_completed
2505 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2506 || (!TARGET_SSE_MATH && optimize_size
2507 && standard_80387_constant_p (operands[1]))
2508 || GET_CODE (operands[1]) != CONST_DOUBLE
2509 || memory_operand (operands[0], SFmode))"
2511 switch (which_alternative)
2515 return output_387_reg_move (insn, operands);
2518 return standard_80387_constant_opcode (operands[1]);
2522 return "mov{l}\t{%1, %0|%0, %1}";
2524 if (get_attr_mode (insn) == MODE_TI)
2525 return "pxor\t%0, %0";
2527 return "xorps\t%0, %0";
2529 if (get_attr_mode (insn) == MODE_V4SF)
2530 return "movaps\t{%1, %0|%0, %1}";
2532 return "movss\t{%1, %0|%0, %1}";
2534 return "movss\t{%1, %0|%0, %1}";
2537 case 12: case 13: case 14: case 15:
2538 return "movd\t{%1, %0|%0, %1}";
2541 return "movq\t{%1, %0|%0, %1}";
2547 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2549 (cond [(eq_attr "alternative" "3,4,9,10")
2551 (eq_attr "alternative" "5")
2553 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2555 (ne (symbol_ref "TARGET_SSE2")
2557 (eq (symbol_ref "optimize_size")
2560 (const_string "V4SF"))
2561 /* For architectures resolving dependencies on
2562 whole SSE registers use APS move to break dependency
2563 chains, otherwise use short move to avoid extra work.
2565 Do the same for architectures resolving dependencies on
2566 the parts. While in DF mode it is better to always handle
2567 just register parts, the SF mode is different due to lack
2568 of instructions to load just part of the register. It is
2569 better to maintain the whole registers in single format
2570 to avoid problems on using packed logical operations. */
2571 (eq_attr "alternative" "6")
2573 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2575 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2577 (const_string "V4SF")
2578 (const_string "SF"))
2579 (eq_attr "alternative" "11")
2580 (const_string "DI")]
2581 (const_string "SF")))])
2583 (define_insn "*swapsf"
2584 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2585 (match_operand:SF 1 "fp_register_operand" "+f"))
2588 "reload_completed || TARGET_80387"
2590 if (STACK_TOP_P (operands[0]))
2595 [(set_attr "type" "fxch")
2596 (set_attr "mode" "SF")])
2598 (define_expand "movdf"
2599 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2600 (match_operand:DF 1 "general_operand" ""))]
2602 "ix86_expand_move (DFmode, operands); DONE;")
2604 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2605 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2606 ;; On the average, pushdf using integers can be still shorter. Allow this
2607 ;; pattern for optimize_size too.
2609 (define_insn "*pushdf_nointeger"
2610 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2611 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Yt"))]
2612 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2614 /* This insn should be already split before reg-stack. */
2617 [(set_attr "type" "multi")
2618 (set_attr "unit" "i387,*,*,*")
2619 (set_attr "mode" "DF,SI,SI,DF")])
2621 (define_insn "*pushdf_integer"
2622 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2623 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Yt"))]
2624 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2626 /* This insn should be already split before reg-stack. */
2629 [(set_attr "type" "multi")
2630 (set_attr "unit" "i387,*,*")
2631 (set_attr "mode" "DF,SI,DF")])
2633 ;; %%% Kill this when call knows how to work this out.
2635 [(set (match_operand:DF 0 "push_operand" "")
2636 (match_operand:DF 1 "any_fp_register_operand" ""))]
2637 "!TARGET_64BIT && reload_completed"
2638 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2639 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2643 [(set (match_operand:DF 0 "push_operand" "")
2644 (match_operand:DF 1 "any_fp_register_operand" ""))]
2645 "TARGET_64BIT && reload_completed"
2646 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2647 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2651 [(set (match_operand:DF 0 "push_operand" "")
2652 (match_operand:DF 1 "general_operand" ""))]
2655 "ix86_split_long_move (operands); DONE;")
2657 ;; Moving is usually shorter when only FP registers are used. This separate
2658 ;; movdf pattern avoids the use of integer registers for FP operations
2659 ;; when optimizing for size.
2661 (define_insn "*movdf_nointeger"
2662 [(set (match_operand:DF 0 "nonimmediate_operand"
2663 "=f,m,f,*r ,o ,Yt*x,Yt*x,Yt*x ,m ")
2664 (match_operand:DF 1 "general_operand"
2665 "fm,f,G,*roF,F*r,C ,Yt*x,mYt*x,Yt*x"))]
2666 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2667 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2668 && (reload_in_progress || reload_completed
2669 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2670 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2671 && standard_80387_constant_p (operands[1]))
2672 || GET_CODE (operands[1]) != CONST_DOUBLE
2673 || memory_operand (operands[0], DFmode))"
2675 switch (which_alternative)
2679 return output_387_reg_move (insn, operands);
2682 return standard_80387_constant_opcode (operands[1]);
2688 switch (get_attr_mode (insn))
2691 return "xorps\t%0, %0";
2693 return "xorpd\t%0, %0";
2695 return "pxor\t%0, %0";
2702 switch (get_attr_mode (insn))
2705 return "movaps\t{%1, %0|%0, %1}";
2707 return "movapd\t{%1, %0|%0, %1}";
2709 return "movdqa\t{%1, %0|%0, %1}";
2711 return "movq\t{%1, %0|%0, %1}";
2713 return "movsd\t{%1, %0|%0, %1}";
2715 return "movlpd\t{%1, %0|%0, %1}";
2717 return "movlps\t{%1, %0|%0, %1}";
2726 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2728 (cond [(eq_attr "alternative" "0,1,2")
2730 (eq_attr "alternative" "3,4")
2733 /* For SSE1, we have many fewer alternatives. */
2734 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2735 (cond [(eq_attr "alternative" "5,6")
2736 (const_string "V4SF")
2738 (const_string "V2SF"))
2740 /* xorps is one byte shorter. */
2741 (eq_attr "alternative" "5")
2742 (cond [(ne (symbol_ref "optimize_size")
2744 (const_string "V4SF")
2745 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2749 (const_string "V2DF"))
2751 /* For architectures resolving dependencies on
2752 whole SSE registers use APD move to break dependency
2753 chains, otherwise use short move to avoid extra work.
2755 movaps encodes one byte shorter. */
2756 (eq_attr "alternative" "6")
2758 [(ne (symbol_ref "optimize_size")
2760 (const_string "V4SF")
2761 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2763 (const_string "V2DF")
2765 (const_string "DF"))
2766 /* For architectures resolving dependencies on register
2767 parts we may avoid extra work to zero out upper part
2769 (eq_attr "alternative" "7")
2771 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2773 (const_string "V1DF")
2774 (const_string "DF"))
2776 (const_string "DF")))])
2778 (define_insn "*movdf_integer_rex64"
2779 [(set (match_operand:DF 0 "nonimmediate_operand"
2780 "=f,m,f,r ,m ,Yt*x,Yt*x,Yt*x,m ,Yi,r ")
2781 (match_operand:DF 1 "general_operand"
2782 "fm,f,G,rmF,Fr,C ,Yt*x,m ,Yt*x,r ,Yi"))]
2783 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2784 && (reload_in_progress || reload_completed
2785 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2786 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2787 && standard_80387_constant_p (operands[1]))
2788 || GET_CODE (operands[1]) != CONST_DOUBLE
2789 || memory_operand (operands[0], DFmode))"
2791 switch (which_alternative)
2795 return output_387_reg_move (insn, operands);
2798 return standard_80387_constant_opcode (operands[1]);
2805 switch (get_attr_mode (insn))
2808 return "xorps\t%0, %0";
2810 return "xorpd\t%0, %0";
2812 return "pxor\t%0, %0";
2819 switch (get_attr_mode (insn))
2822 return "movaps\t{%1, %0|%0, %1}";
2824 return "movapd\t{%1, %0|%0, %1}";
2826 return "movdqa\t{%1, %0|%0, %1}";
2828 return "movq\t{%1, %0|%0, %1}";
2830 return "movsd\t{%1, %0|%0, %1}";
2832 return "movlpd\t{%1, %0|%0, %1}";
2834 return "movlps\t{%1, %0|%0, %1}";
2841 return "movd\t{%1, %0|%0, %1}";
2847 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2849 (cond [(eq_attr "alternative" "0,1,2")
2851 (eq_attr "alternative" "3,4,9,10")
2854 /* For SSE1, we have many fewer alternatives. */
2855 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2856 (cond [(eq_attr "alternative" "5,6")
2857 (const_string "V4SF")
2859 (const_string "V2SF"))
2861 /* xorps is one byte shorter. */
2862 (eq_attr "alternative" "5")
2863 (cond [(ne (symbol_ref "optimize_size")
2865 (const_string "V4SF")
2866 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2870 (const_string "V2DF"))
2872 /* For architectures resolving dependencies on
2873 whole SSE registers use APD move to break dependency
2874 chains, otherwise use short move to avoid extra work.
2876 movaps encodes one byte shorter. */
2877 (eq_attr "alternative" "6")
2879 [(ne (symbol_ref "optimize_size")
2881 (const_string "V4SF")
2882 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2884 (const_string "V2DF")
2886 (const_string "DF"))
2887 /* For architectures resolving dependencies on register
2888 parts we may avoid extra work to zero out upper part
2890 (eq_attr "alternative" "7")
2892 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2894 (const_string "V1DF")
2895 (const_string "DF"))
2897 (const_string "DF")))])
2899 (define_insn "*movdf_integer"
2900 [(set (match_operand:DF 0 "nonimmediate_operand"
2901 "=f,m,f,r ,o ,Yt*x,Yt*x,Yt*x,m ")
2902 (match_operand:DF 1 "general_operand"
2903 "fm,f,G,roF,Fr,C ,Yt*x,m ,Yt*x"))]
2904 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2905 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2906 && (reload_in_progress || reload_completed
2907 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2908 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2909 && standard_80387_constant_p (operands[1]))
2910 || GET_CODE (operands[1]) != CONST_DOUBLE
2911 || memory_operand (operands[0], DFmode))"
2913 switch (which_alternative)
2917 return output_387_reg_move (insn, operands);
2920 return standard_80387_constant_opcode (operands[1]);
2927 switch (get_attr_mode (insn))
2930 return "xorps\t%0, %0";
2932 return "xorpd\t%0, %0";
2934 return "pxor\t%0, %0";
2941 switch (get_attr_mode (insn))
2944 return "movaps\t{%1, %0|%0, %1}";
2946 return "movapd\t{%1, %0|%0, %1}";
2948 return "movdqa\t{%1, %0|%0, %1}";
2950 return "movq\t{%1, %0|%0, %1}";
2952 return "movsd\t{%1, %0|%0, %1}";
2954 return "movlpd\t{%1, %0|%0, %1}";
2956 return "movlps\t{%1, %0|%0, %1}";
2965 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2967 (cond [(eq_attr "alternative" "0,1,2")
2969 (eq_attr "alternative" "3,4")
2972 /* For SSE1, we have many fewer alternatives. */
2973 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2974 (cond [(eq_attr "alternative" "5,6")
2975 (const_string "V4SF")
2977 (const_string "V2SF"))
2979 /* xorps is one byte shorter. */
2980 (eq_attr "alternative" "5")
2981 (cond [(ne (symbol_ref "optimize_size")
2983 (const_string "V4SF")
2984 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2988 (const_string "V2DF"))
2990 /* For architectures resolving dependencies on
2991 whole SSE registers use APD move to break dependency
2992 chains, otherwise use short move to avoid extra work.
2994 movaps encodes one byte shorter. */
2995 (eq_attr "alternative" "6")
2997 [(ne (symbol_ref "optimize_size")
2999 (const_string "V4SF")
3000 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3002 (const_string "V2DF")
3004 (const_string "DF"))
3005 /* For architectures resolving dependencies on register
3006 parts we may avoid extra work to zero out upper part
3008 (eq_attr "alternative" "7")
3010 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3012 (const_string "V1DF")
3013 (const_string "DF"))
3015 (const_string "DF")))])
3018 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3019 (match_operand:DF 1 "general_operand" ""))]
3021 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3022 && ! (ANY_FP_REG_P (operands[0]) ||
3023 (GET_CODE (operands[0]) == SUBREG
3024 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3025 && ! (ANY_FP_REG_P (operands[1]) ||
3026 (GET_CODE (operands[1]) == SUBREG
3027 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3029 "ix86_split_long_move (operands); DONE;")
3031 (define_insn "*swapdf"
3032 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3033 (match_operand:DF 1 "fp_register_operand" "+f"))
3036 "reload_completed || TARGET_80387"
3038 if (STACK_TOP_P (operands[0]))
3043 [(set_attr "type" "fxch")
3044 (set_attr "mode" "DF")])
3046 (define_expand "movxf"
3047 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3048 (match_operand:XF 1 "general_operand" ""))]
3050 "ix86_expand_move (XFmode, operands); DONE;")
3052 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3053 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3054 ;; Pushing using integer instructions is longer except for constants
3055 ;; and direct memory references.
3056 ;; (assuming that any given constant is pushed only once, but this ought to be
3057 ;; handled elsewhere).
3059 (define_insn "*pushxf_nointeger"
3060 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3061 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3064 /* This insn should be already split before reg-stack. */
3067 [(set_attr "type" "multi")
3068 (set_attr "unit" "i387,*,*")
3069 (set_attr "mode" "XF,SI,SI")])
3071 (define_insn "*pushxf_integer"
3072 [(set (match_operand:XF 0 "push_operand" "=<,<")
3073 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3076 /* This insn should be already split before reg-stack. */
3079 [(set_attr "type" "multi")
3080 (set_attr "unit" "i387,*")
3081 (set_attr "mode" "XF,SI")])
3084 [(set (match_operand 0 "push_operand" "")
3085 (match_operand 1 "general_operand" ""))]
3087 && (GET_MODE (operands[0]) == XFmode
3088 || GET_MODE (operands[0]) == DFmode)
3089 && !ANY_FP_REG_P (operands[1])"
3091 "ix86_split_long_move (operands); DONE;")
3094 [(set (match_operand:XF 0 "push_operand" "")
3095 (match_operand:XF 1 "any_fp_register_operand" ""))]
3097 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3098 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3099 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3102 [(set (match_operand:XF 0 "push_operand" "")
3103 (match_operand:XF 1 "any_fp_register_operand" ""))]
3105 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3106 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3107 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3109 ;; Do not use integer registers when optimizing for size
3110 (define_insn "*movxf_nointeger"
3111 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3112 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3114 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3115 && (reload_in_progress || reload_completed
3116 || (optimize_size && standard_80387_constant_p (operands[1]))
3117 || GET_CODE (operands[1]) != CONST_DOUBLE
3118 || memory_operand (operands[0], XFmode))"
3120 switch (which_alternative)
3124 return output_387_reg_move (insn, operands);
3127 return standard_80387_constant_opcode (operands[1]);
3135 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3136 (set_attr "mode" "XF,XF,XF,SI,SI")])
3138 (define_insn "*movxf_integer"
3139 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3140 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3142 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3143 && (reload_in_progress || reload_completed
3144 || (optimize_size && standard_80387_constant_p (operands[1]))
3145 || GET_CODE (operands[1]) != CONST_DOUBLE
3146 || memory_operand (operands[0], XFmode))"
3148 switch (which_alternative)
3152 return output_387_reg_move (insn, operands);
3155 return standard_80387_constant_opcode (operands[1]);
3164 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3165 (set_attr "mode" "XF,XF,XF,SI,SI")])
3167 (define_expand "movtf"
3168 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3169 (match_operand:TF 1 "nonimmediate_operand" ""))]
3172 ix86_expand_move (TFmode, operands);
3176 (define_insn "*movtf_internal"
3177 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3178 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3180 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3182 switch (which_alternative)
3186 if (get_attr_mode (insn) == MODE_V4SF)
3187 return "movaps\t{%1, %0|%0, %1}";
3189 return "movdqa\t{%1, %0|%0, %1}";
3191 if (get_attr_mode (insn) == MODE_V4SF)
3192 return "xorps\t%0, %0";
3194 return "pxor\t%0, %0";
3202 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3204 (cond [(eq_attr "alternative" "0,2")
3206 (ne (symbol_ref "optimize_size")
3208 (const_string "V4SF")
3209 (const_string "TI"))
3210 (eq_attr "alternative" "1")
3212 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3214 (ne (symbol_ref "optimize_size")
3216 (const_string "V4SF")
3217 (const_string "TI"))]
3218 (const_string "DI")))])
3221 [(set (match_operand 0 "nonimmediate_operand" "")
3222 (match_operand 1 "general_operand" ""))]
3224 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3225 && GET_MODE (operands[0]) == XFmode
3226 && ! (ANY_FP_REG_P (operands[0]) ||
3227 (GET_CODE (operands[0]) == SUBREG
3228 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3229 && ! (ANY_FP_REG_P (operands[1]) ||
3230 (GET_CODE (operands[1]) == SUBREG
3231 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3233 "ix86_split_long_move (operands); DONE;")
3236 [(set (match_operand 0 "register_operand" "")
3237 (match_operand 1 "memory_operand" ""))]
3239 && MEM_P (operands[1])
3240 && (GET_MODE (operands[0]) == TFmode
3241 || GET_MODE (operands[0]) == XFmode
3242 || GET_MODE (operands[0]) == SFmode
3243 || GET_MODE (operands[0]) == DFmode)
3244 && (operands[2] = find_constant_src (insn))"
3245 [(set (match_dup 0) (match_dup 2))]
3247 rtx c = operands[2];
3248 rtx r = operands[0];
3250 if (GET_CODE (r) == SUBREG)
3255 if (!standard_sse_constant_p (c))
3258 else if (FP_REG_P (r))
3260 if (!standard_80387_constant_p (c))
3263 else if (MMX_REG_P (r))
3268 [(set (match_operand 0 "register_operand" "")
3269 (float_extend (match_operand 1 "memory_operand" "")))]
3271 && MEM_P (operands[1])
3272 && (GET_MODE (operands[0]) == TFmode
3273 || GET_MODE (operands[0]) == XFmode
3274 || GET_MODE (operands[0]) == SFmode
3275 || GET_MODE (operands[0]) == DFmode)
3276 && (operands[2] = find_constant_src (insn))"
3277 [(set (match_dup 0) (match_dup 2))]
3279 rtx c = operands[2];
3280 rtx r = operands[0];
3282 if (GET_CODE (r) == SUBREG)
3287 if (!standard_sse_constant_p (c))
3290 else if (FP_REG_P (r))
3292 if (!standard_80387_constant_p (c))
3295 else if (MMX_REG_P (r))
3299 (define_insn "swapxf"
3300 [(set (match_operand:XF 0 "register_operand" "+f")
3301 (match_operand:XF 1 "register_operand" "+f"))
3306 if (STACK_TOP_P (operands[0]))
3311 [(set_attr "type" "fxch")
3312 (set_attr "mode" "XF")])
3314 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3316 [(set (match_operand:X87MODEF 0 "register_operand" "")
3317 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3318 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3319 && (standard_80387_constant_p (operands[1]) == 8
3320 || standard_80387_constant_p (operands[1]) == 9)"
3321 [(set (match_dup 0)(match_dup 1))
3323 (neg:X87MODEF (match_dup 0)))]
3327 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3328 if (real_isnegzero (&r))
3329 operands[1] = CONST0_RTX (<MODE>mode);
3331 operands[1] = CONST1_RTX (<MODE>mode);
3335 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3336 (match_operand:TF 1 "general_operand" ""))]
3338 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3340 "ix86_split_long_move (operands); DONE;")
3342 ;; Zero extension instructions
3344 (define_expand "zero_extendhisi2"
3345 [(set (match_operand:SI 0 "register_operand" "")
3346 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3349 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3351 operands[1] = force_reg (HImode, operands[1]);
3352 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3357 (define_insn "zero_extendhisi2_and"
3358 [(set (match_operand:SI 0 "register_operand" "=r")
3359 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3360 (clobber (reg:CC FLAGS_REG))]
3361 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3363 [(set_attr "type" "alu1")
3364 (set_attr "mode" "SI")])
3367 [(set (match_operand:SI 0 "register_operand" "")
3368 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3369 (clobber (reg:CC FLAGS_REG))]
3370 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3371 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3372 (clobber (reg:CC FLAGS_REG))])]
3375 (define_insn "*zero_extendhisi2_movzwl"
3376 [(set (match_operand:SI 0 "register_operand" "=r")
3377 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3378 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3379 "movz{wl|x}\t{%1, %0|%0, %1}"
3380 [(set_attr "type" "imovx")
3381 (set_attr "mode" "SI")])
3383 (define_expand "zero_extendqihi2"
3385 [(set (match_operand:HI 0 "register_operand" "")
3386 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3387 (clobber (reg:CC FLAGS_REG))])]
3391 (define_insn "*zero_extendqihi2_and"
3392 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3393 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3394 (clobber (reg:CC FLAGS_REG))]
3395 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3397 [(set_attr "type" "alu1")
3398 (set_attr "mode" "HI")])
3400 (define_insn "*zero_extendqihi2_movzbw_and"
3401 [(set (match_operand:HI 0 "register_operand" "=r,r")
3402 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3403 (clobber (reg:CC FLAGS_REG))]
3404 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3406 [(set_attr "type" "imovx,alu1")
3407 (set_attr "mode" "HI")])
3409 ; zero extend to SImode here to avoid partial register stalls
3410 (define_insn "*zero_extendqihi2_movzbl"
3411 [(set (match_operand:HI 0 "register_operand" "=r")
3412 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3413 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3414 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3415 [(set_attr "type" "imovx")
3416 (set_attr "mode" "SI")])
3418 ;; For the movzbw case strip only the clobber
3420 [(set (match_operand:HI 0 "register_operand" "")
3421 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3422 (clobber (reg:CC FLAGS_REG))]
3424 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3425 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3426 [(set (match_operand:HI 0 "register_operand" "")
3427 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3429 ;; When source and destination does not overlap, clear destination
3430 ;; first and then do the movb
3432 [(set (match_operand:HI 0 "register_operand" "")
3433 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3434 (clobber (reg:CC FLAGS_REG))]
3436 && ANY_QI_REG_P (operands[0])
3437 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3438 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3439 [(set (match_dup 0) (const_int 0))
3440 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3441 "operands[2] = gen_lowpart (QImode, operands[0]);")
3443 ;; Rest is handled by single and.
3445 [(set (match_operand:HI 0 "register_operand" "")
3446 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3447 (clobber (reg:CC FLAGS_REG))]
3449 && true_regnum (operands[0]) == true_regnum (operands[1])"
3450 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3451 (clobber (reg:CC FLAGS_REG))])]
3454 (define_expand "zero_extendqisi2"
3456 [(set (match_operand:SI 0 "register_operand" "")
3457 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3458 (clobber (reg:CC FLAGS_REG))])]
3462 (define_insn "*zero_extendqisi2_and"
3463 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3464 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3465 (clobber (reg:CC FLAGS_REG))]
3466 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3468 [(set_attr "type" "alu1")
3469 (set_attr "mode" "SI")])
3471 (define_insn "*zero_extendqisi2_movzbw_and"
3472 [(set (match_operand:SI 0 "register_operand" "=r,r")
3473 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3474 (clobber (reg:CC FLAGS_REG))]
3475 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3477 [(set_attr "type" "imovx,alu1")
3478 (set_attr "mode" "SI")])
3480 (define_insn "*zero_extendqisi2_movzbw"
3481 [(set (match_operand:SI 0 "register_operand" "=r")
3482 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3483 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3484 "movz{bl|x}\t{%1, %0|%0, %1}"
3485 [(set_attr "type" "imovx")
3486 (set_attr "mode" "SI")])
3488 ;; For the movzbl case strip only the clobber
3490 [(set (match_operand:SI 0 "register_operand" "")
3491 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3492 (clobber (reg:CC FLAGS_REG))]
3494 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3495 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3497 (zero_extend:SI (match_dup 1)))])
3499 ;; When source and destination does not overlap, clear destination
3500 ;; first and then do the movb
3502 [(set (match_operand:SI 0 "register_operand" "")
3503 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3504 (clobber (reg:CC FLAGS_REG))]
3506 && ANY_QI_REG_P (operands[0])
3507 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3508 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3509 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3510 [(set (match_dup 0) (const_int 0))
3511 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3512 "operands[2] = gen_lowpart (QImode, operands[0]);")
3514 ;; Rest is handled by single and.
3516 [(set (match_operand:SI 0 "register_operand" "")
3517 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3518 (clobber (reg:CC FLAGS_REG))]
3520 && true_regnum (operands[0]) == true_regnum (operands[1])"
3521 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3522 (clobber (reg:CC FLAGS_REG))])]
3525 ;; %%% Kill me once multi-word ops are sane.
3526 (define_expand "zero_extendsidi2"
3527 [(set (match_operand:DI 0 "register_operand" "")
3528 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3533 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3538 (define_insn "zero_extendsidi2_32"
3539 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Yt")
3541 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3542 (clobber (reg:CC FLAGS_REG))]
3548 movd\t{%1, %0|%0, %1}
3549 movd\t{%1, %0|%0, %1}
3550 movd\t{%1, %0|%0, %1}
3551 movd\t{%1, %0|%0, %1}"
3552 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3553 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3555 (define_insn "zero_extendsidi2_rex64"
3556 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Yt")
3558 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3561 mov\t{%k1, %k0|%k0, %k1}
3563 movd\t{%1, %0|%0, %1}
3564 movd\t{%1, %0|%0, %1}
3565 movd\t{%1, %0|%0, %1}
3566 movd\t{%1, %0|%0, %1}"
3567 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3568 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3571 [(set (match_operand:DI 0 "memory_operand" "")
3572 (zero_extend:DI (match_dup 0)))]
3574 [(set (match_dup 4) (const_int 0))]
3575 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3578 [(set (match_operand:DI 0 "register_operand" "")
3579 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3580 (clobber (reg:CC FLAGS_REG))]
3581 "!TARGET_64BIT && reload_completed
3582 && true_regnum (operands[0]) == true_regnum (operands[1])"
3583 [(set (match_dup 4) (const_int 0))]
3584 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3587 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3588 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3589 (clobber (reg:CC FLAGS_REG))]
3590 "!TARGET_64BIT && reload_completed
3591 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3592 [(set (match_dup 3) (match_dup 1))
3593 (set (match_dup 4) (const_int 0))]
3594 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3596 (define_insn "zero_extendhidi2"
3597 [(set (match_operand:DI 0 "register_operand" "=r")
3598 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3600 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3601 [(set_attr "type" "imovx")
3602 (set_attr "mode" "DI")])
3604 (define_insn "zero_extendqidi2"
3605 [(set (match_operand:DI 0 "register_operand" "=r")
3606 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3608 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3609 [(set_attr "type" "imovx")
3610 (set_attr "mode" "DI")])
3612 ;; Sign extension instructions
3614 (define_expand "extendsidi2"
3615 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3616 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3617 (clobber (reg:CC FLAGS_REG))
3618 (clobber (match_scratch:SI 2 ""))])]
3623 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3628 (define_insn "*extendsidi2_1"
3629 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3630 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3631 (clobber (reg:CC FLAGS_REG))
3632 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3636 (define_insn "extendsidi2_rex64"
3637 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3638 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3642 movs{lq|x}\t{%1,%0|%0, %1}"
3643 [(set_attr "type" "imovx")
3644 (set_attr "mode" "DI")
3645 (set_attr "prefix_0f" "0")
3646 (set_attr "modrm" "0,1")])
3648 (define_insn "extendhidi2"
3649 [(set (match_operand:DI 0 "register_operand" "=r")
3650 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3652 "movs{wq|x}\t{%1,%0|%0, %1}"
3653 [(set_attr "type" "imovx")
3654 (set_attr "mode" "DI")])
3656 (define_insn "extendqidi2"
3657 [(set (match_operand:DI 0 "register_operand" "=r")
3658 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3660 "movs{bq|x}\t{%1,%0|%0, %1}"
3661 [(set_attr "type" "imovx")
3662 (set_attr "mode" "DI")])
3664 ;; Extend to memory case when source register does die.
3666 [(set (match_operand:DI 0 "memory_operand" "")
3667 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3668 (clobber (reg:CC FLAGS_REG))
3669 (clobber (match_operand:SI 2 "register_operand" ""))]
3671 && dead_or_set_p (insn, operands[1])
3672 && !reg_mentioned_p (operands[1], operands[0]))"
3673 [(set (match_dup 3) (match_dup 1))
3674 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3675 (clobber (reg:CC FLAGS_REG))])
3676 (set (match_dup 4) (match_dup 1))]
3677 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3679 ;; Extend to memory case when source register does not die.
3681 [(set (match_operand:DI 0 "memory_operand" "")
3682 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3683 (clobber (reg:CC FLAGS_REG))
3684 (clobber (match_operand:SI 2 "register_operand" ""))]
3688 split_di (&operands[0], 1, &operands[3], &operands[4]);
3690 emit_move_insn (operands[3], operands[1]);
3692 /* Generate a cltd if possible and doing so it profitable. */
3693 if ((optimize_size || TARGET_USE_CLTD)
3694 && true_regnum (operands[1]) == 0
3695 && true_regnum (operands[2]) == 1)
3697 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3701 emit_move_insn (operands[2], operands[1]);
3702 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3704 emit_move_insn (operands[4], operands[2]);
3708 ;; Extend to register case. Optimize case where source and destination
3709 ;; registers match and cases where we can use cltd.
3711 [(set (match_operand:DI 0 "register_operand" "")
3712 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3713 (clobber (reg:CC FLAGS_REG))
3714 (clobber (match_scratch:SI 2 ""))]
3718 split_di (&operands[0], 1, &operands[3], &operands[4]);
3720 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3721 emit_move_insn (operands[3], operands[1]);
3723 /* Generate a cltd if possible and doing so it profitable. */
3724 if ((optimize_size || TARGET_USE_CLTD)
3725 && true_regnum (operands[3]) == 0)
3727 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3731 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3732 emit_move_insn (operands[4], operands[1]);
3734 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3738 (define_insn "extendhisi2"
3739 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3740 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3743 switch (get_attr_prefix_0f (insn))
3746 return "{cwtl|cwde}";
3748 return "movs{wl|x}\t{%1,%0|%0, %1}";
3751 [(set_attr "type" "imovx")
3752 (set_attr "mode" "SI")
3753 (set (attr "prefix_0f")
3754 ;; movsx is short decodable while cwtl is vector decoded.
3755 (if_then_else (and (eq_attr "cpu" "!k6")
3756 (eq_attr "alternative" "0"))
3758 (const_string "1")))
3760 (if_then_else (eq_attr "prefix_0f" "0")
3762 (const_string "1")))])
3764 (define_insn "*extendhisi2_zext"
3765 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3767 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3770 switch (get_attr_prefix_0f (insn))
3773 return "{cwtl|cwde}";
3775 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3778 [(set_attr "type" "imovx")
3779 (set_attr "mode" "SI")
3780 (set (attr "prefix_0f")
3781 ;; movsx is short decodable while cwtl is vector decoded.
3782 (if_then_else (and (eq_attr "cpu" "!k6")
3783 (eq_attr "alternative" "0"))
3785 (const_string "1")))
3787 (if_then_else (eq_attr "prefix_0f" "0")
3789 (const_string "1")))])
3791 (define_insn "extendqihi2"
3792 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3793 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3796 switch (get_attr_prefix_0f (insn))
3799 return "{cbtw|cbw}";
3801 return "movs{bw|x}\t{%1,%0|%0, %1}";
3804 [(set_attr "type" "imovx")
3805 (set_attr "mode" "HI")
3806 (set (attr "prefix_0f")
3807 ;; movsx is short decodable while cwtl is vector decoded.
3808 (if_then_else (and (eq_attr "cpu" "!k6")
3809 (eq_attr "alternative" "0"))
3811 (const_string "1")))
3813 (if_then_else (eq_attr "prefix_0f" "0")
3815 (const_string "1")))])
3817 (define_insn "extendqisi2"
3818 [(set (match_operand:SI 0 "register_operand" "=r")
3819 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3821 "movs{bl|x}\t{%1,%0|%0, %1}"
3822 [(set_attr "type" "imovx")
3823 (set_attr "mode" "SI")])
3825 (define_insn "*extendqisi2_zext"
3826 [(set (match_operand:DI 0 "register_operand" "=r")
3828 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3830 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3831 [(set_attr "type" "imovx")
3832 (set_attr "mode" "SI")])
3834 ;; Conversions between float and double.
3836 ;; These are all no-ops in the model used for the 80387. So just
3839 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3840 (define_insn "*dummy_extendsfdf2"
3841 [(set (match_operand:DF 0 "push_operand" "=<")
3842 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3847 [(set (match_operand:DF 0 "push_operand" "")
3848 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3850 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3851 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3854 [(set (match_operand:DF 0 "push_operand" "")
3855 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3857 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3858 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3860 (define_insn "*dummy_extendsfxf2"
3861 [(set (match_operand:XF 0 "push_operand" "=<")
3862 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3867 [(set (match_operand:XF 0 "push_operand" "")
3868 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3870 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3871 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3872 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3875 [(set (match_operand:XF 0 "push_operand" "")
3876 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3878 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3879 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3880 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3883 [(set (match_operand:XF 0 "push_operand" "")
3884 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3886 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3887 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3888 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3891 [(set (match_operand:XF 0 "push_operand" "")
3892 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3894 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3895 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3896 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3898 (define_expand "extendsfdf2"
3899 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3900 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3901 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3903 /* ??? Needed for compress_float_constant since all fp constants
3904 are LEGITIMATE_CONSTANT_P. */
3905 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3907 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3908 && standard_80387_constant_p (operands[1]) > 0)
3910 operands[1] = simplify_const_unary_operation
3911 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3912 emit_move_insn_1 (operands[0], operands[1]);
3915 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3919 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3921 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3923 We do the conversion post reload to avoid producing of 128bit spills
3924 that might lead to ICE on 32bit target. The sequence unlikely combine
3927 [(set (match_operand:DF 0 "register_operand" "")
3929 (match_operand:SF 1 "nonimmediate_operand" "")))]
3930 "TARGET_USE_VECTOR_CONVERTS && !optimize_size
3931 && reload_completed && SSE_REG_P (operands[0])"
3936 (parallel [(const_int 0) (const_int 1)]))))]
3938 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3939 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3940 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3941 Try to avoid move when unpacking can be done in source. */
3942 if (REG_P (operands[1]))
3944 /* If it is unsafe to overwrite upper half of source, we need
3945 to move to destination and unpack there. */
3946 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3947 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3948 && true_regnum (operands[0]) != true_regnum (operands[1]))
3950 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3951 emit_move_insn (tmp, operands[1]);
3954 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3955 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
3958 emit_insn (gen_vec_setv4sf_0 (operands[3],
3959 CONST0_RTX (V4SFmode), operands[1]));
3962 (define_insn "*extendsfdf2_mixed"
3963 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3965 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3966 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3968 switch (which_alternative)
3972 return output_387_reg_move (insn, operands);
3975 return "cvtss2sd\t{%1, %0|%0, %1}";
3981 [(set_attr "type" "fmov,fmov,ssecvt")
3982 (set_attr "mode" "SF,XF,DF")])
3984 (define_insn "*extendsfdf2_sse"
3985 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3986 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3987 "TARGET_SSE2 && TARGET_SSE_MATH"
3988 "cvtss2sd\t{%1, %0|%0, %1}"
3989 [(set_attr "type" "ssecvt")
3990 (set_attr "mode" "DF")])
3992 (define_insn "*extendsfdf2_i387"
3993 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3994 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3996 "* return output_387_reg_move (insn, operands);"
3997 [(set_attr "type" "fmov")
3998 (set_attr "mode" "SF,XF")])
4000 (define_expand "extend<mode>xf2"
4001 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4002 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4005 /* ??? Needed for compress_float_constant since all fp constants
4006 are LEGITIMATE_CONSTANT_P. */
4007 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4009 if (standard_80387_constant_p (operands[1]) > 0)
4011 operands[1] = simplify_const_unary_operation
4012 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4013 emit_move_insn_1 (operands[0], operands[1]);
4016 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4020 (define_insn "*extend<mode>xf2_i387"
4021 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4023 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4025 "* return output_387_reg_move (insn, operands);"
4026 [(set_attr "type" "fmov")
4027 (set_attr "mode" "<MODE>,XF")])
4029 ;; %%% This seems bad bad news.
4030 ;; This cannot output into an f-reg because there is no way to be sure
4031 ;; of truncating in that case. Otherwise this is just like a simple move
4032 ;; insn. So we pretend we can output to a reg in order to get better
4033 ;; register preferencing, but we really use a stack slot.
4035 ;; Conversion from DFmode to SFmode.
4037 (define_expand "truncdfsf2"
4038 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4040 (match_operand:DF 1 "nonimmediate_operand" "")))]
4041 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4043 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4045 else if (flag_unsafe_math_optimizations)
4049 rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
4050 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4055 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4057 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4059 We do the conversion post reload to avoid producing of 128bit spills
4060 that might lead to ICE on 32bit target. The sequence unlikely combine
4063 [(set (match_operand:SF 0 "register_operand" "")
4065 (match_operand:DF 1 "nonimmediate_operand" "")))]
4066 "TARGET_USE_VECTOR_CONVERTS && !optimize_size
4067 && reload_completed && SSE_REG_P (operands[0])"
4070 (float_truncate:V2SF
4074 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4075 operands[3] = CONST0_RTX (V2SFmode);
4076 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4077 /* Use movsd for loading from memory, unpcklpd for registers.
4078 Try to avoid move when unpacking can be done in source, or SSE3
4079 movddup is available. */
4080 if (REG_P (operands[1]))
4083 && true_regnum (operands[0]) != true_regnum (operands[1])
4084 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4085 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4087 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4088 emit_move_insn (tmp, operands[1]);
4091 else if (!TARGET_SSE3)
4092 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4093 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4096 emit_insn (gen_sse2_loadlpd (operands[4],
4097 CONST0_RTX (V2DFmode), operands[1]));
4100 (define_expand "truncdfsf2_with_temp"
4101 [(parallel [(set (match_operand:SF 0 "" "")
4102 (float_truncate:SF (match_operand:DF 1 "" "")))
4103 (clobber (match_operand:SF 2 "" ""))])]
4106 (define_insn "*truncdfsf_fast_mixed"
4107 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
4109 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4110 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4112 switch (which_alternative)
4116 return output_387_reg_move (insn, operands);
4118 return "cvtsd2ss\t{%1, %0|%0, %1}";
4123 [(set_attr "type" "fmov,fmov,ssecvt")
4124 (set_attr "mode" "SF")])
4126 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4127 ;; because nothing we do here is unsafe.
4128 (define_insn "*truncdfsf_fast_sse"
4129 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4131 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4132 "TARGET_SSE2 && TARGET_SSE_MATH"
4133 "cvtsd2ss\t{%1, %0|%0, %1}"
4134 [(set_attr "type" "ssecvt")
4135 (set_attr "mode" "SF")])
4137 (define_insn "*truncdfsf_fast_i387"
4138 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4140 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4141 "TARGET_80387 && flag_unsafe_math_optimizations"
4142 "* return output_387_reg_move (insn, operands);"
4143 [(set_attr "type" "fmov")
4144 (set_attr "mode" "SF")])
4146 (define_insn "*truncdfsf_mixed"
4147 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Yt")
4149 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ytm")))
4150 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4151 "TARGET_MIX_SSE_I387"
4153 switch (which_alternative)
4156 return output_387_reg_move (insn, operands);
4161 return "cvtsd2ss\t{%1, %0|%0, %1}";
4166 [(set_attr "type" "fmov,multi,ssecvt")
4167 (set_attr "unit" "*,i387,*")
4168 (set_attr "mode" "SF")])
4170 (define_insn "*truncdfsf_i387"
4171 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4173 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4174 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4177 switch (which_alternative)
4180 return output_387_reg_move (insn, operands);
4188 [(set_attr "type" "fmov,multi")
4189 (set_attr "unit" "*,i387")
4190 (set_attr "mode" "SF")])
4192 (define_insn "*truncdfsf2_i387_1"
4193 [(set (match_operand:SF 0 "memory_operand" "=m")
4195 (match_operand:DF 1 "register_operand" "f")))]
4197 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4198 && !TARGET_MIX_SSE_I387"
4199 "* return output_387_reg_move (insn, operands);"
4200 [(set_attr "type" "fmov")
4201 (set_attr "mode" "SF")])
4204 [(set (match_operand:SF 0 "register_operand" "")
4206 (match_operand:DF 1 "fp_register_operand" "")))
4207 (clobber (match_operand 2 "" ""))]
4209 [(set (match_dup 2) (match_dup 1))
4210 (set (match_dup 0) (match_dup 2))]
4212 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4215 ;; Conversion from XFmode to {SF,DF}mode
4217 (define_expand "truncxf<mode>2"
4218 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4219 (float_truncate:MODEF
4220 (match_operand:XF 1 "register_operand" "")))
4221 (clobber (match_dup 2))])]
4224 if (flag_unsafe_math_optimizations)
4226 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4227 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4228 if (reg != operands[0])
4229 emit_move_insn (operands[0], reg);
4233 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_VIRTUAL);
4236 (define_insn "*truncxfsf2_mixed"
4237 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4239 (match_operand:XF 1 "register_operand" "f,f")))
4240 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4243 gcc_assert (!which_alternative);
4244 return output_387_reg_move (insn, operands);
4246 [(set_attr "type" "fmov,multi")
4247 (set_attr "unit" "*,i387")
4248 (set_attr "mode" "SF")])
4250 (define_insn "*truncxfdf2_mixed"
4251 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fYt*r")
4253 (match_operand:XF 1 "register_operand" "f,f")))
4254 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4257 gcc_assert (!which_alternative);
4258 return output_387_reg_move (insn, operands);
4260 [(set_attr "type" "fmov,multi")
4261 (set_attr "unit" "*,i387")
4262 (set_attr "mode" "DF")])
4264 (define_insn "truncxf<mode>2_i387_noop"
4265 [(set (match_operand:MODEF 0 "register_operand" "=f")
4266 (float_truncate:MODEF
4267 (match_operand:XF 1 "register_operand" "f")))]
4268 "TARGET_80387 && flag_unsafe_math_optimizations"
4269 "* return output_387_reg_move (insn, operands);"
4270 [(set_attr "type" "fmov")
4271 (set_attr "mode" "<MODE>")])
4273 (define_insn "*truncxf<mode>2_i387"
4274 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4275 (float_truncate:MODEF
4276 (match_operand:XF 1 "register_operand" "f")))]
4278 "* return output_387_reg_move (insn, operands);"
4279 [(set_attr "type" "fmov")
4280 (set_attr "mode" "<MODE>")])
4283 [(set (match_operand:MODEF 0 "register_operand" "")
4284 (float_truncate:MODEF
4285 (match_operand:XF 1 "register_operand" "")))
4286 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4287 "TARGET_80387 && reload_completed"
4288 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4289 (set (match_dup 0) (match_dup 2))]
4293 [(set (match_operand:MODEF 0 "memory_operand" "")
4294 (float_truncate:MODEF
4295 (match_operand:XF 1 "register_operand" "")))
4296 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4298 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4301 ;; Signed conversion to DImode.
4303 (define_expand "fix_truncxfdi2"
4304 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4305 (fix:DI (match_operand:XF 1 "register_operand" "")))
4306 (clobber (reg:CC FLAGS_REG))])]
4311 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4316 (define_expand "fix_trunc<mode>di2"
4317 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4318 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4319 (clobber (reg:CC FLAGS_REG))])]
4320 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4323 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4325 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4328 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4330 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4331 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4332 if (out != operands[0])
4333 emit_move_insn (operands[0], out);
4338 ;; Signed conversion to SImode.
4340 (define_expand "fix_truncxfsi2"
4341 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4342 (fix:SI (match_operand:XF 1 "register_operand" "")))
4343 (clobber (reg:CC FLAGS_REG))])]
4348 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4353 (define_expand "fix_trunc<mode>si2"
4354 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4355 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4356 (clobber (reg:CC FLAGS_REG))])]
4357 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4360 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4362 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4365 if (SSE_FLOAT_MODE_P (<MODE>mode))
4367 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4368 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4369 if (out != operands[0])
4370 emit_move_insn (operands[0], out);
4375 ;; Signed conversion to HImode.
4377 (define_expand "fix_trunc<mode>hi2"
4378 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4379 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4380 (clobber (reg:CC FLAGS_REG))])]
4382 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4386 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4391 ;; Unsigned conversion to SImode.
4393 (define_expand "fixuns_trunc<mode>si2"
4395 [(set (match_operand:SI 0 "register_operand" "")
4397 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4399 (clobber (match_scratch:<ssevecmode> 3 ""))
4400 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4401 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4403 enum machine_mode mode = <MODE>mode;
4404 enum machine_mode vecmode = <ssevecmode>mode;
4405 REAL_VALUE_TYPE TWO31r;
4408 real_ldexp (&TWO31r, &dconst1, 31);
4409 two31 = const_double_from_real_value (TWO31r, mode);
4410 two31 = ix86_build_const_vector (mode, true, two31);
4411 operands[2] = force_reg (vecmode, two31);
4414 (define_insn_and_split "*fixuns_trunc<mode>_1"
4415 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4417 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4418 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4419 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4420 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4421 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4423 "&& reload_completed"
4426 ix86_split_convert_uns_si_sse (operands);
4430 ;; Unsigned conversion to HImode.
4431 ;; Without these patterns, we'll try the unsigned SI conversion which
4432 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4434 (define_expand "fixuns_trunc<mode>hi2"
4436 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4437 (set (match_operand:HI 0 "nonimmediate_operand" "")
4438 (subreg:HI (match_dup 2) 0))]
4439 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4440 "operands[2] = gen_reg_rtx (SImode);")
4442 ;; When SSE is available, it is always faster to use it!
4443 (define_insn "fix_trunc<mode>di_sse"
4444 [(set (match_operand:DI 0 "register_operand" "=r,r")
4445 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4446 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4447 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4448 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4449 [(set_attr "type" "sseicvt")
4450 (set_attr "mode" "<MODE>")
4451 (set_attr "athlon_decode" "double,vector")
4452 (set_attr "amdfam10_decode" "double,double")])
4454 (define_insn "fix_trunc<mode>si_sse"
4455 [(set (match_operand:SI 0 "register_operand" "=r,r")
4456 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4457 "SSE_FLOAT_MODE_P (<MODE>mode)
4458 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4459 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4460 [(set_attr "type" "sseicvt")
4461 (set_attr "mode" "<MODE>")
4462 (set_attr "athlon_decode" "double,vector")
4463 (set_attr "amdfam10_decode" "double,double")])
4465 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4467 [(set (match_operand:MODEF 0 "register_operand" "")
4468 (match_operand:MODEF 1 "memory_operand" ""))
4469 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4470 (fix:SSEMODEI24 (match_dup 0)))]
4471 "TARGET_SHORTEN_X87_SSE
4472 && peep2_reg_dead_p (2, operands[0])"
4473 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4476 ;; Avoid vector decoded forms of the instruction.
4478 [(match_scratch:DF 2 "Yt")
4479 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4480 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4481 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4482 [(set (match_dup 2) (match_dup 1))
4483 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4487 [(match_scratch:SF 2 "x")
4488 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4489 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4490 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4491 [(set (match_dup 2) (match_dup 1))
4492 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4495 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4496 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4497 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4498 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4500 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4501 && (TARGET_64BIT || <MODE>mode != DImode))
4503 && !(reload_completed || reload_in_progress)"
4508 if (memory_operand (operands[0], VOIDmode))
4509 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4512 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4513 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4519 [(set_attr "type" "fisttp")
4520 (set_attr "mode" "<MODE>")])
4522 (define_insn "fix_trunc<mode>_i387_fisttp"
4523 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4524 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4525 (clobber (match_scratch:XF 2 "=&1f"))]
4526 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4528 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4529 && (TARGET_64BIT || <MODE>mode != DImode))
4530 && TARGET_SSE_MATH)"
4531 "* return output_fix_trunc (insn, operands, 1);"
4532 [(set_attr "type" "fisttp")
4533 (set_attr "mode" "<MODE>")])
4535 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4536 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4537 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4538 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4539 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4540 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4542 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4543 && (TARGET_64BIT || <MODE>mode != DImode))
4544 && TARGET_SSE_MATH)"
4546 [(set_attr "type" "fisttp")
4547 (set_attr "mode" "<MODE>")])
4550 [(set (match_operand:X87MODEI 0 "register_operand" "")
4551 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4552 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4553 (clobber (match_scratch 3 ""))]
4555 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4556 (clobber (match_dup 3))])
4557 (set (match_dup 0) (match_dup 2))]
4561 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4562 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4563 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4564 (clobber (match_scratch 3 ""))]
4566 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4567 (clobber (match_dup 3))])]
4570 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4571 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4572 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4573 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4574 ;; function in i386.c.
4575 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4576 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4577 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4578 (clobber (reg:CC FLAGS_REG))]
4579 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4581 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4582 && (TARGET_64BIT || <MODE>mode != DImode))
4583 && !(reload_completed || reload_in_progress)"
4588 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4590 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4591 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4592 if (memory_operand (operands[0], VOIDmode))
4593 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4594 operands[2], operands[3]));
4597 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4598 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4599 operands[2], operands[3],
4604 [(set_attr "type" "fistp")
4605 (set_attr "i387_cw" "trunc")
4606 (set_attr "mode" "<MODE>")])
4608 (define_insn "fix_truncdi_i387"
4609 [(set (match_operand:DI 0 "memory_operand" "=m")
4610 (fix:DI (match_operand 1 "register_operand" "f")))
4611 (use (match_operand:HI 2 "memory_operand" "m"))
4612 (use (match_operand:HI 3 "memory_operand" "m"))
4613 (clobber (match_scratch:XF 4 "=&1f"))]
4614 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4616 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4617 "* return output_fix_trunc (insn, operands, 0);"
4618 [(set_attr "type" "fistp")
4619 (set_attr "i387_cw" "trunc")
4620 (set_attr "mode" "DI")])
4622 (define_insn "fix_truncdi_i387_with_temp"
4623 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4624 (fix:DI (match_operand 1 "register_operand" "f,f")))
4625 (use (match_operand:HI 2 "memory_operand" "m,m"))
4626 (use (match_operand:HI 3 "memory_operand" "m,m"))
4627 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4628 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4629 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4631 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4633 [(set_attr "type" "fistp")
4634 (set_attr "i387_cw" "trunc")
4635 (set_attr "mode" "DI")])
4638 [(set (match_operand:DI 0 "register_operand" "")
4639 (fix:DI (match_operand 1 "register_operand" "")))
4640 (use (match_operand:HI 2 "memory_operand" ""))
4641 (use (match_operand:HI 3 "memory_operand" ""))
4642 (clobber (match_operand:DI 4 "memory_operand" ""))
4643 (clobber (match_scratch 5 ""))]
4645 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4648 (clobber (match_dup 5))])
4649 (set (match_dup 0) (match_dup 4))]
4653 [(set (match_operand:DI 0 "memory_operand" "")
4654 (fix:DI (match_operand 1 "register_operand" "")))
4655 (use (match_operand:HI 2 "memory_operand" ""))
4656 (use (match_operand:HI 3 "memory_operand" ""))
4657 (clobber (match_operand:DI 4 "memory_operand" ""))
4658 (clobber (match_scratch 5 ""))]
4660 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4663 (clobber (match_dup 5))])]
4666 (define_insn "fix_trunc<mode>_i387"
4667 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4668 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4669 (use (match_operand:HI 2 "memory_operand" "m"))
4670 (use (match_operand:HI 3 "memory_operand" "m"))]
4671 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4673 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4674 "* return output_fix_trunc (insn, operands, 0);"
4675 [(set_attr "type" "fistp")
4676 (set_attr "i387_cw" "trunc")
4677 (set_attr "mode" "<MODE>")])
4679 (define_insn "fix_trunc<mode>_i387_with_temp"
4680 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4681 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4682 (use (match_operand:HI 2 "memory_operand" "m,m"))
4683 (use (match_operand:HI 3 "memory_operand" "m,m"))
4684 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4685 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4687 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4689 [(set_attr "type" "fistp")
4690 (set_attr "i387_cw" "trunc")
4691 (set_attr "mode" "<MODE>")])
4694 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4695 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4696 (use (match_operand:HI 2 "memory_operand" ""))
4697 (use (match_operand:HI 3 "memory_operand" ""))
4698 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4700 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4702 (use (match_dup 3))])
4703 (set (match_dup 0) (match_dup 4))]
4707 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4708 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4709 (use (match_operand:HI 2 "memory_operand" ""))
4710 (use (match_operand:HI 3 "memory_operand" ""))
4711 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4713 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4715 (use (match_dup 3))])]
4718 (define_insn "x86_fnstcw_1"
4719 [(set (match_operand:HI 0 "memory_operand" "=m")
4720 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4723 [(set_attr "length" "2")
4724 (set_attr "mode" "HI")
4725 (set_attr "unit" "i387")])
4727 (define_insn "x86_fldcw_1"
4728 [(set (reg:HI FPCR_REG)
4729 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4732 [(set_attr "length" "2")
4733 (set_attr "mode" "HI")
4734 (set_attr "unit" "i387")
4735 (set_attr "athlon_decode" "vector")
4736 (set_attr "amdfam10_decode" "vector")])
4738 ;; Conversion between fixed point and floating point.
4740 ;; Even though we only accept memory inputs, the backend _really_
4741 ;; wants to be able to do this between registers.
4743 (define_expand "floathi<mode>2"
4744 [(set (match_operand:MODEF 0 "register_operand" "")
4745 (float:MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4746 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4748 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4751 (gen_floatsi<mode>2 (operands[0],
4752 convert_to_mode (SImode, operands[1], 0)));
4757 (define_insn "*floathi<mode>2_i387"
4758 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4760 (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4762 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4763 || TARGET_MIX_SSE_I387)"
4767 [(set_attr "type" "fmov,multi")
4768 (set_attr "mode" "<MODE>")
4769 (set_attr "unit" "*,i387")
4770 (set_attr "fp_int_src" "true")])
4772 (define_expand "floatsi<mode>2"
4773 [(set (match_operand:MODEF 0 "register_operand" "")
4774 (float:MODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4775 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4777 /* When we use vector converts, we can't have input in memory. */
4778 if (GET_MODE (operands[0]) == DFmode && GET_MODE (operands[1]) == SImode
4779 && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4780 && SSE_FLOAT_MODE_P (DFmode))
4781 operands[1] = force_reg (SImode, operands[1]);
4783 if (GET_MODE (operands[0]) == SFmode && GET_MODE (operands[1]) == SImode
4784 && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4785 && SSE_FLOAT_MODE_P (SFmode))
4787 /* When !flag_trapping_math, we handle SImode->SFmode vector
4788 conversions same way as SImode->DFmode.
4790 For flat_trapping_math we can't safely use vector conversion without
4791 clearing upper half, otherwise precision exception might occur.
4792 However we can still generate the common sequence converting value
4793 from general register to XMM register as:
4799 because we know that movd clears the upper half.
4801 Sadly in this case we can't rely on reload moving the value to XMM
4802 register, since we need to know if upper half is OK, so we need
4803 to do reloading by hand. We force operand to memory unless target
4804 supports inter unit moves. */
4805 if (!flag_trapping_math)
4806 operands[1] = force_reg (SImode, operands[1]);
4807 else if (!MEM_P (operands[1]))
4809 rtx tmp = assign_386_stack_local (SImode, SLOT_VIRTUAL);
4810 emit_move_insn (tmp, operands[1]);
4816 (define_insn "*floatsisf2_mixed_vector"
4817 [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4818 (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4819 "TARGET_MIX_SSE_I387 && !flag_trapping_math
4820 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4822 cvtpq2ps\t{%1, %0|%0, %1}
4825 [(set_attr "type" "sseicvt,fmov,multi")
4826 (set_attr "mode" "SF")
4827 (set_attr "unit" "*,i387,*")
4828 (set_attr "athlon_decode" "double,*,*")
4829 (set_attr "amdfam10_decode" "double,*,*")
4830 (set_attr "fp_int_src" "false,true,true")])
4832 (define_insn "*floatsisf2_mixed"
4833 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4834 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4835 "TARGET_MIX_SSE_I387
4836 && (!TARGET_USE_VECTOR_CONVERTS || optimize_size)"
4840 cvtsi2ss\t{%1, %0|%0, %1}
4841 cvtsi2ss\t{%1, %0|%0, %1}"
4842 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4843 (set_attr "mode" "SF")
4844 (set_attr "unit" "*,i387,*,*")
4845 (set_attr "athlon_decode" "*,*,vector,double")
4846 (set_attr "amdfam10_decode" "*,*,vector,double")
4847 (set_attr "fp_int_src" "true")])
4849 (define_insn "*floatsisf2_sse_vector_nointernunit"
4850 [(set (match_operand:SF 0 "register_operand" "=x")
4851 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4852 "flag_trapping_math && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4853 && !TARGET_INTER_UNIT_MOVES"
4855 [(set_attr "type" "multi")])
4857 (define_insn "*floatsisf2_sse_vector_internunit"
4858 [(set (match_operand:SF 0 "register_operand" "=x,x")
4859 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4860 "flag_trapping_math && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4861 && TARGET_INTER_UNIT_MOVES"
4863 [(set_attr "type" "multi")])
4866 [(set (match_operand:SF 0 "register_operand" "")
4867 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4869 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4870 && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4871 && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4873 (float:V4SF (match_dup 2)))]
4875 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4876 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4877 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4881 [(set (match_operand:SF 0 "register_operand" "")
4882 (float:SF (match_operand:SI 1 "register_operand" "")))]
4884 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4885 && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4886 [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4888 (float:V4SF (match_dup 2)))]
4890 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4891 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4894 (define_insn "*floatsisf2_sse_vector"
4895 [(set (match_operand:SF 0 "register_operand" "=x")
4896 (float:SF (match_operand:SI 1 "register_operand" "x")))]
4897 "!flag_trapping_math && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4898 && !TARGET_INTER_UNIT_MOVES"
4899 "cvtpq2ps\t{%1, %0|%0, %1}"
4900 [(set_attr "type" "sseicvt")
4901 (set_attr "mode" "SF")
4902 (set_attr "athlon_decode" "double")
4903 (set_attr "amdfam10_decode" "double")
4904 (set_attr "fp_int_src" "true")])
4906 (define_insn "*floatsisf2_sse"
4907 [(set (match_operand:SF 0 "register_operand" "=x,x")
4908 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4910 && (!TARGET_USE_VECTOR_CONVERTS || optimize_size)"
4911 "cvtsi2ss\t{%1, %0|%0, %1}"
4912 [(set_attr "type" "sseicvt")
4913 (set_attr "mode" "SF")
4914 (set_attr "athlon_decode" "vector,double")
4915 (set_attr "amdfam10_decode" "vector,double")
4916 (set_attr "fp_int_src" "true")])
4918 (define_insn "*floatsidf2_mixed_vector"
4919 [(set (match_operand:DF 0 "register_operand" "=x,f,f")
4920 (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4921 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4922 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4924 cvtdq2pd\t{%1, %0|%0, %1}
4927 [(set_attr "type" "sseicvt,fmov,multi")
4928 (set_attr "mode" "V2DF,DF,DF")
4929 (set_attr "unit" "*,*,i387")
4930 (set_attr "athlon_decode" "double,*,*")
4931 (set_attr "amdfam10_decode" "double,*,*")
4932 (set_attr "fp_int_src" "false,true,true")])
4934 (define_insn "*floatsidf2_mixed"
4935 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
4936 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
4937 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4938 && (!TARGET_USE_VECTOR_CONVERTS || !optimize_size)"
4942 cvtsi2sd\t{%1, %0|%0, %1}
4943 cvtsi2sd\t{%1, %0|%0, %1}
4944 cvtdq2pd\t{%1, %0|%0, %1}"
4945 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4946 (set_attr "mode" "DF,DF,DF,DF,V2DF")
4947 (set_attr "unit" "*,i387,*,*,*")
4948 (set_attr "athlon_decode" "*,*,double,direct,double")
4949 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4950 (set_attr "fp_int_src" "true,true,true,true,false")])
4952 (define_insn "*floatsidf2_sse_vector"
4953 [(set (match_operand:DF 0 "register_operand" "=x")
4954 (float:DF (match_operand:SI 1 "register_operand" "x")))]
4955 "TARGET_SSE2 && TARGET_SSE_MATH
4956 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4957 "cvtdq2pd\t{%1, %0|%0, %1}"
4958 [(set_attr "type" "sseicvt")
4959 (set_attr "mode" "V2DF")
4960 (set_attr "athlon_decode" "double")
4961 (set_attr "amdfam10_decode" "double")
4962 (set_attr "fp_int_src" "true")])
4965 [(set (match_operand:DF 0 "register_operand" "")
4966 (float:DF (match_operand:SI 1 "memory_operand" "")))]
4967 "TARGET_USE_VECTOR_CONVERTS && reload_completed
4968 && SSE_REG_P (operands[0])"
4973 (parallel [(const_int 0) (const_int 1)]))))]
4975 operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
4976 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4977 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4980 (define_insn "*floatsidf2_sse"
4981 [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
4982 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
4983 "TARGET_SSE2 && TARGET_SSE_MATH
4984 && (!TARGET_USE_VECTOR_CONVERTS || optimize_size)"
4986 cvtsi2sd\t{%1, %0|%0, %1}
4987 cvtsi2sd\t{%1, %0|%0, %1}
4988 cvtdq2pd\t{%1, %0|%0, %1}"
4989 [(set_attr "type" "sseicvt")
4990 (set_attr "mode" "DF,DF,V2DF")
4991 (set_attr "athlon_decode" "double,direct,double")
4992 (set_attr "amdfam10_decode" "vector,double,double")
4993 (set_attr "fp_int_src" "true")])
4995 (define_insn "*floatsi<mode>2_i387"
4996 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
4998 (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5000 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5004 [(set_attr "type" "fmov,multi")
5005 (set_attr "mode" "<MODE>")
5006 (set_attr "unit" "*,i387")
5007 (set_attr "fp_int_src" "true")])
5009 (define_expand "floatdisf2"
5010 [(set (match_operand:SF 0 "register_operand" "")
5011 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5012 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5015 (define_insn "*floatdisf2_mixed"
5016 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5017 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5018 "TARGET_64BIT && TARGET_MIX_SSE_I387"
5022 cvtsi2ss{q}\t{%1, %0|%0, %1}
5023 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5024 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5025 (set_attr "mode" "SF")
5026 (set_attr "unit" "*,i387,*,*")
5027 (set_attr "athlon_decode" "*,*,vector,double")
5028 (set_attr "amdfam10_decode" "*,*,vector,double")
5029 (set_attr "fp_int_src" "true")])
5031 (define_insn "*floatdisf2_sse"
5032 [(set (match_operand:SF 0 "register_operand" "=x,x")
5033 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5034 "TARGET_64BIT && TARGET_SSE_MATH"
5035 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5036 [(set_attr "type" "sseicvt")
5037 (set_attr "mode" "SF")
5038 (set_attr "athlon_decode" "vector,double")
5039 (set_attr "amdfam10_decode" "vector,double")
5040 (set_attr "fp_int_src" "true")])
5042 (define_expand "floatdidf2"
5043 [(set (match_operand:DF 0 "register_operand" "")
5044 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5045 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5047 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5049 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5054 (define_insn "*floatdidf2_mixed"
5055 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5056 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5057 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
5061 cvtsi2sd{q}\t{%1, %0|%0, %1}
5062 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5063 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5064 (set_attr "mode" "DF")
5065 (set_attr "unit" "*,i387,*,*")
5066 (set_attr "athlon_decode" "*,*,double,direct")
5067 (set_attr "amdfam10_decode" "*,*,vector,double")
5068 (set_attr "fp_int_src" "true")])
5070 (define_insn "*floatdidf2_sse"
5071 [(set (match_operand:DF 0 "register_operand" "=x,x")
5072 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5073 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
5074 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5075 [(set_attr "type" "sseicvt")
5076 (set_attr "mode" "DF")
5077 (set_attr "athlon_decode" "double,direct")
5078 (set_attr "amdfam10_decode" "vector,double")
5079 (set_attr "fp_int_src" "true")])
5081 (define_insn "*floatdi<mode>2_i387"
5082 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5084 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5089 [(set_attr "type" "fmov,multi")
5090 (set_attr "mode" "<MODE>")
5091 (set_attr "unit" "*,i387")
5092 (set_attr "fp_int_src" "true")])
5094 (define_insn "float<mode>xf2"
5095 [(set (match_operand:XF 0 "register_operand" "=f,f")
5096 (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5101 [(set_attr "type" "fmov,multi")
5102 (set_attr "mode" "XF")
5103 (set_attr "unit" "*,i387")
5104 (set_attr "fp_int_src" "true")])
5106 ;; %%% Kill these when reload knows how to do it.
5108 [(set (match_operand 0 "fp_register_operand" "")
5109 (float (match_operand 1 "register_operand" "")))]
5111 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5114 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5115 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5116 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5117 ix86_free_from_memory (GET_MODE (operands[1]));
5121 (define_expand "floatunssisf2"
5122 [(use (match_operand:SF 0 "register_operand" ""))
5123 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5126 if (TARGET_SSE_MATH && TARGET_SSE2)
5127 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5129 x86_emit_floatuns (operands);
5133 (define_expand "floatunssidf2"
5134 [(use (match_operand:DF 0 "register_operand" ""))
5135 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5136 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5137 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5139 (define_expand "floatunsdisf2"
5140 [(use (match_operand:SF 0 "register_operand" ""))
5141 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5142 "TARGET_64BIT && TARGET_SSE_MATH"
5143 "x86_emit_floatuns (operands); DONE;")
5145 (define_expand "floatunsdidf2"
5146 [(use (match_operand:DF 0 "register_operand" ""))
5147 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5148 "TARGET_SSE_MATH && TARGET_SSE2
5149 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5152 x86_emit_floatuns (operands);
5154 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5160 ;; %%% splits for addditi3
5162 (define_expand "addti3"
5163 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5164 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5165 (match_operand:TI 2 "x86_64_general_operand" "")))
5166 (clobber (reg:CC FLAGS_REG))]
5168 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5170 (define_insn "*addti3_1"
5171 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5172 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5173 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5174 (clobber (reg:CC FLAGS_REG))]
5175 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5179 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5180 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5181 (match_operand:TI 2 "x86_64_general_operand" "")))
5182 (clobber (reg:CC FLAGS_REG))]
5183 "TARGET_64BIT && reload_completed"
5184 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5186 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5187 (parallel [(set (match_dup 3)
5188 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5191 (clobber (reg:CC FLAGS_REG))])]
5192 "split_ti (operands+0, 1, operands+0, operands+3);
5193 split_ti (operands+1, 1, operands+1, operands+4);
5194 split_ti (operands+2, 1, operands+2, operands+5);")
5196 ;; %%% splits for addsidi3
5197 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5198 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5199 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5201 (define_expand "adddi3"
5202 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5203 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5204 (match_operand:DI 2 "x86_64_general_operand" "")))
5205 (clobber (reg:CC FLAGS_REG))]
5207 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5209 (define_insn "*adddi3_1"
5210 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5211 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5212 (match_operand:DI 2 "general_operand" "roiF,riF")))
5213 (clobber (reg:CC FLAGS_REG))]
5214 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5218 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5219 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5220 (match_operand:DI 2 "general_operand" "")))
5221 (clobber (reg:CC FLAGS_REG))]
5222 "!TARGET_64BIT && reload_completed"
5223 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5225 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5226 (parallel [(set (match_dup 3)
5227 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5230 (clobber (reg:CC FLAGS_REG))])]
5231 "split_di (operands+0, 1, operands+0, operands+3);
5232 split_di (operands+1, 1, operands+1, operands+4);
5233 split_di (operands+2, 1, operands+2, operands+5);")
5235 (define_insn "adddi3_carry_rex64"
5236 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5237 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5238 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5239 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5240 (clobber (reg:CC FLAGS_REG))]
5241 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5242 "adc{q}\t{%2, %0|%0, %2}"
5243 [(set_attr "type" "alu")
5244 (set_attr "pent_pair" "pu")
5245 (set_attr "mode" "DI")])
5247 (define_insn "*adddi3_cc_rex64"
5248 [(set (reg:CC FLAGS_REG)
5249 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5250 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5252 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5253 (plus:DI (match_dup 1) (match_dup 2)))]
5254 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5255 "add{q}\t{%2, %0|%0, %2}"
5256 [(set_attr "type" "alu")
5257 (set_attr "mode" "DI")])
5259 (define_insn "*<addsub><mode>3_cc_overflow"
5260 [(set (reg:CCC FLAGS_REG)
5263 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5264 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5266 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5267 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5268 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5269 "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5270 [(set_attr "type" "alu")
5271 (set_attr "mode" "<MODE>")])
5273 (define_insn "*add<mode>3_cconly_overflow"
5274 [(set (reg:CCC FLAGS_REG)
5276 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5277 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5279 (clobber (match_scratch:SWI 0 "=<r>"))]
5280 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5281 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5282 [(set_attr "type" "alu")
5283 (set_attr "mode" "<MODE>")])
5285 (define_insn "*sub<mode>3_cconly_overflow"
5286 [(set (reg:CCC FLAGS_REG)
5288 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5289 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5292 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5293 [(set_attr "type" "icmp")
5294 (set_attr "mode" "<MODE>")])
5296 (define_insn "*<addsub>si3_zext_cc_overflow"
5297 [(set (reg:CCC FLAGS_REG)
5299 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5300 (match_operand:SI 2 "general_operand" "g"))
5302 (set (match_operand:DI 0 "register_operand" "=r")
5303 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5304 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5305 "<addsub>{l}\t{%2, %k0|%k0, %2}"
5306 [(set_attr "type" "alu")
5307 (set_attr "mode" "SI")])
5309 (define_insn "addqi3_carry"
5310 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5311 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5312 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5313 (match_operand:QI 2 "general_operand" "qi,qm")))
5314 (clobber (reg:CC FLAGS_REG))]
5315 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5316 "adc{b}\t{%2, %0|%0, %2}"
5317 [(set_attr "type" "alu")
5318 (set_attr "pent_pair" "pu")
5319 (set_attr "mode" "QI")])
5321 (define_insn "addhi3_carry"
5322 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5323 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5324 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5325 (match_operand:HI 2 "general_operand" "ri,rm")))
5326 (clobber (reg:CC FLAGS_REG))]
5327 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5328 "adc{w}\t{%2, %0|%0, %2}"
5329 [(set_attr "type" "alu")
5330 (set_attr "pent_pair" "pu")
5331 (set_attr "mode" "HI")])
5333 (define_insn "addsi3_carry"
5334 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5335 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5336 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5337 (match_operand:SI 2 "general_operand" "ri,rm")))
5338 (clobber (reg:CC FLAGS_REG))]
5339 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5340 "adc{l}\t{%2, %0|%0, %2}"
5341 [(set_attr "type" "alu")
5342 (set_attr "pent_pair" "pu")
5343 (set_attr "mode" "SI")])
5345 (define_insn "*addsi3_carry_zext"
5346 [(set (match_operand:DI 0 "register_operand" "=r")
5348 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5349 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5350 (match_operand:SI 2 "general_operand" "g"))))
5351 (clobber (reg:CC FLAGS_REG))]
5352 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5353 "adc{l}\t{%2, %k0|%k0, %2}"
5354 [(set_attr "type" "alu")
5355 (set_attr "pent_pair" "pu")
5356 (set_attr "mode" "SI")])
5358 (define_insn "*addsi3_cc"
5359 [(set (reg:CC FLAGS_REG)
5360 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5361 (match_operand:SI 2 "general_operand" "ri,rm")]
5363 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5364 (plus:SI (match_dup 1) (match_dup 2)))]
5365 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5366 "add{l}\t{%2, %0|%0, %2}"
5367 [(set_attr "type" "alu")
5368 (set_attr "mode" "SI")])
5370 (define_insn "addqi3_cc"
5371 [(set (reg:CC FLAGS_REG)
5372 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5373 (match_operand:QI 2 "general_operand" "qi,qm")]
5375 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5376 (plus:QI (match_dup 1) (match_dup 2)))]
5377 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5378 "add{b}\t{%2, %0|%0, %2}"
5379 [(set_attr "type" "alu")
5380 (set_attr "mode" "QI")])
5382 (define_expand "addsi3"
5383 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5384 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5385 (match_operand:SI 2 "general_operand" "")))
5386 (clobber (reg:CC FLAGS_REG))])]
5388 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5390 (define_insn "*lea_1"
5391 [(set (match_operand:SI 0 "register_operand" "=r")
5392 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5394 "lea{l}\t{%a1, %0|%0, %a1}"
5395 [(set_attr "type" "lea")
5396 (set_attr "mode" "SI")])
5398 (define_insn "*lea_1_rex64"
5399 [(set (match_operand:SI 0 "register_operand" "=r")
5400 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5402 "lea{l}\t{%a1, %0|%0, %a1}"
5403 [(set_attr "type" "lea")
5404 (set_attr "mode" "SI")])
5406 (define_insn "*lea_1_zext"
5407 [(set (match_operand:DI 0 "register_operand" "=r")
5409 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5411 "lea{l}\t{%a1, %k0|%k0, %a1}"
5412 [(set_attr "type" "lea")
5413 (set_attr "mode" "SI")])
5415 (define_insn "*lea_2_rex64"
5416 [(set (match_operand:DI 0 "register_operand" "=r")
5417 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5419 "lea{q}\t{%a1, %0|%0, %a1}"
5420 [(set_attr "type" "lea")
5421 (set_attr "mode" "DI")])
5423 ;; The lea patterns for non-Pmodes needs to be matched by several
5424 ;; insns converted to real lea by splitters.
5426 (define_insn_and_split "*lea_general_1"
5427 [(set (match_operand 0 "register_operand" "=r")
5428 (plus (plus (match_operand 1 "index_register_operand" "l")
5429 (match_operand 2 "register_operand" "r"))
5430 (match_operand 3 "immediate_operand" "i")))]
5431 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5432 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5433 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5434 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5435 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5436 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5437 || GET_MODE (operands[3]) == VOIDmode)"
5439 "&& reload_completed"
5443 operands[0] = gen_lowpart (SImode, operands[0]);
5444 operands[1] = gen_lowpart (Pmode, operands[1]);
5445 operands[2] = gen_lowpart (Pmode, operands[2]);
5446 operands[3] = gen_lowpart (Pmode, operands[3]);
5447 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5449 if (Pmode != SImode)
5450 pat = gen_rtx_SUBREG (SImode, pat, 0);
5451 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5454 [(set_attr "type" "lea")
5455 (set_attr "mode" "SI")])
5457 (define_insn_and_split "*lea_general_1_zext"
5458 [(set (match_operand:DI 0 "register_operand" "=r")
5460 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5461 (match_operand:SI 2 "register_operand" "r"))
5462 (match_operand:SI 3 "immediate_operand" "i"))))]
5465 "&& reload_completed"
5467 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5469 (match_dup 3)) 0)))]
5471 operands[1] = gen_lowpart (Pmode, operands[1]);
5472 operands[2] = gen_lowpart (Pmode, operands[2]);
5473 operands[3] = gen_lowpart (Pmode, operands[3]);
5475 [(set_attr "type" "lea")
5476 (set_attr "mode" "SI")])
5478 (define_insn_and_split "*lea_general_2"
5479 [(set (match_operand 0 "register_operand" "=r")
5480 (plus (mult (match_operand 1 "index_register_operand" "l")
5481 (match_operand 2 "const248_operand" "i"))
5482 (match_operand 3 "nonmemory_operand" "ri")))]
5483 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5484 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5485 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5486 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5487 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5488 || GET_MODE (operands[3]) == VOIDmode)"
5490 "&& reload_completed"
5494 operands[0] = gen_lowpart (SImode, operands[0]);
5495 operands[1] = gen_lowpart (Pmode, operands[1]);
5496 operands[3] = gen_lowpart (Pmode, operands[3]);
5497 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5499 if (Pmode != SImode)
5500 pat = gen_rtx_SUBREG (SImode, pat, 0);
5501 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5504 [(set_attr "type" "lea")
5505 (set_attr "mode" "SI")])
5507 (define_insn_and_split "*lea_general_2_zext"
5508 [(set (match_operand:DI 0 "register_operand" "=r")
5510 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5511 (match_operand:SI 2 "const248_operand" "n"))
5512 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5515 "&& reload_completed"
5517 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5519 (match_dup 3)) 0)))]
5521 operands[1] = gen_lowpart (Pmode, operands[1]);
5522 operands[3] = gen_lowpart (Pmode, operands[3]);
5524 [(set_attr "type" "lea")
5525 (set_attr "mode" "SI")])
5527 (define_insn_and_split "*lea_general_3"
5528 [(set (match_operand 0 "register_operand" "=r")
5529 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5530 (match_operand 2 "const248_operand" "i"))
5531 (match_operand 3 "register_operand" "r"))
5532 (match_operand 4 "immediate_operand" "i")))]
5533 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5534 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5535 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5536 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5537 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5539 "&& reload_completed"
5543 operands[0] = gen_lowpart (SImode, operands[0]);
5544 operands[1] = gen_lowpart (Pmode, operands[1]);
5545 operands[3] = gen_lowpart (Pmode, operands[3]);
5546 operands[4] = gen_lowpart (Pmode, operands[4]);
5547 pat = gen_rtx_PLUS (Pmode,
5548 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5552 if (Pmode != SImode)
5553 pat = gen_rtx_SUBREG (SImode, pat, 0);
5554 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5557 [(set_attr "type" "lea")
5558 (set_attr "mode" "SI")])
5560 (define_insn_and_split "*lea_general_3_zext"
5561 [(set (match_operand:DI 0 "register_operand" "=r")
5563 (plus:SI (plus:SI (mult:SI
5564 (match_operand:SI 1 "index_register_operand" "l")
5565 (match_operand:SI 2 "const248_operand" "n"))
5566 (match_operand:SI 3 "register_operand" "r"))
5567 (match_operand:SI 4 "immediate_operand" "i"))))]
5570 "&& reload_completed"
5572 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5575 (match_dup 4)) 0)))]
5577 operands[1] = gen_lowpart (Pmode, operands[1]);
5578 operands[3] = gen_lowpart (Pmode, operands[3]);
5579 operands[4] = gen_lowpart (Pmode, operands[4]);
5581 [(set_attr "type" "lea")
5582 (set_attr "mode" "SI")])
5584 (define_insn "*adddi_1_rex64"
5585 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5586 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5587 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5588 (clobber (reg:CC FLAGS_REG))]
5589 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5591 switch (get_attr_type (insn))
5594 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5595 return "lea{q}\t{%a2, %0|%0, %a2}";
5598 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5599 if (operands[2] == const1_rtx)
5600 return "inc{q}\t%0";
5603 gcc_assert (operands[2] == constm1_rtx);
5604 return "dec{q}\t%0";
5608 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5610 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5611 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5612 if (CONST_INT_P (operands[2])
5613 /* Avoid overflows. */
5614 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5615 && (INTVAL (operands[2]) == 128
5616 || (INTVAL (operands[2]) < 0
5617 && INTVAL (operands[2]) != -128)))
5619 operands[2] = GEN_INT (-INTVAL (operands[2]));
5620 return "sub{q}\t{%2, %0|%0, %2}";
5622 return "add{q}\t{%2, %0|%0, %2}";
5626 (cond [(eq_attr "alternative" "2")
5627 (const_string "lea")
5628 ; Current assemblers are broken and do not allow @GOTOFF in
5629 ; ought but a memory context.
5630 (match_operand:DI 2 "pic_symbolic_operand" "")
5631 (const_string "lea")
5632 (match_operand:DI 2 "incdec_operand" "")
5633 (const_string "incdec")
5635 (const_string "alu")))
5636 (set_attr "mode" "DI")])
5638 ;; Convert lea to the lea pattern to avoid flags dependency.
5640 [(set (match_operand:DI 0 "register_operand" "")
5641 (plus:DI (match_operand:DI 1 "register_operand" "")
5642 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5643 (clobber (reg:CC FLAGS_REG))]
5644 "TARGET_64BIT && reload_completed
5645 && true_regnum (operands[0]) != true_regnum (operands[1])"
5647 (plus:DI (match_dup 1)
5651 (define_insn "*adddi_2_rex64"
5652 [(set (reg FLAGS_REG)
5654 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5655 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5657 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5658 (plus:DI (match_dup 1) (match_dup 2)))]
5659 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5660 && ix86_binary_operator_ok (PLUS, DImode, operands)
5661 /* Current assemblers are broken and do not allow @GOTOFF in
5662 ought but a memory context. */
5663 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5665 switch (get_attr_type (insn))
5668 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5669 if (operands[2] == const1_rtx)
5670 return "inc{q}\t%0";
5673 gcc_assert (operands[2] == constm1_rtx);
5674 return "dec{q}\t%0";
5678 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5679 /* ???? We ought to handle there the 32bit case too
5680 - do we need new constraint? */
5681 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5682 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5683 if (CONST_INT_P (operands[2])
5684 /* Avoid overflows. */
5685 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5686 && (INTVAL (operands[2]) == 128
5687 || (INTVAL (operands[2]) < 0
5688 && INTVAL (operands[2]) != -128)))
5690 operands[2] = GEN_INT (-INTVAL (operands[2]));
5691 return "sub{q}\t{%2, %0|%0, %2}";
5693 return "add{q}\t{%2, %0|%0, %2}";
5697 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5698 (const_string "incdec")
5699 (const_string "alu")))
5700 (set_attr "mode" "DI")])
5702 (define_insn "*adddi_3_rex64"
5703 [(set (reg FLAGS_REG)
5704 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5705 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5706 (clobber (match_scratch:DI 0 "=r"))]
5708 && ix86_match_ccmode (insn, CCZmode)
5709 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5710 /* Current assemblers are broken and do not allow @GOTOFF in
5711 ought but a memory context. */
5712 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5714 switch (get_attr_type (insn))
5717 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5718 if (operands[2] == const1_rtx)
5719 return "inc{q}\t%0";
5722 gcc_assert (operands[2] == constm1_rtx);
5723 return "dec{q}\t%0";
5727 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5728 /* ???? We ought to handle there the 32bit case too
5729 - do we need new constraint? */
5730 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5731 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5732 if (CONST_INT_P (operands[2])
5733 /* Avoid overflows. */
5734 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5735 && (INTVAL (operands[2]) == 128
5736 || (INTVAL (operands[2]) < 0
5737 && INTVAL (operands[2]) != -128)))
5739 operands[2] = GEN_INT (-INTVAL (operands[2]));
5740 return "sub{q}\t{%2, %0|%0, %2}";
5742 return "add{q}\t{%2, %0|%0, %2}";
5746 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5747 (const_string "incdec")
5748 (const_string "alu")))
5749 (set_attr "mode" "DI")])
5751 ; For comparisons against 1, -1 and 128, we may generate better code
5752 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5753 ; is matched then. We can't accept general immediate, because for
5754 ; case of overflows, the result is messed up.
5755 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5757 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5758 ; only for comparisons not depending on it.
5759 (define_insn "*adddi_4_rex64"
5760 [(set (reg FLAGS_REG)
5761 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5762 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5763 (clobber (match_scratch:DI 0 "=rm"))]
5765 && ix86_match_ccmode (insn, CCGCmode)"
5767 switch (get_attr_type (insn))
5770 if (operands[2] == constm1_rtx)
5771 return "inc{q}\t%0";
5774 gcc_assert (operands[2] == const1_rtx);
5775 return "dec{q}\t%0";
5779 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5780 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5781 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5782 if ((INTVAL (operands[2]) == -128
5783 || (INTVAL (operands[2]) > 0
5784 && INTVAL (operands[2]) != 128))
5785 /* Avoid overflows. */
5786 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5787 return "sub{q}\t{%2, %0|%0, %2}";
5788 operands[2] = GEN_INT (-INTVAL (operands[2]));
5789 return "add{q}\t{%2, %0|%0, %2}";
5793 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5794 (const_string "incdec")
5795 (const_string "alu")))
5796 (set_attr "mode" "DI")])
5798 (define_insn "*adddi_5_rex64"
5799 [(set (reg FLAGS_REG)
5801 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5802 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5804 (clobber (match_scratch:DI 0 "=r"))]
5806 && ix86_match_ccmode (insn, CCGOCmode)
5807 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5808 /* Current assemblers are broken and do not allow @GOTOFF in
5809 ought but a memory context. */
5810 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5812 switch (get_attr_type (insn))
5815 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5816 if (operands[2] == const1_rtx)
5817 return "inc{q}\t%0";
5820 gcc_assert (operands[2] == constm1_rtx);
5821 return "dec{q}\t%0";
5825 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5826 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5827 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5828 if (CONST_INT_P (operands[2])
5829 /* Avoid overflows. */
5830 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5831 && (INTVAL (operands[2]) == 128
5832 || (INTVAL (operands[2]) < 0
5833 && INTVAL (operands[2]) != -128)))
5835 operands[2] = GEN_INT (-INTVAL (operands[2]));
5836 return "sub{q}\t{%2, %0|%0, %2}";
5838 return "add{q}\t{%2, %0|%0, %2}";
5842 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5843 (const_string "incdec")
5844 (const_string "alu")))
5845 (set_attr "mode" "DI")])
5848 (define_insn "*addsi_1"
5849 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5850 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5851 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5852 (clobber (reg:CC FLAGS_REG))]
5853 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5855 switch (get_attr_type (insn))
5858 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5859 return "lea{l}\t{%a2, %0|%0, %a2}";
5862 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5863 if (operands[2] == const1_rtx)
5864 return "inc{l}\t%0";
5867 gcc_assert (operands[2] == constm1_rtx);
5868 return "dec{l}\t%0";
5872 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5874 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5875 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5876 if (CONST_INT_P (operands[2])
5877 && (INTVAL (operands[2]) == 128
5878 || (INTVAL (operands[2]) < 0
5879 && INTVAL (operands[2]) != -128)))
5881 operands[2] = GEN_INT (-INTVAL (operands[2]));
5882 return "sub{l}\t{%2, %0|%0, %2}";
5884 return "add{l}\t{%2, %0|%0, %2}";
5888 (cond [(eq_attr "alternative" "2")
5889 (const_string "lea")
5890 ; Current assemblers are broken and do not allow @GOTOFF in
5891 ; ought but a memory context.
5892 (match_operand:SI 2 "pic_symbolic_operand" "")
5893 (const_string "lea")
5894 (match_operand:SI 2 "incdec_operand" "")
5895 (const_string "incdec")
5897 (const_string "alu")))
5898 (set_attr "mode" "SI")])
5900 ;; Convert lea to the lea pattern to avoid flags dependency.
5902 [(set (match_operand 0 "register_operand" "")
5903 (plus (match_operand 1 "register_operand" "")
5904 (match_operand 2 "nonmemory_operand" "")))
5905 (clobber (reg:CC FLAGS_REG))]
5907 && true_regnum (operands[0]) != true_regnum (operands[1])"
5911 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5912 may confuse gen_lowpart. */
5913 if (GET_MODE (operands[0]) != Pmode)
5915 operands[1] = gen_lowpart (Pmode, operands[1]);
5916 operands[2] = gen_lowpart (Pmode, operands[2]);
5918 operands[0] = gen_lowpart (SImode, operands[0]);
5919 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5920 if (Pmode != SImode)
5921 pat = gen_rtx_SUBREG (SImode, pat, 0);
5922 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5926 ;; It may seem that nonimmediate operand is proper one for operand 1.
5927 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5928 ;; we take care in ix86_binary_operator_ok to not allow two memory
5929 ;; operands so proper swapping will be done in reload. This allow
5930 ;; patterns constructed from addsi_1 to match.
5931 (define_insn "addsi_1_zext"
5932 [(set (match_operand:DI 0 "register_operand" "=r,r")
5934 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5935 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5936 (clobber (reg:CC FLAGS_REG))]
5937 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5939 switch (get_attr_type (insn))
5942 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5943 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5946 if (operands[2] == const1_rtx)
5947 return "inc{l}\t%k0";
5950 gcc_assert (operands[2] == constm1_rtx);
5951 return "dec{l}\t%k0";
5955 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5956 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5957 if (CONST_INT_P (operands[2])
5958 && (INTVAL (operands[2]) == 128
5959 || (INTVAL (operands[2]) < 0
5960 && INTVAL (operands[2]) != -128)))
5962 operands[2] = GEN_INT (-INTVAL (operands[2]));
5963 return "sub{l}\t{%2, %k0|%k0, %2}";
5965 return "add{l}\t{%2, %k0|%k0, %2}";
5969 (cond [(eq_attr "alternative" "1")
5970 (const_string "lea")
5971 ; Current assemblers are broken and do not allow @GOTOFF in
5972 ; ought but a memory context.
5973 (match_operand:SI 2 "pic_symbolic_operand" "")
5974 (const_string "lea")
5975 (match_operand:SI 2 "incdec_operand" "")
5976 (const_string "incdec")
5978 (const_string "alu")))
5979 (set_attr "mode" "SI")])
5981 ;; Convert lea to the lea pattern to avoid flags dependency.
5983 [(set (match_operand:DI 0 "register_operand" "")
5985 (plus:SI (match_operand:SI 1 "register_operand" "")
5986 (match_operand:SI 2 "nonmemory_operand" ""))))
5987 (clobber (reg:CC FLAGS_REG))]
5988 "TARGET_64BIT && reload_completed
5989 && true_regnum (operands[0]) != true_regnum (operands[1])"
5991 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5993 operands[1] = gen_lowpart (Pmode, operands[1]);
5994 operands[2] = gen_lowpart (Pmode, operands[2]);
5997 (define_insn "*addsi_2"
5998 [(set (reg FLAGS_REG)
6000 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6001 (match_operand:SI 2 "general_operand" "rmni,rni"))
6003 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6004 (plus:SI (match_dup 1) (match_dup 2)))]
6005 "ix86_match_ccmode (insn, CCGOCmode)
6006 && ix86_binary_operator_ok (PLUS, SImode, operands)
6007 /* Current assemblers are broken and do not allow @GOTOFF in
6008 ought but a memory context. */
6009 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6011 switch (get_attr_type (insn))
6014 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6015 if (operands[2] == const1_rtx)
6016 return "inc{l}\t%0";
6019 gcc_assert (operands[2] == constm1_rtx);
6020 return "dec{l}\t%0";
6024 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6025 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6026 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6027 if (CONST_INT_P (operands[2])
6028 && (INTVAL (operands[2]) == 128
6029 || (INTVAL (operands[2]) < 0
6030 && INTVAL (operands[2]) != -128)))
6032 operands[2] = GEN_INT (-INTVAL (operands[2]));
6033 return "sub{l}\t{%2, %0|%0, %2}";
6035 return "add{l}\t{%2, %0|%0, %2}";
6039 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6040 (const_string "incdec")
6041 (const_string "alu")))
6042 (set_attr "mode" "SI")])
6044 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6045 (define_insn "*addsi_2_zext"
6046 [(set (reg FLAGS_REG)
6048 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6049 (match_operand:SI 2 "general_operand" "rmni"))
6051 (set (match_operand:DI 0 "register_operand" "=r")
6052 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6053 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6054 && ix86_binary_operator_ok (PLUS, SImode, operands)
6055 /* Current assemblers are broken and do not allow @GOTOFF in
6056 ought but a memory context. */
6057 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6059 switch (get_attr_type (insn))
6062 if (operands[2] == const1_rtx)
6063 return "inc{l}\t%k0";
6066 gcc_assert (operands[2] == constm1_rtx);
6067 return "dec{l}\t%k0";
6071 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6072 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6073 if (CONST_INT_P (operands[2])
6074 && (INTVAL (operands[2]) == 128
6075 || (INTVAL (operands[2]) < 0
6076 && INTVAL (operands[2]) != -128)))
6078 operands[2] = GEN_INT (-INTVAL (operands[2]));
6079 return "sub{l}\t{%2, %k0|%k0, %2}";
6081 return "add{l}\t{%2, %k0|%k0, %2}";
6085 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6086 (const_string "incdec")
6087 (const_string "alu")))
6088 (set_attr "mode" "SI")])
6090 (define_insn "*addsi_3"
6091 [(set (reg FLAGS_REG)
6092 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6093 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6094 (clobber (match_scratch:SI 0 "=r"))]
6095 "ix86_match_ccmode (insn, CCZmode)
6096 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6097 /* Current assemblers are broken and do not allow @GOTOFF in
6098 ought but a memory context. */
6099 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6101 switch (get_attr_type (insn))
6104 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6105 if (operands[2] == const1_rtx)
6106 return "inc{l}\t%0";
6109 gcc_assert (operands[2] == constm1_rtx);
6110 return "dec{l}\t%0";
6114 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6115 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6116 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6117 if (CONST_INT_P (operands[2])
6118 && (INTVAL (operands[2]) == 128
6119 || (INTVAL (operands[2]) < 0
6120 && INTVAL (operands[2]) != -128)))
6122 operands[2] = GEN_INT (-INTVAL (operands[2]));
6123 return "sub{l}\t{%2, %0|%0, %2}";
6125 return "add{l}\t{%2, %0|%0, %2}";
6129 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6130 (const_string "incdec")
6131 (const_string "alu")))
6132 (set_attr "mode" "SI")])
6134 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6135 (define_insn "*addsi_3_zext"
6136 [(set (reg FLAGS_REG)
6137 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6138 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6139 (set (match_operand:DI 0 "register_operand" "=r")
6140 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6141 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6142 && ix86_binary_operator_ok (PLUS, SImode, operands)
6143 /* Current assemblers are broken and do not allow @GOTOFF in
6144 ought but a memory context. */
6145 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6147 switch (get_attr_type (insn))
6150 if (operands[2] == const1_rtx)
6151 return "inc{l}\t%k0";
6154 gcc_assert (operands[2] == constm1_rtx);
6155 return "dec{l}\t%k0";
6159 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6160 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6161 if (CONST_INT_P (operands[2])
6162 && (INTVAL (operands[2]) == 128
6163 || (INTVAL (operands[2]) < 0
6164 && INTVAL (operands[2]) != -128)))
6166 operands[2] = GEN_INT (-INTVAL (operands[2]));
6167 return "sub{l}\t{%2, %k0|%k0, %2}";
6169 return "add{l}\t{%2, %k0|%k0, %2}";
6173 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6174 (const_string "incdec")
6175 (const_string "alu")))
6176 (set_attr "mode" "SI")])
6178 ; For comparisons against 1, -1 and 128, we may generate better code
6179 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6180 ; is matched then. We can't accept general immediate, because for
6181 ; case of overflows, the result is messed up.
6182 ; This pattern also don't hold of 0x80000000, since the value overflows
6184 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6185 ; only for comparisons not depending on it.
6186 (define_insn "*addsi_4"
6187 [(set (reg FLAGS_REG)
6188 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6189 (match_operand:SI 2 "const_int_operand" "n")))
6190 (clobber (match_scratch:SI 0 "=rm"))]
6191 "ix86_match_ccmode (insn, CCGCmode)
6192 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6194 switch (get_attr_type (insn))
6197 if (operands[2] == constm1_rtx)
6198 return "inc{l}\t%0";
6201 gcc_assert (operands[2] == const1_rtx);
6202 return "dec{l}\t%0";
6206 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6207 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6208 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6209 if ((INTVAL (operands[2]) == -128
6210 || (INTVAL (operands[2]) > 0
6211 && INTVAL (operands[2]) != 128)))
6212 return "sub{l}\t{%2, %0|%0, %2}";
6213 operands[2] = GEN_INT (-INTVAL (operands[2]));
6214 return "add{l}\t{%2, %0|%0, %2}";
6218 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6219 (const_string "incdec")
6220 (const_string "alu")))
6221 (set_attr "mode" "SI")])
6223 (define_insn "*addsi_5"
6224 [(set (reg FLAGS_REG)
6226 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6227 (match_operand:SI 2 "general_operand" "rmni"))
6229 (clobber (match_scratch:SI 0 "=r"))]
6230 "ix86_match_ccmode (insn, CCGOCmode)
6231 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6232 /* Current assemblers are broken and do not allow @GOTOFF in
6233 ought but a memory context. */
6234 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6236 switch (get_attr_type (insn))
6239 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6240 if (operands[2] == const1_rtx)
6241 return "inc{l}\t%0";
6244 gcc_assert (operands[2] == constm1_rtx);
6245 return "dec{l}\t%0";
6249 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6250 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6251 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6252 if (CONST_INT_P (operands[2])
6253 && (INTVAL (operands[2]) == 128
6254 || (INTVAL (operands[2]) < 0
6255 && INTVAL (operands[2]) != -128)))
6257 operands[2] = GEN_INT (-INTVAL (operands[2]));
6258 return "sub{l}\t{%2, %0|%0, %2}";
6260 return "add{l}\t{%2, %0|%0, %2}";
6264 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6265 (const_string "incdec")
6266 (const_string "alu")))
6267 (set_attr "mode" "SI")])
6269 (define_expand "addhi3"
6270 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6271 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6272 (match_operand:HI 2 "general_operand" "")))
6273 (clobber (reg:CC FLAGS_REG))])]
6274 "TARGET_HIMODE_MATH"
6275 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6277 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6278 ;; type optimizations enabled by define-splits. This is not important
6279 ;; for PII, and in fact harmful because of partial register stalls.
6281 (define_insn "*addhi_1_lea"
6282 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6283 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6284 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6285 (clobber (reg:CC FLAGS_REG))]
6286 "!TARGET_PARTIAL_REG_STALL
6287 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6289 switch (get_attr_type (insn))
6294 if (operands[2] == const1_rtx)
6295 return "inc{w}\t%0";
6298 gcc_assert (operands[2] == constm1_rtx);
6299 return "dec{w}\t%0";
6303 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6304 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6305 if (CONST_INT_P (operands[2])
6306 && (INTVAL (operands[2]) == 128
6307 || (INTVAL (operands[2]) < 0
6308 && INTVAL (operands[2]) != -128)))
6310 operands[2] = GEN_INT (-INTVAL (operands[2]));
6311 return "sub{w}\t{%2, %0|%0, %2}";
6313 return "add{w}\t{%2, %0|%0, %2}";
6317 (if_then_else (eq_attr "alternative" "2")
6318 (const_string "lea")
6319 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6320 (const_string "incdec")
6321 (const_string "alu"))))
6322 (set_attr "mode" "HI,HI,SI")])
6324 (define_insn "*addhi_1"
6325 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6326 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6327 (match_operand:HI 2 "general_operand" "ri,rm")))
6328 (clobber (reg:CC FLAGS_REG))]
6329 "TARGET_PARTIAL_REG_STALL
6330 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6332 switch (get_attr_type (insn))
6335 if (operands[2] == const1_rtx)
6336 return "inc{w}\t%0";
6339 gcc_assert (operands[2] == constm1_rtx);
6340 return "dec{w}\t%0";
6344 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6345 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6346 if (CONST_INT_P (operands[2])
6347 && (INTVAL (operands[2]) == 128
6348 || (INTVAL (operands[2]) < 0
6349 && INTVAL (operands[2]) != -128)))
6351 operands[2] = GEN_INT (-INTVAL (operands[2]));
6352 return "sub{w}\t{%2, %0|%0, %2}";
6354 return "add{w}\t{%2, %0|%0, %2}";
6358 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6359 (const_string "incdec")
6360 (const_string "alu")))
6361 (set_attr "mode" "HI")])
6363 (define_insn "*addhi_2"
6364 [(set (reg FLAGS_REG)
6366 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6367 (match_operand:HI 2 "general_operand" "rmni,rni"))
6369 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6370 (plus:HI (match_dup 1) (match_dup 2)))]
6371 "ix86_match_ccmode (insn, CCGOCmode)
6372 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6374 switch (get_attr_type (insn))
6377 if (operands[2] == const1_rtx)
6378 return "inc{w}\t%0";
6381 gcc_assert (operands[2] == constm1_rtx);
6382 return "dec{w}\t%0";
6386 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6387 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6388 if (CONST_INT_P (operands[2])
6389 && (INTVAL (operands[2]) == 128
6390 || (INTVAL (operands[2]) < 0
6391 && INTVAL (operands[2]) != -128)))
6393 operands[2] = GEN_INT (-INTVAL (operands[2]));
6394 return "sub{w}\t{%2, %0|%0, %2}";
6396 return "add{w}\t{%2, %0|%0, %2}";
6400 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6401 (const_string "incdec")
6402 (const_string "alu")))
6403 (set_attr "mode" "HI")])
6405 (define_insn "*addhi_3"
6406 [(set (reg FLAGS_REG)
6407 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6408 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6409 (clobber (match_scratch:HI 0 "=r"))]
6410 "ix86_match_ccmode (insn, CCZmode)
6411 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6413 switch (get_attr_type (insn))
6416 if (operands[2] == const1_rtx)
6417 return "inc{w}\t%0";
6420 gcc_assert (operands[2] == constm1_rtx);
6421 return "dec{w}\t%0";
6425 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6426 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6427 if (CONST_INT_P (operands[2])
6428 && (INTVAL (operands[2]) == 128
6429 || (INTVAL (operands[2]) < 0
6430 && INTVAL (operands[2]) != -128)))
6432 operands[2] = GEN_INT (-INTVAL (operands[2]));
6433 return "sub{w}\t{%2, %0|%0, %2}";
6435 return "add{w}\t{%2, %0|%0, %2}";
6439 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6440 (const_string "incdec")
6441 (const_string "alu")))
6442 (set_attr "mode" "HI")])
6444 ; See comments above addsi_4 for details.
6445 (define_insn "*addhi_4"
6446 [(set (reg FLAGS_REG)
6447 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6448 (match_operand:HI 2 "const_int_operand" "n")))
6449 (clobber (match_scratch:HI 0 "=rm"))]
6450 "ix86_match_ccmode (insn, CCGCmode)
6451 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6453 switch (get_attr_type (insn))
6456 if (operands[2] == constm1_rtx)
6457 return "inc{w}\t%0";
6460 gcc_assert (operands[2] == const1_rtx);
6461 return "dec{w}\t%0";
6465 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6466 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6467 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6468 if ((INTVAL (operands[2]) == -128
6469 || (INTVAL (operands[2]) > 0
6470 && INTVAL (operands[2]) != 128)))
6471 return "sub{w}\t{%2, %0|%0, %2}";
6472 operands[2] = GEN_INT (-INTVAL (operands[2]));
6473 return "add{w}\t{%2, %0|%0, %2}";
6477 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6478 (const_string "incdec")
6479 (const_string "alu")))
6480 (set_attr "mode" "SI")])
6483 (define_insn "*addhi_5"
6484 [(set (reg FLAGS_REG)
6486 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6487 (match_operand:HI 2 "general_operand" "rmni"))
6489 (clobber (match_scratch:HI 0 "=r"))]
6490 "ix86_match_ccmode (insn, CCGOCmode)
6491 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6493 switch (get_attr_type (insn))
6496 if (operands[2] == const1_rtx)
6497 return "inc{w}\t%0";
6500 gcc_assert (operands[2] == constm1_rtx);
6501 return "dec{w}\t%0";
6505 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6506 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6507 if (CONST_INT_P (operands[2])
6508 && (INTVAL (operands[2]) == 128
6509 || (INTVAL (operands[2]) < 0
6510 && INTVAL (operands[2]) != -128)))
6512 operands[2] = GEN_INT (-INTVAL (operands[2]));
6513 return "sub{w}\t{%2, %0|%0, %2}";
6515 return "add{w}\t{%2, %0|%0, %2}";
6519 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6520 (const_string "incdec")
6521 (const_string "alu")))
6522 (set_attr "mode" "HI")])
6524 (define_expand "addqi3"
6525 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6526 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6527 (match_operand:QI 2 "general_operand" "")))
6528 (clobber (reg:CC FLAGS_REG))])]
6529 "TARGET_QIMODE_MATH"
6530 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6532 ;; %%% Potential partial reg stall on alternative 2. What to do?
6533 (define_insn "*addqi_1_lea"
6534 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6535 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6536 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6537 (clobber (reg:CC FLAGS_REG))]
6538 "!TARGET_PARTIAL_REG_STALL
6539 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6541 int widen = (which_alternative == 2);
6542 switch (get_attr_type (insn))
6547 if (operands[2] == const1_rtx)
6548 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6551 gcc_assert (operands[2] == constm1_rtx);
6552 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6556 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6557 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6558 if (CONST_INT_P (operands[2])
6559 && (INTVAL (operands[2]) == 128
6560 || (INTVAL (operands[2]) < 0
6561 && INTVAL (operands[2]) != -128)))
6563 operands[2] = GEN_INT (-INTVAL (operands[2]));
6565 return "sub{l}\t{%2, %k0|%k0, %2}";
6567 return "sub{b}\t{%2, %0|%0, %2}";
6570 return "add{l}\t{%k2, %k0|%k0, %k2}";
6572 return "add{b}\t{%2, %0|%0, %2}";
6576 (if_then_else (eq_attr "alternative" "3")
6577 (const_string "lea")
6578 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6579 (const_string "incdec")
6580 (const_string "alu"))))
6581 (set_attr "mode" "QI,QI,SI,SI")])
6583 (define_insn "*addqi_1"
6584 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6585 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6586 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6587 (clobber (reg:CC FLAGS_REG))]
6588 "TARGET_PARTIAL_REG_STALL
6589 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6591 int widen = (which_alternative == 2);
6592 switch (get_attr_type (insn))
6595 if (operands[2] == const1_rtx)
6596 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6599 gcc_assert (operands[2] == constm1_rtx);
6600 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6604 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6605 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6606 if (CONST_INT_P (operands[2])
6607 && (INTVAL (operands[2]) == 128
6608 || (INTVAL (operands[2]) < 0
6609 && INTVAL (operands[2]) != -128)))
6611 operands[2] = GEN_INT (-INTVAL (operands[2]));
6613 return "sub{l}\t{%2, %k0|%k0, %2}";
6615 return "sub{b}\t{%2, %0|%0, %2}";
6618 return "add{l}\t{%k2, %k0|%k0, %k2}";
6620 return "add{b}\t{%2, %0|%0, %2}";
6624 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6625 (const_string "incdec")
6626 (const_string "alu")))
6627 (set_attr "mode" "QI,QI,SI")])
6629 (define_insn "*addqi_1_slp"
6630 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6631 (plus:QI (match_dup 0)
6632 (match_operand:QI 1 "general_operand" "qn,qnm")))
6633 (clobber (reg:CC FLAGS_REG))]
6634 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6635 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6637 switch (get_attr_type (insn))
6640 if (operands[1] == const1_rtx)
6641 return "inc{b}\t%0";
6644 gcc_assert (operands[1] == constm1_rtx);
6645 return "dec{b}\t%0";
6649 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6650 if (CONST_INT_P (operands[1])
6651 && INTVAL (operands[1]) < 0)
6653 operands[1] = GEN_INT (-INTVAL (operands[1]));
6654 return "sub{b}\t{%1, %0|%0, %1}";
6656 return "add{b}\t{%1, %0|%0, %1}";
6660 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6661 (const_string "incdec")
6662 (const_string "alu1")))
6663 (set (attr "memory")
6664 (if_then_else (match_operand 1 "memory_operand" "")
6665 (const_string "load")
6666 (const_string "none")))
6667 (set_attr "mode" "QI")])
6669 (define_insn "*addqi_2"
6670 [(set (reg FLAGS_REG)
6672 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6673 (match_operand:QI 2 "general_operand" "qmni,qni"))
6675 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6676 (plus:QI (match_dup 1) (match_dup 2)))]
6677 "ix86_match_ccmode (insn, CCGOCmode)
6678 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6680 switch (get_attr_type (insn))
6683 if (operands[2] == const1_rtx)
6684 return "inc{b}\t%0";
6687 gcc_assert (operands[2] == constm1_rtx
6688 || (CONST_INT_P (operands[2])
6689 && INTVAL (operands[2]) == 255));
6690 return "dec{b}\t%0";
6694 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6695 if (CONST_INT_P (operands[2])
6696 && INTVAL (operands[2]) < 0)
6698 operands[2] = GEN_INT (-INTVAL (operands[2]));
6699 return "sub{b}\t{%2, %0|%0, %2}";
6701 return "add{b}\t{%2, %0|%0, %2}";
6705 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6706 (const_string "incdec")
6707 (const_string "alu")))
6708 (set_attr "mode" "QI")])
6710 (define_insn "*addqi_3"
6711 [(set (reg FLAGS_REG)
6712 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6713 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6714 (clobber (match_scratch:QI 0 "=q"))]
6715 "ix86_match_ccmode (insn, CCZmode)
6716 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6718 switch (get_attr_type (insn))
6721 if (operands[2] == const1_rtx)
6722 return "inc{b}\t%0";
6725 gcc_assert (operands[2] == constm1_rtx
6726 || (CONST_INT_P (operands[2])
6727 && INTVAL (operands[2]) == 255));
6728 return "dec{b}\t%0";
6732 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6733 if (CONST_INT_P (operands[2])
6734 && INTVAL (operands[2]) < 0)
6736 operands[2] = GEN_INT (-INTVAL (operands[2]));
6737 return "sub{b}\t{%2, %0|%0, %2}";
6739 return "add{b}\t{%2, %0|%0, %2}";
6743 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6744 (const_string "incdec")
6745 (const_string "alu")))
6746 (set_attr "mode" "QI")])
6748 ; See comments above addsi_4 for details.
6749 (define_insn "*addqi_4"
6750 [(set (reg FLAGS_REG)
6751 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6752 (match_operand:QI 2 "const_int_operand" "n")))
6753 (clobber (match_scratch:QI 0 "=qm"))]
6754 "ix86_match_ccmode (insn, CCGCmode)
6755 && (INTVAL (operands[2]) & 0xff) != 0x80"
6757 switch (get_attr_type (insn))
6760 if (operands[2] == constm1_rtx
6761 || (CONST_INT_P (operands[2])
6762 && INTVAL (operands[2]) == 255))
6763 return "inc{b}\t%0";
6766 gcc_assert (operands[2] == const1_rtx);
6767 return "dec{b}\t%0";
6771 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6772 if (INTVAL (operands[2]) < 0)
6774 operands[2] = GEN_INT (-INTVAL (operands[2]));
6775 return "add{b}\t{%2, %0|%0, %2}";
6777 return "sub{b}\t{%2, %0|%0, %2}";
6781 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6782 (const_string "incdec")
6783 (const_string "alu")))
6784 (set_attr "mode" "QI")])
6787 (define_insn "*addqi_5"
6788 [(set (reg FLAGS_REG)
6790 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6791 (match_operand:QI 2 "general_operand" "qmni"))
6793 (clobber (match_scratch:QI 0 "=q"))]
6794 "ix86_match_ccmode (insn, CCGOCmode)
6795 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6797 switch (get_attr_type (insn))
6800 if (operands[2] == const1_rtx)
6801 return "inc{b}\t%0";
6804 gcc_assert (operands[2] == constm1_rtx
6805 || (CONST_INT_P (operands[2])
6806 && INTVAL (operands[2]) == 255));
6807 return "dec{b}\t%0";
6811 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6812 if (CONST_INT_P (operands[2])
6813 && INTVAL (operands[2]) < 0)
6815 operands[2] = GEN_INT (-INTVAL (operands[2]));
6816 return "sub{b}\t{%2, %0|%0, %2}";
6818 return "add{b}\t{%2, %0|%0, %2}";
6822 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6823 (const_string "incdec")
6824 (const_string "alu")))
6825 (set_attr "mode" "QI")])
6828 (define_insn "addqi_ext_1"
6829 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6834 (match_operand 1 "ext_register_operand" "0")
6837 (match_operand:QI 2 "general_operand" "Qmn")))
6838 (clobber (reg:CC FLAGS_REG))]
6841 switch (get_attr_type (insn))
6844 if (operands[2] == const1_rtx)
6845 return "inc{b}\t%h0";
6848 gcc_assert (operands[2] == constm1_rtx
6849 || (CONST_INT_P (operands[2])
6850 && INTVAL (operands[2]) == 255));
6851 return "dec{b}\t%h0";
6855 return "add{b}\t{%2, %h0|%h0, %2}";
6859 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6860 (const_string "incdec")
6861 (const_string "alu")))
6862 (set_attr "mode" "QI")])
6864 (define_insn "*addqi_ext_1_rex64"
6865 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6870 (match_operand 1 "ext_register_operand" "0")
6873 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6874 (clobber (reg:CC FLAGS_REG))]
6877 switch (get_attr_type (insn))
6880 if (operands[2] == const1_rtx)
6881 return "inc{b}\t%h0";
6884 gcc_assert (operands[2] == constm1_rtx
6885 || (CONST_INT_P (operands[2])
6886 && INTVAL (operands[2]) == 255));
6887 return "dec{b}\t%h0";
6891 return "add{b}\t{%2, %h0|%h0, %2}";
6895 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6896 (const_string "incdec")
6897 (const_string "alu")))
6898 (set_attr "mode" "QI")])
6900 (define_insn "*addqi_ext_2"
6901 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6906 (match_operand 1 "ext_register_operand" "%0")
6910 (match_operand 2 "ext_register_operand" "Q")
6913 (clobber (reg:CC FLAGS_REG))]
6915 "add{b}\t{%h2, %h0|%h0, %h2}"
6916 [(set_attr "type" "alu")
6917 (set_attr "mode" "QI")])
6919 ;; The patterns that match these are at the end of this file.
6921 (define_expand "addxf3"
6922 [(set (match_operand:XF 0 "register_operand" "")
6923 (plus:XF (match_operand:XF 1 "register_operand" "")
6924 (match_operand:XF 2 "register_operand" "")))]
6928 (define_expand "add<mode>3"
6929 [(set (match_operand:MODEF 0 "register_operand" "")
6930 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
6931 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6932 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6935 ;; Subtract instructions
6937 ;; %%% splits for subditi3
6939 (define_expand "subti3"
6940 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6941 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6942 (match_operand:TI 2 "x86_64_general_operand" "")))
6943 (clobber (reg:CC FLAGS_REG))])]
6945 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6947 (define_insn "*subti3_1"
6948 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6949 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6950 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6951 (clobber (reg:CC FLAGS_REG))]
6952 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6956 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6957 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6958 (match_operand:TI 2 "x86_64_general_operand" "")))
6959 (clobber (reg:CC FLAGS_REG))]
6960 "TARGET_64BIT && reload_completed"
6961 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6962 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6963 (parallel [(set (match_dup 3)
6964 (minus:DI (match_dup 4)
6965 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6967 (clobber (reg:CC FLAGS_REG))])]
6968 "split_ti (operands+0, 1, operands+0, operands+3);
6969 split_ti (operands+1, 1, operands+1, operands+4);
6970 split_ti (operands+2, 1, operands+2, operands+5);")
6972 ;; %%% splits for subsidi3
6974 (define_expand "subdi3"
6975 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6976 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6977 (match_operand:DI 2 "x86_64_general_operand" "")))
6978 (clobber (reg:CC FLAGS_REG))])]
6980 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6982 (define_insn "*subdi3_1"
6983 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6984 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6985 (match_operand:DI 2 "general_operand" "roiF,riF")))
6986 (clobber (reg:CC FLAGS_REG))]
6987 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6991 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6992 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6993 (match_operand:DI 2 "general_operand" "")))
6994 (clobber (reg:CC FLAGS_REG))]
6995 "!TARGET_64BIT && reload_completed"
6996 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6997 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6998 (parallel [(set (match_dup 3)
6999 (minus:SI (match_dup 4)
7000 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7002 (clobber (reg:CC FLAGS_REG))])]
7003 "split_di (operands+0, 1, operands+0, operands+3);
7004 split_di (operands+1, 1, operands+1, operands+4);
7005 split_di (operands+2, 1, operands+2, operands+5);")
7007 (define_insn "subdi3_carry_rex64"
7008 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7009 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7010 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7011 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7012 (clobber (reg:CC FLAGS_REG))]
7013 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7014 "sbb{q}\t{%2, %0|%0, %2}"
7015 [(set_attr "type" "alu")
7016 (set_attr "pent_pair" "pu")
7017 (set_attr "mode" "DI")])
7019 (define_insn "*subdi_1_rex64"
7020 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7021 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7022 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7023 (clobber (reg:CC FLAGS_REG))]
7024 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7025 "sub{q}\t{%2, %0|%0, %2}"
7026 [(set_attr "type" "alu")
7027 (set_attr "mode" "DI")])
7029 (define_insn "*subdi_2_rex64"
7030 [(set (reg FLAGS_REG)
7032 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7033 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7035 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7036 (minus:DI (match_dup 1) (match_dup 2)))]
7037 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7038 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7039 "sub{q}\t{%2, %0|%0, %2}"
7040 [(set_attr "type" "alu")
7041 (set_attr "mode" "DI")])
7043 (define_insn "*subdi_3_rex63"
7044 [(set (reg FLAGS_REG)
7045 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7046 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7047 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7048 (minus:DI (match_dup 1) (match_dup 2)))]
7049 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7050 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7051 "sub{q}\t{%2, %0|%0, %2}"
7052 [(set_attr "type" "alu")
7053 (set_attr "mode" "DI")])
7055 (define_insn "subqi3_carry"
7056 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7057 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7058 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7059 (match_operand:QI 2 "general_operand" "qi,qm"))))
7060 (clobber (reg:CC FLAGS_REG))]
7061 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7062 "sbb{b}\t{%2, %0|%0, %2}"
7063 [(set_attr "type" "alu")
7064 (set_attr "pent_pair" "pu")
7065 (set_attr "mode" "QI")])
7067 (define_insn "subhi3_carry"
7068 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7069 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7070 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7071 (match_operand:HI 2 "general_operand" "ri,rm"))))
7072 (clobber (reg:CC FLAGS_REG))]
7073 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7074 "sbb{w}\t{%2, %0|%0, %2}"
7075 [(set_attr "type" "alu")
7076 (set_attr "pent_pair" "pu")
7077 (set_attr "mode" "HI")])
7079 (define_insn "subsi3_carry"
7080 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7081 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7082 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7083 (match_operand:SI 2 "general_operand" "ri,rm"))))
7084 (clobber (reg:CC FLAGS_REG))]
7085 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7086 "sbb{l}\t{%2, %0|%0, %2}"
7087 [(set_attr "type" "alu")
7088 (set_attr "pent_pair" "pu")
7089 (set_attr "mode" "SI")])
7091 (define_insn "subsi3_carry_zext"
7092 [(set (match_operand:DI 0 "register_operand" "=r")
7094 (minus:SI (match_operand:SI 1 "register_operand" "0")
7095 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7096 (match_operand:SI 2 "general_operand" "g")))))
7097 (clobber (reg:CC FLAGS_REG))]
7098 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7099 "sbb{l}\t{%2, %k0|%k0, %2}"
7100 [(set_attr "type" "alu")
7101 (set_attr "pent_pair" "pu")
7102 (set_attr "mode" "SI")])
7104 (define_expand "subsi3"
7105 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7106 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7107 (match_operand:SI 2 "general_operand" "")))
7108 (clobber (reg:CC FLAGS_REG))])]
7110 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7112 (define_insn "*subsi_1"
7113 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7114 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7115 (match_operand:SI 2 "general_operand" "ri,rm")))
7116 (clobber (reg:CC FLAGS_REG))]
7117 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7118 "sub{l}\t{%2, %0|%0, %2}"
7119 [(set_attr "type" "alu")
7120 (set_attr "mode" "SI")])
7122 (define_insn "*subsi_1_zext"
7123 [(set (match_operand:DI 0 "register_operand" "=r")
7125 (minus:SI (match_operand:SI 1 "register_operand" "0")
7126 (match_operand:SI 2 "general_operand" "g"))))
7127 (clobber (reg:CC FLAGS_REG))]
7128 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7129 "sub{l}\t{%2, %k0|%k0, %2}"
7130 [(set_attr "type" "alu")
7131 (set_attr "mode" "SI")])
7133 (define_insn "*subsi_2"
7134 [(set (reg FLAGS_REG)
7136 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7137 (match_operand:SI 2 "general_operand" "ri,rm"))
7139 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7140 (minus:SI (match_dup 1) (match_dup 2)))]
7141 "ix86_match_ccmode (insn, CCGOCmode)
7142 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7143 "sub{l}\t{%2, %0|%0, %2}"
7144 [(set_attr "type" "alu")
7145 (set_attr "mode" "SI")])
7147 (define_insn "*subsi_2_zext"
7148 [(set (reg FLAGS_REG)
7150 (minus:SI (match_operand:SI 1 "register_operand" "0")
7151 (match_operand:SI 2 "general_operand" "g"))
7153 (set (match_operand:DI 0 "register_operand" "=r")
7155 (minus:SI (match_dup 1)
7157 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7158 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7159 "sub{l}\t{%2, %k0|%k0, %2}"
7160 [(set_attr "type" "alu")
7161 (set_attr "mode" "SI")])
7163 (define_insn "*subsi_3"
7164 [(set (reg FLAGS_REG)
7165 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7166 (match_operand:SI 2 "general_operand" "ri,rm")))
7167 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7168 (minus:SI (match_dup 1) (match_dup 2)))]
7169 "ix86_match_ccmode (insn, CCmode)
7170 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7171 "sub{l}\t{%2, %0|%0, %2}"
7172 [(set_attr "type" "alu")
7173 (set_attr "mode" "SI")])
7175 (define_insn "*subsi_3_zext"
7176 [(set (reg FLAGS_REG)
7177 (compare (match_operand:SI 1 "register_operand" "0")
7178 (match_operand:SI 2 "general_operand" "g")))
7179 (set (match_operand:DI 0 "register_operand" "=r")
7181 (minus:SI (match_dup 1)
7183 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7184 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7185 "sub{l}\t{%2, %1|%1, %2}"
7186 [(set_attr "type" "alu")
7187 (set_attr "mode" "DI")])
7189 (define_expand "subhi3"
7190 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7191 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7192 (match_operand:HI 2 "general_operand" "")))
7193 (clobber (reg:CC FLAGS_REG))])]
7194 "TARGET_HIMODE_MATH"
7195 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7197 (define_insn "*subhi_1"
7198 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7199 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7200 (match_operand:HI 2 "general_operand" "ri,rm")))
7201 (clobber (reg:CC FLAGS_REG))]
7202 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7203 "sub{w}\t{%2, %0|%0, %2}"
7204 [(set_attr "type" "alu")
7205 (set_attr "mode" "HI")])
7207 (define_insn "*subhi_2"
7208 [(set (reg FLAGS_REG)
7210 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7211 (match_operand:HI 2 "general_operand" "ri,rm"))
7213 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7214 (minus:HI (match_dup 1) (match_dup 2)))]
7215 "ix86_match_ccmode (insn, CCGOCmode)
7216 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7217 "sub{w}\t{%2, %0|%0, %2}"
7218 [(set_attr "type" "alu")
7219 (set_attr "mode" "HI")])
7221 (define_insn "*subhi_3"
7222 [(set (reg FLAGS_REG)
7223 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7224 (match_operand:HI 2 "general_operand" "ri,rm")))
7225 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7226 (minus:HI (match_dup 1) (match_dup 2)))]
7227 "ix86_match_ccmode (insn, CCmode)
7228 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7229 "sub{w}\t{%2, %0|%0, %2}"
7230 [(set_attr "type" "alu")
7231 (set_attr "mode" "HI")])
7233 (define_expand "subqi3"
7234 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7235 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7236 (match_operand:QI 2 "general_operand" "")))
7237 (clobber (reg:CC FLAGS_REG))])]
7238 "TARGET_QIMODE_MATH"
7239 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7241 (define_insn "*subqi_1"
7242 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7243 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7244 (match_operand:QI 2 "general_operand" "qn,qmn")))
7245 (clobber (reg:CC FLAGS_REG))]
7246 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7247 "sub{b}\t{%2, %0|%0, %2}"
7248 [(set_attr "type" "alu")
7249 (set_attr "mode" "QI")])
7251 (define_insn "*subqi_1_slp"
7252 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7253 (minus:QI (match_dup 0)
7254 (match_operand:QI 1 "general_operand" "qn,qmn")))
7255 (clobber (reg:CC FLAGS_REG))]
7256 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7257 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7258 "sub{b}\t{%1, %0|%0, %1}"
7259 [(set_attr "type" "alu1")
7260 (set_attr "mode" "QI")])
7262 (define_insn "*subqi_2"
7263 [(set (reg FLAGS_REG)
7265 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7266 (match_operand:QI 2 "general_operand" "qi,qm"))
7268 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7269 (minus:HI (match_dup 1) (match_dup 2)))]
7270 "ix86_match_ccmode (insn, CCGOCmode)
7271 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7272 "sub{b}\t{%2, %0|%0, %2}"
7273 [(set_attr "type" "alu")
7274 (set_attr "mode" "QI")])
7276 (define_insn "*subqi_3"
7277 [(set (reg FLAGS_REG)
7278 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7279 (match_operand:QI 2 "general_operand" "qi,qm")))
7280 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7281 (minus:HI (match_dup 1) (match_dup 2)))]
7282 "ix86_match_ccmode (insn, CCmode)
7283 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7284 "sub{b}\t{%2, %0|%0, %2}"
7285 [(set_attr "type" "alu")
7286 (set_attr "mode" "QI")])
7288 ;; The patterns that match these are at the end of this file.
7290 (define_expand "subxf3"
7291 [(set (match_operand:XF 0 "register_operand" "")
7292 (minus:XF (match_operand:XF 1 "register_operand" "")
7293 (match_operand:XF 2 "register_operand" "")))]
7297 (define_expand "sub<mode>3"
7298 [(set (match_operand:MODEF 0 "register_operand" "")
7299 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7300 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7301 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7304 ;; Multiply instructions
7306 (define_expand "muldi3"
7307 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7308 (mult:DI (match_operand:DI 1 "register_operand" "")
7309 (match_operand:DI 2 "x86_64_general_operand" "")))
7310 (clobber (reg:CC FLAGS_REG))])]
7315 ;; IMUL reg64, reg64, imm8 Direct
7316 ;; IMUL reg64, mem64, imm8 VectorPath
7317 ;; IMUL reg64, reg64, imm32 Direct
7318 ;; IMUL reg64, mem64, imm32 VectorPath
7319 ;; IMUL reg64, reg64 Direct
7320 ;; IMUL reg64, mem64 Direct
7322 (define_insn "*muldi3_1_rex64"
7323 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7324 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7325 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7326 (clobber (reg:CC FLAGS_REG))]
7328 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7330 imul{q}\t{%2, %1, %0|%0, %1, %2}
7331 imul{q}\t{%2, %1, %0|%0, %1, %2}
7332 imul{q}\t{%2, %0|%0, %2}"
7333 [(set_attr "type" "imul")
7334 (set_attr "prefix_0f" "0,0,1")
7335 (set (attr "athlon_decode")
7336 (cond [(eq_attr "cpu" "athlon")
7337 (const_string "vector")
7338 (eq_attr "alternative" "1")
7339 (const_string "vector")
7340 (and (eq_attr "alternative" "2")
7341 (match_operand 1 "memory_operand" ""))
7342 (const_string "vector")]
7343 (const_string "direct")))
7344 (set (attr "amdfam10_decode")
7345 (cond [(and (eq_attr "alternative" "0,1")
7346 (match_operand 1 "memory_operand" ""))
7347 (const_string "vector")]
7348 (const_string "direct")))
7349 (set_attr "mode" "DI")])
7351 (define_expand "mulsi3"
7352 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7353 (mult:SI (match_operand:SI 1 "register_operand" "")
7354 (match_operand:SI 2 "general_operand" "")))
7355 (clobber (reg:CC FLAGS_REG))])]
7360 ;; IMUL reg32, reg32, imm8 Direct
7361 ;; IMUL reg32, mem32, imm8 VectorPath
7362 ;; IMUL reg32, reg32, imm32 Direct
7363 ;; IMUL reg32, mem32, imm32 VectorPath
7364 ;; IMUL reg32, reg32 Direct
7365 ;; IMUL reg32, mem32 Direct
7367 (define_insn "*mulsi3_1"
7368 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7369 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7370 (match_operand:SI 2 "general_operand" "K,i,mr")))
7371 (clobber (reg:CC FLAGS_REG))]
7372 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7374 imul{l}\t{%2, %1, %0|%0, %1, %2}
7375 imul{l}\t{%2, %1, %0|%0, %1, %2}
7376 imul{l}\t{%2, %0|%0, %2}"
7377 [(set_attr "type" "imul")
7378 (set_attr "prefix_0f" "0,0,1")
7379 (set (attr "athlon_decode")
7380 (cond [(eq_attr "cpu" "athlon")
7381 (const_string "vector")
7382 (eq_attr "alternative" "1")
7383 (const_string "vector")
7384 (and (eq_attr "alternative" "2")
7385 (match_operand 1 "memory_operand" ""))
7386 (const_string "vector")]
7387 (const_string "direct")))
7388 (set (attr "amdfam10_decode")
7389 (cond [(and (eq_attr "alternative" "0,1")
7390 (match_operand 1 "memory_operand" ""))
7391 (const_string "vector")]
7392 (const_string "direct")))
7393 (set_attr "mode" "SI")])
7395 (define_insn "*mulsi3_1_zext"
7396 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7398 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7399 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7400 (clobber (reg:CC FLAGS_REG))]
7402 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7404 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7405 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7406 imul{l}\t{%2, %k0|%k0, %2}"
7407 [(set_attr "type" "imul")
7408 (set_attr "prefix_0f" "0,0,1")
7409 (set (attr "athlon_decode")
7410 (cond [(eq_attr "cpu" "athlon")
7411 (const_string "vector")
7412 (eq_attr "alternative" "1")
7413 (const_string "vector")
7414 (and (eq_attr "alternative" "2")
7415 (match_operand 1 "memory_operand" ""))
7416 (const_string "vector")]
7417 (const_string "direct")))
7418 (set (attr "amdfam10_decode")
7419 (cond [(and (eq_attr "alternative" "0,1")
7420 (match_operand 1 "memory_operand" ""))
7421 (const_string "vector")]
7422 (const_string "direct")))
7423 (set_attr "mode" "SI")])
7425 (define_expand "mulhi3"
7426 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7427 (mult:HI (match_operand:HI 1 "register_operand" "")
7428 (match_operand:HI 2 "general_operand" "")))
7429 (clobber (reg:CC FLAGS_REG))])]
7430 "TARGET_HIMODE_MATH"
7434 ;; IMUL reg16, reg16, imm8 VectorPath
7435 ;; IMUL reg16, mem16, imm8 VectorPath
7436 ;; IMUL reg16, reg16, imm16 VectorPath
7437 ;; IMUL reg16, mem16, imm16 VectorPath
7438 ;; IMUL reg16, reg16 Direct
7439 ;; IMUL reg16, mem16 Direct
7440 (define_insn "*mulhi3_1"
7441 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7442 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7443 (match_operand:HI 2 "general_operand" "K,i,mr")))
7444 (clobber (reg:CC FLAGS_REG))]
7445 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7447 imul{w}\t{%2, %1, %0|%0, %1, %2}
7448 imul{w}\t{%2, %1, %0|%0, %1, %2}
7449 imul{w}\t{%2, %0|%0, %2}"
7450 [(set_attr "type" "imul")
7451 (set_attr "prefix_0f" "0,0,1")
7452 (set (attr "athlon_decode")
7453 (cond [(eq_attr "cpu" "athlon")
7454 (const_string "vector")
7455 (eq_attr "alternative" "1,2")
7456 (const_string "vector")]
7457 (const_string "direct")))
7458 (set (attr "amdfam10_decode")
7459 (cond [(eq_attr "alternative" "0,1")
7460 (const_string "vector")]
7461 (const_string "direct")))
7462 (set_attr "mode" "HI")])
7464 (define_expand "mulqi3"
7465 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7466 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7467 (match_operand:QI 2 "register_operand" "")))
7468 (clobber (reg:CC FLAGS_REG))])]
7469 "TARGET_QIMODE_MATH"
7476 (define_insn "*mulqi3_1"
7477 [(set (match_operand:QI 0 "register_operand" "=a")
7478 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7479 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7480 (clobber (reg:CC FLAGS_REG))]
7482 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7484 [(set_attr "type" "imul")
7485 (set_attr "length_immediate" "0")
7486 (set (attr "athlon_decode")
7487 (if_then_else (eq_attr "cpu" "athlon")
7488 (const_string "vector")
7489 (const_string "direct")))
7490 (set_attr "amdfam10_decode" "direct")
7491 (set_attr "mode" "QI")])
7493 (define_expand "umulqihi3"
7494 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7495 (mult:HI (zero_extend:HI
7496 (match_operand:QI 1 "nonimmediate_operand" ""))
7498 (match_operand:QI 2 "register_operand" ""))))
7499 (clobber (reg:CC FLAGS_REG))])]
7500 "TARGET_QIMODE_MATH"
7503 (define_insn "*umulqihi3_1"
7504 [(set (match_operand:HI 0 "register_operand" "=a")
7505 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7506 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7507 (clobber (reg:CC FLAGS_REG))]
7509 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7511 [(set_attr "type" "imul")
7512 (set_attr "length_immediate" "0")
7513 (set (attr "athlon_decode")
7514 (if_then_else (eq_attr "cpu" "athlon")
7515 (const_string "vector")
7516 (const_string "direct")))
7517 (set_attr "amdfam10_decode" "direct")
7518 (set_attr "mode" "QI")])
7520 (define_expand "mulqihi3"
7521 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7522 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7523 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7524 (clobber (reg:CC FLAGS_REG))])]
7525 "TARGET_QIMODE_MATH"
7528 (define_insn "*mulqihi3_insn"
7529 [(set (match_operand:HI 0 "register_operand" "=a")
7530 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7531 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7532 (clobber (reg:CC FLAGS_REG))]
7534 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7536 [(set_attr "type" "imul")
7537 (set_attr "length_immediate" "0")
7538 (set (attr "athlon_decode")
7539 (if_then_else (eq_attr "cpu" "athlon")
7540 (const_string "vector")
7541 (const_string "direct")))
7542 (set_attr "amdfam10_decode" "direct")
7543 (set_attr "mode" "QI")])
7545 (define_expand "umulditi3"
7546 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7547 (mult:TI (zero_extend:TI
7548 (match_operand:DI 1 "nonimmediate_operand" ""))
7550 (match_operand:DI 2 "register_operand" ""))))
7551 (clobber (reg:CC FLAGS_REG))])]
7555 (define_insn "*umulditi3_insn"
7556 [(set (match_operand:TI 0 "register_operand" "=A")
7557 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7558 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7559 (clobber (reg:CC FLAGS_REG))]
7561 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7563 [(set_attr "type" "imul")
7564 (set_attr "length_immediate" "0")
7565 (set (attr "athlon_decode")
7566 (if_then_else (eq_attr "cpu" "athlon")
7567 (const_string "vector")
7568 (const_string "double")))
7569 (set_attr "amdfam10_decode" "double")
7570 (set_attr "mode" "DI")])
7572 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7573 (define_expand "umulsidi3"
7574 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7575 (mult:DI (zero_extend:DI
7576 (match_operand:SI 1 "nonimmediate_operand" ""))
7578 (match_operand:SI 2 "register_operand" ""))))
7579 (clobber (reg:CC FLAGS_REG))])]
7583 (define_insn "*umulsidi3_insn"
7584 [(set (match_operand:DI 0 "register_operand" "=A")
7585 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7586 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7587 (clobber (reg:CC FLAGS_REG))]
7589 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7591 [(set_attr "type" "imul")
7592 (set_attr "length_immediate" "0")
7593 (set (attr "athlon_decode")
7594 (if_then_else (eq_attr "cpu" "athlon")
7595 (const_string "vector")
7596 (const_string "double")))
7597 (set_attr "amdfam10_decode" "double")
7598 (set_attr "mode" "SI")])
7600 (define_expand "mulditi3"
7601 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7602 (mult:TI (sign_extend:TI
7603 (match_operand:DI 1 "nonimmediate_operand" ""))
7605 (match_operand:DI 2 "register_operand" ""))))
7606 (clobber (reg:CC FLAGS_REG))])]
7610 (define_insn "*mulditi3_insn"
7611 [(set (match_operand:TI 0 "register_operand" "=A")
7612 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7613 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7614 (clobber (reg:CC FLAGS_REG))]
7616 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7618 [(set_attr "type" "imul")
7619 (set_attr "length_immediate" "0")
7620 (set (attr "athlon_decode")
7621 (if_then_else (eq_attr "cpu" "athlon")
7622 (const_string "vector")
7623 (const_string "double")))
7624 (set_attr "amdfam10_decode" "double")
7625 (set_attr "mode" "DI")])
7627 (define_expand "mulsidi3"
7628 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7629 (mult:DI (sign_extend:DI
7630 (match_operand:SI 1 "nonimmediate_operand" ""))
7632 (match_operand:SI 2 "register_operand" ""))))
7633 (clobber (reg:CC FLAGS_REG))])]
7637 (define_insn "*mulsidi3_insn"
7638 [(set (match_operand:DI 0 "register_operand" "=A")
7639 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7640 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7641 (clobber (reg:CC FLAGS_REG))]
7643 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7645 [(set_attr "type" "imul")
7646 (set_attr "length_immediate" "0")
7647 (set (attr "athlon_decode")
7648 (if_then_else (eq_attr "cpu" "athlon")
7649 (const_string "vector")
7650 (const_string "double")))
7651 (set_attr "amdfam10_decode" "double")
7652 (set_attr "mode" "SI")])
7654 (define_expand "umuldi3_highpart"
7655 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7658 (mult:TI (zero_extend:TI
7659 (match_operand:DI 1 "nonimmediate_operand" ""))
7661 (match_operand:DI 2 "register_operand" "")))
7663 (clobber (match_scratch:DI 3 ""))
7664 (clobber (reg:CC FLAGS_REG))])]
7668 (define_insn "*umuldi3_highpart_rex64"
7669 [(set (match_operand:DI 0 "register_operand" "=d")
7672 (mult:TI (zero_extend:TI
7673 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7675 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7677 (clobber (match_scratch:DI 3 "=1"))
7678 (clobber (reg:CC FLAGS_REG))]
7680 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7682 [(set_attr "type" "imul")
7683 (set_attr "length_immediate" "0")
7684 (set (attr "athlon_decode")
7685 (if_then_else (eq_attr "cpu" "athlon")
7686 (const_string "vector")
7687 (const_string "double")))
7688 (set_attr "amdfam10_decode" "double")
7689 (set_attr "mode" "DI")])
7691 (define_expand "umulsi3_highpart"
7692 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7695 (mult:DI (zero_extend:DI
7696 (match_operand:SI 1 "nonimmediate_operand" ""))
7698 (match_operand:SI 2 "register_operand" "")))
7700 (clobber (match_scratch:SI 3 ""))
7701 (clobber (reg:CC FLAGS_REG))])]
7705 (define_insn "*umulsi3_highpart_insn"
7706 [(set (match_operand:SI 0 "register_operand" "=d")
7709 (mult:DI (zero_extend:DI
7710 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7712 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7714 (clobber (match_scratch:SI 3 "=1"))
7715 (clobber (reg:CC FLAGS_REG))]
7716 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7718 [(set_attr "type" "imul")
7719 (set_attr "length_immediate" "0")
7720 (set (attr "athlon_decode")
7721 (if_then_else (eq_attr "cpu" "athlon")
7722 (const_string "vector")
7723 (const_string "double")))
7724 (set_attr "amdfam10_decode" "double")
7725 (set_attr "mode" "SI")])
7727 (define_insn "*umulsi3_highpart_zext"
7728 [(set (match_operand:DI 0 "register_operand" "=d")
7729 (zero_extend:DI (truncate:SI
7731 (mult:DI (zero_extend:DI
7732 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7734 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7736 (clobber (match_scratch:SI 3 "=1"))
7737 (clobber (reg:CC FLAGS_REG))]
7739 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7741 [(set_attr "type" "imul")
7742 (set_attr "length_immediate" "0")
7743 (set (attr "athlon_decode")
7744 (if_then_else (eq_attr "cpu" "athlon")
7745 (const_string "vector")
7746 (const_string "double")))
7747 (set_attr "amdfam10_decode" "double")
7748 (set_attr "mode" "SI")])
7750 (define_expand "smuldi3_highpart"
7751 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7754 (mult:TI (sign_extend:TI
7755 (match_operand:DI 1 "nonimmediate_operand" ""))
7757 (match_operand:DI 2 "register_operand" "")))
7759 (clobber (match_scratch:DI 3 ""))
7760 (clobber (reg:CC FLAGS_REG))])]
7764 (define_insn "*smuldi3_highpart_rex64"
7765 [(set (match_operand:DI 0 "register_operand" "=d")
7768 (mult:TI (sign_extend:TI
7769 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7771 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7773 (clobber (match_scratch:DI 3 "=1"))
7774 (clobber (reg:CC FLAGS_REG))]
7776 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7778 [(set_attr "type" "imul")
7779 (set (attr "athlon_decode")
7780 (if_then_else (eq_attr "cpu" "athlon")
7781 (const_string "vector")
7782 (const_string "double")))
7783 (set_attr "amdfam10_decode" "double")
7784 (set_attr "mode" "DI")])
7786 (define_expand "smulsi3_highpart"
7787 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7790 (mult:DI (sign_extend:DI
7791 (match_operand:SI 1 "nonimmediate_operand" ""))
7793 (match_operand:SI 2 "register_operand" "")))
7795 (clobber (match_scratch:SI 3 ""))
7796 (clobber (reg:CC FLAGS_REG))])]
7800 (define_insn "*smulsi3_highpart_insn"
7801 [(set (match_operand:SI 0 "register_operand" "=d")
7804 (mult:DI (sign_extend:DI
7805 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7807 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7809 (clobber (match_scratch:SI 3 "=1"))
7810 (clobber (reg:CC FLAGS_REG))]
7811 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7813 [(set_attr "type" "imul")
7814 (set (attr "athlon_decode")
7815 (if_then_else (eq_attr "cpu" "athlon")
7816 (const_string "vector")
7817 (const_string "double")))
7818 (set_attr "amdfam10_decode" "double")
7819 (set_attr "mode" "SI")])
7821 (define_insn "*smulsi3_highpart_zext"
7822 [(set (match_operand:DI 0 "register_operand" "=d")
7823 (zero_extend:DI (truncate:SI
7825 (mult:DI (sign_extend:DI
7826 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7828 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7830 (clobber (match_scratch:SI 3 "=1"))
7831 (clobber (reg:CC FLAGS_REG))]
7833 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7835 [(set_attr "type" "imul")
7836 (set (attr "athlon_decode")
7837 (if_then_else (eq_attr "cpu" "athlon")
7838 (const_string "vector")
7839 (const_string "double")))
7840 (set_attr "amdfam10_decode" "double")
7841 (set_attr "mode" "SI")])
7843 ;; The patterns that match these are at the end of this file.
7845 (define_expand "mulxf3"
7846 [(set (match_operand:XF 0 "register_operand" "")
7847 (mult:XF (match_operand:XF 1 "register_operand" "")
7848 (match_operand:XF 2 "register_operand" "")))]
7852 (define_expand "mul<mode>3"
7853 [(set (match_operand:MODEF 0 "register_operand" "")
7854 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7855 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7856 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7859 ;; Divide instructions
7861 (define_insn "divqi3"
7862 [(set (match_operand:QI 0 "register_operand" "=a")
7863 (div:QI (match_operand:HI 1 "register_operand" "0")
7864 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7865 (clobber (reg:CC FLAGS_REG))]
7866 "TARGET_QIMODE_MATH"
7868 [(set_attr "type" "idiv")
7869 (set_attr "mode" "QI")])
7871 (define_insn "udivqi3"
7872 [(set (match_operand:QI 0 "register_operand" "=a")
7873 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7874 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7875 (clobber (reg:CC FLAGS_REG))]
7876 "TARGET_QIMODE_MATH"
7878 [(set_attr "type" "idiv")
7879 (set_attr "mode" "QI")])
7881 ;; The patterns that match these are at the end of this file.
7883 (define_expand "divxf3"
7884 [(set (match_operand:XF 0 "register_operand" "")
7885 (div:XF (match_operand:XF 1 "register_operand" "")
7886 (match_operand:XF 2 "register_operand" "")))]
7890 (define_expand "divdf3"
7891 [(set (match_operand:DF 0 "register_operand" "")
7892 (div:DF (match_operand:DF 1 "register_operand" "")
7893 (match_operand:DF 2 "nonimmediate_operand" "")))]
7894 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7897 (define_expand "divsf3"
7898 [(set (match_operand:SF 0 "register_operand" "")
7899 (div:SF (match_operand:SF 1 "register_operand" "")
7900 (match_operand:SF 2 "nonimmediate_operand" "")))]
7901 "TARGET_80387 || TARGET_SSE_MATH"
7903 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
7904 && flag_finite_math_only && !flag_trapping_math
7905 && flag_unsafe_math_optimizations)
7907 ix86_emit_swdivsf (operands[0], operands[1],
7908 operands[2], SFmode);
7913 ;; Remainder instructions.
7915 (define_expand "divmoddi4"
7916 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7917 (div:DI (match_operand:DI 1 "register_operand" "")
7918 (match_operand:DI 2 "nonimmediate_operand" "")))
7919 (set (match_operand:DI 3 "register_operand" "")
7920 (mod:DI (match_dup 1) (match_dup 2)))
7921 (clobber (reg:CC FLAGS_REG))])]
7925 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7926 ;; Penalize eax case slightly because it results in worse scheduling
7928 (define_insn "*divmoddi4_nocltd_rex64"
7929 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7930 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7931 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7932 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7933 (mod:DI (match_dup 2) (match_dup 3)))
7934 (clobber (reg:CC FLAGS_REG))]
7935 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7937 [(set_attr "type" "multi")])
7939 (define_insn "*divmoddi4_cltd_rex64"
7940 [(set (match_operand:DI 0 "register_operand" "=a")
7941 (div:DI (match_operand:DI 2 "register_operand" "a")
7942 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7943 (set (match_operand:DI 1 "register_operand" "=&d")
7944 (mod:DI (match_dup 2) (match_dup 3)))
7945 (clobber (reg:CC FLAGS_REG))]
7946 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7948 [(set_attr "type" "multi")])
7950 (define_insn "*divmoddi_noext_rex64"
7951 [(set (match_operand:DI 0 "register_operand" "=a")
7952 (div:DI (match_operand:DI 1 "register_operand" "0")
7953 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7954 (set (match_operand:DI 3 "register_operand" "=d")
7955 (mod:DI (match_dup 1) (match_dup 2)))
7956 (use (match_operand:DI 4 "register_operand" "3"))
7957 (clobber (reg:CC FLAGS_REG))]
7960 [(set_attr "type" "idiv")
7961 (set_attr "mode" "DI")])
7964 [(set (match_operand:DI 0 "register_operand" "")
7965 (div:DI (match_operand:DI 1 "register_operand" "")
7966 (match_operand:DI 2 "nonimmediate_operand" "")))
7967 (set (match_operand:DI 3 "register_operand" "")
7968 (mod:DI (match_dup 1) (match_dup 2)))
7969 (clobber (reg:CC FLAGS_REG))]
7970 "TARGET_64BIT && reload_completed"
7971 [(parallel [(set (match_dup 3)
7972 (ashiftrt:DI (match_dup 4) (const_int 63)))
7973 (clobber (reg:CC FLAGS_REG))])
7974 (parallel [(set (match_dup 0)
7975 (div:DI (reg:DI 0) (match_dup 2)))
7977 (mod:DI (reg:DI 0) (match_dup 2)))
7979 (clobber (reg:CC FLAGS_REG))])]
7981 /* Avoid use of cltd in favor of a mov+shift. */
7982 if (!TARGET_USE_CLTD && !optimize_size)
7984 if (true_regnum (operands[1]))
7985 emit_move_insn (operands[0], operands[1]);
7987 emit_move_insn (operands[3], operands[1]);
7988 operands[4] = operands[3];
7992 gcc_assert (!true_regnum (operands[1]));
7993 operands[4] = operands[1];
7998 (define_expand "divmodsi4"
7999 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8000 (div:SI (match_operand:SI 1 "register_operand" "")
8001 (match_operand:SI 2 "nonimmediate_operand" "")))
8002 (set (match_operand:SI 3 "register_operand" "")
8003 (mod:SI (match_dup 1) (match_dup 2)))
8004 (clobber (reg:CC FLAGS_REG))])]
8008 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8009 ;; Penalize eax case slightly because it results in worse scheduling
8011 (define_insn "*divmodsi4_nocltd"
8012 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8013 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8014 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8015 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8016 (mod:SI (match_dup 2) (match_dup 3)))
8017 (clobber (reg:CC FLAGS_REG))]
8018 "!optimize_size && !TARGET_USE_CLTD"
8020 [(set_attr "type" "multi")])
8022 (define_insn "*divmodsi4_cltd"
8023 [(set (match_operand:SI 0 "register_operand" "=a")
8024 (div:SI (match_operand:SI 2 "register_operand" "a")
8025 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8026 (set (match_operand:SI 1 "register_operand" "=&d")
8027 (mod:SI (match_dup 2) (match_dup 3)))
8028 (clobber (reg:CC FLAGS_REG))]
8029 "optimize_size || TARGET_USE_CLTD"
8031 [(set_attr "type" "multi")])
8033 (define_insn "*divmodsi_noext"
8034 [(set (match_operand:SI 0 "register_operand" "=a")
8035 (div:SI (match_operand:SI 1 "register_operand" "0")
8036 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8037 (set (match_operand:SI 3 "register_operand" "=d")
8038 (mod:SI (match_dup 1) (match_dup 2)))
8039 (use (match_operand:SI 4 "register_operand" "3"))
8040 (clobber (reg:CC FLAGS_REG))]
8043 [(set_attr "type" "idiv")
8044 (set_attr "mode" "SI")])
8047 [(set (match_operand:SI 0 "register_operand" "")
8048 (div:SI (match_operand:SI 1 "register_operand" "")
8049 (match_operand:SI 2 "nonimmediate_operand" "")))
8050 (set (match_operand:SI 3 "register_operand" "")
8051 (mod:SI (match_dup 1) (match_dup 2)))
8052 (clobber (reg:CC FLAGS_REG))]
8054 [(parallel [(set (match_dup 3)
8055 (ashiftrt:SI (match_dup 4) (const_int 31)))
8056 (clobber (reg:CC FLAGS_REG))])
8057 (parallel [(set (match_dup 0)
8058 (div:SI (reg:SI 0) (match_dup 2)))
8060 (mod:SI (reg:SI 0) (match_dup 2)))
8062 (clobber (reg:CC FLAGS_REG))])]
8064 /* Avoid use of cltd in favor of a mov+shift. */
8065 if (!TARGET_USE_CLTD && !optimize_size)
8067 if (true_regnum (operands[1]))
8068 emit_move_insn (operands[0], operands[1]);
8070 emit_move_insn (operands[3], operands[1]);
8071 operands[4] = operands[3];
8075 gcc_assert (!true_regnum (operands[1]));
8076 operands[4] = operands[1];
8080 (define_insn "divmodhi4"
8081 [(set (match_operand:HI 0 "register_operand" "=a")
8082 (div:HI (match_operand:HI 1 "register_operand" "0")
8083 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8084 (set (match_operand:HI 3 "register_operand" "=&d")
8085 (mod:HI (match_dup 1) (match_dup 2)))
8086 (clobber (reg:CC FLAGS_REG))]
8087 "TARGET_HIMODE_MATH"
8089 [(set_attr "type" "multi")
8090 (set_attr "length_immediate" "0")
8091 (set_attr "mode" "SI")])
8093 (define_insn "udivmoddi4"
8094 [(set (match_operand:DI 0 "register_operand" "=a")
8095 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8096 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8097 (set (match_operand:DI 3 "register_operand" "=&d")
8098 (umod:DI (match_dup 1) (match_dup 2)))
8099 (clobber (reg:CC FLAGS_REG))]
8101 "xor{q}\t%3, %3\;div{q}\t%2"
8102 [(set_attr "type" "multi")
8103 (set_attr "length_immediate" "0")
8104 (set_attr "mode" "DI")])
8106 (define_insn "*udivmoddi4_noext"
8107 [(set (match_operand:DI 0 "register_operand" "=a")
8108 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8109 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8110 (set (match_operand:DI 3 "register_operand" "=d")
8111 (umod:DI (match_dup 1) (match_dup 2)))
8113 (clobber (reg:CC FLAGS_REG))]
8116 [(set_attr "type" "idiv")
8117 (set_attr "mode" "DI")])
8120 [(set (match_operand:DI 0 "register_operand" "")
8121 (udiv:DI (match_operand:DI 1 "register_operand" "")
8122 (match_operand:DI 2 "nonimmediate_operand" "")))
8123 (set (match_operand:DI 3 "register_operand" "")
8124 (umod:DI (match_dup 1) (match_dup 2)))
8125 (clobber (reg:CC FLAGS_REG))]
8126 "TARGET_64BIT && reload_completed"
8127 [(set (match_dup 3) (const_int 0))
8128 (parallel [(set (match_dup 0)
8129 (udiv:DI (match_dup 1) (match_dup 2)))
8131 (umod:DI (match_dup 1) (match_dup 2)))
8133 (clobber (reg:CC FLAGS_REG))])]
8136 (define_insn "udivmodsi4"
8137 [(set (match_operand:SI 0 "register_operand" "=a")
8138 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8139 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8140 (set (match_operand:SI 3 "register_operand" "=&d")
8141 (umod:SI (match_dup 1) (match_dup 2)))
8142 (clobber (reg:CC FLAGS_REG))]
8144 "xor{l}\t%3, %3\;div{l}\t%2"
8145 [(set_attr "type" "multi")
8146 (set_attr "length_immediate" "0")
8147 (set_attr "mode" "SI")])
8149 (define_insn "*udivmodsi4_noext"
8150 [(set (match_operand:SI 0 "register_operand" "=a")
8151 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8152 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8153 (set (match_operand:SI 3 "register_operand" "=d")
8154 (umod:SI (match_dup 1) (match_dup 2)))
8156 (clobber (reg:CC FLAGS_REG))]
8159 [(set_attr "type" "idiv")
8160 (set_attr "mode" "SI")])
8163 [(set (match_operand:SI 0 "register_operand" "")
8164 (udiv:SI (match_operand:SI 1 "register_operand" "")
8165 (match_operand:SI 2 "nonimmediate_operand" "")))
8166 (set (match_operand:SI 3 "register_operand" "")
8167 (umod:SI (match_dup 1) (match_dup 2)))
8168 (clobber (reg:CC FLAGS_REG))]
8170 [(set (match_dup 3) (const_int 0))
8171 (parallel [(set (match_dup 0)
8172 (udiv:SI (match_dup 1) (match_dup 2)))
8174 (umod:SI (match_dup 1) (match_dup 2)))
8176 (clobber (reg:CC FLAGS_REG))])]
8179 (define_expand "udivmodhi4"
8180 [(set (match_dup 4) (const_int 0))
8181 (parallel [(set (match_operand:HI 0 "register_operand" "")
8182 (udiv:HI (match_operand:HI 1 "register_operand" "")
8183 (match_operand:HI 2 "nonimmediate_operand" "")))
8184 (set (match_operand:HI 3 "register_operand" "")
8185 (umod:HI (match_dup 1) (match_dup 2)))
8187 (clobber (reg:CC FLAGS_REG))])]
8188 "TARGET_HIMODE_MATH"
8189 "operands[4] = gen_reg_rtx (HImode);")
8191 (define_insn "*udivmodhi_noext"
8192 [(set (match_operand:HI 0 "register_operand" "=a")
8193 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8194 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8195 (set (match_operand:HI 3 "register_operand" "=d")
8196 (umod:HI (match_dup 1) (match_dup 2)))
8197 (use (match_operand:HI 4 "register_operand" "3"))
8198 (clobber (reg:CC FLAGS_REG))]
8201 [(set_attr "type" "idiv")
8202 (set_attr "mode" "HI")])
8204 ;; We cannot use div/idiv for double division, because it causes
8205 ;; "division by zero" on the overflow and that's not what we expect
8206 ;; from truncate. Because true (non truncating) double division is
8207 ;; never generated, we can't create this insn anyway.
8210 ; [(set (match_operand:SI 0 "register_operand" "=a")
8212 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8214 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8215 ; (set (match_operand:SI 3 "register_operand" "=d")
8217 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8218 ; (clobber (reg:CC FLAGS_REG))]
8220 ; "div{l}\t{%2, %0|%0, %2}"
8221 ; [(set_attr "type" "idiv")])
8223 ;;- Logical AND instructions
8225 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8226 ;; Note that this excludes ah.
8228 (define_insn "*testdi_1_rex64"
8229 [(set (reg FLAGS_REG)
8231 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8232 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8234 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8235 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8237 test{l}\t{%k1, %k0|%k0, %k1}
8238 test{l}\t{%k1, %k0|%k0, %k1}
8239 test{q}\t{%1, %0|%0, %1}
8240 test{q}\t{%1, %0|%0, %1}
8241 test{q}\t{%1, %0|%0, %1}"
8242 [(set_attr "type" "test")
8243 (set_attr "modrm" "0,1,0,1,1")
8244 (set_attr "mode" "SI,SI,DI,DI,DI")
8245 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8247 (define_insn "testsi_1"
8248 [(set (reg FLAGS_REG)
8250 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8251 (match_operand:SI 1 "general_operand" "in,in,rin"))
8253 "ix86_match_ccmode (insn, CCNOmode)
8254 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8255 "test{l}\t{%1, %0|%0, %1}"
8256 [(set_attr "type" "test")
8257 (set_attr "modrm" "0,1,1")
8258 (set_attr "mode" "SI")
8259 (set_attr "pent_pair" "uv,np,uv")])
8261 (define_expand "testsi_ccno_1"
8262 [(set (reg:CCNO FLAGS_REG)
8264 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8265 (match_operand:SI 1 "nonmemory_operand" ""))
8270 (define_insn "*testhi_1"
8271 [(set (reg FLAGS_REG)
8272 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8273 (match_operand:HI 1 "general_operand" "n,n,rn"))
8275 "ix86_match_ccmode (insn, CCNOmode)
8276 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8277 "test{w}\t{%1, %0|%0, %1}"
8278 [(set_attr "type" "test")
8279 (set_attr "modrm" "0,1,1")
8280 (set_attr "mode" "HI")
8281 (set_attr "pent_pair" "uv,np,uv")])
8283 (define_expand "testqi_ccz_1"
8284 [(set (reg:CCZ FLAGS_REG)
8285 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8286 (match_operand:QI 1 "nonmemory_operand" ""))
8291 (define_insn "*testqi_1_maybe_si"
8292 [(set (reg FLAGS_REG)
8295 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8296 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8298 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8299 && ix86_match_ccmode (insn,
8300 CONST_INT_P (operands[1])
8301 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8303 if (which_alternative == 3)
8305 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8306 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8307 return "test{l}\t{%1, %k0|%k0, %1}";
8309 return "test{b}\t{%1, %0|%0, %1}";
8311 [(set_attr "type" "test")
8312 (set_attr "modrm" "0,1,1,1")
8313 (set_attr "mode" "QI,QI,QI,SI")
8314 (set_attr "pent_pair" "uv,np,uv,np")])
8316 (define_insn "*testqi_1"
8317 [(set (reg FLAGS_REG)
8320 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8321 (match_operand:QI 1 "general_operand" "n,n,qn"))
8323 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8324 && ix86_match_ccmode (insn, CCNOmode)"
8325 "test{b}\t{%1, %0|%0, %1}"
8326 [(set_attr "type" "test")
8327 (set_attr "modrm" "0,1,1")
8328 (set_attr "mode" "QI")
8329 (set_attr "pent_pair" "uv,np,uv")])
8331 (define_expand "testqi_ext_ccno_0"
8332 [(set (reg:CCNO FLAGS_REG)
8336 (match_operand 0 "ext_register_operand" "")
8339 (match_operand 1 "const_int_operand" ""))
8344 (define_insn "*testqi_ext_0"
8345 [(set (reg FLAGS_REG)
8349 (match_operand 0 "ext_register_operand" "Q")
8352 (match_operand 1 "const_int_operand" "n"))
8354 "ix86_match_ccmode (insn, CCNOmode)"
8355 "test{b}\t{%1, %h0|%h0, %1}"
8356 [(set_attr "type" "test")
8357 (set_attr "mode" "QI")
8358 (set_attr "length_immediate" "1")
8359 (set_attr "pent_pair" "np")])
8361 (define_insn "*testqi_ext_1"
8362 [(set (reg FLAGS_REG)
8366 (match_operand 0 "ext_register_operand" "Q")
8370 (match_operand:QI 1 "general_operand" "Qm")))
8372 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8373 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8374 "test{b}\t{%1, %h0|%h0, %1}"
8375 [(set_attr "type" "test")
8376 (set_attr "mode" "QI")])
8378 (define_insn "*testqi_ext_1_rex64"
8379 [(set (reg FLAGS_REG)
8383 (match_operand 0 "ext_register_operand" "Q")
8387 (match_operand:QI 1 "register_operand" "Q")))
8389 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8390 "test{b}\t{%1, %h0|%h0, %1}"
8391 [(set_attr "type" "test")
8392 (set_attr "mode" "QI")])
8394 (define_insn "*testqi_ext_2"
8395 [(set (reg FLAGS_REG)
8399 (match_operand 0 "ext_register_operand" "Q")
8403 (match_operand 1 "ext_register_operand" "Q")
8407 "ix86_match_ccmode (insn, CCNOmode)"
8408 "test{b}\t{%h1, %h0|%h0, %h1}"
8409 [(set_attr "type" "test")
8410 (set_attr "mode" "QI")])
8412 ;; Combine likes to form bit extractions for some tests. Humor it.
8413 (define_insn "*testqi_ext_3"
8414 [(set (reg FLAGS_REG)
8415 (compare (zero_extract:SI
8416 (match_operand 0 "nonimmediate_operand" "rm")
8417 (match_operand:SI 1 "const_int_operand" "")
8418 (match_operand:SI 2 "const_int_operand" ""))
8420 "ix86_match_ccmode (insn, CCNOmode)
8421 && INTVAL (operands[1]) > 0
8422 && INTVAL (operands[2]) >= 0
8423 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8424 && (GET_MODE (operands[0]) == SImode
8425 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8426 || GET_MODE (operands[0]) == HImode
8427 || GET_MODE (operands[0]) == QImode)"
8430 (define_insn "*testqi_ext_3_rex64"
8431 [(set (reg FLAGS_REG)
8432 (compare (zero_extract:DI
8433 (match_operand 0 "nonimmediate_operand" "rm")
8434 (match_operand:DI 1 "const_int_operand" "")
8435 (match_operand:DI 2 "const_int_operand" ""))
8438 && ix86_match_ccmode (insn, CCNOmode)
8439 && INTVAL (operands[1]) > 0
8440 && INTVAL (operands[2]) >= 0
8441 /* Ensure that resulting mask is zero or sign extended operand. */
8442 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8443 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8444 && INTVAL (operands[1]) > 32))
8445 && (GET_MODE (operands[0]) == SImode
8446 || GET_MODE (operands[0]) == DImode
8447 || GET_MODE (operands[0]) == HImode
8448 || GET_MODE (operands[0]) == QImode)"
8452 [(set (match_operand 0 "flags_reg_operand" "")
8453 (match_operator 1 "compare_operator"
8455 (match_operand 2 "nonimmediate_operand" "")
8456 (match_operand 3 "const_int_operand" "")
8457 (match_operand 4 "const_int_operand" ""))
8459 "ix86_match_ccmode (insn, CCNOmode)"
8460 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8462 rtx val = operands[2];
8463 HOST_WIDE_INT len = INTVAL (operands[3]);
8464 HOST_WIDE_INT pos = INTVAL (operands[4]);
8466 enum machine_mode mode, submode;
8468 mode = GET_MODE (val);
8471 /* ??? Combine likes to put non-volatile mem extractions in QImode
8472 no matter the size of the test. So find a mode that works. */
8473 if (! MEM_VOLATILE_P (val))
8475 mode = smallest_mode_for_size (pos + len, MODE_INT);
8476 val = adjust_address (val, mode, 0);
8479 else if (GET_CODE (val) == SUBREG
8480 && (submode = GET_MODE (SUBREG_REG (val)),
8481 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8482 && pos + len <= GET_MODE_BITSIZE (submode))
8484 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8486 val = SUBREG_REG (val);
8488 else if (mode == HImode && pos + len <= 8)
8490 /* Small HImode tests can be converted to QImode. */
8492 val = gen_lowpart (QImode, val);
8495 if (len == HOST_BITS_PER_WIDE_INT)
8498 mask = ((HOST_WIDE_INT)1 << len) - 1;
8501 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8504 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8505 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8506 ;; this is relatively important trick.
8507 ;; Do the conversion only post-reload to avoid limiting of the register class
8510 [(set (match_operand 0 "flags_reg_operand" "")
8511 (match_operator 1 "compare_operator"
8512 [(and (match_operand 2 "register_operand" "")
8513 (match_operand 3 "const_int_operand" ""))
8516 && QI_REG_P (operands[2])
8517 && GET_MODE (operands[2]) != QImode
8518 && ((ix86_match_ccmode (insn, CCZmode)
8519 && !(INTVAL (operands[3]) & ~(255 << 8)))
8520 || (ix86_match_ccmode (insn, CCNOmode)
8521 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8524 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8527 "operands[2] = gen_lowpart (SImode, operands[2]);
8528 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8531 [(set (match_operand 0 "flags_reg_operand" "")
8532 (match_operator 1 "compare_operator"
8533 [(and (match_operand 2 "nonimmediate_operand" "")
8534 (match_operand 3 "const_int_operand" ""))
8537 && GET_MODE (operands[2]) != QImode
8538 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8539 && ((ix86_match_ccmode (insn, CCZmode)
8540 && !(INTVAL (operands[3]) & ~255))
8541 || (ix86_match_ccmode (insn, CCNOmode)
8542 && !(INTVAL (operands[3]) & ~127)))"
8544 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8546 "operands[2] = gen_lowpart (QImode, operands[2]);
8547 operands[3] = gen_lowpart (QImode, operands[3]);")
8550 ;; %%% This used to optimize known byte-wide and operations to memory,
8551 ;; and sometimes to QImode registers. If this is considered useful,
8552 ;; it should be done with splitters.
8554 (define_expand "anddi3"
8555 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8556 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8557 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8558 (clobber (reg:CC FLAGS_REG))]
8560 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8562 (define_insn "*anddi_1_rex64"
8563 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8564 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8565 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8566 (clobber (reg:CC FLAGS_REG))]
8567 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8569 switch (get_attr_type (insn))
8573 enum machine_mode mode;
8575 gcc_assert (CONST_INT_P (operands[2]));
8576 if (INTVAL (operands[2]) == 0xff)
8580 gcc_assert (INTVAL (operands[2]) == 0xffff);
8584 operands[1] = gen_lowpart (mode, operands[1]);
8586 return "movz{bq|x}\t{%1,%0|%0, %1}";
8588 return "movz{wq|x}\t{%1,%0|%0, %1}";
8592 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8593 if (get_attr_mode (insn) == MODE_SI)
8594 return "and{l}\t{%k2, %k0|%k0, %k2}";
8596 return "and{q}\t{%2, %0|%0, %2}";
8599 [(set_attr "type" "alu,alu,alu,imovx")
8600 (set_attr "length_immediate" "*,*,*,0")
8601 (set_attr "mode" "SI,DI,DI,DI")])
8603 (define_insn "*anddi_2"
8604 [(set (reg FLAGS_REG)
8605 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8606 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8608 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8609 (and:DI (match_dup 1) (match_dup 2)))]
8610 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8611 && ix86_binary_operator_ok (AND, DImode, operands)"
8613 and{l}\t{%k2, %k0|%k0, %k2}
8614 and{q}\t{%2, %0|%0, %2}
8615 and{q}\t{%2, %0|%0, %2}"
8616 [(set_attr "type" "alu")
8617 (set_attr "mode" "SI,DI,DI")])
8619 (define_expand "andsi3"
8620 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8621 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8622 (match_operand:SI 2 "general_operand" "")))
8623 (clobber (reg:CC FLAGS_REG))]
8625 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8627 (define_insn "*andsi_1"
8628 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8629 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8630 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8631 (clobber (reg:CC FLAGS_REG))]
8632 "ix86_binary_operator_ok (AND, SImode, operands)"
8634 switch (get_attr_type (insn))
8638 enum machine_mode mode;
8640 gcc_assert (CONST_INT_P (operands[2]));
8641 if (INTVAL (operands[2]) == 0xff)
8645 gcc_assert (INTVAL (operands[2]) == 0xffff);
8649 operands[1] = gen_lowpart (mode, operands[1]);
8651 return "movz{bl|x}\t{%1,%0|%0, %1}";
8653 return "movz{wl|x}\t{%1,%0|%0, %1}";
8657 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8658 return "and{l}\t{%2, %0|%0, %2}";
8661 [(set_attr "type" "alu,alu,imovx")
8662 (set_attr "length_immediate" "*,*,0")
8663 (set_attr "mode" "SI")])
8666 [(set (match_operand 0 "register_operand" "")
8668 (const_int -65536)))
8669 (clobber (reg:CC FLAGS_REG))]
8670 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8671 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8672 "operands[1] = gen_lowpart (HImode, operands[0]);")
8675 [(set (match_operand 0 "ext_register_operand" "")
8678 (clobber (reg:CC FLAGS_REG))]
8679 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8680 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8681 "operands[1] = gen_lowpart (QImode, operands[0]);")
8684 [(set (match_operand 0 "ext_register_operand" "")
8686 (const_int -65281)))
8687 (clobber (reg:CC FLAGS_REG))]
8688 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8689 [(parallel [(set (zero_extract:SI (match_dup 0)
8693 (zero_extract:SI (match_dup 0)
8696 (zero_extract:SI (match_dup 0)
8699 (clobber (reg:CC FLAGS_REG))])]
8700 "operands[0] = gen_lowpart (SImode, operands[0]);")
8702 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8703 (define_insn "*andsi_1_zext"
8704 [(set (match_operand:DI 0 "register_operand" "=r")
8706 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8707 (match_operand:SI 2 "general_operand" "g"))))
8708 (clobber (reg:CC FLAGS_REG))]
8709 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8710 "and{l}\t{%2, %k0|%k0, %2}"
8711 [(set_attr "type" "alu")
8712 (set_attr "mode" "SI")])
8714 (define_insn "*andsi_2"
8715 [(set (reg FLAGS_REG)
8716 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8717 (match_operand:SI 2 "general_operand" "g,ri"))
8719 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8720 (and:SI (match_dup 1) (match_dup 2)))]
8721 "ix86_match_ccmode (insn, CCNOmode)
8722 && ix86_binary_operator_ok (AND, SImode, operands)"
8723 "and{l}\t{%2, %0|%0, %2}"
8724 [(set_attr "type" "alu")
8725 (set_attr "mode" "SI")])
8727 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8728 (define_insn "*andsi_2_zext"
8729 [(set (reg FLAGS_REG)
8730 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8731 (match_operand:SI 2 "general_operand" "g"))
8733 (set (match_operand:DI 0 "register_operand" "=r")
8734 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8735 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8736 && ix86_binary_operator_ok (AND, SImode, operands)"
8737 "and{l}\t{%2, %k0|%k0, %2}"
8738 [(set_attr "type" "alu")
8739 (set_attr "mode" "SI")])
8741 (define_expand "andhi3"
8742 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8743 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8744 (match_operand:HI 2 "general_operand" "")))
8745 (clobber (reg:CC FLAGS_REG))]
8746 "TARGET_HIMODE_MATH"
8747 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8749 (define_insn "*andhi_1"
8750 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8751 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8752 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8753 (clobber (reg:CC FLAGS_REG))]
8754 "ix86_binary_operator_ok (AND, HImode, operands)"
8756 switch (get_attr_type (insn))
8759 gcc_assert (CONST_INT_P (operands[2]));
8760 gcc_assert (INTVAL (operands[2]) == 0xff);
8761 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8764 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8766 return "and{w}\t{%2, %0|%0, %2}";
8769 [(set_attr "type" "alu,alu,imovx")
8770 (set_attr "length_immediate" "*,*,0")
8771 (set_attr "mode" "HI,HI,SI")])
8773 (define_insn "*andhi_2"
8774 [(set (reg FLAGS_REG)
8775 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8776 (match_operand:HI 2 "general_operand" "g,ri"))
8778 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8779 (and:HI (match_dup 1) (match_dup 2)))]
8780 "ix86_match_ccmode (insn, CCNOmode)
8781 && ix86_binary_operator_ok (AND, HImode, operands)"
8782 "and{w}\t{%2, %0|%0, %2}"
8783 [(set_attr "type" "alu")
8784 (set_attr "mode" "HI")])
8786 (define_expand "andqi3"
8787 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8788 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8789 (match_operand:QI 2 "general_operand" "")))
8790 (clobber (reg:CC FLAGS_REG))]
8791 "TARGET_QIMODE_MATH"
8792 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8794 ;; %%% Potential partial reg stall on alternative 2. What to do?
8795 (define_insn "*andqi_1"
8796 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8797 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8798 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8799 (clobber (reg:CC FLAGS_REG))]
8800 "ix86_binary_operator_ok (AND, QImode, operands)"
8802 and{b}\t{%2, %0|%0, %2}
8803 and{b}\t{%2, %0|%0, %2}
8804 and{l}\t{%k2, %k0|%k0, %k2}"
8805 [(set_attr "type" "alu")
8806 (set_attr "mode" "QI,QI,SI")])
8808 (define_insn "*andqi_1_slp"
8809 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8810 (and:QI (match_dup 0)
8811 (match_operand:QI 1 "general_operand" "qi,qmi")))
8812 (clobber (reg:CC FLAGS_REG))]
8813 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8814 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8815 "and{b}\t{%1, %0|%0, %1}"
8816 [(set_attr "type" "alu1")
8817 (set_attr "mode" "QI")])
8819 (define_insn "*andqi_2_maybe_si"
8820 [(set (reg FLAGS_REG)
8822 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8823 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8825 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8826 (and:QI (match_dup 1) (match_dup 2)))]
8827 "ix86_binary_operator_ok (AND, QImode, operands)
8828 && ix86_match_ccmode (insn,
8829 CONST_INT_P (operands[2])
8830 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8832 if (which_alternative == 2)
8834 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8835 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8836 return "and{l}\t{%2, %k0|%k0, %2}";
8838 return "and{b}\t{%2, %0|%0, %2}";
8840 [(set_attr "type" "alu")
8841 (set_attr "mode" "QI,QI,SI")])
8843 (define_insn "*andqi_2"
8844 [(set (reg FLAGS_REG)
8846 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8847 (match_operand:QI 2 "general_operand" "qim,qi"))
8849 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8850 (and:QI (match_dup 1) (match_dup 2)))]
8851 "ix86_match_ccmode (insn, CCNOmode)
8852 && ix86_binary_operator_ok (AND, QImode, operands)"
8853 "and{b}\t{%2, %0|%0, %2}"
8854 [(set_attr "type" "alu")
8855 (set_attr "mode" "QI")])
8857 (define_insn "*andqi_2_slp"
8858 [(set (reg FLAGS_REG)
8860 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8861 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8863 (set (strict_low_part (match_dup 0))
8864 (and:QI (match_dup 0) (match_dup 1)))]
8865 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8866 && ix86_match_ccmode (insn, CCNOmode)
8867 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8868 "and{b}\t{%1, %0|%0, %1}"
8869 [(set_attr "type" "alu1")
8870 (set_attr "mode" "QI")])
8872 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8873 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8874 ;; for a QImode operand, which of course failed.
8876 (define_insn "andqi_ext_0"
8877 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8882 (match_operand 1 "ext_register_operand" "0")
8885 (match_operand 2 "const_int_operand" "n")))
8886 (clobber (reg:CC FLAGS_REG))]
8888 "and{b}\t{%2, %h0|%h0, %2}"
8889 [(set_attr "type" "alu")
8890 (set_attr "length_immediate" "1")
8891 (set_attr "mode" "QI")])
8893 ;; Generated by peephole translating test to and. This shows up
8894 ;; often in fp comparisons.
8896 (define_insn "*andqi_ext_0_cc"
8897 [(set (reg FLAGS_REG)
8901 (match_operand 1 "ext_register_operand" "0")
8904 (match_operand 2 "const_int_operand" "n"))
8906 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8915 "ix86_match_ccmode (insn, CCNOmode)"
8916 "and{b}\t{%2, %h0|%h0, %2}"
8917 [(set_attr "type" "alu")
8918 (set_attr "length_immediate" "1")
8919 (set_attr "mode" "QI")])
8921 (define_insn "*andqi_ext_1"
8922 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8927 (match_operand 1 "ext_register_operand" "0")
8931 (match_operand:QI 2 "general_operand" "Qm"))))
8932 (clobber (reg:CC FLAGS_REG))]
8934 "and{b}\t{%2, %h0|%h0, %2}"
8935 [(set_attr "type" "alu")
8936 (set_attr "length_immediate" "0")
8937 (set_attr "mode" "QI")])
8939 (define_insn "*andqi_ext_1_rex64"
8940 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8945 (match_operand 1 "ext_register_operand" "0")
8949 (match_operand 2 "ext_register_operand" "Q"))))
8950 (clobber (reg:CC FLAGS_REG))]
8952 "and{b}\t{%2, %h0|%h0, %2}"
8953 [(set_attr "type" "alu")
8954 (set_attr "length_immediate" "0")
8955 (set_attr "mode" "QI")])
8957 (define_insn "*andqi_ext_2"
8958 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8963 (match_operand 1 "ext_register_operand" "%0")
8967 (match_operand 2 "ext_register_operand" "Q")
8970 (clobber (reg:CC FLAGS_REG))]
8972 "and{b}\t{%h2, %h0|%h0, %h2}"
8973 [(set_attr "type" "alu")
8974 (set_attr "length_immediate" "0")
8975 (set_attr "mode" "QI")])
8977 ;; Convert wide AND instructions with immediate operand to shorter QImode
8978 ;; equivalents when possible.
8979 ;; Don't do the splitting with memory operands, since it introduces risk
8980 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8981 ;; for size, but that can (should?) be handled by generic code instead.
8983 [(set (match_operand 0 "register_operand" "")
8984 (and (match_operand 1 "register_operand" "")
8985 (match_operand 2 "const_int_operand" "")))
8986 (clobber (reg:CC FLAGS_REG))]
8988 && QI_REG_P (operands[0])
8989 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8990 && !(~INTVAL (operands[2]) & ~(255 << 8))
8991 && GET_MODE (operands[0]) != QImode"
8992 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8993 (and:SI (zero_extract:SI (match_dup 1)
8994 (const_int 8) (const_int 8))
8996 (clobber (reg:CC FLAGS_REG))])]
8997 "operands[0] = gen_lowpart (SImode, operands[0]);
8998 operands[1] = gen_lowpart (SImode, operands[1]);
8999 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9001 ;; Since AND can be encoded with sign extended immediate, this is only
9002 ;; profitable when 7th bit is not set.
9004 [(set (match_operand 0 "register_operand" "")
9005 (and (match_operand 1 "general_operand" "")
9006 (match_operand 2 "const_int_operand" "")))
9007 (clobber (reg:CC FLAGS_REG))]
9009 && ANY_QI_REG_P (operands[0])
9010 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9011 && !(~INTVAL (operands[2]) & ~255)
9012 && !(INTVAL (operands[2]) & 128)
9013 && GET_MODE (operands[0]) != QImode"
9014 [(parallel [(set (strict_low_part (match_dup 0))
9015 (and:QI (match_dup 1)
9017 (clobber (reg:CC FLAGS_REG))])]
9018 "operands[0] = gen_lowpart (QImode, operands[0]);
9019 operands[1] = gen_lowpart (QImode, operands[1]);
9020 operands[2] = gen_lowpart (QImode, operands[2]);")
9022 ;; Logical inclusive OR instructions
9024 ;; %%% This used to optimize known byte-wide and operations to memory.
9025 ;; If this is considered useful, it should be done with splitters.
9027 (define_expand "iordi3"
9028 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9029 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9030 (match_operand:DI 2 "x86_64_general_operand" "")))
9031 (clobber (reg:CC FLAGS_REG))]
9033 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9035 (define_insn "*iordi_1_rex64"
9036 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9037 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9038 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9039 (clobber (reg:CC FLAGS_REG))]
9041 && ix86_binary_operator_ok (IOR, DImode, operands)"
9042 "or{q}\t{%2, %0|%0, %2}"
9043 [(set_attr "type" "alu")
9044 (set_attr "mode" "DI")])
9046 (define_insn "*iordi_2_rex64"
9047 [(set (reg FLAGS_REG)
9048 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9049 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9051 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9052 (ior:DI (match_dup 1) (match_dup 2)))]
9054 && ix86_match_ccmode (insn, CCNOmode)
9055 && ix86_binary_operator_ok (IOR, DImode, operands)"
9056 "or{q}\t{%2, %0|%0, %2}"
9057 [(set_attr "type" "alu")
9058 (set_attr "mode" "DI")])
9060 (define_insn "*iordi_3_rex64"
9061 [(set (reg FLAGS_REG)
9062 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9063 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9065 (clobber (match_scratch:DI 0 "=r"))]
9067 && ix86_match_ccmode (insn, CCNOmode)
9068 && ix86_binary_operator_ok (IOR, DImode, operands)"
9069 "or{q}\t{%2, %0|%0, %2}"
9070 [(set_attr "type" "alu")
9071 (set_attr "mode" "DI")])
9074 (define_expand "iorsi3"
9075 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9076 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9077 (match_operand:SI 2 "general_operand" "")))
9078 (clobber (reg:CC FLAGS_REG))]
9080 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9082 (define_insn "*iorsi_1"
9083 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9084 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9085 (match_operand:SI 2 "general_operand" "ri,g")))
9086 (clobber (reg:CC FLAGS_REG))]
9087 "ix86_binary_operator_ok (IOR, SImode, operands)"
9088 "or{l}\t{%2, %0|%0, %2}"
9089 [(set_attr "type" "alu")
9090 (set_attr "mode" "SI")])
9092 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9093 (define_insn "*iorsi_1_zext"
9094 [(set (match_operand:DI 0 "register_operand" "=r")
9096 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9097 (match_operand:SI 2 "general_operand" "g"))))
9098 (clobber (reg:CC FLAGS_REG))]
9099 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9100 "or{l}\t{%2, %k0|%k0, %2}"
9101 [(set_attr "type" "alu")
9102 (set_attr "mode" "SI")])
9104 (define_insn "*iorsi_1_zext_imm"
9105 [(set (match_operand:DI 0 "register_operand" "=r")
9106 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9107 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9108 (clobber (reg:CC FLAGS_REG))]
9110 "or{l}\t{%2, %k0|%k0, %2}"
9111 [(set_attr "type" "alu")
9112 (set_attr "mode" "SI")])
9114 (define_insn "*iorsi_2"
9115 [(set (reg FLAGS_REG)
9116 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9117 (match_operand:SI 2 "general_operand" "g,ri"))
9119 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9120 (ior:SI (match_dup 1) (match_dup 2)))]
9121 "ix86_match_ccmode (insn, CCNOmode)
9122 && ix86_binary_operator_ok (IOR, SImode, operands)"
9123 "or{l}\t{%2, %0|%0, %2}"
9124 [(set_attr "type" "alu")
9125 (set_attr "mode" "SI")])
9127 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9128 ;; ??? Special case for immediate operand is missing - it is tricky.
9129 (define_insn "*iorsi_2_zext"
9130 [(set (reg FLAGS_REG)
9131 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9132 (match_operand:SI 2 "general_operand" "g"))
9134 (set (match_operand:DI 0 "register_operand" "=r")
9135 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9136 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9137 && ix86_binary_operator_ok (IOR, SImode, operands)"
9138 "or{l}\t{%2, %k0|%k0, %2}"
9139 [(set_attr "type" "alu")
9140 (set_attr "mode" "SI")])
9142 (define_insn "*iorsi_2_zext_imm"
9143 [(set (reg FLAGS_REG)
9144 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9145 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9147 (set (match_operand:DI 0 "register_operand" "=r")
9148 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9149 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9150 && ix86_binary_operator_ok (IOR, SImode, operands)"
9151 "or{l}\t{%2, %k0|%k0, %2}"
9152 [(set_attr "type" "alu")
9153 (set_attr "mode" "SI")])
9155 (define_insn "*iorsi_3"
9156 [(set (reg FLAGS_REG)
9157 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9158 (match_operand:SI 2 "general_operand" "g"))
9160 (clobber (match_scratch:SI 0 "=r"))]
9161 "ix86_match_ccmode (insn, CCNOmode)
9162 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9163 "or{l}\t{%2, %0|%0, %2}"
9164 [(set_attr "type" "alu")
9165 (set_attr "mode" "SI")])
9167 (define_expand "iorhi3"
9168 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9169 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9170 (match_operand:HI 2 "general_operand" "")))
9171 (clobber (reg:CC FLAGS_REG))]
9172 "TARGET_HIMODE_MATH"
9173 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9175 (define_insn "*iorhi_1"
9176 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9177 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9178 (match_operand:HI 2 "general_operand" "g,ri")))
9179 (clobber (reg:CC FLAGS_REG))]
9180 "ix86_binary_operator_ok (IOR, HImode, operands)"
9181 "or{w}\t{%2, %0|%0, %2}"
9182 [(set_attr "type" "alu")
9183 (set_attr "mode" "HI")])
9185 (define_insn "*iorhi_2"
9186 [(set (reg FLAGS_REG)
9187 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9188 (match_operand:HI 2 "general_operand" "g,ri"))
9190 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9191 (ior:HI (match_dup 1) (match_dup 2)))]
9192 "ix86_match_ccmode (insn, CCNOmode)
9193 && ix86_binary_operator_ok (IOR, HImode, operands)"
9194 "or{w}\t{%2, %0|%0, %2}"
9195 [(set_attr "type" "alu")
9196 (set_attr "mode" "HI")])
9198 (define_insn "*iorhi_3"
9199 [(set (reg FLAGS_REG)
9200 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9201 (match_operand:HI 2 "general_operand" "g"))
9203 (clobber (match_scratch:HI 0 "=r"))]
9204 "ix86_match_ccmode (insn, CCNOmode)
9205 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9206 "or{w}\t{%2, %0|%0, %2}"
9207 [(set_attr "type" "alu")
9208 (set_attr "mode" "HI")])
9210 (define_expand "iorqi3"
9211 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9212 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9213 (match_operand:QI 2 "general_operand" "")))
9214 (clobber (reg:CC FLAGS_REG))]
9215 "TARGET_QIMODE_MATH"
9216 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9218 ;; %%% Potential partial reg stall on alternative 2. What to do?
9219 (define_insn "*iorqi_1"
9220 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9221 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9222 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9223 (clobber (reg:CC FLAGS_REG))]
9224 "ix86_binary_operator_ok (IOR, QImode, operands)"
9226 or{b}\t{%2, %0|%0, %2}
9227 or{b}\t{%2, %0|%0, %2}
9228 or{l}\t{%k2, %k0|%k0, %k2}"
9229 [(set_attr "type" "alu")
9230 (set_attr "mode" "QI,QI,SI")])
9232 (define_insn "*iorqi_1_slp"
9233 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9234 (ior:QI (match_dup 0)
9235 (match_operand:QI 1 "general_operand" "qmi,qi")))
9236 (clobber (reg:CC FLAGS_REG))]
9237 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9238 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9239 "or{b}\t{%1, %0|%0, %1}"
9240 [(set_attr "type" "alu1")
9241 (set_attr "mode" "QI")])
9243 (define_insn "*iorqi_2"
9244 [(set (reg FLAGS_REG)
9245 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9246 (match_operand:QI 2 "general_operand" "qim,qi"))
9248 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9249 (ior:QI (match_dup 1) (match_dup 2)))]
9250 "ix86_match_ccmode (insn, CCNOmode)
9251 && ix86_binary_operator_ok (IOR, QImode, operands)"
9252 "or{b}\t{%2, %0|%0, %2}"
9253 [(set_attr "type" "alu")
9254 (set_attr "mode" "QI")])
9256 (define_insn "*iorqi_2_slp"
9257 [(set (reg FLAGS_REG)
9258 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9259 (match_operand:QI 1 "general_operand" "qim,qi"))
9261 (set (strict_low_part (match_dup 0))
9262 (ior:QI (match_dup 0) (match_dup 1)))]
9263 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9264 && ix86_match_ccmode (insn, CCNOmode)
9265 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9266 "or{b}\t{%1, %0|%0, %1}"
9267 [(set_attr "type" "alu1")
9268 (set_attr "mode" "QI")])
9270 (define_insn "*iorqi_3"
9271 [(set (reg FLAGS_REG)
9272 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9273 (match_operand:QI 2 "general_operand" "qim"))
9275 (clobber (match_scratch:QI 0 "=q"))]
9276 "ix86_match_ccmode (insn, CCNOmode)
9277 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9278 "or{b}\t{%2, %0|%0, %2}"
9279 [(set_attr "type" "alu")
9280 (set_attr "mode" "QI")])
9282 (define_insn "iorqi_ext_0"
9283 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9288 (match_operand 1 "ext_register_operand" "0")
9291 (match_operand 2 "const_int_operand" "n")))
9292 (clobber (reg:CC FLAGS_REG))]
9293 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9294 "or{b}\t{%2, %h0|%h0, %2}"
9295 [(set_attr "type" "alu")
9296 (set_attr "length_immediate" "1")
9297 (set_attr "mode" "QI")])
9299 (define_insn "*iorqi_ext_1"
9300 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9305 (match_operand 1 "ext_register_operand" "0")
9309 (match_operand:QI 2 "general_operand" "Qm"))))
9310 (clobber (reg:CC FLAGS_REG))]
9312 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9313 "or{b}\t{%2, %h0|%h0, %2}"
9314 [(set_attr "type" "alu")
9315 (set_attr "length_immediate" "0")
9316 (set_attr "mode" "QI")])
9318 (define_insn "*iorqi_ext_1_rex64"
9319 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9324 (match_operand 1 "ext_register_operand" "0")
9328 (match_operand 2 "ext_register_operand" "Q"))))
9329 (clobber (reg:CC FLAGS_REG))]
9331 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9332 "or{b}\t{%2, %h0|%h0, %2}"
9333 [(set_attr "type" "alu")
9334 (set_attr "length_immediate" "0")
9335 (set_attr "mode" "QI")])
9337 (define_insn "*iorqi_ext_2"
9338 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9342 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9345 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9348 (clobber (reg:CC FLAGS_REG))]
9349 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9350 "ior{b}\t{%h2, %h0|%h0, %h2}"
9351 [(set_attr "type" "alu")
9352 (set_attr "length_immediate" "0")
9353 (set_attr "mode" "QI")])
9356 [(set (match_operand 0 "register_operand" "")
9357 (ior (match_operand 1 "register_operand" "")
9358 (match_operand 2 "const_int_operand" "")))
9359 (clobber (reg:CC FLAGS_REG))]
9361 && QI_REG_P (operands[0])
9362 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9363 && !(INTVAL (operands[2]) & ~(255 << 8))
9364 && GET_MODE (operands[0]) != QImode"
9365 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9366 (ior:SI (zero_extract:SI (match_dup 1)
9367 (const_int 8) (const_int 8))
9369 (clobber (reg:CC FLAGS_REG))])]
9370 "operands[0] = gen_lowpart (SImode, operands[0]);
9371 operands[1] = gen_lowpart (SImode, operands[1]);
9372 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9374 ;; Since OR can be encoded with sign extended immediate, this is only
9375 ;; profitable when 7th bit is set.
9377 [(set (match_operand 0 "register_operand" "")
9378 (ior (match_operand 1 "general_operand" "")
9379 (match_operand 2 "const_int_operand" "")))
9380 (clobber (reg:CC FLAGS_REG))]
9382 && ANY_QI_REG_P (operands[0])
9383 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9384 && !(INTVAL (operands[2]) & ~255)
9385 && (INTVAL (operands[2]) & 128)
9386 && GET_MODE (operands[0]) != QImode"
9387 [(parallel [(set (strict_low_part (match_dup 0))
9388 (ior:QI (match_dup 1)
9390 (clobber (reg:CC FLAGS_REG))])]
9391 "operands[0] = gen_lowpart (QImode, operands[0]);
9392 operands[1] = gen_lowpart (QImode, operands[1]);
9393 operands[2] = gen_lowpart (QImode, operands[2]);")
9395 ;; Logical XOR instructions
9397 ;; %%% This used to optimize known byte-wide and operations to memory.
9398 ;; If this is considered useful, it should be done with splitters.
9400 (define_expand "xordi3"
9401 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9402 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9403 (match_operand:DI 2 "x86_64_general_operand" "")))
9404 (clobber (reg:CC FLAGS_REG))]
9406 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9408 (define_insn "*xordi_1_rex64"
9409 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9410 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9411 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9412 (clobber (reg:CC FLAGS_REG))]
9414 && ix86_binary_operator_ok (XOR, DImode, operands)"
9416 xor{q}\t{%2, %0|%0, %2}
9417 xor{q}\t{%2, %0|%0, %2}"
9418 [(set_attr "type" "alu")
9419 (set_attr "mode" "DI,DI")])
9421 (define_insn "*xordi_2_rex64"
9422 [(set (reg FLAGS_REG)
9423 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9424 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9426 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9427 (xor:DI (match_dup 1) (match_dup 2)))]
9429 && ix86_match_ccmode (insn, CCNOmode)
9430 && ix86_binary_operator_ok (XOR, DImode, operands)"
9432 xor{q}\t{%2, %0|%0, %2}
9433 xor{q}\t{%2, %0|%0, %2}"
9434 [(set_attr "type" "alu")
9435 (set_attr "mode" "DI,DI")])
9437 (define_insn "*xordi_3_rex64"
9438 [(set (reg FLAGS_REG)
9439 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9440 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9442 (clobber (match_scratch:DI 0 "=r"))]
9444 && ix86_match_ccmode (insn, CCNOmode)
9445 && ix86_binary_operator_ok (XOR, DImode, operands)"
9446 "xor{q}\t{%2, %0|%0, %2}"
9447 [(set_attr "type" "alu")
9448 (set_attr "mode" "DI")])
9450 (define_expand "xorsi3"
9451 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9452 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9453 (match_operand:SI 2 "general_operand" "")))
9454 (clobber (reg:CC FLAGS_REG))]
9456 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9458 (define_insn "*xorsi_1"
9459 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9460 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9461 (match_operand:SI 2 "general_operand" "ri,rm")))
9462 (clobber (reg:CC FLAGS_REG))]
9463 "ix86_binary_operator_ok (XOR, SImode, operands)"
9464 "xor{l}\t{%2, %0|%0, %2}"
9465 [(set_attr "type" "alu")
9466 (set_attr "mode" "SI")])
9468 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9469 ;; Add speccase for immediates
9470 (define_insn "*xorsi_1_zext"
9471 [(set (match_operand:DI 0 "register_operand" "=r")
9473 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9474 (match_operand:SI 2 "general_operand" "g"))))
9475 (clobber (reg:CC FLAGS_REG))]
9476 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9477 "xor{l}\t{%2, %k0|%k0, %2}"
9478 [(set_attr "type" "alu")
9479 (set_attr "mode" "SI")])
9481 (define_insn "*xorsi_1_zext_imm"
9482 [(set (match_operand:DI 0 "register_operand" "=r")
9483 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9484 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9485 (clobber (reg:CC FLAGS_REG))]
9486 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9487 "xor{l}\t{%2, %k0|%k0, %2}"
9488 [(set_attr "type" "alu")
9489 (set_attr "mode" "SI")])
9491 (define_insn "*xorsi_2"
9492 [(set (reg FLAGS_REG)
9493 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9494 (match_operand:SI 2 "general_operand" "g,ri"))
9496 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9497 (xor:SI (match_dup 1) (match_dup 2)))]
9498 "ix86_match_ccmode (insn, CCNOmode)
9499 && ix86_binary_operator_ok (XOR, SImode, operands)"
9500 "xor{l}\t{%2, %0|%0, %2}"
9501 [(set_attr "type" "alu")
9502 (set_attr "mode" "SI")])
9504 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9505 ;; ??? Special case for immediate operand is missing - it is tricky.
9506 (define_insn "*xorsi_2_zext"
9507 [(set (reg FLAGS_REG)
9508 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9509 (match_operand:SI 2 "general_operand" "g"))
9511 (set (match_operand:DI 0 "register_operand" "=r")
9512 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9513 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9514 && ix86_binary_operator_ok (XOR, SImode, operands)"
9515 "xor{l}\t{%2, %k0|%k0, %2}"
9516 [(set_attr "type" "alu")
9517 (set_attr "mode" "SI")])
9519 (define_insn "*xorsi_2_zext_imm"
9520 [(set (reg FLAGS_REG)
9521 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9522 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9524 (set (match_operand:DI 0 "register_operand" "=r")
9525 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9526 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9527 && ix86_binary_operator_ok (XOR, SImode, operands)"
9528 "xor{l}\t{%2, %k0|%k0, %2}"
9529 [(set_attr "type" "alu")
9530 (set_attr "mode" "SI")])
9532 (define_insn "*xorsi_3"
9533 [(set (reg FLAGS_REG)
9534 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9535 (match_operand:SI 2 "general_operand" "g"))
9537 (clobber (match_scratch:SI 0 "=r"))]
9538 "ix86_match_ccmode (insn, CCNOmode)
9539 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9540 "xor{l}\t{%2, %0|%0, %2}"
9541 [(set_attr "type" "alu")
9542 (set_attr "mode" "SI")])
9544 (define_expand "xorhi3"
9545 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9546 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9547 (match_operand:HI 2 "general_operand" "")))
9548 (clobber (reg:CC FLAGS_REG))]
9549 "TARGET_HIMODE_MATH"
9550 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9552 (define_insn "*xorhi_1"
9553 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9554 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9555 (match_operand:HI 2 "general_operand" "g,ri")))
9556 (clobber (reg:CC FLAGS_REG))]
9557 "ix86_binary_operator_ok (XOR, HImode, operands)"
9558 "xor{w}\t{%2, %0|%0, %2}"
9559 [(set_attr "type" "alu")
9560 (set_attr "mode" "HI")])
9562 (define_insn "*xorhi_2"
9563 [(set (reg FLAGS_REG)
9564 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9565 (match_operand:HI 2 "general_operand" "g,ri"))
9567 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9568 (xor:HI (match_dup 1) (match_dup 2)))]
9569 "ix86_match_ccmode (insn, CCNOmode)
9570 && ix86_binary_operator_ok (XOR, HImode, operands)"
9571 "xor{w}\t{%2, %0|%0, %2}"
9572 [(set_attr "type" "alu")
9573 (set_attr "mode" "HI")])
9575 (define_insn "*xorhi_3"
9576 [(set (reg FLAGS_REG)
9577 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9578 (match_operand:HI 2 "general_operand" "g"))
9580 (clobber (match_scratch:HI 0 "=r"))]
9581 "ix86_match_ccmode (insn, CCNOmode)
9582 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9583 "xor{w}\t{%2, %0|%0, %2}"
9584 [(set_attr "type" "alu")
9585 (set_attr "mode" "HI")])
9587 (define_expand "xorqi3"
9588 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9589 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9590 (match_operand:QI 2 "general_operand" "")))
9591 (clobber (reg:CC FLAGS_REG))]
9592 "TARGET_QIMODE_MATH"
9593 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9595 ;; %%% Potential partial reg stall on alternative 2. What to do?
9596 (define_insn "*xorqi_1"
9597 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9598 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9599 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9600 (clobber (reg:CC FLAGS_REG))]
9601 "ix86_binary_operator_ok (XOR, QImode, operands)"
9603 xor{b}\t{%2, %0|%0, %2}
9604 xor{b}\t{%2, %0|%0, %2}
9605 xor{l}\t{%k2, %k0|%k0, %k2}"
9606 [(set_attr "type" "alu")
9607 (set_attr "mode" "QI,QI,SI")])
9609 (define_insn "*xorqi_1_slp"
9610 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9611 (xor:QI (match_dup 0)
9612 (match_operand:QI 1 "general_operand" "qi,qmi")))
9613 (clobber (reg:CC FLAGS_REG))]
9614 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9615 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9616 "xor{b}\t{%1, %0|%0, %1}"
9617 [(set_attr "type" "alu1")
9618 (set_attr "mode" "QI")])
9620 (define_insn "xorqi_ext_0"
9621 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9626 (match_operand 1 "ext_register_operand" "0")
9629 (match_operand 2 "const_int_operand" "n")))
9630 (clobber (reg:CC FLAGS_REG))]
9631 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9632 "xor{b}\t{%2, %h0|%h0, %2}"
9633 [(set_attr "type" "alu")
9634 (set_attr "length_immediate" "1")
9635 (set_attr "mode" "QI")])
9637 (define_insn "*xorqi_ext_1"
9638 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9643 (match_operand 1 "ext_register_operand" "0")
9647 (match_operand:QI 2 "general_operand" "Qm"))))
9648 (clobber (reg:CC FLAGS_REG))]
9650 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9651 "xor{b}\t{%2, %h0|%h0, %2}"
9652 [(set_attr "type" "alu")
9653 (set_attr "length_immediate" "0")
9654 (set_attr "mode" "QI")])
9656 (define_insn "*xorqi_ext_1_rex64"
9657 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9662 (match_operand 1 "ext_register_operand" "0")
9666 (match_operand 2 "ext_register_operand" "Q"))))
9667 (clobber (reg:CC FLAGS_REG))]
9669 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9670 "xor{b}\t{%2, %h0|%h0, %2}"
9671 [(set_attr "type" "alu")
9672 (set_attr "length_immediate" "0")
9673 (set_attr "mode" "QI")])
9675 (define_insn "*xorqi_ext_2"
9676 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9680 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9683 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9686 (clobber (reg:CC FLAGS_REG))]
9687 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9688 "xor{b}\t{%h2, %h0|%h0, %h2}"
9689 [(set_attr "type" "alu")
9690 (set_attr "length_immediate" "0")
9691 (set_attr "mode" "QI")])
9693 (define_insn "*xorqi_cc_1"
9694 [(set (reg FLAGS_REG)
9696 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9697 (match_operand:QI 2 "general_operand" "qim,qi"))
9699 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9700 (xor:QI (match_dup 1) (match_dup 2)))]
9701 "ix86_match_ccmode (insn, CCNOmode)
9702 && ix86_binary_operator_ok (XOR, QImode, operands)"
9703 "xor{b}\t{%2, %0|%0, %2}"
9704 [(set_attr "type" "alu")
9705 (set_attr "mode" "QI")])
9707 (define_insn "*xorqi_2_slp"
9708 [(set (reg FLAGS_REG)
9709 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9710 (match_operand:QI 1 "general_operand" "qim,qi"))
9712 (set (strict_low_part (match_dup 0))
9713 (xor:QI (match_dup 0) (match_dup 1)))]
9714 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9715 && ix86_match_ccmode (insn, CCNOmode)
9716 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9717 "xor{b}\t{%1, %0|%0, %1}"
9718 [(set_attr "type" "alu1")
9719 (set_attr "mode" "QI")])
9721 (define_insn "*xorqi_cc_2"
9722 [(set (reg FLAGS_REG)
9724 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9725 (match_operand:QI 2 "general_operand" "qim"))
9727 (clobber (match_scratch:QI 0 "=q"))]
9728 "ix86_match_ccmode (insn, CCNOmode)
9729 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9730 "xor{b}\t{%2, %0|%0, %2}"
9731 [(set_attr "type" "alu")
9732 (set_attr "mode" "QI")])
9734 (define_insn "*xorqi_cc_ext_1"
9735 [(set (reg FLAGS_REG)
9739 (match_operand 1 "ext_register_operand" "0")
9742 (match_operand:QI 2 "general_operand" "qmn"))
9744 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9748 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9750 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9751 "xor{b}\t{%2, %h0|%h0, %2}"
9752 [(set_attr "type" "alu")
9753 (set_attr "mode" "QI")])
9755 (define_insn "*xorqi_cc_ext_1_rex64"
9756 [(set (reg FLAGS_REG)
9760 (match_operand 1 "ext_register_operand" "0")
9763 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9765 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9769 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9771 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9772 "xor{b}\t{%2, %h0|%h0, %2}"
9773 [(set_attr "type" "alu")
9774 (set_attr "mode" "QI")])
9776 (define_expand "xorqi_cc_ext_1"
9778 (set (reg:CCNO FLAGS_REG)
9782 (match_operand 1 "ext_register_operand" "")
9785 (match_operand:QI 2 "general_operand" ""))
9787 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9791 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9797 [(set (match_operand 0 "register_operand" "")
9798 (xor (match_operand 1 "register_operand" "")
9799 (match_operand 2 "const_int_operand" "")))
9800 (clobber (reg:CC FLAGS_REG))]
9802 && QI_REG_P (operands[0])
9803 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9804 && !(INTVAL (operands[2]) & ~(255 << 8))
9805 && GET_MODE (operands[0]) != QImode"
9806 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9807 (xor:SI (zero_extract:SI (match_dup 1)
9808 (const_int 8) (const_int 8))
9810 (clobber (reg:CC FLAGS_REG))])]
9811 "operands[0] = gen_lowpart (SImode, operands[0]);
9812 operands[1] = gen_lowpart (SImode, operands[1]);
9813 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9815 ;; Since XOR can be encoded with sign extended immediate, this is only
9816 ;; profitable when 7th bit is set.
9818 [(set (match_operand 0 "register_operand" "")
9819 (xor (match_operand 1 "general_operand" "")
9820 (match_operand 2 "const_int_operand" "")))
9821 (clobber (reg:CC FLAGS_REG))]
9823 && ANY_QI_REG_P (operands[0])
9824 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9825 && !(INTVAL (operands[2]) & ~255)
9826 && (INTVAL (operands[2]) & 128)
9827 && GET_MODE (operands[0]) != QImode"
9828 [(parallel [(set (strict_low_part (match_dup 0))
9829 (xor:QI (match_dup 1)
9831 (clobber (reg:CC FLAGS_REG))])]
9832 "operands[0] = gen_lowpart (QImode, operands[0]);
9833 operands[1] = gen_lowpart (QImode, operands[1]);
9834 operands[2] = gen_lowpart (QImode, operands[2]);")
9836 ;; Negation instructions
9838 (define_expand "negti2"
9839 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9840 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9841 (clobber (reg:CC FLAGS_REG))])]
9843 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9845 (define_insn "*negti2_1"
9846 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9847 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9848 (clobber (reg:CC FLAGS_REG))]
9850 && ix86_unary_operator_ok (NEG, TImode, operands)"
9854 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9855 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9856 (clobber (reg:CC FLAGS_REG))]
9857 "TARGET_64BIT && reload_completed"
9859 [(set (reg:CCZ FLAGS_REG)
9860 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9861 (set (match_dup 0) (neg:DI (match_dup 2)))])
9864 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9867 (clobber (reg:CC FLAGS_REG))])
9870 (neg:DI (match_dup 1)))
9871 (clobber (reg:CC FLAGS_REG))])]
9872 "split_ti (operands+1, 1, operands+2, operands+3);
9873 split_ti (operands+0, 1, operands+0, operands+1);")
9875 (define_expand "negdi2"
9876 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9877 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9878 (clobber (reg:CC FLAGS_REG))])]
9880 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9882 (define_insn "*negdi2_1"
9883 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9884 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9885 (clobber (reg:CC FLAGS_REG))]
9887 && ix86_unary_operator_ok (NEG, DImode, operands)"
9891 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9892 (neg:DI (match_operand:DI 1 "general_operand" "")))
9893 (clobber (reg:CC FLAGS_REG))]
9894 "!TARGET_64BIT && reload_completed"
9896 [(set (reg:CCZ FLAGS_REG)
9897 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9898 (set (match_dup 0) (neg:SI (match_dup 2)))])
9901 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9904 (clobber (reg:CC FLAGS_REG))])
9907 (neg:SI (match_dup 1)))
9908 (clobber (reg:CC FLAGS_REG))])]
9909 "split_di (operands+1, 1, operands+2, operands+3);
9910 split_di (operands+0, 1, operands+0, operands+1);")
9912 (define_insn "*negdi2_1_rex64"
9913 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9914 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9915 (clobber (reg:CC FLAGS_REG))]
9916 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9918 [(set_attr "type" "negnot")
9919 (set_attr "mode" "DI")])
9921 ;; The problem with neg is that it does not perform (compare x 0),
9922 ;; it really performs (compare 0 x), which leaves us with the zero
9923 ;; flag being the only useful item.
9925 (define_insn "*negdi2_cmpz_rex64"
9926 [(set (reg:CCZ FLAGS_REG)
9927 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9929 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9930 (neg:DI (match_dup 1)))]
9931 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9933 [(set_attr "type" "negnot")
9934 (set_attr "mode" "DI")])
9937 (define_expand "negsi2"
9938 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9939 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9940 (clobber (reg:CC FLAGS_REG))])]
9942 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9944 (define_insn "*negsi2_1"
9945 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9946 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9947 (clobber (reg:CC FLAGS_REG))]
9948 "ix86_unary_operator_ok (NEG, SImode, operands)"
9950 [(set_attr "type" "negnot")
9951 (set_attr "mode" "SI")])
9953 ;; Combine is quite creative about this pattern.
9954 (define_insn "*negsi2_1_zext"
9955 [(set (match_operand:DI 0 "register_operand" "=r")
9956 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9959 (clobber (reg:CC FLAGS_REG))]
9960 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9962 [(set_attr "type" "negnot")
9963 (set_attr "mode" "SI")])
9965 ;; The problem with neg is that it does not perform (compare x 0),
9966 ;; it really performs (compare 0 x), which leaves us with the zero
9967 ;; flag being the only useful item.
9969 (define_insn "*negsi2_cmpz"
9970 [(set (reg:CCZ FLAGS_REG)
9971 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9973 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9974 (neg:SI (match_dup 1)))]
9975 "ix86_unary_operator_ok (NEG, SImode, operands)"
9977 [(set_attr "type" "negnot")
9978 (set_attr "mode" "SI")])
9980 (define_insn "*negsi2_cmpz_zext"
9981 [(set (reg:CCZ FLAGS_REG)
9982 (compare:CCZ (lshiftrt:DI
9984 (match_operand:DI 1 "register_operand" "0")
9988 (set (match_operand:DI 0 "register_operand" "=r")
9989 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9992 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9994 [(set_attr "type" "negnot")
9995 (set_attr "mode" "SI")])
9997 (define_expand "neghi2"
9998 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9999 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10000 (clobber (reg:CC FLAGS_REG))])]
10001 "TARGET_HIMODE_MATH"
10002 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10004 (define_insn "*neghi2_1"
10005 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10006 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10007 (clobber (reg:CC FLAGS_REG))]
10008 "ix86_unary_operator_ok (NEG, HImode, operands)"
10010 [(set_attr "type" "negnot")
10011 (set_attr "mode" "HI")])
10013 (define_insn "*neghi2_cmpz"
10014 [(set (reg:CCZ FLAGS_REG)
10015 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10017 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10018 (neg:HI (match_dup 1)))]
10019 "ix86_unary_operator_ok (NEG, HImode, operands)"
10021 [(set_attr "type" "negnot")
10022 (set_attr "mode" "HI")])
10024 (define_expand "negqi2"
10025 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10026 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10027 (clobber (reg:CC FLAGS_REG))])]
10028 "TARGET_QIMODE_MATH"
10029 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10031 (define_insn "*negqi2_1"
10032 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10033 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10034 (clobber (reg:CC FLAGS_REG))]
10035 "ix86_unary_operator_ok (NEG, QImode, operands)"
10037 [(set_attr "type" "negnot")
10038 (set_attr "mode" "QI")])
10040 (define_insn "*negqi2_cmpz"
10041 [(set (reg:CCZ FLAGS_REG)
10042 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10044 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10045 (neg:QI (match_dup 1)))]
10046 "ix86_unary_operator_ok (NEG, QImode, operands)"
10048 [(set_attr "type" "negnot")
10049 (set_attr "mode" "QI")])
10051 ;; Changing of sign for FP values is doable using integer unit too.
10053 (define_expand "negsf2"
10054 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10055 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10056 "TARGET_80387 || TARGET_SSE_MATH"
10057 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
10059 (define_expand "abssf2"
10060 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10061 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10062 "TARGET_80387 || TARGET_SSE_MATH"
10063 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
10065 (define_insn "*absnegsf2_mixed"
10066 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
10067 (match_operator:SF 3 "absneg_operator"
10068 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
10069 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
10070 (clobber (reg:CC FLAGS_REG))]
10071 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10072 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10075 (define_insn "*absnegsf2_sse"
10076 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
10077 (match_operator:SF 3 "absneg_operator"
10078 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
10079 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
10080 (clobber (reg:CC FLAGS_REG))]
10082 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10085 (define_insn "*absnegsf2_i387"
10086 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
10087 (match_operator:SF 3 "absneg_operator"
10088 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
10089 (use (match_operand 2 "" ""))
10090 (clobber (reg:CC FLAGS_REG))]
10091 "TARGET_80387 && !TARGET_SSE_MATH
10092 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10095 (define_expand "negdf2"
10096 [(set (match_operand:DF 0 "nonimmediate_operand" "")
10097 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10098 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10099 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
10101 (define_expand "absdf2"
10102 [(set (match_operand:DF 0 "nonimmediate_operand" "")
10103 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10104 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10105 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
10107 (define_insn "*absnegdf2_mixed"
10108 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
10109 (match_operator:DF 3 "absneg_operator"
10110 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
10111 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
10112 (clobber (reg:CC FLAGS_REG))]
10113 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10114 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10117 (define_insn "*absnegdf2_sse"
10118 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
10119 (match_operator:DF 3 "absneg_operator"
10120 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10121 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
10122 (clobber (reg:CC FLAGS_REG))]
10123 "TARGET_SSE2 && TARGET_SSE_MATH
10124 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10127 (define_insn "*absnegdf2_i387"
10128 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10129 (match_operator:DF 3 "absneg_operator"
10130 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10131 (use (match_operand 2 "" ""))
10132 (clobber (reg:CC FLAGS_REG))]
10133 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10134 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10137 (define_expand "negxf2"
10138 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10139 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10141 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10143 (define_expand "absxf2"
10144 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10145 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10147 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10149 (define_insn "*absnegxf2_i387"
10150 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10151 (match_operator:XF 3 "absneg_operator"
10152 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10153 (use (match_operand 2 "" ""))
10154 (clobber (reg:CC FLAGS_REG))]
10156 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10159 (define_expand "negtf2"
10160 [(set (match_operand:TF 0 "nonimmediate_operand" "")
10161 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
10163 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10165 (define_expand "abstf2"
10166 [(set (match_operand:TF 0 "nonimmediate_operand" "")
10167 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
10169 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10171 (define_insn "*absnegtf2_sse"
10172 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x,m")
10173 (match_operator:TF 3 "absneg_operator"
10174 [(match_operand:TF 1 "nonimmediate_operand" "0, x,0")]))
10175 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0,X"))
10176 (clobber (reg:CC FLAGS_REG))]
10178 && ix86_unary_operator_ok (GET_CODE (operands[3]), TFmode, operands)"
10181 ;; Splitters for fp abs and neg.
10184 [(set (match_operand 0 "fp_register_operand" "")
10185 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10186 (use (match_operand 2 "" ""))
10187 (clobber (reg:CC FLAGS_REG))]
10189 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10192 [(set (match_operand 0 "register_operand" "")
10193 (match_operator 3 "absneg_operator"
10194 [(match_operand 1 "register_operand" "")]))
10195 (use (match_operand 2 "nonimmediate_operand" ""))
10196 (clobber (reg:CC FLAGS_REG))]
10197 "reload_completed && SSE_REG_P (operands[0])"
10198 [(set (match_dup 0) (match_dup 3))]
10200 enum machine_mode mode = GET_MODE (operands[0]);
10201 enum machine_mode vmode = GET_MODE (operands[2]);
10204 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10205 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10206 if (operands_match_p (operands[0], operands[2]))
10209 operands[1] = operands[2];
10212 if (GET_CODE (operands[3]) == ABS)
10213 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10215 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10220 [(set (match_operand:SF 0 "register_operand" "")
10221 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10222 (use (match_operand:V4SF 2 "" ""))
10223 (clobber (reg:CC FLAGS_REG))]
10225 [(parallel [(set (match_dup 0) (match_dup 1))
10226 (clobber (reg:CC FLAGS_REG))])]
10229 operands[0] = gen_lowpart (SImode, operands[0]);
10230 if (GET_CODE (operands[1]) == ABS)
10232 tmp = gen_int_mode (0x7fffffff, SImode);
10233 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10237 tmp = gen_int_mode (0x80000000, SImode);
10238 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10244 [(set (match_operand:DF 0 "register_operand" "")
10245 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10246 (use (match_operand 2 "" ""))
10247 (clobber (reg:CC FLAGS_REG))]
10249 [(parallel [(set (match_dup 0) (match_dup 1))
10250 (clobber (reg:CC FLAGS_REG))])]
10255 tmp = gen_lowpart (DImode, operands[0]);
10256 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10259 if (GET_CODE (operands[1]) == ABS)
10262 tmp = gen_rtx_NOT (DImode, tmp);
10266 operands[0] = gen_highpart (SImode, operands[0]);
10267 if (GET_CODE (operands[1]) == ABS)
10269 tmp = gen_int_mode (0x7fffffff, SImode);
10270 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10274 tmp = gen_int_mode (0x80000000, SImode);
10275 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10282 [(set (match_operand:XF 0 "register_operand" "")
10283 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10284 (use (match_operand 2 "" ""))
10285 (clobber (reg:CC FLAGS_REG))]
10287 [(parallel [(set (match_dup 0) (match_dup 1))
10288 (clobber (reg:CC FLAGS_REG))])]
10291 operands[0] = gen_rtx_REG (SImode,
10292 true_regnum (operands[0])
10293 + (TARGET_64BIT ? 1 : 2));
10294 if (GET_CODE (operands[1]) == ABS)
10296 tmp = GEN_INT (0x7fff);
10297 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10301 tmp = GEN_INT (0x8000);
10302 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10308 [(set (match_operand 0 "memory_operand" "")
10309 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10310 (use (match_operand 2 "" ""))
10311 (clobber (reg:CC FLAGS_REG))]
10313 [(parallel [(set (match_dup 0) (match_dup 1))
10314 (clobber (reg:CC FLAGS_REG))])]
10316 enum machine_mode mode = GET_MODE (operands[0]);
10317 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10320 operands[0] = adjust_address (operands[0], QImode, size - 1);
10321 if (GET_CODE (operands[1]) == ABS)
10323 tmp = gen_int_mode (0x7f, QImode);
10324 tmp = gen_rtx_AND (QImode, operands[0], tmp);
10328 tmp = gen_int_mode (0x80, QImode);
10329 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10334 ;; Conditionalize these after reload. If they match before reload, we
10335 ;; lose the clobber and ability to use integer instructions.
10337 (define_insn "*negsf2_1"
10338 [(set (match_operand:SF 0 "register_operand" "=f")
10339 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10340 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10342 [(set_attr "type" "fsgn")
10343 (set_attr "mode" "SF")])
10345 (define_insn "*negdf2_1"
10346 [(set (match_operand:DF 0 "register_operand" "=f")
10347 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10348 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10350 [(set_attr "type" "fsgn")
10351 (set_attr "mode" "DF")])
10353 (define_insn "*negxf2_1"
10354 [(set (match_operand:XF 0 "register_operand" "=f")
10355 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10358 [(set_attr "type" "fsgn")
10359 (set_attr "mode" "XF")])
10361 (define_insn "*abssf2_1"
10362 [(set (match_operand:SF 0 "register_operand" "=f")
10363 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10364 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10366 [(set_attr "type" "fsgn")
10367 (set_attr "mode" "SF")])
10369 (define_insn "*absdf2_1"
10370 [(set (match_operand:DF 0 "register_operand" "=f")
10371 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10372 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10374 [(set_attr "type" "fsgn")
10375 (set_attr "mode" "DF")])
10377 (define_insn "*absxf2_1"
10378 [(set (match_operand:XF 0 "register_operand" "=f")
10379 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10382 [(set_attr "type" "fsgn")
10383 (set_attr "mode" "DF")])
10385 (define_insn "*negextendsfdf2"
10386 [(set (match_operand:DF 0 "register_operand" "=f")
10387 (neg:DF (float_extend:DF
10388 (match_operand:SF 1 "register_operand" "0"))))]
10389 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10391 [(set_attr "type" "fsgn")
10392 (set_attr "mode" "DF")])
10394 (define_insn "*negextenddfxf2"
10395 [(set (match_operand:XF 0 "register_operand" "=f")
10396 (neg:XF (float_extend:XF
10397 (match_operand:DF 1 "register_operand" "0"))))]
10400 [(set_attr "type" "fsgn")
10401 (set_attr "mode" "XF")])
10403 (define_insn "*negextendsfxf2"
10404 [(set (match_operand:XF 0 "register_operand" "=f")
10405 (neg:XF (float_extend:XF
10406 (match_operand:SF 1 "register_operand" "0"))))]
10409 [(set_attr "type" "fsgn")
10410 (set_attr "mode" "XF")])
10412 (define_insn "*absextendsfdf2"
10413 [(set (match_operand:DF 0 "register_operand" "=f")
10414 (abs:DF (float_extend:DF
10415 (match_operand:SF 1 "register_operand" "0"))))]
10416 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10418 [(set_attr "type" "fsgn")
10419 (set_attr "mode" "DF")])
10421 (define_insn "*absextenddfxf2"
10422 [(set (match_operand:XF 0 "register_operand" "=f")
10423 (abs:XF (float_extend:XF
10424 (match_operand:DF 1 "register_operand" "0"))))]
10427 [(set_attr "type" "fsgn")
10428 (set_attr "mode" "XF")])
10430 (define_insn "*absextendsfxf2"
10431 [(set (match_operand:XF 0 "register_operand" "=f")
10432 (abs:XF (float_extend:XF
10433 (match_operand:SF 1 "register_operand" "0"))))]
10436 [(set_attr "type" "fsgn")
10437 (set_attr "mode" "XF")])
10439 ;; Copysign instructions
10441 (define_mode_iterator CSGNMODE [SF DF TF])
10442 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10444 (define_expand "copysign<mode>3"
10445 [(match_operand:CSGNMODE 0 "register_operand" "")
10446 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10447 (match_operand:CSGNMODE 2 "register_operand" "")]
10448 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10449 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10451 ix86_expand_copysign (operands);
10455 (define_insn_and_split "copysign<mode>3_const"
10456 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10458 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10459 (match_operand:CSGNMODE 2 "register_operand" "0")
10460 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10462 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10463 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10465 "&& reload_completed"
10468 ix86_split_copysign_const (operands);
10472 (define_insn "copysign<mode>3_var"
10473 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10475 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10476 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10477 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10478 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10480 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10481 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10482 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10486 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10488 [(match_operand:CSGNMODE 2 "register_operand" "")
10489 (match_operand:CSGNMODE 3 "register_operand" "")
10490 (match_operand:<CSGNVMODE> 4 "" "")
10491 (match_operand:<CSGNVMODE> 5 "" "")]
10493 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10494 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10495 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10496 && reload_completed"
10499 ix86_split_copysign_var (operands);
10503 ;; One complement instructions
10505 (define_expand "one_cmpldi2"
10506 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10507 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10509 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10511 (define_insn "*one_cmpldi2_1_rex64"
10512 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10513 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10514 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10516 [(set_attr "type" "negnot")
10517 (set_attr "mode" "DI")])
10519 (define_insn "*one_cmpldi2_2_rex64"
10520 [(set (reg FLAGS_REG)
10521 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10523 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10524 (not:DI (match_dup 1)))]
10525 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10526 && ix86_unary_operator_ok (NOT, DImode, operands)"
10528 [(set_attr "type" "alu1")
10529 (set_attr "mode" "DI")])
10532 [(set (match_operand 0 "flags_reg_operand" "")
10533 (match_operator 2 "compare_operator"
10534 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10536 (set (match_operand:DI 1 "nonimmediate_operand" "")
10537 (not:DI (match_dup 3)))]
10538 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10539 [(parallel [(set (match_dup 0)
10541 [(xor:DI (match_dup 3) (const_int -1))
10544 (xor:DI (match_dup 3) (const_int -1)))])]
10547 (define_expand "one_cmplsi2"
10548 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10549 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10551 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10553 (define_insn "*one_cmplsi2_1"
10554 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10555 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10556 "ix86_unary_operator_ok (NOT, SImode, operands)"
10558 [(set_attr "type" "negnot")
10559 (set_attr "mode" "SI")])
10561 ;; ??? Currently never generated - xor is used instead.
10562 (define_insn "*one_cmplsi2_1_zext"
10563 [(set (match_operand:DI 0 "register_operand" "=r")
10564 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10565 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10567 [(set_attr "type" "negnot")
10568 (set_attr "mode" "SI")])
10570 (define_insn "*one_cmplsi2_2"
10571 [(set (reg FLAGS_REG)
10572 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10574 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10575 (not:SI (match_dup 1)))]
10576 "ix86_match_ccmode (insn, CCNOmode)
10577 && ix86_unary_operator_ok (NOT, SImode, operands)"
10579 [(set_attr "type" "alu1")
10580 (set_attr "mode" "SI")])
10583 [(set (match_operand 0 "flags_reg_operand" "")
10584 (match_operator 2 "compare_operator"
10585 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10587 (set (match_operand:SI 1 "nonimmediate_operand" "")
10588 (not:SI (match_dup 3)))]
10589 "ix86_match_ccmode (insn, CCNOmode)"
10590 [(parallel [(set (match_dup 0)
10591 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10594 (xor:SI (match_dup 3) (const_int -1)))])]
10597 ;; ??? Currently never generated - xor is used instead.
10598 (define_insn "*one_cmplsi2_2_zext"
10599 [(set (reg FLAGS_REG)
10600 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10602 (set (match_operand:DI 0 "register_operand" "=r")
10603 (zero_extend:DI (not:SI (match_dup 1))))]
10604 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10605 && ix86_unary_operator_ok (NOT, SImode, operands)"
10607 [(set_attr "type" "alu1")
10608 (set_attr "mode" "SI")])
10611 [(set (match_operand 0 "flags_reg_operand" "")
10612 (match_operator 2 "compare_operator"
10613 [(not:SI (match_operand:SI 3 "register_operand" ""))
10615 (set (match_operand:DI 1 "register_operand" "")
10616 (zero_extend:DI (not:SI (match_dup 3))))]
10617 "ix86_match_ccmode (insn, CCNOmode)"
10618 [(parallel [(set (match_dup 0)
10619 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10622 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10625 (define_expand "one_cmplhi2"
10626 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10627 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10628 "TARGET_HIMODE_MATH"
10629 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10631 (define_insn "*one_cmplhi2_1"
10632 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10633 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10634 "ix86_unary_operator_ok (NOT, HImode, operands)"
10636 [(set_attr "type" "negnot")
10637 (set_attr "mode" "HI")])
10639 (define_insn "*one_cmplhi2_2"
10640 [(set (reg FLAGS_REG)
10641 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10643 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10644 (not:HI (match_dup 1)))]
10645 "ix86_match_ccmode (insn, CCNOmode)
10646 && ix86_unary_operator_ok (NEG, HImode, operands)"
10648 [(set_attr "type" "alu1")
10649 (set_attr "mode" "HI")])
10652 [(set (match_operand 0 "flags_reg_operand" "")
10653 (match_operator 2 "compare_operator"
10654 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10656 (set (match_operand:HI 1 "nonimmediate_operand" "")
10657 (not:HI (match_dup 3)))]
10658 "ix86_match_ccmode (insn, CCNOmode)"
10659 [(parallel [(set (match_dup 0)
10660 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10663 (xor:HI (match_dup 3) (const_int -1)))])]
10666 ;; %%% Potential partial reg stall on alternative 1. What to do?
10667 (define_expand "one_cmplqi2"
10668 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10669 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10670 "TARGET_QIMODE_MATH"
10671 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10673 (define_insn "*one_cmplqi2_1"
10674 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10675 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10676 "ix86_unary_operator_ok (NOT, QImode, operands)"
10680 [(set_attr "type" "negnot")
10681 (set_attr "mode" "QI,SI")])
10683 (define_insn "*one_cmplqi2_2"
10684 [(set (reg FLAGS_REG)
10685 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10687 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10688 (not:QI (match_dup 1)))]
10689 "ix86_match_ccmode (insn, CCNOmode)
10690 && ix86_unary_operator_ok (NOT, QImode, operands)"
10692 [(set_attr "type" "alu1")
10693 (set_attr "mode" "QI")])
10696 [(set (match_operand 0 "flags_reg_operand" "")
10697 (match_operator 2 "compare_operator"
10698 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10700 (set (match_operand:QI 1 "nonimmediate_operand" "")
10701 (not:QI (match_dup 3)))]
10702 "ix86_match_ccmode (insn, CCNOmode)"
10703 [(parallel [(set (match_dup 0)
10704 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10707 (xor:QI (match_dup 3) (const_int -1)))])]
10710 ;; Arithmetic shift instructions
10712 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10713 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10714 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10715 ;; from the assembler input.
10717 ;; This instruction shifts the target reg/mem as usual, but instead of
10718 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10719 ;; is a left shift double, bits are taken from the high order bits of
10720 ;; reg, else if the insn is a shift right double, bits are taken from the
10721 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10722 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10724 ;; Since sh[lr]d does not change the `reg' operand, that is done
10725 ;; separately, making all shifts emit pairs of shift double and normal
10726 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10727 ;; support a 63 bit shift, each shift where the count is in a reg expands
10728 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10730 ;; If the shift count is a constant, we need never emit more than one
10731 ;; shift pair, instead using moves and sign extension for counts greater
10734 (define_expand "ashlti3"
10735 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10736 (ashift:TI (match_operand:TI 1 "register_operand" "")
10737 (match_operand:QI 2 "nonmemory_operand" "")))
10738 (clobber (reg:CC FLAGS_REG))])]
10741 if (! immediate_operand (operands[2], QImode))
10743 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10746 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10750 (define_insn "ashlti3_1"
10751 [(set (match_operand:TI 0 "register_operand" "=r")
10752 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10753 (match_operand:QI 2 "register_operand" "c")))
10754 (clobber (match_scratch:DI 3 "=&r"))
10755 (clobber (reg:CC FLAGS_REG))]
10758 [(set_attr "type" "multi")])
10760 ;; This pattern must be defined before *ashlti3_2 to prevent
10761 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10763 (define_insn "sse2_ashlti3"
10764 [(set (match_operand:TI 0 "register_operand" "=x")
10765 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10766 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10769 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10770 return "pslldq\t{%2, %0|%0, %2}";
10772 [(set_attr "type" "sseishft")
10773 (set_attr "prefix_data16" "1")
10774 (set_attr "mode" "TI")])
10776 (define_insn "*ashlti3_2"
10777 [(set (match_operand:TI 0 "register_operand" "=r")
10778 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10779 (match_operand:QI 2 "immediate_operand" "O")))
10780 (clobber (reg:CC FLAGS_REG))]
10783 [(set_attr "type" "multi")])
10786 [(set (match_operand:TI 0 "register_operand" "")
10787 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10788 (match_operand:QI 2 "register_operand" "")))
10789 (clobber (match_scratch:DI 3 ""))
10790 (clobber (reg:CC FLAGS_REG))]
10791 "TARGET_64BIT && reload_completed"
10793 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10796 [(set (match_operand:TI 0 "register_operand" "")
10797 (ashift:TI (match_operand:TI 1 "register_operand" "")
10798 (match_operand:QI 2 "immediate_operand" "")))
10799 (clobber (reg:CC FLAGS_REG))]
10800 "TARGET_64BIT && reload_completed"
10802 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10804 (define_insn "x86_64_shld"
10805 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10806 (ior:DI (ashift:DI (match_dup 0)
10807 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10808 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10809 (minus:QI (const_int 64) (match_dup 2)))))
10810 (clobber (reg:CC FLAGS_REG))]
10813 shld{q}\t{%2, %1, %0|%0, %1, %2}
10814 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10815 [(set_attr "type" "ishift")
10816 (set_attr "prefix_0f" "1")
10817 (set_attr "mode" "DI")
10818 (set_attr "athlon_decode" "vector")
10819 (set_attr "amdfam10_decode" "vector")])
10821 (define_expand "x86_64_shift_adj"
10822 [(set (reg:CCZ FLAGS_REG)
10823 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10826 (set (match_operand:DI 0 "register_operand" "")
10827 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10828 (match_operand:DI 1 "register_operand" "")
10831 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10832 (match_operand:DI 3 "register_operand" "r")
10837 (define_expand "ashldi3"
10838 [(set (match_operand:DI 0 "shiftdi_operand" "")
10839 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10840 (match_operand:QI 2 "nonmemory_operand" "")))]
10842 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10844 (define_insn "*ashldi3_1_rex64"
10845 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10846 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10847 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10848 (clobber (reg:CC FLAGS_REG))]
10849 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10851 switch (get_attr_type (insn))
10854 gcc_assert (operands[2] == const1_rtx);
10855 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10856 return "add{q}\t%0, %0";
10859 gcc_assert (CONST_INT_P (operands[2]));
10860 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10861 operands[1] = gen_rtx_MULT (DImode, operands[1],
10862 GEN_INT (1 << INTVAL (operands[2])));
10863 return "lea{q}\t{%a1, %0|%0, %a1}";
10866 if (REG_P (operands[2]))
10867 return "sal{q}\t{%b2, %0|%0, %b2}";
10868 else if (operands[2] == const1_rtx
10869 && (TARGET_SHIFT1 || optimize_size))
10870 return "sal{q}\t%0";
10872 return "sal{q}\t{%2, %0|%0, %2}";
10875 [(set (attr "type")
10876 (cond [(eq_attr "alternative" "1")
10877 (const_string "lea")
10878 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10880 (match_operand 0 "register_operand" ""))
10881 (match_operand 2 "const1_operand" ""))
10882 (const_string "alu")
10884 (const_string "ishift")))
10885 (set_attr "mode" "DI")])
10887 ;; Convert lea to the lea pattern to avoid flags dependency.
10889 [(set (match_operand:DI 0 "register_operand" "")
10890 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10891 (match_operand:QI 2 "immediate_operand" "")))
10892 (clobber (reg:CC FLAGS_REG))]
10893 "TARGET_64BIT && reload_completed
10894 && true_regnum (operands[0]) != true_regnum (operands[1])"
10895 [(set (match_dup 0)
10896 (mult:DI (match_dup 1)
10898 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10900 ;; This pattern can't accept a variable shift count, since shifts by
10901 ;; zero don't affect the flags. We assume that shifts by constant
10902 ;; zero are optimized away.
10903 (define_insn "*ashldi3_cmp_rex64"
10904 [(set (reg FLAGS_REG)
10906 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10907 (match_operand:QI 2 "immediate_operand" "e"))
10909 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10910 (ashift:DI (match_dup 1) (match_dup 2)))]
10913 || !TARGET_PARTIAL_FLAG_REG_STALL
10914 || (operands[2] == const1_rtx
10916 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10917 && ix86_match_ccmode (insn, CCGOCmode)
10918 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10920 switch (get_attr_type (insn))
10923 gcc_assert (operands[2] == const1_rtx);
10924 return "add{q}\t%0, %0";
10927 if (REG_P (operands[2]))
10928 return "sal{q}\t{%b2, %0|%0, %b2}";
10929 else if (operands[2] == const1_rtx
10930 && (TARGET_SHIFT1 || optimize_size))
10931 return "sal{q}\t%0";
10933 return "sal{q}\t{%2, %0|%0, %2}";
10936 [(set (attr "type")
10937 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10939 (match_operand 0 "register_operand" ""))
10940 (match_operand 2 "const1_operand" ""))
10941 (const_string "alu")
10943 (const_string "ishift")))
10944 (set_attr "mode" "DI")])
10946 (define_insn "*ashldi3_cconly_rex64"
10947 [(set (reg FLAGS_REG)
10949 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10950 (match_operand:QI 2 "immediate_operand" "e"))
10952 (clobber (match_scratch:DI 0 "=r"))]
10955 || !TARGET_PARTIAL_FLAG_REG_STALL
10956 || (operands[2] == const1_rtx
10958 || TARGET_DOUBLE_WITH_ADD)))
10959 && ix86_match_ccmode (insn, CCGOCmode)
10960 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10962 switch (get_attr_type (insn))
10965 gcc_assert (operands[2] == const1_rtx);
10966 return "add{q}\t%0, %0";
10969 if (REG_P (operands[2]))
10970 return "sal{q}\t{%b2, %0|%0, %b2}";
10971 else if (operands[2] == const1_rtx
10972 && (TARGET_SHIFT1 || optimize_size))
10973 return "sal{q}\t%0";
10975 return "sal{q}\t{%2, %0|%0, %2}";
10978 [(set (attr "type")
10979 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10981 (match_operand 0 "register_operand" ""))
10982 (match_operand 2 "const1_operand" ""))
10983 (const_string "alu")
10985 (const_string "ishift")))
10986 (set_attr "mode" "DI")])
10988 (define_insn "*ashldi3_1"
10989 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10990 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10991 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10992 (clobber (reg:CC FLAGS_REG))]
10995 [(set_attr "type" "multi")])
10997 ;; By default we don't ask for a scratch register, because when DImode
10998 ;; values are manipulated, registers are already at a premium. But if
10999 ;; we have one handy, we won't turn it away.
11001 [(match_scratch:SI 3 "r")
11002 (parallel [(set (match_operand:DI 0 "register_operand" "")
11003 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11004 (match_operand:QI 2 "nonmemory_operand" "")))
11005 (clobber (reg:CC FLAGS_REG))])
11007 "!TARGET_64BIT && TARGET_CMOVE"
11009 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11012 [(set (match_operand:DI 0 "register_operand" "")
11013 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11014 (match_operand:QI 2 "nonmemory_operand" "")))
11015 (clobber (reg:CC FLAGS_REG))]
11016 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11017 ? epilogue_completed : reload_completed)"
11019 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11021 (define_insn "x86_shld_1"
11022 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11023 (ior:SI (ashift:SI (match_dup 0)
11024 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11025 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11026 (minus:QI (const_int 32) (match_dup 2)))))
11027 (clobber (reg:CC FLAGS_REG))]
11030 shld{l}\t{%2, %1, %0|%0, %1, %2}
11031 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11032 [(set_attr "type" "ishift")
11033 (set_attr "prefix_0f" "1")
11034 (set_attr "mode" "SI")
11035 (set_attr "pent_pair" "np")
11036 (set_attr "athlon_decode" "vector")
11037 (set_attr "amdfam10_decode" "vector")])
11039 (define_expand "x86_shift_adj_1"
11040 [(set (reg:CCZ FLAGS_REG)
11041 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11044 (set (match_operand:SI 0 "register_operand" "")
11045 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11046 (match_operand:SI 1 "register_operand" "")
11049 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11050 (match_operand:SI 3 "register_operand" "r")
11055 (define_expand "x86_shift_adj_2"
11056 [(use (match_operand:SI 0 "register_operand" ""))
11057 (use (match_operand:SI 1 "register_operand" ""))
11058 (use (match_operand:QI 2 "register_operand" ""))]
11061 rtx label = gen_label_rtx ();
11064 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11066 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11067 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11068 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11069 gen_rtx_LABEL_REF (VOIDmode, label),
11071 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11072 JUMP_LABEL (tmp) = label;
11074 emit_move_insn (operands[0], operands[1]);
11075 ix86_expand_clear (operands[1]);
11077 emit_label (label);
11078 LABEL_NUSES (label) = 1;
11083 (define_expand "ashlsi3"
11084 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11085 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11086 (match_operand:QI 2 "nonmemory_operand" "")))
11087 (clobber (reg:CC FLAGS_REG))]
11089 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11091 (define_insn "*ashlsi3_1"
11092 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11093 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11094 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11095 (clobber (reg:CC FLAGS_REG))]
11096 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11098 switch (get_attr_type (insn))
11101 gcc_assert (operands[2] == const1_rtx);
11102 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11103 return "add{l}\t%0, %0";
11109 if (REG_P (operands[2]))
11110 return "sal{l}\t{%b2, %0|%0, %b2}";
11111 else if (operands[2] == const1_rtx
11112 && (TARGET_SHIFT1 || optimize_size))
11113 return "sal{l}\t%0";
11115 return "sal{l}\t{%2, %0|%0, %2}";
11118 [(set (attr "type")
11119 (cond [(eq_attr "alternative" "1")
11120 (const_string "lea")
11121 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11123 (match_operand 0 "register_operand" ""))
11124 (match_operand 2 "const1_operand" ""))
11125 (const_string "alu")
11127 (const_string "ishift")))
11128 (set_attr "mode" "SI")])
11130 ;; Convert lea to the lea pattern to avoid flags dependency.
11132 [(set (match_operand 0 "register_operand" "")
11133 (ashift (match_operand 1 "index_register_operand" "")
11134 (match_operand:QI 2 "const_int_operand" "")))
11135 (clobber (reg:CC FLAGS_REG))]
11137 && true_regnum (operands[0]) != true_regnum (operands[1])
11138 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11142 enum machine_mode mode = GET_MODE (operands[0]);
11144 if (GET_MODE_SIZE (mode) < 4)
11145 operands[0] = gen_lowpart (SImode, operands[0]);
11147 operands[1] = gen_lowpart (Pmode, operands[1]);
11148 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11150 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11151 if (Pmode != SImode)
11152 pat = gen_rtx_SUBREG (SImode, pat, 0);
11153 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11157 ;; Rare case of shifting RSP is handled by generating move and shift
11159 [(set (match_operand 0 "register_operand" "")
11160 (ashift (match_operand 1 "register_operand" "")
11161 (match_operand:QI 2 "const_int_operand" "")))
11162 (clobber (reg:CC FLAGS_REG))]
11164 && true_regnum (operands[0]) != true_regnum (operands[1])"
11168 emit_move_insn (operands[0], operands[1]);
11169 pat = gen_rtx_SET (VOIDmode, operands[0],
11170 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11171 operands[0], operands[2]));
11172 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11173 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11177 (define_insn "*ashlsi3_1_zext"
11178 [(set (match_operand:DI 0 "register_operand" "=r,r")
11179 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11180 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11181 (clobber (reg:CC FLAGS_REG))]
11182 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11184 switch (get_attr_type (insn))
11187 gcc_assert (operands[2] == const1_rtx);
11188 return "add{l}\t%k0, %k0";
11194 if (REG_P (operands[2]))
11195 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11196 else if (operands[2] == const1_rtx
11197 && (TARGET_SHIFT1 || optimize_size))
11198 return "sal{l}\t%k0";
11200 return "sal{l}\t{%2, %k0|%k0, %2}";
11203 [(set (attr "type")
11204 (cond [(eq_attr "alternative" "1")
11205 (const_string "lea")
11206 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11208 (match_operand 2 "const1_operand" ""))
11209 (const_string "alu")
11211 (const_string "ishift")))
11212 (set_attr "mode" "SI")])
11214 ;; Convert lea to the lea pattern to avoid flags dependency.
11216 [(set (match_operand:DI 0 "register_operand" "")
11217 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11218 (match_operand:QI 2 "const_int_operand" ""))))
11219 (clobber (reg:CC FLAGS_REG))]
11220 "TARGET_64BIT && reload_completed
11221 && true_regnum (operands[0]) != true_regnum (operands[1])"
11222 [(set (match_dup 0) (zero_extend:DI
11223 (subreg:SI (mult:SI (match_dup 1)
11224 (match_dup 2)) 0)))]
11226 operands[1] = gen_lowpart (Pmode, operands[1]);
11227 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11230 ;; This pattern can't accept a variable shift count, since shifts by
11231 ;; zero don't affect the flags. We assume that shifts by constant
11232 ;; zero are optimized away.
11233 (define_insn "*ashlsi3_cmp"
11234 [(set (reg FLAGS_REG)
11236 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11237 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11239 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11240 (ashift:SI (match_dup 1) (match_dup 2)))]
11242 || !TARGET_PARTIAL_FLAG_REG_STALL
11243 || (operands[2] == const1_rtx
11245 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11246 && ix86_match_ccmode (insn, CCGOCmode)
11247 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11249 switch (get_attr_type (insn))
11252 gcc_assert (operands[2] == const1_rtx);
11253 return "add{l}\t%0, %0";
11256 if (REG_P (operands[2]))
11257 return "sal{l}\t{%b2, %0|%0, %b2}";
11258 else if (operands[2] == const1_rtx
11259 && (TARGET_SHIFT1 || optimize_size))
11260 return "sal{l}\t%0";
11262 return "sal{l}\t{%2, %0|%0, %2}";
11265 [(set (attr "type")
11266 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11268 (match_operand 0 "register_operand" ""))
11269 (match_operand 2 "const1_operand" ""))
11270 (const_string "alu")
11272 (const_string "ishift")))
11273 (set_attr "mode" "SI")])
11275 (define_insn "*ashlsi3_cconly"
11276 [(set (reg FLAGS_REG)
11278 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11279 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11281 (clobber (match_scratch:SI 0 "=r"))]
11283 || !TARGET_PARTIAL_FLAG_REG_STALL
11284 || (operands[2] == const1_rtx
11286 || TARGET_DOUBLE_WITH_ADD)))
11287 && ix86_match_ccmode (insn, CCGOCmode)
11288 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11290 switch (get_attr_type (insn))
11293 gcc_assert (operands[2] == const1_rtx);
11294 return "add{l}\t%0, %0";
11297 if (REG_P (operands[2]))
11298 return "sal{l}\t{%b2, %0|%0, %b2}";
11299 else if (operands[2] == const1_rtx
11300 && (TARGET_SHIFT1 || optimize_size))
11301 return "sal{l}\t%0";
11303 return "sal{l}\t{%2, %0|%0, %2}";
11306 [(set (attr "type")
11307 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11309 (match_operand 0 "register_operand" ""))
11310 (match_operand 2 "const1_operand" ""))
11311 (const_string "alu")
11313 (const_string "ishift")))
11314 (set_attr "mode" "SI")])
11316 (define_insn "*ashlsi3_cmp_zext"
11317 [(set (reg FLAGS_REG)
11319 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11320 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11322 (set (match_operand:DI 0 "register_operand" "=r")
11323 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11326 || !TARGET_PARTIAL_FLAG_REG_STALL
11327 || (operands[2] == const1_rtx
11329 || TARGET_DOUBLE_WITH_ADD)))
11330 && ix86_match_ccmode (insn, CCGOCmode)
11331 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11333 switch (get_attr_type (insn))
11336 gcc_assert (operands[2] == const1_rtx);
11337 return "add{l}\t%k0, %k0";
11340 if (REG_P (operands[2]))
11341 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11342 else if (operands[2] == const1_rtx
11343 && (TARGET_SHIFT1 || optimize_size))
11344 return "sal{l}\t%k0";
11346 return "sal{l}\t{%2, %k0|%k0, %2}";
11349 [(set (attr "type")
11350 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11352 (match_operand 2 "const1_operand" ""))
11353 (const_string "alu")
11355 (const_string "ishift")))
11356 (set_attr "mode" "SI")])
11358 (define_expand "ashlhi3"
11359 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11360 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11361 (match_operand:QI 2 "nonmemory_operand" "")))
11362 (clobber (reg:CC FLAGS_REG))]
11363 "TARGET_HIMODE_MATH"
11364 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11366 (define_insn "*ashlhi3_1_lea"
11367 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11368 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11369 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11370 (clobber (reg:CC FLAGS_REG))]
11371 "!TARGET_PARTIAL_REG_STALL
11372 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11374 switch (get_attr_type (insn))
11379 gcc_assert (operands[2] == const1_rtx);
11380 return "add{w}\t%0, %0";
11383 if (REG_P (operands[2]))
11384 return "sal{w}\t{%b2, %0|%0, %b2}";
11385 else if (operands[2] == const1_rtx
11386 && (TARGET_SHIFT1 || optimize_size))
11387 return "sal{w}\t%0";
11389 return "sal{w}\t{%2, %0|%0, %2}";
11392 [(set (attr "type")
11393 (cond [(eq_attr "alternative" "1")
11394 (const_string "lea")
11395 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11397 (match_operand 0 "register_operand" ""))
11398 (match_operand 2 "const1_operand" ""))
11399 (const_string "alu")
11401 (const_string "ishift")))
11402 (set_attr "mode" "HI,SI")])
11404 (define_insn "*ashlhi3_1"
11405 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11406 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11407 (match_operand:QI 2 "nonmemory_operand" "cI")))
11408 (clobber (reg:CC FLAGS_REG))]
11409 "TARGET_PARTIAL_REG_STALL
11410 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11412 switch (get_attr_type (insn))
11415 gcc_assert (operands[2] == const1_rtx);
11416 return "add{w}\t%0, %0";
11419 if (REG_P (operands[2]))
11420 return "sal{w}\t{%b2, %0|%0, %b2}";
11421 else if (operands[2] == const1_rtx
11422 && (TARGET_SHIFT1 || optimize_size))
11423 return "sal{w}\t%0";
11425 return "sal{w}\t{%2, %0|%0, %2}";
11428 [(set (attr "type")
11429 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11431 (match_operand 0 "register_operand" ""))
11432 (match_operand 2 "const1_operand" ""))
11433 (const_string "alu")
11435 (const_string "ishift")))
11436 (set_attr "mode" "HI")])
11438 ;; This pattern can't accept a variable shift count, since shifts by
11439 ;; zero don't affect the flags. We assume that shifts by constant
11440 ;; zero are optimized away.
11441 (define_insn "*ashlhi3_cmp"
11442 [(set (reg FLAGS_REG)
11444 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11445 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11447 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11448 (ashift:HI (match_dup 1) (match_dup 2)))]
11450 || !TARGET_PARTIAL_FLAG_REG_STALL
11451 || (operands[2] == const1_rtx
11453 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11454 && ix86_match_ccmode (insn, CCGOCmode)
11455 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11457 switch (get_attr_type (insn))
11460 gcc_assert (operands[2] == const1_rtx);
11461 return "add{w}\t%0, %0";
11464 if (REG_P (operands[2]))
11465 return "sal{w}\t{%b2, %0|%0, %b2}";
11466 else if (operands[2] == const1_rtx
11467 && (TARGET_SHIFT1 || optimize_size))
11468 return "sal{w}\t%0";
11470 return "sal{w}\t{%2, %0|%0, %2}";
11473 [(set (attr "type")
11474 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11476 (match_operand 0 "register_operand" ""))
11477 (match_operand 2 "const1_operand" ""))
11478 (const_string "alu")
11480 (const_string "ishift")))
11481 (set_attr "mode" "HI")])
11483 (define_insn "*ashlhi3_cconly"
11484 [(set (reg FLAGS_REG)
11486 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11487 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11489 (clobber (match_scratch:HI 0 "=r"))]
11491 || !TARGET_PARTIAL_FLAG_REG_STALL
11492 || (operands[2] == const1_rtx
11494 || TARGET_DOUBLE_WITH_ADD)))
11495 && ix86_match_ccmode (insn, CCGOCmode)
11496 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11498 switch (get_attr_type (insn))
11501 gcc_assert (operands[2] == const1_rtx);
11502 return "add{w}\t%0, %0";
11505 if (REG_P (operands[2]))
11506 return "sal{w}\t{%b2, %0|%0, %b2}";
11507 else if (operands[2] == const1_rtx
11508 && (TARGET_SHIFT1 || optimize_size))
11509 return "sal{w}\t%0";
11511 return "sal{w}\t{%2, %0|%0, %2}";
11514 [(set (attr "type")
11515 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11517 (match_operand 0 "register_operand" ""))
11518 (match_operand 2 "const1_operand" ""))
11519 (const_string "alu")
11521 (const_string "ishift")))
11522 (set_attr "mode" "HI")])
11524 (define_expand "ashlqi3"
11525 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11526 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11527 (match_operand:QI 2 "nonmemory_operand" "")))
11528 (clobber (reg:CC FLAGS_REG))]
11529 "TARGET_QIMODE_MATH"
11530 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11532 ;; %%% Potential partial reg stall on alternative 2. What to do?
11534 (define_insn "*ashlqi3_1_lea"
11535 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11536 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11537 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11538 (clobber (reg:CC FLAGS_REG))]
11539 "!TARGET_PARTIAL_REG_STALL
11540 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11542 switch (get_attr_type (insn))
11547 gcc_assert (operands[2] == const1_rtx);
11548 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11549 return "add{l}\t%k0, %k0";
11551 return "add{b}\t%0, %0";
11554 if (REG_P (operands[2]))
11556 if (get_attr_mode (insn) == MODE_SI)
11557 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11559 return "sal{b}\t{%b2, %0|%0, %b2}";
11561 else if (operands[2] == const1_rtx
11562 && (TARGET_SHIFT1 || optimize_size))
11564 if (get_attr_mode (insn) == MODE_SI)
11565 return "sal{l}\t%0";
11567 return "sal{b}\t%0";
11571 if (get_attr_mode (insn) == MODE_SI)
11572 return "sal{l}\t{%2, %k0|%k0, %2}";
11574 return "sal{b}\t{%2, %0|%0, %2}";
11578 [(set (attr "type")
11579 (cond [(eq_attr "alternative" "2")
11580 (const_string "lea")
11581 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11583 (match_operand 0 "register_operand" ""))
11584 (match_operand 2 "const1_operand" ""))
11585 (const_string "alu")
11587 (const_string "ishift")))
11588 (set_attr "mode" "QI,SI,SI")])
11590 (define_insn "*ashlqi3_1"
11591 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11592 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11593 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11594 (clobber (reg:CC FLAGS_REG))]
11595 "TARGET_PARTIAL_REG_STALL
11596 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11598 switch (get_attr_type (insn))
11601 gcc_assert (operands[2] == const1_rtx);
11602 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11603 return "add{l}\t%k0, %k0";
11605 return "add{b}\t%0, %0";
11608 if (REG_P (operands[2]))
11610 if (get_attr_mode (insn) == MODE_SI)
11611 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11613 return "sal{b}\t{%b2, %0|%0, %b2}";
11615 else if (operands[2] == const1_rtx
11616 && (TARGET_SHIFT1 || optimize_size))
11618 if (get_attr_mode (insn) == MODE_SI)
11619 return "sal{l}\t%0";
11621 return "sal{b}\t%0";
11625 if (get_attr_mode (insn) == MODE_SI)
11626 return "sal{l}\t{%2, %k0|%k0, %2}";
11628 return "sal{b}\t{%2, %0|%0, %2}";
11632 [(set (attr "type")
11633 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11635 (match_operand 0 "register_operand" ""))
11636 (match_operand 2 "const1_operand" ""))
11637 (const_string "alu")
11639 (const_string "ishift")))
11640 (set_attr "mode" "QI,SI")])
11642 ;; This pattern can't accept a variable shift count, since shifts by
11643 ;; zero don't affect the flags. We assume that shifts by constant
11644 ;; zero are optimized away.
11645 (define_insn "*ashlqi3_cmp"
11646 [(set (reg FLAGS_REG)
11648 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11649 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11651 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11652 (ashift:QI (match_dup 1) (match_dup 2)))]
11654 || !TARGET_PARTIAL_FLAG_REG_STALL
11655 || (operands[2] == const1_rtx
11657 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11658 && ix86_match_ccmode (insn, CCGOCmode)
11659 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11661 switch (get_attr_type (insn))
11664 gcc_assert (operands[2] == const1_rtx);
11665 return "add{b}\t%0, %0";
11668 if (REG_P (operands[2]))
11669 return "sal{b}\t{%b2, %0|%0, %b2}";
11670 else if (operands[2] == const1_rtx
11671 && (TARGET_SHIFT1 || optimize_size))
11672 return "sal{b}\t%0";
11674 return "sal{b}\t{%2, %0|%0, %2}";
11677 [(set (attr "type")
11678 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11680 (match_operand 0 "register_operand" ""))
11681 (match_operand 2 "const1_operand" ""))
11682 (const_string "alu")
11684 (const_string "ishift")))
11685 (set_attr "mode" "QI")])
11687 (define_insn "*ashlqi3_cconly"
11688 [(set (reg FLAGS_REG)
11690 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11691 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11693 (clobber (match_scratch:QI 0 "=q"))]
11695 || !TARGET_PARTIAL_FLAG_REG_STALL
11696 || (operands[2] == const1_rtx
11698 || TARGET_DOUBLE_WITH_ADD)))
11699 && ix86_match_ccmode (insn, CCGOCmode)
11700 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11702 switch (get_attr_type (insn))
11705 gcc_assert (operands[2] == const1_rtx);
11706 return "add{b}\t%0, %0";
11709 if (REG_P (operands[2]))
11710 return "sal{b}\t{%b2, %0|%0, %b2}";
11711 else if (operands[2] == const1_rtx
11712 && (TARGET_SHIFT1 || optimize_size))
11713 return "sal{b}\t%0";
11715 return "sal{b}\t{%2, %0|%0, %2}";
11718 [(set (attr "type")
11719 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11721 (match_operand 0 "register_operand" ""))
11722 (match_operand 2 "const1_operand" ""))
11723 (const_string "alu")
11725 (const_string "ishift")))
11726 (set_attr "mode" "QI")])
11728 ;; See comment above `ashldi3' about how this works.
11730 (define_expand "ashrti3"
11731 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11732 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11733 (match_operand:QI 2 "nonmemory_operand" "")))
11734 (clobber (reg:CC FLAGS_REG))])]
11737 if (! immediate_operand (operands[2], QImode))
11739 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11742 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11746 (define_insn "ashrti3_1"
11747 [(set (match_operand:TI 0 "register_operand" "=r")
11748 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11749 (match_operand:QI 2 "register_operand" "c")))
11750 (clobber (match_scratch:DI 3 "=&r"))
11751 (clobber (reg:CC FLAGS_REG))]
11754 [(set_attr "type" "multi")])
11756 (define_insn "*ashrti3_2"
11757 [(set (match_operand:TI 0 "register_operand" "=r")
11758 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11759 (match_operand:QI 2 "immediate_operand" "O")))
11760 (clobber (reg:CC FLAGS_REG))]
11763 [(set_attr "type" "multi")])
11766 [(set (match_operand:TI 0 "register_operand" "")
11767 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11768 (match_operand:QI 2 "register_operand" "")))
11769 (clobber (match_scratch:DI 3 ""))
11770 (clobber (reg:CC FLAGS_REG))]
11771 "TARGET_64BIT && reload_completed"
11773 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11776 [(set (match_operand:TI 0 "register_operand" "")
11777 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11778 (match_operand:QI 2 "immediate_operand" "")))
11779 (clobber (reg:CC FLAGS_REG))]
11780 "TARGET_64BIT && reload_completed"
11782 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11784 (define_insn "x86_64_shrd"
11785 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11786 (ior:DI (ashiftrt:DI (match_dup 0)
11787 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11788 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11789 (minus:QI (const_int 64) (match_dup 2)))))
11790 (clobber (reg:CC FLAGS_REG))]
11793 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11794 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11795 [(set_attr "type" "ishift")
11796 (set_attr "prefix_0f" "1")
11797 (set_attr "mode" "DI")
11798 (set_attr "athlon_decode" "vector")
11799 (set_attr "amdfam10_decode" "vector")])
11801 (define_expand "ashrdi3"
11802 [(set (match_operand:DI 0 "shiftdi_operand" "")
11803 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11804 (match_operand:QI 2 "nonmemory_operand" "")))]
11806 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11808 (define_insn "*ashrdi3_63_rex64"
11809 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11810 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11811 (match_operand:DI 2 "const_int_operand" "i,i")))
11812 (clobber (reg:CC FLAGS_REG))]
11813 "TARGET_64BIT && INTVAL (operands[2]) == 63
11814 && (TARGET_USE_CLTD || optimize_size)
11815 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11818 sar{q}\t{%2, %0|%0, %2}"
11819 [(set_attr "type" "imovx,ishift")
11820 (set_attr "prefix_0f" "0,*")
11821 (set_attr "length_immediate" "0,*")
11822 (set_attr "modrm" "0,1")
11823 (set_attr "mode" "DI")])
11825 (define_insn "*ashrdi3_1_one_bit_rex64"
11826 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11827 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11828 (match_operand:QI 2 "const1_operand" "")))
11829 (clobber (reg:CC FLAGS_REG))]
11831 && (TARGET_SHIFT1 || optimize_size)
11832 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11834 [(set_attr "type" "ishift")
11835 (set (attr "length")
11836 (if_then_else (match_operand:DI 0 "register_operand" "")
11838 (const_string "*")))])
11840 (define_insn "*ashrdi3_1_rex64"
11841 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11842 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11843 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11844 (clobber (reg:CC FLAGS_REG))]
11845 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11847 sar{q}\t{%2, %0|%0, %2}
11848 sar{q}\t{%b2, %0|%0, %b2}"
11849 [(set_attr "type" "ishift")
11850 (set_attr "mode" "DI")])
11852 ;; This pattern can't accept a variable shift count, since shifts by
11853 ;; zero don't affect the flags. We assume that shifts by constant
11854 ;; zero are optimized away.
11855 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11856 [(set (reg FLAGS_REG)
11858 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11859 (match_operand:QI 2 "const1_operand" ""))
11861 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11862 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11864 && (TARGET_SHIFT1 || optimize_size)
11865 && ix86_match_ccmode (insn, CCGOCmode)
11866 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11868 [(set_attr "type" "ishift")
11869 (set (attr "length")
11870 (if_then_else (match_operand:DI 0 "register_operand" "")
11872 (const_string "*")))])
11874 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11875 [(set (reg FLAGS_REG)
11877 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11878 (match_operand:QI 2 "const1_operand" ""))
11880 (clobber (match_scratch:DI 0 "=r"))]
11882 && (TARGET_SHIFT1 || optimize_size)
11883 && ix86_match_ccmode (insn, CCGOCmode)
11884 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11886 [(set_attr "type" "ishift")
11887 (set_attr "length" "2")])
11889 ;; This pattern can't accept a variable shift count, since shifts by
11890 ;; zero don't affect the flags. We assume that shifts by constant
11891 ;; zero are optimized away.
11892 (define_insn "*ashrdi3_cmp_rex64"
11893 [(set (reg FLAGS_REG)
11895 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11896 (match_operand:QI 2 "const_int_operand" "n"))
11898 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11899 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11901 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11902 && ix86_match_ccmode (insn, CCGOCmode)
11903 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11904 "sar{q}\t{%2, %0|%0, %2}"
11905 [(set_attr "type" "ishift")
11906 (set_attr "mode" "DI")])
11908 (define_insn "*ashrdi3_cconly_rex64"
11909 [(set (reg FLAGS_REG)
11911 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11912 (match_operand:QI 2 "const_int_operand" "n"))
11914 (clobber (match_scratch:DI 0 "=r"))]
11916 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11917 && ix86_match_ccmode (insn, CCGOCmode)
11918 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11919 "sar{q}\t{%2, %0|%0, %2}"
11920 [(set_attr "type" "ishift")
11921 (set_attr "mode" "DI")])
11923 (define_insn "*ashrdi3_1"
11924 [(set (match_operand:DI 0 "register_operand" "=r")
11925 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11926 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11927 (clobber (reg:CC FLAGS_REG))]
11930 [(set_attr "type" "multi")])
11932 ;; By default we don't ask for a scratch register, because when DImode
11933 ;; values are manipulated, registers are already at a premium. But if
11934 ;; we have one handy, we won't turn it away.
11936 [(match_scratch:SI 3 "r")
11937 (parallel [(set (match_operand:DI 0 "register_operand" "")
11938 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11939 (match_operand:QI 2 "nonmemory_operand" "")))
11940 (clobber (reg:CC FLAGS_REG))])
11942 "!TARGET_64BIT && TARGET_CMOVE"
11944 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11947 [(set (match_operand:DI 0 "register_operand" "")
11948 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11949 (match_operand:QI 2 "nonmemory_operand" "")))
11950 (clobber (reg:CC FLAGS_REG))]
11951 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11952 ? epilogue_completed : reload_completed)"
11954 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11956 (define_insn "x86_shrd_1"
11957 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11958 (ior:SI (ashiftrt:SI (match_dup 0)
11959 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11960 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11961 (minus:QI (const_int 32) (match_dup 2)))))
11962 (clobber (reg:CC FLAGS_REG))]
11965 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11966 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11967 [(set_attr "type" "ishift")
11968 (set_attr "prefix_0f" "1")
11969 (set_attr "pent_pair" "np")
11970 (set_attr "mode" "SI")])
11972 (define_expand "x86_shift_adj_3"
11973 [(use (match_operand:SI 0 "register_operand" ""))
11974 (use (match_operand:SI 1 "register_operand" ""))
11975 (use (match_operand:QI 2 "register_operand" ""))]
11978 rtx label = gen_label_rtx ();
11981 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11983 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11984 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11985 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11986 gen_rtx_LABEL_REF (VOIDmode, label),
11988 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11989 JUMP_LABEL (tmp) = label;
11991 emit_move_insn (operands[0], operands[1]);
11992 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11994 emit_label (label);
11995 LABEL_NUSES (label) = 1;
12000 (define_insn "ashrsi3_31"
12001 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12002 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12003 (match_operand:SI 2 "const_int_operand" "i,i")))
12004 (clobber (reg:CC FLAGS_REG))]
12005 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12006 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12009 sar{l}\t{%2, %0|%0, %2}"
12010 [(set_attr "type" "imovx,ishift")
12011 (set_attr "prefix_0f" "0,*")
12012 (set_attr "length_immediate" "0,*")
12013 (set_attr "modrm" "0,1")
12014 (set_attr "mode" "SI")])
12016 (define_insn "*ashrsi3_31_zext"
12017 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12018 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12019 (match_operand:SI 2 "const_int_operand" "i,i"))))
12020 (clobber (reg:CC FLAGS_REG))]
12021 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12022 && INTVAL (operands[2]) == 31
12023 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12026 sar{l}\t{%2, %k0|%k0, %2}"
12027 [(set_attr "type" "imovx,ishift")
12028 (set_attr "prefix_0f" "0,*")
12029 (set_attr "length_immediate" "0,*")
12030 (set_attr "modrm" "0,1")
12031 (set_attr "mode" "SI")])
12033 (define_expand "ashrsi3"
12034 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12035 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12036 (match_operand:QI 2 "nonmemory_operand" "")))
12037 (clobber (reg:CC FLAGS_REG))]
12039 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12041 (define_insn "*ashrsi3_1_one_bit"
12042 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12043 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12044 (match_operand:QI 2 "const1_operand" "")))
12045 (clobber (reg:CC FLAGS_REG))]
12046 "(TARGET_SHIFT1 || optimize_size)
12047 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12049 [(set_attr "type" "ishift")
12050 (set (attr "length")
12051 (if_then_else (match_operand:SI 0 "register_operand" "")
12053 (const_string "*")))])
12055 (define_insn "*ashrsi3_1_one_bit_zext"
12056 [(set (match_operand:DI 0 "register_operand" "=r")
12057 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12058 (match_operand:QI 2 "const1_operand" ""))))
12059 (clobber (reg:CC FLAGS_REG))]
12061 && (TARGET_SHIFT1 || optimize_size)
12062 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12064 [(set_attr "type" "ishift")
12065 (set_attr "length" "2")])
12067 (define_insn "*ashrsi3_1"
12068 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12069 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12070 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12071 (clobber (reg:CC FLAGS_REG))]
12072 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12074 sar{l}\t{%2, %0|%0, %2}
12075 sar{l}\t{%b2, %0|%0, %b2}"
12076 [(set_attr "type" "ishift")
12077 (set_attr "mode" "SI")])
12079 (define_insn "*ashrsi3_1_zext"
12080 [(set (match_operand:DI 0 "register_operand" "=r,r")
12081 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12082 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12083 (clobber (reg:CC FLAGS_REG))]
12084 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12086 sar{l}\t{%2, %k0|%k0, %2}
12087 sar{l}\t{%b2, %k0|%k0, %b2}"
12088 [(set_attr "type" "ishift")
12089 (set_attr "mode" "SI")])
12091 ;; This pattern can't accept a variable shift count, since shifts by
12092 ;; zero don't affect the flags. We assume that shifts by constant
12093 ;; zero are optimized away.
12094 (define_insn "*ashrsi3_one_bit_cmp"
12095 [(set (reg FLAGS_REG)
12097 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12098 (match_operand:QI 2 "const1_operand" ""))
12100 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12101 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12102 "(TARGET_SHIFT1 || optimize_size)
12103 && ix86_match_ccmode (insn, CCGOCmode)
12104 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12106 [(set_attr "type" "ishift")
12107 (set (attr "length")
12108 (if_then_else (match_operand:SI 0 "register_operand" "")
12110 (const_string "*")))])
12112 (define_insn "*ashrsi3_one_bit_cconly"
12113 [(set (reg FLAGS_REG)
12115 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12116 (match_operand:QI 2 "const1_operand" ""))
12118 (clobber (match_scratch:SI 0 "=r"))]
12119 "(TARGET_SHIFT1 || optimize_size)
12120 && ix86_match_ccmode (insn, CCGOCmode)
12121 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12123 [(set_attr "type" "ishift")
12124 (set_attr "length" "2")])
12126 (define_insn "*ashrsi3_one_bit_cmp_zext"
12127 [(set (reg FLAGS_REG)
12129 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12130 (match_operand:QI 2 "const1_operand" ""))
12132 (set (match_operand:DI 0 "register_operand" "=r")
12133 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12135 && (TARGET_SHIFT1 || optimize_size)
12136 && ix86_match_ccmode (insn, CCmode)
12137 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12139 [(set_attr "type" "ishift")
12140 (set_attr "length" "2")])
12142 ;; This pattern can't accept a variable shift count, since shifts by
12143 ;; zero don't affect the flags. We assume that shifts by constant
12144 ;; zero are optimized away.
12145 (define_insn "*ashrsi3_cmp"
12146 [(set (reg FLAGS_REG)
12148 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12149 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12151 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12152 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12153 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12154 && ix86_match_ccmode (insn, CCGOCmode)
12155 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12156 "sar{l}\t{%2, %0|%0, %2}"
12157 [(set_attr "type" "ishift")
12158 (set_attr "mode" "SI")])
12160 (define_insn "*ashrsi3_cconly"
12161 [(set (reg FLAGS_REG)
12163 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12164 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12166 (clobber (match_scratch:SI 0 "=r"))]
12167 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12168 && ix86_match_ccmode (insn, CCGOCmode)
12169 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12170 "sar{l}\t{%2, %0|%0, %2}"
12171 [(set_attr "type" "ishift")
12172 (set_attr "mode" "SI")])
12174 (define_insn "*ashrsi3_cmp_zext"
12175 [(set (reg FLAGS_REG)
12177 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12178 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12180 (set (match_operand:DI 0 "register_operand" "=r")
12181 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12183 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12184 && ix86_match_ccmode (insn, CCGOCmode)
12185 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12186 "sar{l}\t{%2, %k0|%k0, %2}"
12187 [(set_attr "type" "ishift")
12188 (set_attr "mode" "SI")])
12190 (define_expand "ashrhi3"
12191 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12192 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12193 (match_operand:QI 2 "nonmemory_operand" "")))
12194 (clobber (reg:CC FLAGS_REG))]
12195 "TARGET_HIMODE_MATH"
12196 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12198 (define_insn "*ashrhi3_1_one_bit"
12199 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12200 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12201 (match_operand:QI 2 "const1_operand" "")))
12202 (clobber (reg:CC FLAGS_REG))]
12203 "(TARGET_SHIFT1 || optimize_size)
12204 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12206 [(set_attr "type" "ishift")
12207 (set (attr "length")
12208 (if_then_else (match_operand 0 "register_operand" "")
12210 (const_string "*")))])
12212 (define_insn "*ashrhi3_1"
12213 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12214 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12215 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12216 (clobber (reg:CC FLAGS_REG))]
12217 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12219 sar{w}\t{%2, %0|%0, %2}
12220 sar{w}\t{%b2, %0|%0, %b2}"
12221 [(set_attr "type" "ishift")
12222 (set_attr "mode" "HI")])
12224 ;; This pattern can't accept a variable shift count, since shifts by
12225 ;; zero don't affect the flags. We assume that shifts by constant
12226 ;; zero are optimized away.
12227 (define_insn "*ashrhi3_one_bit_cmp"
12228 [(set (reg FLAGS_REG)
12230 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12231 (match_operand:QI 2 "const1_operand" ""))
12233 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12234 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12235 "(TARGET_SHIFT1 || optimize_size)
12236 && ix86_match_ccmode (insn, CCGOCmode)
12237 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12239 [(set_attr "type" "ishift")
12240 (set (attr "length")
12241 (if_then_else (match_operand 0 "register_operand" "")
12243 (const_string "*")))])
12245 (define_insn "*ashrhi3_one_bit_cconly"
12246 [(set (reg FLAGS_REG)
12248 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12249 (match_operand:QI 2 "const1_operand" ""))
12251 (clobber (match_scratch:HI 0 "=r"))]
12252 "(TARGET_SHIFT1 || optimize_size)
12253 && ix86_match_ccmode (insn, CCGOCmode)
12254 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12256 [(set_attr "type" "ishift")
12257 (set_attr "length" "2")])
12259 ;; This pattern can't accept a variable shift count, since shifts by
12260 ;; zero don't affect the flags. We assume that shifts by constant
12261 ;; zero are optimized away.
12262 (define_insn "*ashrhi3_cmp"
12263 [(set (reg FLAGS_REG)
12265 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12266 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12268 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12269 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12270 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12271 && ix86_match_ccmode (insn, CCGOCmode)
12272 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12273 "sar{w}\t{%2, %0|%0, %2}"
12274 [(set_attr "type" "ishift")
12275 (set_attr "mode" "HI")])
12277 (define_insn "*ashrhi3_cconly"
12278 [(set (reg FLAGS_REG)
12280 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12281 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12283 (clobber (match_scratch:HI 0 "=r"))]
12284 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12285 && ix86_match_ccmode (insn, CCGOCmode)
12286 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12287 "sar{w}\t{%2, %0|%0, %2}"
12288 [(set_attr "type" "ishift")
12289 (set_attr "mode" "HI")])
12291 (define_expand "ashrqi3"
12292 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12293 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12294 (match_operand:QI 2 "nonmemory_operand" "")))
12295 (clobber (reg:CC FLAGS_REG))]
12296 "TARGET_QIMODE_MATH"
12297 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12299 (define_insn "*ashrqi3_1_one_bit"
12300 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12301 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12302 (match_operand:QI 2 "const1_operand" "")))
12303 (clobber (reg:CC FLAGS_REG))]
12304 "(TARGET_SHIFT1 || optimize_size)
12305 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12307 [(set_attr "type" "ishift")
12308 (set (attr "length")
12309 (if_then_else (match_operand 0 "register_operand" "")
12311 (const_string "*")))])
12313 (define_insn "*ashrqi3_1_one_bit_slp"
12314 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12315 (ashiftrt:QI (match_dup 0)
12316 (match_operand:QI 1 "const1_operand" "")))
12317 (clobber (reg:CC FLAGS_REG))]
12318 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12319 && (TARGET_SHIFT1 || optimize_size)
12320 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12322 [(set_attr "type" "ishift1")
12323 (set (attr "length")
12324 (if_then_else (match_operand 0 "register_operand" "")
12326 (const_string "*")))])
12328 (define_insn "*ashrqi3_1"
12329 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12330 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12331 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12332 (clobber (reg:CC FLAGS_REG))]
12333 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12335 sar{b}\t{%2, %0|%0, %2}
12336 sar{b}\t{%b2, %0|%0, %b2}"
12337 [(set_attr "type" "ishift")
12338 (set_attr "mode" "QI")])
12340 (define_insn "*ashrqi3_1_slp"
12341 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12342 (ashiftrt:QI (match_dup 0)
12343 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12344 (clobber (reg:CC FLAGS_REG))]
12345 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12346 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12348 sar{b}\t{%1, %0|%0, %1}
12349 sar{b}\t{%b1, %0|%0, %b1}"
12350 [(set_attr "type" "ishift1")
12351 (set_attr "mode" "QI")])
12353 ;; This pattern can't accept a variable shift count, since shifts by
12354 ;; zero don't affect the flags. We assume that shifts by constant
12355 ;; zero are optimized away.
12356 (define_insn "*ashrqi3_one_bit_cmp"
12357 [(set (reg FLAGS_REG)
12359 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12360 (match_operand:QI 2 "const1_operand" "I"))
12362 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12363 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12364 "(TARGET_SHIFT1 || optimize_size)
12365 && ix86_match_ccmode (insn, CCGOCmode)
12366 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12368 [(set_attr "type" "ishift")
12369 (set (attr "length")
12370 (if_then_else (match_operand 0 "register_operand" "")
12372 (const_string "*")))])
12374 (define_insn "*ashrqi3_one_bit_cconly"
12375 [(set (reg FLAGS_REG)
12377 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12378 (match_operand:QI 2 "const1_operand" "I"))
12380 (clobber (match_scratch:QI 0 "=q"))]
12381 "(TARGET_SHIFT1 || optimize_size)
12382 && ix86_match_ccmode (insn, CCGOCmode)
12383 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12385 [(set_attr "type" "ishift")
12386 (set_attr "length" "2")])
12388 ;; This pattern can't accept a variable shift count, since shifts by
12389 ;; zero don't affect the flags. We assume that shifts by constant
12390 ;; zero are optimized away.
12391 (define_insn "*ashrqi3_cmp"
12392 [(set (reg FLAGS_REG)
12394 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12395 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12397 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12398 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12399 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12400 && ix86_match_ccmode (insn, CCGOCmode)
12401 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12402 "sar{b}\t{%2, %0|%0, %2}"
12403 [(set_attr "type" "ishift")
12404 (set_attr "mode" "QI")])
12406 (define_insn "*ashrqi3_cconly"
12407 [(set (reg FLAGS_REG)
12409 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12410 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12412 (clobber (match_scratch:QI 0 "=q"))]
12413 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12414 && ix86_match_ccmode (insn, CCGOCmode)
12415 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12416 "sar{b}\t{%2, %0|%0, %2}"
12417 [(set_attr "type" "ishift")
12418 (set_attr "mode" "QI")])
12421 ;; Logical shift instructions
12423 ;; See comment above `ashldi3' about how this works.
12425 (define_expand "lshrti3"
12426 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12427 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12428 (match_operand:QI 2 "nonmemory_operand" "")))
12429 (clobber (reg:CC FLAGS_REG))])]
12432 if (! immediate_operand (operands[2], QImode))
12434 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12437 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12441 (define_insn "lshrti3_1"
12442 [(set (match_operand:TI 0 "register_operand" "=r")
12443 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12444 (match_operand:QI 2 "register_operand" "c")))
12445 (clobber (match_scratch:DI 3 "=&r"))
12446 (clobber (reg:CC FLAGS_REG))]
12449 [(set_attr "type" "multi")])
12451 ;; This pattern must be defined before *lshrti3_2 to prevent
12452 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12454 (define_insn "sse2_lshrti3"
12455 [(set (match_operand:TI 0 "register_operand" "=x")
12456 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12457 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12460 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12461 return "psrldq\t{%2, %0|%0, %2}";
12463 [(set_attr "type" "sseishft")
12464 (set_attr "prefix_data16" "1")
12465 (set_attr "mode" "TI")])
12467 (define_insn "*lshrti3_2"
12468 [(set (match_operand:TI 0 "register_operand" "=r")
12469 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12470 (match_operand:QI 2 "immediate_operand" "O")))
12471 (clobber (reg:CC FLAGS_REG))]
12474 [(set_attr "type" "multi")])
12477 [(set (match_operand:TI 0 "register_operand" "")
12478 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12479 (match_operand:QI 2 "register_operand" "")))
12480 (clobber (match_scratch:DI 3 ""))
12481 (clobber (reg:CC FLAGS_REG))]
12482 "TARGET_64BIT && reload_completed"
12484 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12487 [(set (match_operand:TI 0 "register_operand" "")
12488 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12489 (match_operand:QI 2 "immediate_operand" "")))
12490 (clobber (reg:CC FLAGS_REG))]
12491 "TARGET_64BIT && reload_completed"
12493 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12495 (define_expand "lshrdi3"
12496 [(set (match_operand:DI 0 "shiftdi_operand" "")
12497 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12498 (match_operand:QI 2 "nonmemory_operand" "")))]
12500 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12502 (define_insn "*lshrdi3_1_one_bit_rex64"
12503 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12504 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12505 (match_operand:QI 2 "const1_operand" "")))
12506 (clobber (reg:CC FLAGS_REG))]
12508 && (TARGET_SHIFT1 || optimize_size)
12509 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12511 [(set_attr "type" "ishift")
12512 (set (attr "length")
12513 (if_then_else (match_operand:DI 0 "register_operand" "")
12515 (const_string "*")))])
12517 (define_insn "*lshrdi3_1_rex64"
12518 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12519 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12520 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12521 (clobber (reg:CC FLAGS_REG))]
12522 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12524 shr{q}\t{%2, %0|%0, %2}
12525 shr{q}\t{%b2, %0|%0, %b2}"
12526 [(set_attr "type" "ishift")
12527 (set_attr "mode" "DI")])
12529 ;; This pattern can't accept a variable shift count, since shifts by
12530 ;; zero don't affect the flags. We assume that shifts by constant
12531 ;; zero are optimized away.
12532 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12533 [(set (reg FLAGS_REG)
12535 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12536 (match_operand:QI 2 "const1_operand" ""))
12538 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12539 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12541 && (TARGET_SHIFT1 || optimize_size)
12542 && ix86_match_ccmode (insn, CCGOCmode)
12543 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12545 [(set_attr "type" "ishift")
12546 (set (attr "length")
12547 (if_then_else (match_operand:DI 0 "register_operand" "")
12549 (const_string "*")))])
12551 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12552 [(set (reg FLAGS_REG)
12554 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12555 (match_operand:QI 2 "const1_operand" ""))
12557 (clobber (match_scratch:DI 0 "=r"))]
12559 && (TARGET_SHIFT1 || optimize_size)
12560 && ix86_match_ccmode (insn, CCGOCmode)
12561 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12563 [(set_attr "type" "ishift")
12564 (set_attr "length" "2")])
12566 ;; This pattern can't accept a variable shift count, since shifts by
12567 ;; zero don't affect the flags. We assume that shifts by constant
12568 ;; zero are optimized away.
12569 (define_insn "*lshrdi3_cmp_rex64"
12570 [(set (reg FLAGS_REG)
12572 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12573 (match_operand:QI 2 "const_int_operand" "e"))
12575 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12576 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12578 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12579 && ix86_match_ccmode (insn, CCGOCmode)
12580 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12581 "shr{q}\t{%2, %0|%0, %2}"
12582 [(set_attr "type" "ishift")
12583 (set_attr "mode" "DI")])
12585 (define_insn "*lshrdi3_cconly_rex64"
12586 [(set (reg FLAGS_REG)
12588 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12589 (match_operand:QI 2 "const_int_operand" "e"))
12591 (clobber (match_scratch:DI 0 "=r"))]
12593 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12594 && ix86_match_ccmode (insn, CCGOCmode)
12595 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12596 "shr{q}\t{%2, %0|%0, %2}"
12597 [(set_attr "type" "ishift")
12598 (set_attr "mode" "DI")])
12600 (define_insn "*lshrdi3_1"
12601 [(set (match_operand:DI 0 "register_operand" "=r")
12602 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12603 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12604 (clobber (reg:CC FLAGS_REG))]
12607 [(set_attr "type" "multi")])
12609 ;; By default we don't ask for a scratch register, because when DImode
12610 ;; values are manipulated, registers are already at a premium. But if
12611 ;; we have one handy, we won't turn it away.
12613 [(match_scratch:SI 3 "r")
12614 (parallel [(set (match_operand:DI 0 "register_operand" "")
12615 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12616 (match_operand:QI 2 "nonmemory_operand" "")))
12617 (clobber (reg:CC FLAGS_REG))])
12619 "!TARGET_64BIT && TARGET_CMOVE"
12621 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12624 [(set (match_operand:DI 0 "register_operand" "")
12625 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12626 (match_operand:QI 2 "nonmemory_operand" "")))
12627 (clobber (reg:CC FLAGS_REG))]
12628 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12629 ? epilogue_completed : reload_completed)"
12631 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12633 (define_expand "lshrsi3"
12634 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12635 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12636 (match_operand:QI 2 "nonmemory_operand" "")))
12637 (clobber (reg:CC FLAGS_REG))]
12639 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12641 (define_insn "*lshrsi3_1_one_bit"
12642 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12643 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12644 (match_operand:QI 2 "const1_operand" "")))
12645 (clobber (reg:CC FLAGS_REG))]
12646 "(TARGET_SHIFT1 || optimize_size)
12647 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12649 [(set_attr "type" "ishift")
12650 (set (attr "length")
12651 (if_then_else (match_operand:SI 0 "register_operand" "")
12653 (const_string "*")))])
12655 (define_insn "*lshrsi3_1_one_bit_zext"
12656 [(set (match_operand:DI 0 "register_operand" "=r")
12657 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12658 (match_operand:QI 2 "const1_operand" "")))
12659 (clobber (reg:CC FLAGS_REG))]
12661 && (TARGET_SHIFT1 || optimize_size)
12662 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12664 [(set_attr "type" "ishift")
12665 (set_attr "length" "2")])
12667 (define_insn "*lshrsi3_1"
12668 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12669 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12670 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12671 (clobber (reg:CC FLAGS_REG))]
12672 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12674 shr{l}\t{%2, %0|%0, %2}
12675 shr{l}\t{%b2, %0|%0, %b2}"
12676 [(set_attr "type" "ishift")
12677 (set_attr "mode" "SI")])
12679 (define_insn "*lshrsi3_1_zext"
12680 [(set (match_operand:DI 0 "register_operand" "=r,r")
12682 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12683 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12684 (clobber (reg:CC FLAGS_REG))]
12685 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12687 shr{l}\t{%2, %k0|%k0, %2}
12688 shr{l}\t{%b2, %k0|%k0, %b2}"
12689 [(set_attr "type" "ishift")
12690 (set_attr "mode" "SI")])
12692 ;; This pattern can't accept a variable shift count, since shifts by
12693 ;; zero don't affect the flags. We assume that shifts by constant
12694 ;; zero are optimized away.
12695 (define_insn "*lshrsi3_one_bit_cmp"
12696 [(set (reg FLAGS_REG)
12698 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12699 (match_operand:QI 2 "const1_operand" ""))
12701 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12702 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12703 "(TARGET_SHIFT1 || optimize_size)
12704 && ix86_match_ccmode (insn, CCGOCmode)
12705 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12707 [(set_attr "type" "ishift")
12708 (set (attr "length")
12709 (if_then_else (match_operand:SI 0 "register_operand" "")
12711 (const_string "*")))])
12713 (define_insn "*lshrsi3_one_bit_cconly"
12714 [(set (reg FLAGS_REG)
12716 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12717 (match_operand:QI 2 "const1_operand" ""))
12719 (clobber (match_scratch:SI 0 "=r"))]
12720 "(TARGET_SHIFT1 || optimize_size)
12721 && ix86_match_ccmode (insn, CCGOCmode)
12722 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12724 [(set_attr "type" "ishift")
12725 (set_attr "length" "2")])
12727 (define_insn "*lshrsi3_cmp_one_bit_zext"
12728 [(set (reg FLAGS_REG)
12730 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12731 (match_operand:QI 2 "const1_operand" ""))
12733 (set (match_operand:DI 0 "register_operand" "=r")
12734 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12736 && (TARGET_SHIFT1 || optimize_size)
12737 && ix86_match_ccmode (insn, CCGOCmode)
12738 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12740 [(set_attr "type" "ishift")
12741 (set_attr "length" "2")])
12743 ;; This pattern can't accept a variable shift count, since shifts by
12744 ;; zero don't affect the flags. We assume that shifts by constant
12745 ;; zero are optimized away.
12746 (define_insn "*lshrsi3_cmp"
12747 [(set (reg FLAGS_REG)
12749 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12750 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12752 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12753 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12754 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12755 && ix86_match_ccmode (insn, CCGOCmode)
12756 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12757 "shr{l}\t{%2, %0|%0, %2}"
12758 [(set_attr "type" "ishift")
12759 (set_attr "mode" "SI")])
12761 (define_insn "*lshrsi3_cconly"
12762 [(set (reg FLAGS_REG)
12764 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12765 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12767 (clobber (match_scratch:SI 0 "=r"))]
12768 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12769 && ix86_match_ccmode (insn, CCGOCmode)
12770 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12771 "shr{l}\t{%2, %0|%0, %2}"
12772 [(set_attr "type" "ishift")
12773 (set_attr "mode" "SI")])
12775 (define_insn "*lshrsi3_cmp_zext"
12776 [(set (reg FLAGS_REG)
12778 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12779 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12781 (set (match_operand:DI 0 "register_operand" "=r")
12782 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12784 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12785 && ix86_match_ccmode (insn, CCGOCmode)
12786 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12787 "shr{l}\t{%2, %k0|%k0, %2}"
12788 [(set_attr "type" "ishift")
12789 (set_attr "mode" "SI")])
12791 (define_expand "lshrhi3"
12792 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12793 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12794 (match_operand:QI 2 "nonmemory_operand" "")))
12795 (clobber (reg:CC FLAGS_REG))]
12796 "TARGET_HIMODE_MATH"
12797 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12799 (define_insn "*lshrhi3_1_one_bit"
12800 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12801 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12802 (match_operand:QI 2 "const1_operand" "")))
12803 (clobber (reg:CC FLAGS_REG))]
12804 "(TARGET_SHIFT1 || optimize_size)
12805 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12807 [(set_attr "type" "ishift")
12808 (set (attr "length")
12809 (if_then_else (match_operand 0 "register_operand" "")
12811 (const_string "*")))])
12813 (define_insn "*lshrhi3_1"
12814 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12815 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12816 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12817 (clobber (reg:CC FLAGS_REG))]
12818 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12820 shr{w}\t{%2, %0|%0, %2}
12821 shr{w}\t{%b2, %0|%0, %b2}"
12822 [(set_attr "type" "ishift")
12823 (set_attr "mode" "HI")])
12825 ;; This pattern can't accept a variable shift count, since shifts by
12826 ;; zero don't affect the flags. We assume that shifts by constant
12827 ;; zero are optimized away.
12828 (define_insn "*lshrhi3_one_bit_cmp"
12829 [(set (reg FLAGS_REG)
12831 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12832 (match_operand:QI 2 "const1_operand" ""))
12834 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12835 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12836 "(TARGET_SHIFT1 || optimize_size)
12837 && ix86_match_ccmode (insn, CCGOCmode)
12838 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12840 [(set_attr "type" "ishift")
12841 (set (attr "length")
12842 (if_then_else (match_operand:SI 0 "register_operand" "")
12844 (const_string "*")))])
12846 (define_insn "*lshrhi3_one_bit_cconly"
12847 [(set (reg FLAGS_REG)
12849 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12850 (match_operand:QI 2 "const1_operand" ""))
12852 (clobber (match_scratch:HI 0 "=r"))]
12853 "(TARGET_SHIFT1 || optimize_size)
12854 && ix86_match_ccmode (insn, CCGOCmode)
12855 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12857 [(set_attr "type" "ishift")
12858 (set_attr "length" "2")])
12860 ;; This pattern can't accept a variable shift count, since shifts by
12861 ;; zero don't affect the flags. We assume that shifts by constant
12862 ;; zero are optimized away.
12863 (define_insn "*lshrhi3_cmp"
12864 [(set (reg FLAGS_REG)
12866 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12867 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12869 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12870 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12871 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12872 && ix86_match_ccmode (insn, CCGOCmode)
12873 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12874 "shr{w}\t{%2, %0|%0, %2}"
12875 [(set_attr "type" "ishift")
12876 (set_attr "mode" "HI")])
12878 (define_insn "*lshrhi3_cconly"
12879 [(set (reg FLAGS_REG)
12881 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12882 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12884 (clobber (match_scratch:HI 0 "=r"))]
12885 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12886 && ix86_match_ccmode (insn, CCGOCmode)
12887 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12888 "shr{w}\t{%2, %0|%0, %2}"
12889 [(set_attr "type" "ishift")
12890 (set_attr "mode" "HI")])
12892 (define_expand "lshrqi3"
12893 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12894 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12895 (match_operand:QI 2 "nonmemory_operand" "")))
12896 (clobber (reg:CC FLAGS_REG))]
12897 "TARGET_QIMODE_MATH"
12898 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12900 (define_insn "*lshrqi3_1_one_bit"
12901 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12902 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12903 (match_operand:QI 2 "const1_operand" "")))
12904 (clobber (reg:CC FLAGS_REG))]
12905 "(TARGET_SHIFT1 || optimize_size)
12906 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12908 [(set_attr "type" "ishift")
12909 (set (attr "length")
12910 (if_then_else (match_operand 0 "register_operand" "")
12912 (const_string "*")))])
12914 (define_insn "*lshrqi3_1_one_bit_slp"
12915 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12916 (lshiftrt:QI (match_dup 0)
12917 (match_operand:QI 1 "const1_operand" "")))
12918 (clobber (reg:CC FLAGS_REG))]
12919 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12920 && (TARGET_SHIFT1 || optimize_size)"
12922 [(set_attr "type" "ishift1")
12923 (set (attr "length")
12924 (if_then_else (match_operand 0 "register_operand" "")
12926 (const_string "*")))])
12928 (define_insn "*lshrqi3_1"
12929 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12930 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12931 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12932 (clobber (reg:CC FLAGS_REG))]
12933 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12935 shr{b}\t{%2, %0|%0, %2}
12936 shr{b}\t{%b2, %0|%0, %b2}"
12937 [(set_attr "type" "ishift")
12938 (set_attr "mode" "QI")])
12940 (define_insn "*lshrqi3_1_slp"
12941 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12942 (lshiftrt:QI (match_dup 0)
12943 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12944 (clobber (reg:CC FLAGS_REG))]
12945 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12946 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12948 shr{b}\t{%1, %0|%0, %1}
12949 shr{b}\t{%b1, %0|%0, %b1}"
12950 [(set_attr "type" "ishift1")
12951 (set_attr "mode" "QI")])
12953 ;; This pattern can't accept a variable shift count, since shifts by
12954 ;; zero don't affect the flags. We assume that shifts by constant
12955 ;; zero are optimized away.
12956 (define_insn "*lshrqi2_one_bit_cmp"
12957 [(set (reg FLAGS_REG)
12959 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12960 (match_operand:QI 2 "const1_operand" ""))
12962 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12963 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12964 "(TARGET_SHIFT1 || optimize_size)
12965 && ix86_match_ccmode (insn, CCGOCmode)
12966 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12968 [(set_attr "type" "ishift")
12969 (set (attr "length")
12970 (if_then_else (match_operand:SI 0 "register_operand" "")
12972 (const_string "*")))])
12974 (define_insn "*lshrqi2_one_bit_cconly"
12975 [(set (reg FLAGS_REG)
12977 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12978 (match_operand:QI 2 "const1_operand" ""))
12980 (clobber (match_scratch:QI 0 "=q"))]
12981 "(TARGET_SHIFT1 || optimize_size)
12982 && ix86_match_ccmode (insn, CCGOCmode)
12983 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12985 [(set_attr "type" "ishift")
12986 (set_attr "length" "2")])
12988 ;; This pattern can't accept a variable shift count, since shifts by
12989 ;; zero don't affect the flags. We assume that shifts by constant
12990 ;; zero are optimized away.
12991 (define_insn "*lshrqi2_cmp"
12992 [(set (reg FLAGS_REG)
12994 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12995 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12997 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12998 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12999 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13000 && ix86_match_ccmode (insn, CCGOCmode)
13001 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13002 "shr{b}\t{%2, %0|%0, %2}"
13003 [(set_attr "type" "ishift")
13004 (set_attr "mode" "QI")])
13006 (define_insn "*lshrqi2_cconly"
13007 [(set (reg FLAGS_REG)
13009 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13010 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13012 (clobber (match_scratch:QI 0 "=q"))]
13013 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13014 && ix86_match_ccmode (insn, CCGOCmode)
13015 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13016 "shr{b}\t{%2, %0|%0, %2}"
13017 [(set_attr "type" "ishift")
13018 (set_attr "mode" "QI")])
13020 ;; Rotate instructions
13022 (define_expand "rotldi3"
13023 [(set (match_operand:DI 0 "shiftdi_operand" "")
13024 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13025 (match_operand:QI 2 "nonmemory_operand" "")))
13026 (clobber (reg:CC FLAGS_REG))]
13031 ix86_expand_binary_operator (ROTATE, DImode, operands);
13034 if (!const_1_to_31_operand (operands[2], VOIDmode))
13036 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13040 ;; Implement rotation using two double-precision shift instructions
13041 ;; and a scratch register.
13042 (define_insn_and_split "ix86_rotldi3"
13043 [(set (match_operand:DI 0 "register_operand" "=r")
13044 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13045 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13046 (clobber (reg:CC FLAGS_REG))
13047 (clobber (match_scratch:SI 3 "=&r"))]
13050 "&& reload_completed"
13051 [(set (match_dup 3) (match_dup 4))
13053 [(set (match_dup 4)
13054 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13055 (lshiftrt:SI (match_dup 5)
13056 (minus:QI (const_int 32) (match_dup 2)))))
13057 (clobber (reg:CC FLAGS_REG))])
13059 [(set (match_dup 5)
13060 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13061 (lshiftrt:SI (match_dup 3)
13062 (minus:QI (const_int 32) (match_dup 2)))))
13063 (clobber (reg:CC FLAGS_REG))])]
13064 "split_di (operands, 1, operands + 4, operands + 5);")
13066 (define_insn "*rotlsi3_1_one_bit_rex64"
13067 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13068 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13069 (match_operand:QI 2 "const1_operand" "")))
13070 (clobber (reg:CC FLAGS_REG))]
13072 && (TARGET_SHIFT1 || optimize_size)
13073 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13075 [(set_attr "type" "rotate")
13076 (set (attr "length")
13077 (if_then_else (match_operand:DI 0 "register_operand" "")
13079 (const_string "*")))])
13081 (define_insn "*rotldi3_1_rex64"
13082 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13083 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13084 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13085 (clobber (reg:CC FLAGS_REG))]
13086 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13088 rol{q}\t{%2, %0|%0, %2}
13089 rol{q}\t{%b2, %0|%0, %b2}"
13090 [(set_attr "type" "rotate")
13091 (set_attr "mode" "DI")])
13093 (define_expand "rotlsi3"
13094 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13095 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13096 (match_operand:QI 2 "nonmemory_operand" "")))
13097 (clobber (reg:CC FLAGS_REG))]
13099 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13101 (define_insn "*rotlsi3_1_one_bit"
13102 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13103 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13104 (match_operand:QI 2 "const1_operand" "")))
13105 (clobber (reg:CC FLAGS_REG))]
13106 "(TARGET_SHIFT1 || optimize_size)
13107 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13109 [(set_attr "type" "rotate")
13110 (set (attr "length")
13111 (if_then_else (match_operand:SI 0 "register_operand" "")
13113 (const_string "*")))])
13115 (define_insn "*rotlsi3_1_one_bit_zext"
13116 [(set (match_operand:DI 0 "register_operand" "=r")
13118 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13119 (match_operand:QI 2 "const1_operand" ""))))
13120 (clobber (reg:CC FLAGS_REG))]
13122 && (TARGET_SHIFT1 || optimize_size)
13123 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13125 [(set_attr "type" "rotate")
13126 (set_attr "length" "2")])
13128 (define_insn "*rotlsi3_1"
13129 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13130 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13131 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13132 (clobber (reg:CC FLAGS_REG))]
13133 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13135 rol{l}\t{%2, %0|%0, %2}
13136 rol{l}\t{%b2, %0|%0, %b2}"
13137 [(set_attr "type" "rotate")
13138 (set_attr "mode" "SI")])
13140 (define_insn "*rotlsi3_1_zext"
13141 [(set (match_operand:DI 0 "register_operand" "=r,r")
13143 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13144 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13145 (clobber (reg:CC FLAGS_REG))]
13146 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13148 rol{l}\t{%2, %k0|%k0, %2}
13149 rol{l}\t{%b2, %k0|%k0, %b2}"
13150 [(set_attr "type" "rotate")
13151 (set_attr "mode" "SI")])
13153 (define_expand "rotlhi3"
13154 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13155 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13156 (match_operand:QI 2 "nonmemory_operand" "")))
13157 (clobber (reg:CC FLAGS_REG))]
13158 "TARGET_HIMODE_MATH"
13159 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13161 (define_insn "*rotlhi3_1_one_bit"
13162 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13163 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13164 (match_operand:QI 2 "const1_operand" "")))
13165 (clobber (reg:CC FLAGS_REG))]
13166 "(TARGET_SHIFT1 || optimize_size)
13167 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13169 [(set_attr "type" "rotate")
13170 (set (attr "length")
13171 (if_then_else (match_operand 0 "register_operand" "")
13173 (const_string "*")))])
13175 (define_insn "*rotlhi3_1"
13176 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13177 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13178 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13179 (clobber (reg:CC FLAGS_REG))]
13180 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13182 rol{w}\t{%2, %0|%0, %2}
13183 rol{w}\t{%b2, %0|%0, %b2}"
13184 [(set_attr "type" "rotate")
13185 (set_attr "mode" "HI")])
13188 [(set (match_operand:HI 0 "register_operand" "")
13189 (rotate:HI (match_dup 0) (const_int 8)))
13190 (clobber (reg:CC FLAGS_REG))]
13192 [(parallel [(set (strict_low_part (match_dup 0))
13193 (bswap:HI (match_dup 0)))
13194 (clobber (reg:CC FLAGS_REG))])]
13197 (define_expand "rotlqi3"
13198 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13199 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13200 (match_operand:QI 2 "nonmemory_operand" "")))
13201 (clobber (reg:CC FLAGS_REG))]
13202 "TARGET_QIMODE_MATH"
13203 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13205 (define_insn "*rotlqi3_1_one_bit_slp"
13206 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13207 (rotate:QI (match_dup 0)
13208 (match_operand:QI 1 "const1_operand" "")))
13209 (clobber (reg:CC FLAGS_REG))]
13210 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13211 && (TARGET_SHIFT1 || optimize_size)"
13213 [(set_attr "type" "rotate1")
13214 (set (attr "length")
13215 (if_then_else (match_operand 0 "register_operand" "")
13217 (const_string "*")))])
13219 (define_insn "*rotlqi3_1_one_bit"
13220 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13221 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13222 (match_operand:QI 2 "const1_operand" "")))
13223 (clobber (reg:CC FLAGS_REG))]
13224 "(TARGET_SHIFT1 || optimize_size)
13225 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13227 [(set_attr "type" "rotate")
13228 (set (attr "length")
13229 (if_then_else (match_operand 0 "register_operand" "")
13231 (const_string "*")))])
13233 (define_insn "*rotlqi3_1_slp"
13234 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13235 (rotate:QI (match_dup 0)
13236 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13237 (clobber (reg:CC FLAGS_REG))]
13238 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13239 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13241 rol{b}\t{%1, %0|%0, %1}
13242 rol{b}\t{%b1, %0|%0, %b1}"
13243 [(set_attr "type" "rotate1")
13244 (set_attr "mode" "QI")])
13246 (define_insn "*rotlqi3_1"
13247 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13248 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13249 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13250 (clobber (reg:CC FLAGS_REG))]
13251 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13253 rol{b}\t{%2, %0|%0, %2}
13254 rol{b}\t{%b2, %0|%0, %b2}"
13255 [(set_attr "type" "rotate")
13256 (set_attr "mode" "QI")])
13258 (define_expand "rotrdi3"
13259 [(set (match_operand:DI 0 "shiftdi_operand" "")
13260 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13261 (match_operand:QI 2 "nonmemory_operand" "")))
13262 (clobber (reg:CC FLAGS_REG))]
13267 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13270 if (!const_1_to_31_operand (operands[2], VOIDmode))
13272 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13276 ;; Implement rotation using two double-precision shift instructions
13277 ;; and a scratch register.
13278 (define_insn_and_split "ix86_rotrdi3"
13279 [(set (match_operand:DI 0 "register_operand" "=r")
13280 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13281 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13282 (clobber (reg:CC FLAGS_REG))
13283 (clobber (match_scratch:SI 3 "=&r"))]
13286 "&& reload_completed"
13287 [(set (match_dup 3) (match_dup 4))
13289 [(set (match_dup 4)
13290 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13291 (ashift:SI (match_dup 5)
13292 (minus:QI (const_int 32) (match_dup 2)))))
13293 (clobber (reg:CC FLAGS_REG))])
13295 [(set (match_dup 5)
13296 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13297 (ashift:SI (match_dup 3)
13298 (minus:QI (const_int 32) (match_dup 2)))))
13299 (clobber (reg:CC FLAGS_REG))])]
13300 "split_di (operands, 1, operands + 4, operands + 5);")
13302 (define_insn "*rotrdi3_1_one_bit_rex64"
13303 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13304 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13305 (match_operand:QI 2 "const1_operand" "")))
13306 (clobber (reg:CC FLAGS_REG))]
13308 && (TARGET_SHIFT1 || optimize_size)
13309 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13311 [(set_attr "type" "rotate")
13312 (set (attr "length")
13313 (if_then_else (match_operand:DI 0 "register_operand" "")
13315 (const_string "*")))])
13317 (define_insn "*rotrdi3_1_rex64"
13318 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13319 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13320 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13321 (clobber (reg:CC FLAGS_REG))]
13322 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13324 ror{q}\t{%2, %0|%0, %2}
13325 ror{q}\t{%b2, %0|%0, %b2}"
13326 [(set_attr "type" "rotate")
13327 (set_attr "mode" "DI")])
13329 (define_expand "rotrsi3"
13330 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13331 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13332 (match_operand:QI 2 "nonmemory_operand" "")))
13333 (clobber (reg:CC FLAGS_REG))]
13335 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13337 (define_insn "*rotrsi3_1_one_bit"
13338 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13339 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13340 (match_operand:QI 2 "const1_operand" "")))
13341 (clobber (reg:CC FLAGS_REG))]
13342 "(TARGET_SHIFT1 || optimize_size)
13343 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13345 [(set_attr "type" "rotate")
13346 (set (attr "length")
13347 (if_then_else (match_operand:SI 0 "register_operand" "")
13349 (const_string "*")))])
13351 (define_insn "*rotrsi3_1_one_bit_zext"
13352 [(set (match_operand:DI 0 "register_operand" "=r")
13354 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13355 (match_operand:QI 2 "const1_operand" ""))))
13356 (clobber (reg:CC FLAGS_REG))]
13358 && (TARGET_SHIFT1 || optimize_size)
13359 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13361 [(set_attr "type" "rotate")
13362 (set (attr "length")
13363 (if_then_else (match_operand:SI 0 "register_operand" "")
13365 (const_string "*")))])
13367 (define_insn "*rotrsi3_1"
13368 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13369 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13370 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13371 (clobber (reg:CC FLAGS_REG))]
13372 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13374 ror{l}\t{%2, %0|%0, %2}
13375 ror{l}\t{%b2, %0|%0, %b2}"
13376 [(set_attr "type" "rotate")
13377 (set_attr "mode" "SI")])
13379 (define_insn "*rotrsi3_1_zext"
13380 [(set (match_operand:DI 0 "register_operand" "=r,r")
13382 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13383 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13384 (clobber (reg:CC FLAGS_REG))]
13385 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13387 ror{l}\t{%2, %k0|%k0, %2}
13388 ror{l}\t{%b2, %k0|%k0, %b2}"
13389 [(set_attr "type" "rotate")
13390 (set_attr "mode" "SI")])
13392 (define_expand "rotrhi3"
13393 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13394 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13395 (match_operand:QI 2 "nonmemory_operand" "")))
13396 (clobber (reg:CC FLAGS_REG))]
13397 "TARGET_HIMODE_MATH"
13398 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13400 (define_insn "*rotrhi3_one_bit"
13401 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13402 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13403 (match_operand:QI 2 "const1_operand" "")))
13404 (clobber (reg:CC FLAGS_REG))]
13405 "(TARGET_SHIFT1 || optimize_size)
13406 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13408 [(set_attr "type" "rotate")
13409 (set (attr "length")
13410 (if_then_else (match_operand 0 "register_operand" "")
13412 (const_string "*")))])
13414 (define_insn "*rotrhi3_1"
13415 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13416 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13417 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13418 (clobber (reg:CC FLAGS_REG))]
13419 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13421 ror{w}\t{%2, %0|%0, %2}
13422 ror{w}\t{%b2, %0|%0, %b2}"
13423 [(set_attr "type" "rotate")
13424 (set_attr "mode" "HI")])
13427 [(set (match_operand:HI 0 "register_operand" "")
13428 (rotatert:HI (match_dup 0) (const_int 8)))
13429 (clobber (reg:CC FLAGS_REG))]
13431 [(parallel [(set (strict_low_part (match_dup 0))
13432 (bswap:HI (match_dup 0)))
13433 (clobber (reg:CC FLAGS_REG))])]
13436 (define_expand "rotrqi3"
13437 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13438 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13439 (match_operand:QI 2 "nonmemory_operand" "")))
13440 (clobber (reg:CC FLAGS_REG))]
13441 "TARGET_QIMODE_MATH"
13442 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13444 (define_insn "*rotrqi3_1_one_bit"
13445 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13446 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13447 (match_operand:QI 2 "const1_operand" "")))
13448 (clobber (reg:CC FLAGS_REG))]
13449 "(TARGET_SHIFT1 || optimize_size)
13450 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13452 [(set_attr "type" "rotate")
13453 (set (attr "length")
13454 (if_then_else (match_operand 0 "register_operand" "")
13456 (const_string "*")))])
13458 (define_insn "*rotrqi3_1_one_bit_slp"
13459 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13460 (rotatert:QI (match_dup 0)
13461 (match_operand:QI 1 "const1_operand" "")))
13462 (clobber (reg:CC FLAGS_REG))]
13463 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13464 && (TARGET_SHIFT1 || optimize_size)"
13466 [(set_attr "type" "rotate1")
13467 (set (attr "length")
13468 (if_then_else (match_operand 0 "register_operand" "")
13470 (const_string "*")))])
13472 (define_insn "*rotrqi3_1"
13473 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13474 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13475 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13476 (clobber (reg:CC FLAGS_REG))]
13477 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13479 ror{b}\t{%2, %0|%0, %2}
13480 ror{b}\t{%b2, %0|%0, %b2}"
13481 [(set_attr "type" "rotate")
13482 (set_attr "mode" "QI")])
13484 (define_insn "*rotrqi3_1_slp"
13485 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13486 (rotatert:QI (match_dup 0)
13487 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13488 (clobber (reg:CC FLAGS_REG))]
13489 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13490 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13492 ror{b}\t{%1, %0|%0, %1}
13493 ror{b}\t{%b1, %0|%0, %b1}"
13494 [(set_attr "type" "rotate1")
13495 (set_attr "mode" "QI")])
13497 ;; Bit set / bit test instructions
13499 (define_expand "extv"
13500 [(set (match_operand:SI 0 "register_operand" "")
13501 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13502 (match_operand:SI 2 "const8_operand" "")
13503 (match_operand:SI 3 "const8_operand" "")))]
13506 /* Handle extractions from %ah et al. */
13507 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13510 /* From mips.md: extract_bit_field doesn't verify that our source
13511 matches the predicate, so check it again here. */
13512 if (! ext_register_operand (operands[1], VOIDmode))
13516 (define_expand "extzv"
13517 [(set (match_operand:SI 0 "register_operand" "")
13518 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13519 (match_operand:SI 2 "const8_operand" "")
13520 (match_operand:SI 3 "const8_operand" "")))]
13523 /* Handle extractions from %ah et al. */
13524 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13527 /* From mips.md: extract_bit_field doesn't verify that our source
13528 matches the predicate, so check it again here. */
13529 if (! ext_register_operand (operands[1], VOIDmode))
13533 (define_expand "insv"
13534 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13535 (match_operand 1 "const8_operand" "")
13536 (match_operand 2 "const8_operand" ""))
13537 (match_operand 3 "register_operand" ""))]
13540 /* Handle insertions to %ah et al. */
13541 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13544 /* From mips.md: insert_bit_field doesn't verify that our source
13545 matches the predicate, so check it again here. */
13546 if (! ext_register_operand (operands[0], VOIDmode))
13550 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13552 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13557 ;; %%% bts, btr, btc, bt.
13558 ;; In general these instructions are *slow* when applied to memory,
13559 ;; since they enforce atomic operation. When applied to registers,
13560 ;; it depends on the cpu implementation. They're never faster than
13561 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13562 ;; no point. But in 64-bit, we can't hold the relevant immediates
13563 ;; within the instruction itself, so operating on bits in the high
13564 ;; 32-bits of a register becomes easier.
13566 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13567 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13568 ;; negdf respectively, so they can never be disabled entirely.
13570 (define_insn "*btsq"
13571 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13573 (match_operand:DI 1 "const_0_to_63_operand" ""))
13575 (clobber (reg:CC FLAGS_REG))]
13576 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13578 [(set_attr "type" "alu1")])
13580 (define_insn "*btrq"
13581 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13583 (match_operand:DI 1 "const_0_to_63_operand" ""))
13585 (clobber (reg:CC FLAGS_REG))]
13586 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13588 [(set_attr "type" "alu1")])
13590 (define_insn "*btcq"
13591 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13593 (match_operand:DI 1 "const_0_to_63_operand" ""))
13594 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13595 (clobber (reg:CC FLAGS_REG))]
13596 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13598 [(set_attr "type" "alu1")])
13600 ;; Allow Nocona to avoid these instructions if a register is available.
13603 [(match_scratch:DI 2 "r")
13604 (parallel [(set (zero_extract:DI
13605 (match_operand:DI 0 "register_operand" "")
13607 (match_operand:DI 1 "const_0_to_63_operand" ""))
13609 (clobber (reg:CC FLAGS_REG))])]
13610 "TARGET_64BIT && !TARGET_USE_BT"
13613 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13616 if (HOST_BITS_PER_WIDE_INT >= 64)
13617 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13618 else if (i < HOST_BITS_PER_WIDE_INT)
13619 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13621 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13623 op1 = immed_double_const (lo, hi, DImode);
13626 emit_move_insn (operands[2], op1);
13630 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13635 [(match_scratch:DI 2 "r")
13636 (parallel [(set (zero_extract:DI
13637 (match_operand:DI 0 "register_operand" "")
13639 (match_operand:DI 1 "const_0_to_63_operand" ""))
13641 (clobber (reg:CC FLAGS_REG))])]
13642 "TARGET_64BIT && !TARGET_USE_BT"
13645 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13648 if (HOST_BITS_PER_WIDE_INT >= 64)
13649 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13650 else if (i < HOST_BITS_PER_WIDE_INT)
13651 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13653 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13655 op1 = immed_double_const (~lo, ~hi, DImode);
13658 emit_move_insn (operands[2], op1);
13662 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13667 [(match_scratch:DI 2 "r")
13668 (parallel [(set (zero_extract:DI
13669 (match_operand:DI 0 "register_operand" "")
13671 (match_operand:DI 1 "const_0_to_63_operand" ""))
13672 (not:DI (zero_extract:DI
13673 (match_dup 0) (const_int 1) (match_dup 1))))
13674 (clobber (reg:CC FLAGS_REG))])]
13675 "TARGET_64BIT && !TARGET_USE_BT"
13678 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13681 if (HOST_BITS_PER_WIDE_INT >= 64)
13682 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13683 else if (i < HOST_BITS_PER_WIDE_INT)
13684 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13686 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13688 op1 = immed_double_const (lo, hi, DImode);
13691 emit_move_insn (operands[2], op1);
13695 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13699 ;; Store-flag instructions.
13701 ;; For all sCOND expanders, also expand the compare or test insn that
13702 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13704 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13705 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13706 ;; way, which can later delete the movzx if only QImode is needed.
13708 (define_expand "seq"
13709 [(set (match_operand:QI 0 "register_operand" "")
13710 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13712 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13714 (define_expand "sne"
13715 [(set (match_operand:QI 0 "register_operand" "")
13716 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13718 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13720 (define_expand "sgt"
13721 [(set (match_operand:QI 0 "register_operand" "")
13722 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13724 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13726 (define_expand "sgtu"
13727 [(set (match_operand:QI 0 "register_operand" "")
13728 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13730 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13732 (define_expand "slt"
13733 [(set (match_operand:QI 0 "register_operand" "")
13734 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13736 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13738 (define_expand "sltu"
13739 [(set (match_operand:QI 0 "register_operand" "")
13740 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13742 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13744 (define_expand "sge"
13745 [(set (match_operand:QI 0 "register_operand" "")
13746 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13748 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13750 (define_expand "sgeu"
13751 [(set (match_operand:QI 0 "register_operand" "")
13752 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13754 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13756 (define_expand "sle"
13757 [(set (match_operand:QI 0 "register_operand" "")
13758 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13760 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13762 (define_expand "sleu"
13763 [(set (match_operand:QI 0 "register_operand" "")
13764 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13766 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13768 (define_expand "sunordered"
13769 [(set (match_operand:QI 0 "register_operand" "")
13770 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13771 "TARGET_80387 || TARGET_SSE"
13772 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13774 (define_expand "sordered"
13775 [(set (match_operand:QI 0 "register_operand" "")
13776 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13778 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13780 (define_expand "suneq"
13781 [(set (match_operand:QI 0 "register_operand" "")
13782 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13783 "TARGET_80387 || TARGET_SSE"
13784 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13786 (define_expand "sunge"
13787 [(set (match_operand:QI 0 "register_operand" "")
13788 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13789 "TARGET_80387 || TARGET_SSE"
13790 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13792 (define_expand "sungt"
13793 [(set (match_operand:QI 0 "register_operand" "")
13794 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13795 "TARGET_80387 || TARGET_SSE"
13796 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13798 (define_expand "sunle"
13799 [(set (match_operand:QI 0 "register_operand" "")
13800 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13801 "TARGET_80387 || TARGET_SSE"
13802 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13804 (define_expand "sunlt"
13805 [(set (match_operand:QI 0 "register_operand" "")
13806 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13807 "TARGET_80387 || TARGET_SSE"
13808 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13810 (define_expand "sltgt"
13811 [(set (match_operand:QI 0 "register_operand" "")
13812 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13813 "TARGET_80387 || TARGET_SSE"
13814 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13816 (define_insn "*setcc_1"
13817 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13818 (match_operator:QI 1 "ix86_comparison_operator"
13819 [(reg FLAGS_REG) (const_int 0)]))]
13822 [(set_attr "type" "setcc")
13823 (set_attr "mode" "QI")])
13825 (define_insn "*setcc_2"
13826 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13827 (match_operator:QI 1 "ix86_comparison_operator"
13828 [(reg FLAGS_REG) (const_int 0)]))]
13831 [(set_attr "type" "setcc")
13832 (set_attr "mode" "QI")])
13834 ;; In general it is not safe to assume too much about CCmode registers,
13835 ;; so simplify-rtx stops when it sees a second one. Under certain
13836 ;; conditions this is safe on x86, so help combine not create
13843 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13844 (ne:QI (match_operator 1 "ix86_comparison_operator"
13845 [(reg FLAGS_REG) (const_int 0)])
13848 [(set (match_dup 0) (match_dup 1))]
13850 PUT_MODE (operands[1], QImode);
13854 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13855 (ne:QI (match_operator 1 "ix86_comparison_operator"
13856 [(reg FLAGS_REG) (const_int 0)])
13859 [(set (match_dup 0) (match_dup 1))]
13861 PUT_MODE (operands[1], QImode);
13865 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13866 (eq:QI (match_operator 1 "ix86_comparison_operator"
13867 [(reg FLAGS_REG) (const_int 0)])
13870 [(set (match_dup 0) (match_dup 1))]
13872 rtx new_op1 = copy_rtx (operands[1]);
13873 operands[1] = new_op1;
13874 PUT_MODE (new_op1, QImode);
13875 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13876 GET_MODE (XEXP (new_op1, 0))));
13878 /* Make sure that (a) the CCmode we have for the flags is strong
13879 enough for the reversed compare or (b) we have a valid FP compare. */
13880 if (! ix86_comparison_operator (new_op1, VOIDmode))
13885 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13886 (eq:QI (match_operator 1 "ix86_comparison_operator"
13887 [(reg FLAGS_REG) (const_int 0)])
13890 [(set (match_dup 0) (match_dup 1))]
13892 rtx new_op1 = copy_rtx (operands[1]);
13893 operands[1] = new_op1;
13894 PUT_MODE (new_op1, QImode);
13895 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13896 GET_MODE (XEXP (new_op1, 0))));
13898 /* Make sure that (a) the CCmode we have for the flags is strong
13899 enough for the reversed compare or (b) we have a valid FP compare. */
13900 if (! ix86_comparison_operator (new_op1, VOIDmode))
13904 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13905 ;; subsequent logical operations are used to imitate conditional moves.
13906 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13909 (define_insn "*sse_setccsf"
13910 [(set (match_operand:SF 0 "register_operand" "=x")
13911 (match_operator:SF 1 "sse_comparison_operator"
13912 [(match_operand:SF 2 "register_operand" "0")
13913 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13915 "cmp%D1ss\t{%3, %0|%0, %3}"
13916 [(set_attr "type" "ssecmp")
13917 (set_attr "mode" "SF")])
13919 (define_insn "*sse_setccdf"
13920 [(set (match_operand:DF 0 "register_operand" "=x")
13921 (match_operator:DF 1 "sse_comparison_operator"
13922 [(match_operand:DF 2 "register_operand" "0")
13923 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13925 "cmp%D1sd\t{%3, %0|%0, %3}"
13926 [(set_attr "type" "ssecmp")
13927 (set_attr "mode" "DF")])
13929 ;; Basic conditional jump instructions.
13930 ;; We ignore the overflow flag for signed branch instructions.
13932 ;; For all bCOND expanders, also expand the compare or test insn that
13933 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13935 (define_expand "beq"
13937 (if_then_else (match_dup 1)
13938 (label_ref (match_operand 0 "" ""))
13941 "ix86_expand_branch (EQ, operands[0]); DONE;")
13943 (define_expand "bne"
13945 (if_then_else (match_dup 1)
13946 (label_ref (match_operand 0 "" ""))
13949 "ix86_expand_branch (NE, operands[0]); DONE;")
13951 (define_expand "bgt"
13953 (if_then_else (match_dup 1)
13954 (label_ref (match_operand 0 "" ""))
13957 "ix86_expand_branch (GT, operands[0]); DONE;")
13959 (define_expand "bgtu"
13961 (if_then_else (match_dup 1)
13962 (label_ref (match_operand 0 "" ""))
13965 "ix86_expand_branch (GTU, operands[0]); DONE;")
13967 (define_expand "blt"
13969 (if_then_else (match_dup 1)
13970 (label_ref (match_operand 0 "" ""))
13973 "ix86_expand_branch (LT, operands[0]); DONE;")
13975 (define_expand "bltu"
13977 (if_then_else (match_dup 1)
13978 (label_ref (match_operand 0 "" ""))
13981 "ix86_expand_branch (LTU, operands[0]); DONE;")
13983 (define_expand "bge"
13985 (if_then_else (match_dup 1)
13986 (label_ref (match_operand 0 "" ""))
13989 "ix86_expand_branch (GE, operands[0]); DONE;")
13991 (define_expand "bgeu"
13993 (if_then_else (match_dup 1)
13994 (label_ref (match_operand 0 "" ""))
13997 "ix86_expand_branch (GEU, operands[0]); DONE;")
13999 (define_expand "ble"
14001 (if_then_else (match_dup 1)
14002 (label_ref (match_operand 0 "" ""))
14005 "ix86_expand_branch (LE, operands[0]); DONE;")
14007 (define_expand "bleu"
14009 (if_then_else (match_dup 1)
14010 (label_ref (match_operand 0 "" ""))
14013 "ix86_expand_branch (LEU, operands[0]); DONE;")
14015 (define_expand "bunordered"
14017 (if_then_else (match_dup 1)
14018 (label_ref (match_operand 0 "" ""))
14020 "TARGET_80387 || TARGET_SSE_MATH"
14021 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
14023 (define_expand "bordered"
14025 (if_then_else (match_dup 1)
14026 (label_ref (match_operand 0 "" ""))
14028 "TARGET_80387 || TARGET_SSE_MATH"
14029 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
14031 (define_expand "buneq"
14033 (if_then_else (match_dup 1)
14034 (label_ref (match_operand 0 "" ""))
14036 "TARGET_80387 || TARGET_SSE_MATH"
14037 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
14039 (define_expand "bunge"
14041 (if_then_else (match_dup 1)
14042 (label_ref (match_operand 0 "" ""))
14044 "TARGET_80387 || TARGET_SSE_MATH"
14045 "ix86_expand_branch (UNGE, operands[0]); DONE;")
14047 (define_expand "bungt"
14049 (if_then_else (match_dup 1)
14050 (label_ref (match_operand 0 "" ""))
14052 "TARGET_80387 || TARGET_SSE_MATH"
14053 "ix86_expand_branch (UNGT, operands[0]); DONE;")
14055 (define_expand "bunle"
14057 (if_then_else (match_dup 1)
14058 (label_ref (match_operand 0 "" ""))
14060 "TARGET_80387 || TARGET_SSE_MATH"
14061 "ix86_expand_branch (UNLE, operands[0]); DONE;")
14063 (define_expand "bunlt"
14065 (if_then_else (match_dup 1)
14066 (label_ref (match_operand 0 "" ""))
14068 "TARGET_80387 || TARGET_SSE_MATH"
14069 "ix86_expand_branch (UNLT, operands[0]); DONE;")
14071 (define_expand "bltgt"
14073 (if_then_else (match_dup 1)
14074 (label_ref (match_operand 0 "" ""))
14076 "TARGET_80387 || TARGET_SSE_MATH"
14077 "ix86_expand_branch (LTGT, operands[0]); DONE;")
14079 (define_insn "*jcc_1"
14081 (if_then_else (match_operator 1 "ix86_comparison_operator"
14082 [(reg FLAGS_REG) (const_int 0)])
14083 (label_ref (match_operand 0 "" ""))
14087 [(set_attr "type" "ibr")
14088 (set_attr "modrm" "0")
14089 (set (attr "length")
14090 (if_then_else (and (ge (minus (match_dup 0) (pc))
14092 (lt (minus (match_dup 0) (pc))
14097 (define_insn "*jcc_2"
14099 (if_then_else (match_operator 1 "ix86_comparison_operator"
14100 [(reg FLAGS_REG) (const_int 0)])
14102 (label_ref (match_operand 0 "" ""))))]
14105 [(set_attr "type" "ibr")
14106 (set_attr "modrm" "0")
14107 (set (attr "length")
14108 (if_then_else (and (ge (minus (match_dup 0) (pc))
14110 (lt (minus (match_dup 0) (pc))
14115 ;; In general it is not safe to assume too much about CCmode registers,
14116 ;; so simplify-rtx stops when it sees a second one. Under certain
14117 ;; conditions this is safe on x86, so help combine not create
14125 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14126 [(reg FLAGS_REG) (const_int 0)])
14128 (label_ref (match_operand 1 "" ""))
14132 (if_then_else (match_dup 0)
14133 (label_ref (match_dup 1))
14136 PUT_MODE (operands[0], VOIDmode);
14141 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14142 [(reg FLAGS_REG) (const_int 0)])
14144 (label_ref (match_operand 1 "" ""))
14148 (if_then_else (match_dup 0)
14149 (label_ref (match_dup 1))
14152 rtx new_op0 = copy_rtx (operands[0]);
14153 operands[0] = new_op0;
14154 PUT_MODE (new_op0, VOIDmode);
14155 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14156 GET_MODE (XEXP (new_op0, 0))));
14158 /* Make sure that (a) the CCmode we have for the flags is strong
14159 enough for the reversed compare or (b) we have a valid FP compare. */
14160 if (! ix86_comparison_operator (new_op0, VOIDmode))
14164 ;; Define combination compare-and-branch fp compare instructions to use
14165 ;; during early optimization. Splitting the operation apart early makes
14166 ;; for bad code when we want to reverse the operation.
14168 (define_insn "*fp_jcc_1_mixed"
14170 (if_then_else (match_operator 0 "comparison_operator"
14171 [(match_operand 1 "register_operand" "f,x")
14172 (match_operand 2 "nonimmediate_operand" "f,xm")])
14173 (label_ref (match_operand 3 "" ""))
14175 (clobber (reg:CCFP FPSR_REG))
14176 (clobber (reg:CCFP FLAGS_REG))]
14177 "TARGET_MIX_SSE_I387
14178 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14179 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14180 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14183 (define_insn "*fp_jcc_1_sse"
14185 (if_then_else (match_operator 0 "comparison_operator"
14186 [(match_operand 1 "register_operand" "x")
14187 (match_operand 2 "nonimmediate_operand" "xm")])
14188 (label_ref (match_operand 3 "" ""))
14190 (clobber (reg:CCFP FPSR_REG))
14191 (clobber (reg:CCFP FLAGS_REG))]
14193 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14194 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14195 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14198 (define_insn "*fp_jcc_1_387"
14200 (if_then_else (match_operator 0 "comparison_operator"
14201 [(match_operand 1 "register_operand" "f")
14202 (match_operand 2 "register_operand" "f")])
14203 (label_ref (match_operand 3 "" ""))
14205 (clobber (reg:CCFP FPSR_REG))
14206 (clobber (reg:CCFP FLAGS_REG))]
14207 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14209 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14210 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14213 (define_insn "*fp_jcc_2_mixed"
14215 (if_then_else (match_operator 0 "comparison_operator"
14216 [(match_operand 1 "register_operand" "f,x")
14217 (match_operand 2 "nonimmediate_operand" "f,xm")])
14219 (label_ref (match_operand 3 "" ""))))
14220 (clobber (reg:CCFP FPSR_REG))
14221 (clobber (reg:CCFP FLAGS_REG))]
14222 "TARGET_MIX_SSE_I387
14223 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14224 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14225 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14228 (define_insn "*fp_jcc_2_sse"
14230 (if_then_else (match_operator 0 "comparison_operator"
14231 [(match_operand 1 "register_operand" "x")
14232 (match_operand 2 "nonimmediate_operand" "xm")])
14234 (label_ref (match_operand 3 "" ""))))
14235 (clobber (reg:CCFP FPSR_REG))
14236 (clobber (reg:CCFP FLAGS_REG))]
14238 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14239 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14240 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14243 (define_insn "*fp_jcc_2_387"
14245 (if_then_else (match_operator 0 "comparison_operator"
14246 [(match_operand 1 "register_operand" "f")
14247 (match_operand 2 "register_operand" "f")])
14249 (label_ref (match_operand 3 "" ""))))
14250 (clobber (reg:CCFP FPSR_REG))
14251 (clobber (reg:CCFP FLAGS_REG))]
14252 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14254 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14255 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14258 (define_insn "*fp_jcc_3_387"
14260 (if_then_else (match_operator 0 "comparison_operator"
14261 [(match_operand 1 "register_operand" "f")
14262 (match_operand 2 "nonimmediate_operand" "fm")])
14263 (label_ref (match_operand 3 "" ""))
14265 (clobber (reg:CCFP FPSR_REG))
14266 (clobber (reg:CCFP FLAGS_REG))
14267 (clobber (match_scratch:HI 4 "=a"))]
14269 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14270 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14271 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14272 && SELECT_CC_MODE (GET_CODE (operands[0]),
14273 operands[1], operands[2]) == CCFPmode
14274 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14277 (define_insn "*fp_jcc_4_387"
14279 (if_then_else (match_operator 0 "comparison_operator"
14280 [(match_operand 1 "register_operand" "f")
14281 (match_operand 2 "nonimmediate_operand" "fm")])
14283 (label_ref (match_operand 3 "" ""))))
14284 (clobber (reg:CCFP FPSR_REG))
14285 (clobber (reg:CCFP FLAGS_REG))
14286 (clobber (match_scratch:HI 4 "=a"))]
14288 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14289 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14290 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14291 && SELECT_CC_MODE (GET_CODE (operands[0]),
14292 operands[1], operands[2]) == CCFPmode
14293 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14296 (define_insn "*fp_jcc_5_387"
14298 (if_then_else (match_operator 0 "comparison_operator"
14299 [(match_operand 1 "register_operand" "f")
14300 (match_operand 2 "register_operand" "f")])
14301 (label_ref (match_operand 3 "" ""))
14303 (clobber (reg:CCFP FPSR_REG))
14304 (clobber (reg:CCFP FLAGS_REG))
14305 (clobber (match_scratch:HI 4 "=a"))]
14306 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14307 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14308 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14311 (define_insn "*fp_jcc_6_387"
14313 (if_then_else (match_operator 0 "comparison_operator"
14314 [(match_operand 1 "register_operand" "f")
14315 (match_operand 2 "register_operand" "f")])
14317 (label_ref (match_operand 3 "" ""))))
14318 (clobber (reg:CCFP FPSR_REG))
14319 (clobber (reg:CCFP FLAGS_REG))
14320 (clobber (match_scratch:HI 4 "=a"))]
14321 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14322 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14323 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14326 (define_insn "*fp_jcc_7_387"
14328 (if_then_else (match_operator 0 "comparison_operator"
14329 [(match_operand 1 "register_operand" "f")
14330 (match_operand 2 "const0_operand" "X")])
14331 (label_ref (match_operand 3 "" ""))
14333 (clobber (reg:CCFP FPSR_REG))
14334 (clobber (reg:CCFP FLAGS_REG))
14335 (clobber (match_scratch:HI 4 "=a"))]
14336 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14337 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14338 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14339 && SELECT_CC_MODE (GET_CODE (operands[0]),
14340 operands[1], operands[2]) == CCFPmode
14341 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14344 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14345 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14346 ;; with a precedence over other operators and is always put in the first
14347 ;; place. Swap condition and operands to match ficom instruction.
14349 (define_insn "*fp_jcc_8<mode>_387"
14351 (if_then_else (match_operator 0 "comparison_operator"
14352 [(match_operator 1 "float_operator"
14353 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14354 (match_operand 3 "register_operand" "f,f")])
14355 (label_ref (match_operand 4 "" ""))
14357 (clobber (reg:CCFP FPSR_REG))
14358 (clobber (reg:CCFP FLAGS_REG))
14359 (clobber (match_scratch:HI 5 "=a,a"))]
14360 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14361 && TARGET_USE_<MODE>MODE_FIOP
14362 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14363 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14364 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14365 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14370 (if_then_else (match_operator 0 "comparison_operator"
14371 [(match_operand 1 "register_operand" "")
14372 (match_operand 2 "nonimmediate_operand" "")])
14373 (match_operand 3 "" "")
14374 (match_operand 4 "" "")))
14375 (clobber (reg:CCFP FPSR_REG))
14376 (clobber (reg:CCFP FLAGS_REG))]
14380 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14381 operands[3], operands[4], NULL_RTX, NULL_RTX);
14387 (if_then_else (match_operator 0 "comparison_operator"
14388 [(match_operand 1 "register_operand" "")
14389 (match_operand 2 "general_operand" "")])
14390 (match_operand 3 "" "")
14391 (match_operand 4 "" "")))
14392 (clobber (reg:CCFP FPSR_REG))
14393 (clobber (reg:CCFP FLAGS_REG))
14394 (clobber (match_scratch:HI 5 "=a"))]
14398 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14399 operands[3], operands[4], operands[5], NULL_RTX);
14405 (if_then_else (match_operator 0 "comparison_operator"
14406 [(match_operator 1 "float_operator"
14407 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14408 (match_operand 3 "register_operand" "")])
14409 (match_operand 4 "" "")
14410 (match_operand 5 "" "")))
14411 (clobber (reg:CCFP FPSR_REG))
14412 (clobber (reg:CCFP FLAGS_REG))
14413 (clobber (match_scratch:HI 6 "=a"))]
14417 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14418 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14419 operands[3], operands[7],
14420 operands[4], operands[5], operands[6], NULL_RTX);
14424 ;; %%% Kill this when reload knows how to do it.
14427 (if_then_else (match_operator 0 "comparison_operator"
14428 [(match_operator 1 "float_operator"
14429 [(match_operand:X87MODEI12 2 "register_operand" "")])
14430 (match_operand 3 "register_operand" "")])
14431 (match_operand 4 "" "")
14432 (match_operand 5 "" "")))
14433 (clobber (reg:CCFP FPSR_REG))
14434 (clobber (reg:CCFP FLAGS_REG))
14435 (clobber (match_scratch:HI 6 "=a"))]
14439 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14440 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14441 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14442 operands[3], operands[7],
14443 operands[4], operands[5], operands[6], operands[2]);
14447 ;; Unconditional and other jump instructions
14449 (define_insn "jump"
14451 (label_ref (match_operand 0 "" "")))]
14454 [(set_attr "type" "ibr")
14455 (set (attr "length")
14456 (if_then_else (and (ge (minus (match_dup 0) (pc))
14458 (lt (minus (match_dup 0) (pc))
14462 (set_attr "modrm" "0")])
14464 (define_expand "indirect_jump"
14465 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14469 (define_insn "*indirect_jump"
14470 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14473 [(set_attr "type" "ibr")
14474 (set_attr "length_immediate" "0")])
14476 (define_insn "*indirect_jump_rtx64"
14477 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14480 [(set_attr "type" "ibr")
14481 (set_attr "length_immediate" "0")])
14483 (define_expand "tablejump"
14484 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14485 (use (label_ref (match_operand 1 "" "")))])]
14488 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14489 relative. Convert the relative address to an absolute address. */
14493 enum rtx_code code;
14495 /* We can't use @GOTOFF for text labels on VxWorks;
14496 see gotoff_operand. */
14497 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14501 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14503 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14507 op1 = pic_offset_table_rtx;
14512 op0 = pic_offset_table_rtx;
14516 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14521 (define_insn "*tablejump_1"
14522 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14523 (use (label_ref (match_operand 1 "" "")))]
14526 [(set_attr "type" "ibr")
14527 (set_attr "length_immediate" "0")])
14529 (define_insn "*tablejump_1_rtx64"
14530 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14531 (use (label_ref (match_operand 1 "" "")))]
14534 [(set_attr "type" "ibr")
14535 (set_attr "length_immediate" "0")])
14537 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14540 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14541 (set (match_operand:QI 1 "register_operand" "")
14542 (match_operator:QI 2 "ix86_comparison_operator"
14543 [(reg FLAGS_REG) (const_int 0)]))
14544 (set (match_operand 3 "q_regs_operand" "")
14545 (zero_extend (match_dup 1)))]
14546 "(peep2_reg_dead_p (3, operands[1])
14547 || operands_match_p (operands[1], operands[3]))
14548 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14549 [(set (match_dup 4) (match_dup 0))
14550 (set (strict_low_part (match_dup 5))
14553 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14554 operands[5] = gen_lowpart (QImode, operands[3]);
14555 ix86_expand_clear (operands[3]);
14558 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14561 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14562 (set (match_operand:QI 1 "register_operand" "")
14563 (match_operator:QI 2 "ix86_comparison_operator"
14564 [(reg FLAGS_REG) (const_int 0)]))
14565 (parallel [(set (match_operand 3 "q_regs_operand" "")
14566 (zero_extend (match_dup 1)))
14567 (clobber (reg:CC FLAGS_REG))])]
14568 "(peep2_reg_dead_p (3, operands[1])
14569 || operands_match_p (operands[1], operands[3]))
14570 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14571 [(set (match_dup 4) (match_dup 0))
14572 (set (strict_low_part (match_dup 5))
14575 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14576 operands[5] = gen_lowpart (QImode, operands[3]);
14577 ix86_expand_clear (operands[3]);
14580 ;; Call instructions.
14582 ;; The predicates normally associated with named expanders are not properly
14583 ;; checked for calls. This is a bug in the generic code, but it isn't that
14584 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14586 ;; Call subroutine returning no value.
14588 (define_expand "call_pop"
14589 [(parallel [(call (match_operand:QI 0 "" "")
14590 (match_operand:SI 1 "" ""))
14591 (set (reg:SI SP_REG)
14592 (plus:SI (reg:SI SP_REG)
14593 (match_operand:SI 3 "" "")))])]
14596 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14600 (define_insn "*call_pop_0"
14601 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14602 (match_operand:SI 1 "" ""))
14603 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14604 (match_operand:SI 2 "immediate_operand" "")))]
14607 if (SIBLING_CALL_P (insn))
14610 return "call\t%P0";
14612 [(set_attr "type" "call")])
14614 (define_insn "*call_pop_1"
14615 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14616 (match_operand:SI 1 "" ""))
14617 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14618 (match_operand:SI 2 "immediate_operand" "i")))]
14621 if (constant_call_address_operand (operands[0], Pmode))
14623 if (SIBLING_CALL_P (insn))
14626 return "call\t%P0";
14628 if (SIBLING_CALL_P (insn))
14631 return "call\t%A0";
14633 [(set_attr "type" "call")])
14635 (define_expand "call"
14636 [(call (match_operand:QI 0 "" "")
14637 (match_operand 1 "" ""))
14638 (use (match_operand 2 "" ""))]
14641 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14645 (define_expand "sibcall"
14646 [(call (match_operand:QI 0 "" "")
14647 (match_operand 1 "" ""))
14648 (use (match_operand 2 "" ""))]
14651 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14655 (define_insn "*call_0"
14656 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14657 (match_operand 1 "" ""))]
14660 if (SIBLING_CALL_P (insn))
14663 return "call\t%P0";
14665 [(set_attr "type" "call")])
14667 (define_insn "*call_1"
14668 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14669 (match_operand 1 "" ""))]
14670 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14672 if (constant_call_address_operand (operands[0], Pmode))
14673 return "call\t%P0";
14674 return "call\t%A0";
14676 [(set_attr "type" "call")])
14678 (define_insn "*sibcall_1"
14679 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14680 (match_operand 1 "" ""))]
14681 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14683 if (constant_call_address_operand (operands[0], Pmode))
14687 [(set_attr "type" "call")])
14689 (define_insn "*call_1_rex64"
14690 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14691 (match_operand 1 "" ""))]
14692 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14693 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14695 if (constant_call_address_operand (operands[0], Pmode))
14696 return "call\t%P0";
14697 return "call\t%A0";
14699 [(set_attr "type" "call")])
14701 (define_insn "*call_1_rex64_large"
14702 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14703 (match_operand 1 "" ""))]
14704 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14706 [(set_attr "type" "call")])
14708 (define_insn "*sibcall_1_rex64"
14709 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14710 (match_operand 1 "" ""))]
14711 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14713 [(set_attr "type" "call")])
14715 (define_insn "*sibcall_1_rex64_v"
14716 [(call (mem:QI (reg:DI R11_REG))
14717 (match_operand 0 "" ""))]
14718 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14720 [(set_attr "type" "call")])
14723 ;; Call subroutine, returning value in operand 0
14725 (define_expand "call_value_pop"
14726 [(parallel [(set (match_operand 0 "" "")
14727 (call (match_operand:QI 1 "" "")
14728 (match_operand:SI 2 "" "")))
14729 (set (reg:SI SP_REG)
14730 (plus:SI (reg:SI SP_REG)
14731 (match_operand:SI 4 "" "")))])]
14734 ix86_expand_call (operands[0], operands[1], operands[2],
14735 operands[3], operands[4], 0);
14739 (define_expand "call_value"
14740 [(set (match_operand 0 "" "")
14741 (call (match_operand:QI 1 "" "")
14742 (match_operand:SI 2 "" "")))
14743 (use (match_operand:SI 3 "" ""))]
14744 ;; Operand 2 not used on the i386.
14747 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14751 (define_expand "sibcall_value"
14752 [(set (match_operand 0 "" "")
14753 (call (match_operand:QI 1 "" "")
14754 (match_operand:SI 2 "" "")))
14755 (use (match_operand:SI 3 "" ""))]
14756 ;; Operand 2 not used on the i386.
14759 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14763 ;; Call subroutine returning any type.
14765 (define_expand "untyped_call"
14766 [(parallel [(call (match_operand 0 "" "")
14768 (match_operand 1 "" "")
14769 (match_operand 2 "" "")])]
14774 /* In order to give reg-stack an easier job in validating two
14775 coprocessor registers as containing a possible return value,
14776 simply pretend the untyped call returns a complex long double
14779 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14780 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14781 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14784 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14786 rtx set = XVECEXP (operands[2], 0, i);
14787 emit_move_insn (SET_DEST (set), SET_SRC (set));
14790 /* The optimizer does not know that the call sets the function value
14791 registers we stored in the result block. We avoid problems by
14792 claiming that all hard registers are used and clobbered at this
14794 emit_insn (gen_blockage ());
14799 ;; Prologue and epilogue instructions
14801 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14802 ;; all of memory. This blocks insns from being moved across this point.
14804 (define_insn "blockage"
14805 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14808 [(set_attr "length" "0")])
14810 ;; As USE insns aren't meaningful after reload, this is used instead
14811 ;; to prevent deleting instructions setting registers for PIC code
14812 (define_insn "prologue_use"
14813 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14816 [(set_attr "length" "0")])
14818 ;; Insn emitted into the body of a function to return from a function.
14819 ;; This is only done if the function's epilogue is known to be simple.
14820 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14822 (define_expand "return"
14824 "ix86_can_use_return_insn_p ()"
14826 if (current_function_pops_args)
14828 rtx popc = GEN_INT (current_function_pops_args);
14829 emit_jump_insn (gen_return_pop_internal (popc));
14834 (define_insn "return_internal"
14838 [(set_attr "length" "1")
14839 (set_attr "length_immediate" "0")
14840 (set_attr "modrm" "0")])
14842 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14843 ;; instruction Athlon and K8 have.
14845 (define_insn "return_internal_long"
14847 (unspec [(const_int 0)] UNSPEC_REP)]
14850 [(set_attr "length" "1")
14851 (set_attr "length_immediate" "0")
14852 (set_attr "prefix_rep" "1")
14853 (set_attr "modrm" "0")])
14855 (define_insn "return_pop_internal"
14857 (use (match_operand:SI 0 "const_int_operand" ""))]
14860 [(set_attr "length" "3")
14861 (set_attr "length_immediate" "2")
14862 (set_attr "modrm" "0")])
14864 (define_insn "return_indirect_internal"
14866 (use (match_operand:SI 0 "register_operand" "r"))]
14869 [(set_attr "type" "ibr")
14870 (set_attr "length_immediate" "0")])
14876 [(set_attr "length" "1")
14877 (set_attr "length_immediate" "0")
14878 (set_attr "modrm" "0")])
14880 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14881 ;; branch prediction penalty for the third jump in a 16-byte
14884 (define_insn "align"
14885 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14888 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14889 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14891 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14892 The align insn is used to avoid 3 jump instructions in the row to improve
14893 branch prediction and the benefits hardly outweigh the cost of extra 8
14894 nops on the average inserted by full alignment pseudo operation. */
14898 [(set_attr "length" "16")])
14900 (define_expand "prologue"
14903 "ix86_expand_prologue (); DONE;")
14905 (define_insn "set_got"
14906 [(set (match_operand:SI 0 "register_operand" "=r")
14907 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14908 (clobber (reg:CC FLAGS_REG))]
14910 { return output_set_got (operands[0], NULL_RTX); }
14911 [(set_attr "type" "multi")
14912 (set_attr "length" "12")])
14914 (define_insn "set_got_labelled"
14915 [(set (match_operand:SI 0 "register_operand" "=r")
14916 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14918 (clobber (reg:CC FLAGS_REG))]
14920 { return output_set_got (operands[0], operands[1]); }
14921 [(set_attr "type" "multi")
14922 (set_attr "length" "12")])
14924 (define_insn "set_got_rex64"
14925 [(set (match_operand:DI 0 "register_operand" "=r")
14926 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14928 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14929 [(set_attr "type" "lea")
14930 (set_attr "length" "6")])
14932 (define_insn "set_rip_rex64"
14933 [(set (match_operand:DI 0 "register_operand" "=r")
14934 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14936 "lea{q}\t%l1(%%rip), %0"
14937 [(set_attr "type" "lea")
14938 (set_attr "length" "6")])
14940 (define_insn "set_got_offset_rex64"
14941 [(set (match_operand:DI 0 "register_operand" "=r")
14942 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14944 "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
14945 [(set_attr "type" "imov")
14946 (set_attr "length" "11")])
14948 (define_expand "epilogue"
14951 "ix86_expand_epilogue (1); DONE;")
14953 (define_expand "sibcall_epilogue"
14956 "ix86_expand_epilogue (0); DONE;")
14958 (define_expand "eh_return"
14959 [(use (match_operand 0 "register_operand" ""))]
14962 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14964 /* Tricky bit: we write the address of the handler to which we will
14965 be returning into someone else's stack frame, one word below the
14966 stack address we wish to restore. */
14967 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14968 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14969 tmp = gen_rtx_MEM (Pmode, tmp);
14970 emit_move_insn (tmp, ra);
14972 if (Pmode == SImode)
14973 emit_jump_insn (gen_eh_return_si (sa));
14975 emit_jump_insn (gen_eh_return_di (sa));
14980 (define_insn_and_split "eh_return_si"
14982 (unspec [(match_operand:SI 0 "register_operand" "c")]
14983 UNSPEC_EH_RETURN))]
14988 "ix86_expand_epilogue (2); DONE;")
14990 (define_insn_and_split "eh_return_di"
14992 (unspec [(match_operand:DI 0 "register_operand" "c")]
14993 UNSPEC_EH_RETURN))]
14998 "ix86_expand_epilogue (2); DONE;")
15000 (define_insn "leave"
15001 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15002 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15003 (clobber (mem:BLK (scratch)))]
15006 [(set_attr "type" "leave")])
15008 (define_insn "leave_rex64"
15009 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15010 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15011 (clobber (mem:BLK (scratch)))]
15014 [(set_attr "type" "leave")])
15016 (define_expand "ffssi2"
15018 [(set (match_operand:SI 0 "register_operand" "")
15019 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15020 (clobber (match_scratch:SI 2 ""))
15021 (clobber (reg:CC FLAGS_REG))])]
15026 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15031 (define_expand "ffs_cmove"
15032 [(set (match_dup 2) (const_int -1))
15033 (parallel [(set (reg:CCZ FLAGS_REG)
15034 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15036 (set (match_operand:SI 0 "nonimmediate_operand" "")
15037 (ctz:SI (match_dup 1)))])
15038 (set (match_dup 0) (if_then_else:SI
15039 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15042 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15043 (clobber (reg:CC FLAGS_REG))])]
15045 "operands[2] = gen_reg_rtx (SImode);")
15047 (define_insn_and_split "*ffs_no_cmove"
15048 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15049 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15050 (clobber (match_scratch:SI 2 "=&q"))
15051 (clobber (reg:CC FLAGS_REG))]
15054 "&& reload_completed"
15055 [(parallel [(set (reg:CCZ FLAGS_REG)
15056 (compare:CCZ (match_dup 1) (const_int 0)))
15057 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15058 (set (strict_low_part (match_dup 3))
15059 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15060 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15061 (clobber (reg:CC FLAGS_REG))])
15062 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15063 (clobber (reg:CC FLAGS_REG))])
15064 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15065 (clobber (reg:CC FLAGS_REG))])]
15067 operands[3] = gen_lowpart (QImode, operands[2]);
15068 ix86_expand_clear (operands[2]);
15071 (define_insn "*ffssi_1"
15072 [(set (reg:CCZ FLAGS_REG)
15073 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15075 (set (match_operand:SI 0 "register_operand" "=r")
15076 (ctz:SI (match_dup 1)))]
15078 "bsf{l}\t{%1, %0|%0, %1}"
15079 [(set_attr "prefix_0f" "1")])
15081 (define_expand "ffsdi2"
15082 [(set (match_dup 2) (const_int -1))
15083 (parallel [(set (reg:CCZ FLAGS_REG)
15084 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15086 (set (match_operand:DI 0 "nonimmediate_operand" "")
15087 (ctz:DI (match_dup 1)))])
15088 (set (match_dup 0) (if_then_else:DI
15089 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15092 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15093 (clobber (reg:CC FLAGS_REG))])]
15095 "operands[2] = gen_reg_rtx (DImode);")
15097 (define_insn "*ffsdi_1"
15098 [(set (reg:CCZ FLAGS_REG)
15099 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15101 (set (match_operand:DI 0 "register_operand" "=r")
15102 (ctz:DI (match_dup 1)))]
15104 "bsf{q}\t{%1, %0|%0, %1}"
15105 [(set_attr "prefix_0f" "1")])
15107 (define_insn "ctzsi2"
15108 [(set (match_operand:SI 0 "register_operand" "=r")
15109 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15110 (clobber (reg:CC FLAGS_REG))]
15112 "bsf{l}\t{%1, %0|%0, %1}"
15113 [(set_attr "prefix_0f" "1")])
15115 (define_insn "ctzdi2"
15116 [(set (match_operand:DI 0 "register_operand" "=r")
15117 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15118 (clobber (reg:CC FLAGS_REG))]
15120 "bsf{q}\t{%1, %0|%0, %1}"
15121 [(set_attr "prefix_0f" "1")])
15123 (define_expand "clzsi2"
15125 [(set (match_operand:SI 0 "register_operand" "")
15126 (minus:SI (const_int 31)
15127 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15128 (clobber (reg:CC FLAGS_REG))])
15130 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15131 (clobber (reg:CC FLAGS_REG))])]
15136 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15141 (define_insn "clzsi2_abm"
15142 [(set (match_operand:SI 0 "register_operand" "=r")
15143 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15144 (clobber (reg:CC FLAGS_REG))]
15146 "lzcnt{l}\t{%1, %0|%0, %1}"
15147 [(set_attr "prefix_rep" "1")
15148 (set_attr "type" "bitmanip")
15149 (set_attr "mode" "SI")])
15151 (define_insn "*bsr"
15152 [(set (match_operand:SI 0 "register_operand" "=r")
15153 (minus:SI (const_int 31)
15154 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15155 (clobber (reg:CC FLAGS_REG))]
15157 "bsr{l}\t{%1, %0|%0, %1}"
15158 [(set_attr "prefix_0f" "1")
15159 (set_attr "mode" "SI")])
15161 (define_insn "popcountsi2"
15162 [(set (match_operand:SI 0 "register_operand" "=r")
15163 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15164 (clobber (reg:CC FLAGS_REG))]
15166 "popcnt{l}\t{%1, %0|%0, %1}"
15167 [(set_attr "prefix_rep" "1")
15168 (set_attr "type" "bitmanip")
15169 (set_attr "mode" "SI")])
15171 (define_insn "*popcountsi2_cmp"
15172 [(set (reg FLAGS_REG)
15174 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15176 (set (match_operand:SI 0 "register_operand" "=r")
15177 (popcount:SI (match_dup 1)))]
15178 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15179 "popcnt{l}\t{%1, %0|%0, %1}"
15180 [(set_attr "prefix_rep" "1")
15181 (set_attr "type" "bitmanip")
15182 (set_attr "mode" "SI")])
15184 (define_insn "*popcountsi2_cmp_zext"
15185 [(set (reg FLAGS_REG)
15187 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15189 (set (match_operand:DI 0 "register_operand" "=r")
15190 (zero_extend:DI(popcount:SI (match_dup 1))))]
15191 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15192 "popcnt{l}\t{%1, %0|%0, %1}"
15193 [(set_attr "prefix_rep" "1")
15194 (set_attr "type" "bitmanip")
15195 (set_attr "mode" "SI")])
15197 (define_expand "bswapsi2"
15198 [(set (match_operand:SI 0 "register_operand" "")
15199 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15204 rtx x = operands[0];
15206 emit_move_insn (x, operands[1]);
15207 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15208 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15209 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15214 (define_insn "*bswapsi_1"
15215 [(set (match_operand:SI 0 "register_operand" "=r")
15216 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15219 [(set_attr "prefix_0f" "1")
15220 (set_attr "length" "2")])
15222 (define_insn "*bswaphi_lowpart_1"
15223 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15224 (bswap:HI (match_dup 0)))
15225 (clobber (reg:CC FLAGS_REG))]
15226 "TARGET_USE_XCHGB || optimize_size"
15228 xchg{b}\t{%h0, %b0|%b0, %h0}
15229 rol{w}\t{$8, %0|%0, 8}"
15230 [(set_attr "length" "2,4")
15231 (set_attr "mode" "QI,HI")])
15233 (define_insn "bswaphi_lowpart"
15234 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15235 (bswap:HI (match_dup 0)))
15236 (clobber (reg:CC FLAGS_REG))]
15238 "rol{w}\t{$8, %0|%0, 8}"
15239 [(set_attr "length" "4")
15240 (set_attr "mode" "HI")])
15242 (define_insn "bswapdi2"
15243 [(set (match_operand:DI 0 "register_operand" "=r")
15244 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15247 [(set_attr "prefix_0f" "1")
15248 (set_attr "length" "3")])
15250 (define_expand "clzdi2"
15252 [(set (match_operand:DI 0 "register_operand" "")
15253 (minus:DI (const_int 63)
15254 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15255 (clobber (reg:CC FLAGS_REG))])
15257 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15258 (clobber (reg:CC FLAGS_REG))])]
15263 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15268 (define_insn "clzdi2_abm"
15269 [(set (match_operand:DI 0 "register_operand" "=r")
15270 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15271 (clobber (reg:CC FLAGS_REG))]
15272 "TARGET_64BIT && TARGET_ABM"
15273 "lzcnt{q}\t{%1, %0|%0, %1}"
15274 [(set_attr "prefix_rep" "1")
15275 (set_attr "type" "bitmanip")
15276 (set_attr "mode" "DI")])
15278 (define_insn "*bsr_rex64"
15279 [(set (match_operand:DI 0 "register_operand" "=r")
15280 (minus:DI (const_int 63)
15281 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15282 (clobber (reg:CC FLAGS_REG))]
15284 "bsr{q}\t{%1, %0|%0, %1}"
15285 [(set_attr "prefix_0f" "1")
15286 (set_attr "mode" "DI")])
15288 (define_insn "popcountdi2"
15289 [(set (match_operand:DI 0 "register_operand" "=r")
15290 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15291 (clobber (reg:CC FLAGS_REG))]
15292 "TARGET_64BIT && TARGET_POPCNT"
15293 "popcnt{q}\t{%1, %0|%0, %1}"
15294 [(set_attr "prefix_rep" "1")
15295 (set_attr "type" "bitmanip")
15296 (set_attr "mode" "DI")])
15298 (define_insn "*popcountdi2_cmp"
15299 [(set (reg FLAGS_REG)
15301 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15303 (set (match_operand:DI 0 "register_operand" "=r")
15304 (popcount:DI (match_dup 1)))]
15305 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15306 "popcnt{q}\t{%1, %0|%0, %1}"
15307 [(set_attr "prefix_rep" "1")
15308 (set_attr "type" "bitmanip")
15309 (set_attr "mode" "DI")])
15311 (define_expand "clzhi2"
15313 [(set (match_operand:HI 0 "register_operand" "")
15314 (minus:HI (const_int 15)
15315 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15316 (clobber (reg:CC FLAGS_REG))])
15318 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15319 (clobber (reg:CC FLAGS_REG))])]
15324 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15329 (define_insn "clzhi2_abm"
15330 [(set (match_operand:HI 0 "register_operand" "=r")
15331 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15332 (clobber (reg:CC FLAGS_REG))]
15334 "lzcnt{w}\t{%1, %0|%0, %1}"
15335 [(set_attr "prefix_rep" "1")
15336 (set_attr "type" "bitmanip")
15337 (set_attr "mode" "HI")])
15339 (define_insn "*bsrhi"
15340 [(set (match_operand:HI 0 "register_operand" "=r")
15341 (minus:HI (const_int 15)
15342 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15343 (clobber (reg:CC FLAGS_REG))]
15345 "bsr{w}\t{%1, %0|%0, %1}"
15346 [(set_attr "prefix_0f" "1")
15347 (set_attr "mode" "HI")])
15349 (define_insn "popcounthi2"
15350 [(set (match_operand:HI 0 "register_operand" "=r")
15351 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15352 (clobber (reg:CC FLAGS_REG))]
15354 "popcnt{w}\t{%1, %0|%0, %1}"
15355 [(set_attr "prefix_rep" "1")
15356 (set_attr "type" "bitmanip")
15357 (set_attr "mode" "HI")])
15359 (define_insn "*popcounthi2_cmp"
15360 [(set (reg FLAGS_REG)
15362 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15364 (set (match_operand:HI 0 "register_operand" "=r")
15365 (popcount:HI (match_dup 1)))]
15366 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15367 "popcnt{w}\t{%1, %0|%0, %1}"
15368 [(set_attr "prefix_rep" "1")
15369 (set_attr "type" "bitmanip")
15370 (set_attr "mode" "HI")])
15372 (define_expand "paritydi2"
15373 [(set (match_operand:DI 0 "register_operand" "")
15374 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15377 rtx scratch = gen_reg_rtx (QImode);
15380 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15381 NULL_RTX, operands[1]));
15383 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15384 gen_rtx_REG (CCmode, FLAGS_REG),
15386 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15389 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15392 rtx tmp = gen_reg_rtx (SImode);
15394 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15395 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15400 (define_insn_and_split "paritydi2_cmp"
15401 [(set (reg:CC FLAGS_REG)
15402 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15403 (clobber (match_scratch:DI 0 "=r,X"))
15404 (clobber (match_scratch:SI 1 "=r,r"))
15405 (clobber (match_scratch:HI 2 "=Q,Q"))]
15408 "&& reload_completed"
15410 [(set (match_dup 1)
15411 (xor:SI (match_dup 1) (match_dup 4)))
15412 (clobber (reg:CC FLAGS_REG))])
15414 [(set (reg:CC FLAGS_REG)
15415 (parity:CC (match_dup 1)))
15416 (clobber (match_dup 1))
15417 (clobber (match_dup 2))])]
15419 operands[4] = gen_lowpart (SImode, operands[3]);
15421 if (MEM_P (operands[3]))
15422 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15423 else if (! TARGET_64BIT)
15424 operands[1] = gen_highpart (SImode, operands[3]);
15427 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15428 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15432 (define_expand "paritysi2"
15433 [(set (match_operand:SI 0 "register_operand" "")
15434 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15437 rtx scratch = gen_reg_rtx (QImode);
15440 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15442 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15443 gen_rtx_REG (CCmode, FLAGS_REG),
15445 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15447 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15451 (define_insn_and_split "paritysi2_cmp"
15452 [(set (reg:CC FLAGS_REG)
15453 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15454 (clobber (match_scratch:SI 0 "=r,X"))
15455 (clobber (match_scratch:HI 1 "=Q,Q"))]
15458 "&& reload_completed"
15460 [(set (match_dup 1)
15461 (xor:HI (match_dup 1) (match_dup 3)))
15462 (clobber (reg:CC FLAGS_REG))])
15464 [(set (reg:CC FLAGS_REG)
15465 (parity:CC (match_dup 1)))
15466 (clobber (match_dup 1))])]
15468 operands[3] = gen_lowpart (HImode, operands[2]);
15470 if (MEM_P (operands[2]))
15471 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15474 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15475 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15479 (define_insn "*parityhi2_cmp"
15480 [(set (reg:CC FLAGS_REG)
15481 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15482 (clobber (match_scratch:HI 0 "=Q"))]
15484 "xor{b}\t{%h0, %b0|%b0, %h0}"
15485 [(set_attr "length" "2")
15486 (set_attr "mode" "HI")])
15488 (define_insn "*parityqi2_cmp"
15489 [(set (reg:CC FLAGS_REG)
15490 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15493 [(set_attr "length" "2")
15494 (set_attr "mode" "QI")])
15496 ;; Thread-local storage patterns for ELF.
15498 ;; Note that these code sequences must appear exactly as shown
15499 ;; in order to allow linker relaxation.
15501 (define_insn "*tls_global_dynamic_32_gnu"
15502 [(set (match_operand:SI 0 "register_operand" "=a")
15503 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15504 (match_operand:SI 2 "tls_symbolic_operand" "")
15505 (match_operand:SI 3 "call_insn_operand" "")]
15507 (clobber (match_scratch:SI 4 "=d"))
15508 (clobber (match_scratch:SI 5 "=c"))
15509 (clobber (reg:CC FLAGS_REG))]
15510 "!TARGET_64BIT && TARGET_GNU_TLS"
15511 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15512 [(set_attr "type" "multi")
15513 (set_attr "length" "12")])
15515 (define_insn "*tls_global_dynamic_32_sun"
15516 [(set (match_operand:SI 0 "register_operand" "=a")
15517 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15518 (match_operand:SI 2 "tls_symbolic_operand" "")
15519 (match_operand:SI 3 "call_insn_operand" "")]
15521 (clobber (match_scratch:SI 4 "=d"))
15522 (clobber (match_scratch:SI 5 "=c"))
15523 (clobber (reg:CC FLAGS_REG))]
15524 "!TARGET_64BIT && TARGET_SUN_TLS"
15525 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15526 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15527 [(set_attr "type" "multi")
15528 (set_attr "length" "14")])
15530 (define_expand "tls_global_dynamic_32"
15531 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15534 (match_operand:SI 1 "tls_symbolic_operand" "")
15537 (clobber (match_scratch:SI 4 ""))
15538 (clobber (match_scratch:SI 5 ""))
15539 (clobber (reg:CC FLAGS_REG))])]
15543 operands[2] = pic_offset_table_rtx;
15546 operands[2] = gen_reg_rtx (Pmode);
15547 emit_insn (gen_set_got (operands[2]));
15549 if (TARGET_GNU2_TLS)
15551 emit_insn (gen_tls_dynamic_gnu2_32
15552 (operands[0], operands[1], operands[2]));
15555 operands[3] = ix86_tls_get_addr ();
15558 (define_insn "*tls_global_dynamic_64"
15559 [(set (match_operand:DI 0 "register_operand" "=a")
15560 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15561 (match_operand:DI 3 "" "")))
15562 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15565 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15566 [(set_attr "type" "multi")
15567 (set_attr "length" "16")])
15569 (define_expand "tls_global_dynamic_64"
15570 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15571 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15572 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15576 if (TARGET_GNU2_TLS)
15578 emit_insn (gen_tls_dynamic_gnu2_64
15579 (operands[0], operands[1]));
15582 operands[2] = ix86_tls_get_addr ();
15585 (define_insn "*tls_local_dynamic_base_32_gnu"
15586 [(set (match_operand:SI 0 "register_operand" "=a")
15587 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15588 (match_operand:SI 2 "call_insn_operand" "")]
15589 UNSPEC_TLS_LD_BASE))
15590 (clobber (match_scratch:SI 3 "=d"))
15591 (clobber (match_scratch:SI 4 "=c"))
15592 (clobber (reg:CC FLAGS_REG))]
15593 "!TARGET_64BIT && TARGET_GNU_TLS"
15594 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15595 [(set_attr "type" "multi")
15596 (set_attr "length" "11")])
15598 (define_insn "*tls_local_dynamic_base_32_sun"
15599 [(set (match_operand:SI 0 "register_operand" "=a")
15600 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15601 (match_operand:SI 2 "call_insn_operand" "")]
15602 UNSPEC_TLS_LD_BASE))
15603 (clobber (match_scratch:SI 3 "=d"))
15604 (clobber (match_scratch:SI 4 "=c"))
15605 (clobber (reg:CC FLAGS_REG))]
15606 "!TARGET_64BIT && TARGET_SUN_TLS"
15607 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15608 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15609 [(set_attr "type" "multi")
15610 (set_attr "length" "13")])
15612 (define_expand "tls_local_dynamic_base_32"
15613 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15614 (unspec:SI [(match_dup 1) (match_dup 2)]
15615 UNSPEC_TLS_LD_BASE))
15616 (clobber (match_scratch:SI 3 ""))
15617 (clobber (match_scratch:SI 4 ""))
15618 (clobber (reg:CC FLAGS_REG))])]
15622 operands[1] = pic_offset_table_rtx;
15625 operands[1] = gen_reg_rtx (Pmode);
15626 emit_insn (gen_set_got (operands[1]));
15628 if (TARGET_GNU2_TLS)
15630 emit_insn (gen_tls_dynamic_gnu2_32
15631 (operands[0], ix86_tls_module_base (), operands[1]));
15634 operands[2] = ix86_tls_get_addr ();
15637 (define_insn "*tls_local_dynamic_base_64"
15638 [(set (match_operand:DI 0 "register_operand" "=a")
15639 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15640 (match_operand:DI 2 "" "")))
15641 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15643 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15644 [(set_attr "type" "multi")
15645 (set_attr "length" "12")])
15647 (define_expand "tls_local_dynamic_base_64"
15648 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15649 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15650 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15653 if (TARGET_GNU2_TLS)
15655 emit_insn (gen_tls_dynamic_gnu2_64
15656 (operands[0], ix86_tls_module_base ()));
15659 operands[1] = ix86_tls_get_addr ();
15662 ;; Local dynamic of a single variable is a lose. Show combine how
15663 ;; to convert that back to global dynamic.
15665 (define_insn_and_split "*tls_local_dynamic_32_once"
15666 [(set (match_operand:SI 0 "register_operand" "=a")
15667 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15668 (match_operand:SI 2 "call_insn_operand" "")]
15669 UNSPEC_TLS_LD_BASE)
15670 (const:SI (unspec:SI
15671 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15673 (clobber (match_scratch:SI 4 "=d"))
15674 (clobber (match_scratch:SI 5 "=c"))
15675 (clobber (reg:CC FLAGS_REG))]
15679 [(parallel [(set (match_dup 0)
15680 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15682 (clobber (match_dup 4))
15683 (clobber (match_dup 5))
15684 (clobber (reg:CC FLAGS_REG))])]
15687 ;; Load and add the thread base pointer from %gs:0.
15689 (define_insn "*load_tp_si"
15690 [(set (match_operand:SI 0 "register_operand" "=r")
15691 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15693 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15694 [(set_attr "type" "imov")
15695 (set_attr "modrm" "0")
15696 (set_attr "length" "7")
15697 (set_attr "memory" "load")
15698 (set_attr "imm_disp" "false")])
15700 (define_insn "*add_tp_si"
15701 [(set (match_operand:SI 0 "register_operand" "=r")
15702 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15703 (match_operand:SI 1 "register_operand" "0")))
15704 (clobber (reg:CC FLAGS_REG))]
15706 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15707 [(set_attr "type" "alu")
15708 (set_attr "modrm" "0")
15709 (set_attr "length" "7")
15710 (set_attr "memory" "load")
15711 (set_attr "imm_disp" "false")])
15713 (define_insn "*load_tp_di"
15714 [(set (match_operand:DI 0 "register_operand" "=r")
15715 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15717 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15718 [(set_attr "type" "imov")
15719 (set_attr "modrm" "0")
15720 (set_attr "length" "7")
15721 (set_attr "memory" "load")
15722 (set_attr "imm_disp" "false")])
15724 (define_insn "*add_tp_di"
15725 [(set (match_operand:DI 0 "register_operand" "=r")
15726 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15727 (match_operand:DI 1 "register_operand" "0")))
15728 (clobber (reg:CC FLAGS_REG))]
15730 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15731 [(set_attr "type" "alu")
15732 (set_attr "modrm" "0")
15733 (set_attr "length" "7")
15734 (set_attr "memory" "load")
15735 (set_attr "imm_disp" "false")])
15737 ;; GNU2 TLS patterns can be split.
15739 (define_expand "tls_dynamic_gnu2_32"
15740 [(set (match_dup 3)
15741 (plus:SI (match_operand:SI 2 "register_operand" "")
15743 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15746 [(set (match_operand:SI 0 "register_operand" "")
15747 (unspec:SI [(match_dup 1) (match_dup 3)
15748 (match_dup 2) (reg:SI SP_REG)]
15750 (clobber (reg:CC FLAGS_REG))])]
15751 "!TARGET_64BIT && TARGET_GNU2_TLS"
15753 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15754 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15757 (define_insn "*tls_dynamic_lea_32"
15758 [(set (match_operand:SI 0 "register_operand" "=r")
15759 (plus:SI (match_operand:SI 1 "register_operand" "b")
15761 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15762 UNSPEC_TLSDESC))))]
15763 "!TARGET_64BIT && TARGET_GNU2_TLS"
15764 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15765 [(set_attr "type" "lea")
15766 (set_attr "mode" "SI")
15767 (set_attr "length" "6")
15768 (set_attr "length_address" "4")])
15770 (define_insn "*tls_dynamic_call_32"
15771 [(set (match_operand:SI 0 "register_operand" "=a")
15772 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15773 (match_operand:SI 2 "register_operand" "0")
15774 ;; we have to make sure %ebx still points to the GOT
15775 (match_operand:SI 3 "register_operand" "b")
15778 (clobber (reg:CC FLAGS_REG))]
15779 "!TARGET_64BIT && TARGET_GNU2_TLS"
15780 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15781 [(set_attr "type" "call")
15782 (set_attr "length" "2")
15783 (set_attr "length_address" "0")])
15785 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15786 [(set (match_operand:SI 0 "register_operand" "=&a")
15788 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15789 (match_operand:SI 4 "" "")
15790 (match_operand:SI 2 "register_operand" "b")
15793 (const:SI (unspec:SI
15794 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15796 (clobber (reg:CC FLAGS_REG))]
15797 "!TARGET_64BIT && TARGET_GNU2_TLS"
15800 [(set (match_dup 0) (match_dup 5))]
15802 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15803 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15806 (define_expand "tls_dynamic_gnu2_64"
15807 [(set (match_dup 2)
15808 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15811 [(set (match_operand:DI 0 "register_operand" "")
15812 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15814 (clobber (reg:CC FLAGS_REG))])]
15815 "TARGET_64BIT && TARGET_GNU2_TLS"
15817 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15818 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15821 (define_insn "*tls_dynamic_lea_64"
15822 [(set (match_operand:DI 0 "register_operand" "=r")
15823 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15825 "TARGET_64BIT && TARGET_GNU2_TLS"
15826 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15827 [(set_attr "type" "lea")
15828 (set_attr "mode" "DI")
15829 (set_attr "length" "7")
15830 (set_attr "length_address" "4")])
15832 (define_insn "*tls_dynamic_call_64"
15833 [(set (match_operand:DI 0 "register_operand" "=a")
15834 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15835 (match_operand:DI 2 "register_operand" "0")
15838 (clobber (reg:CC FLAGS_REG))]
15839 "TARGET_64BIT && TARGET_GNU2_TLS"
15840 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15841 [(set_attr "type" "call")
15842 (set_attr "length" "2")
15843 (set_attr "length_address" "0")])
15845 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15846 [(set (match_operand:DI 0 "register_operand" "=&a")
15848 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15849 (match_operand:DI 3 "" "")
15852 (const:DI (unspec:DI
15853 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15855 (clobber (reg:CC FLAGS_REG))]
15856 "TARGET_64BIT && TARGET_GNU2_TLS"
15859 [(set (match_dup 0) (match_dup 4))]
15861 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15862 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15867 ;; These patterns match the binary 387 instructions for addM3, subM3,
15868 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15869 ;; SFmode. The first is the normal insn, the second the same insn but
15870 ;; with one operand a conversion, and the third the same insn but with
15871 ;; the other operand a conversion. The conversion may be SFmode or
15872 ;; SImode if the target mode DFmode, but only SImode if the target mode
15875 ;; Gcc is slightly more smart about handling normal two address instructions
15876 ;; so use special patterns for add and mull.
15878 (define_insn "*fop_sf_comm_mixed"
15879 [(set (match_operand:SF 0 "register_operand" "=f,x")
15880 (match_operator:SF 3 "binary_fp_operator"
15881 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15882 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15883 "TARGET_MIX_SSE_I387
15884 && COMMUTATIVE_ARITH_P (operands[3])
15885 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15886 "* return output_387_binary_op (insn, operands);"
15887 [(set (attr "type")
15888 (if_then_else (eq_attr "alternative" "1")
15889 (if_then_else (match_operand:SF 3 "mult_operator" "")
15890 (const_string "ssemul")
15891 (const_string "sseadd"))
15892 (if_then_else (match_operand:SF 3 "mult_operator" "")
15893 (const_string "fmul")
15894 (const_string "fop"))))
15895 (set_attr "mode" "SF")])
15897 (define_insn "*fop_sf_comm_sse"
15898 [(set (match_operand:SF 0 "register_operand" "=x")
15899 (match_operator:SF 3 "binary_fp_operator"
15900 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15901 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15903 && COMMUTATIVE_ARITH_P (operands[3])
15904 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15905 "* return output_387_binary_op (insn, operands);"
15906 [(set (attr "type")
15907 (if_then_else (match_operand:SF 3 "mult_operator" "")
15908 (const_string "ssemul")
15909 (const_string "sseadd")))
15910 (set_attr "mode" "SF")])
15912 (define_insn "*fop_sf_comm_i387"
15913 [(set (match_operand:SF 0 "register_operand" "=f")
15914 (match_operator:SF 3 "binary_fp_operator"
15915 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15916 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15918 && COMMUTATIVE_ARITH_P (operands[3])
15919 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15920 "* return output_387_binary_op (insn, operands);"
15921 [(set (attr "type")
15922 (if_then_else (match_operand:SF 3 "mult_operator" "")
15923 (const_string "fmul")
15924 (const_string "fop")))
15925 (set_attr "mode" "SF")])
15927 (define_insn "*fop_sf_1_mixed"
15928 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15929 (match_operator:SF 3 "binary_fp_operator"
15930 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15931 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15932 "TARGET_MIX_SSE_I387
15933 && !COMMUTATIVE_ARITH_P (operands[3])
15934 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15935 "* return output_387_binary_op (insn, operands);"
15936 [(set (attr "type")
15937 (cond [(and (eq_attr "alternative" "2")
15938 (match_operand:SF 3 "mult_operator" ""))
15939 (const_string "ssemul")
15940 (and (eq_attr "alternative" "2")
15941 (match_operand:SF 3 "div_operator" ""))
15942 (const_string "ssediv")
15943 (eq_attr "alternative" "2")
15944 (const_string "sseadd")
15945 (match_operand:SF 3 "mult_operator" "")
15946 (const_string "fmul")
15947 (match_operand:SF 3 "div_operator" "")
15948 (const_string "fdiv")
15950 (const_string "fop")))
15951 (set_attr "mode" "SF")])
15953 (define_insn "*rcpsf2_sse"
15954 [(set (match_operand:SF 0 "register_operand" "=x")
15955 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15958 "rcpss\t{%1, %0|%0, %1}"
15959 [(set_attr "type" "sse")
15960 (set_attr "mode" "SF")])
15962 (define_insn "*fop_sf_1_sse"
15963 [(set (match_operand:SF 0 "register_operand" "=x")
15964 (match_operator:SF 3 "binary_fp_operator"
15965 [(match_operand:SF 1 "register_operand" "0")
15966 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15968 && !COMMUTATIVE_ARITH_P (operands[3])"
15969 "* return output_387_binary_op (insn, operands);"
15970 [(set (attr "type")
15971 (cond [(match_operand:SF 3 "mult_operator" "")
15972 (const_string "ssemul")
15973 (match_operand:SF 3 "div_operator" "")
15974 (const_string "ssediv")
15976 (const_string "sseadd")))
15977 (set_attr "mode" "SF")])
15979 ;; This pattern is not fully shadowed by the pattern above.
15980 (define_insn "*fop_sf_1_i387"
15981 [(set (match_operand:SF 0 "register_operand" "=f,f")
15982 (match_operator:SF 3 "binary_fp_operator"
15983 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15984 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15985 "TARGET_80387 && !TARGET_SSE_MATH
15986 && !COMMUTATIVE_ARITH_P (operands[3])
15987 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15988 "* return output_387_binary_op (insn, operands);"
15989 [(set (attr "type")
15990 (cond [(match_operand:SF 3 "mult_operator" "")
15991 (const_string "fmul")
15992 (match_operand:SF 3 "div_operator" "")
15993 (const_string "fdiv")
15995 (const_string "fop")))
15996 (set_attr "mode" "SF")])
15998 ;; ??? Add SSE splitters for these!
15999 (define_insn "*fop_sf_2<mode>_i387"
16000 [(set (match_operand:SF 0 "register_operand" "=f,f")
16001 (match_operator:SF 3 "binary_fp_operator"
16002 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16003 (match_operand:SF 2 "register_operand" "0,0")]))]
16004 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16005 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16006 [(set (attr "type")
16007 (cond [(match_operand:SF 3 "mult_operator" "")
16008 (const_string "fmul")
16009 (match_operand:SF 3 "div_operator" "")
16010 (const_string "fdiv")
16012 (const_string "fop")))
16013 (set_attr "fp_int_src" "true")
16014 (set_attr "mode" "<MODE>")])
16016 (define_insn "*fop_sf_3<mode>_i387"
16017 [(set (match_operand:SF 0 "register_operand" "=f,f")
16018 (match_operator:SF 3 "binary_fp_operator"
16019 [(match_operand:SF 1 "register_operand" "0,0")
16020 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16021 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16022 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16023 [(set (attr "type")
16024 (cond [(match_operand:SF 3 "mult_operator" "")
16025 (const_string "fmul")
16026 (match_operand:SF 3 "div_operator" "")
16027 (const_string "fdiv")
16029 (const_string "fop")))
16030 (set_attr "fp_int_src" "true")
16031 (set_attr "mode" "<MODE>")])
16033 (define_insn "*fop_df_comm_mixed"
16034 [(set (match_operand:DF 0 "register_operand" "=f,x")
16035 (match_operator:DF 3 "binary_fp_operator"
16036 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16037 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16038 "TARGET_SSE2 && TARGET_MIX_SSE_I387
16039 && COMMUTATIVE_ARITH_P (operands[3])
16040 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16041 "* return output_387_binary_op (insn, operands);"
16042 [(set (attr "type")
16043 (if_then_else (eq_attr "alternative" "1")
16044 (if_then_else (match_operand:DF 3 "mult_operator" "")
16045 (const_string "ssemul")
16046 (const_string "sseadd"))
16047 (if_then_else (match_operand:DF 3 "mult_operator" "")
16048 (const_string "fmul")
16049 (const_string "fop"))))
16050 (set_attr "mode" "DF")])
16052 (define_insn "*fop_df_comm_sse"
16053 [(set (match_operand:DF 0 "register_operand" "=x")
16054 (match_operator:DF 3 "binary_fp_operator"
16055 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16056 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16057 "TARGET_SSE2 && TARGET_SSE_MATH
16058 && COMMUTATIVE_ARITH_P (operands[3])
16059 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16060 "* return output_387_binary_op (insn, operands);"
16061 [(set (attr "type")
16062 (if_then_else (match_operand:DF 3 "mult_operator" "")
16063 (const_string "ssemul")
16064 (const_string "sseadd")))
16065 (set_attr "mode" "DF")])
16067 (define_insn "*fop_df_comm_i387"
16068 [(set (match_operand:DF 0 "register_operand" "=f")
16069 (match_operator:DF 3 "binary_fp_operator"
16070 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16071 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16073 && COMMUTATIVE_ARITH_P (operands[3])
16074 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16075 "* return output_387_binary_op (insn, operands);"
16076 [(set (attr "type")
16077 (if_then_else (match_operand:DF 3 "mult_operator" "")
16078 (const_string "fmul")
16079 (const_string "fop")))
16080 (set_attr "mode" "DF")])
16082 (define_insn "*fop_df_1_mixed"
16083 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16084 (match_operator:DF 3 "binary_fp_operator"
16085 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16086 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16087 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16088 && !COMMUTATIVE_ARITH_P (operands[3])
16089 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16090 "* return output_387_binary_op (insn, operands);"
16091 [(set (attr "type")
16092 (cond [(and (eq_attr "alternative" "2")
16093 (match_operand:DF 3 "mult_operator" ""))
16094 (const_string "ssemul")
16095 (and (eq_attr "alternative" "2")
16096 (match_operand:DF 3 "div_operator" ""))
16097 (const_string "ssediv")
16098 (eq_attr "alternative" "2")
16099 (const_string "sseadd")
16100 (match_operand:DF 3 "mult_operator" "")
16101 (const_string "fmul")
16102 (match_operand:DF 3 "div_operator" "")
16103 (const_string "fdiv")
16105 (const_string "fop")))
16106 (set_attr "mode" "DF")])
16108 (define_insn "*fop_df_1_sse"
16109 [(set (match_operand:DF 0 "register_operand" "=x")
16110 (match_operator:DF 3 "binary_fp_operator"
16111 [(match_operand:DF 1 "register_operand" "0")
16112 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16113 "TARGET_SSE2 && TARGET_SSE_MATH
16114 && !COMMUTATIVE_ARITH_P (operands[3])"
16115 "* return output_387_binary_op (insn, operands);"
16116 [(set_attr "mode" "DF")
16118 (cond [(match_operand:DF 3 "mult_operator" "")
16119 (const_string "ssemul")
16120 (match_operand:DF 3 "div_operator" "")
16121 (const_string "ssediv")
16123 (const_string "sseadd")))])
16125 ;; This pattern is not fully shadowed by the pattern above.
16126 (define_insn "*fop_df_1_i387"
16127 [(set (match_operand:DF 0 "register_operand" "=f,f")
16128 (match_operator:DF 3 "binary_fp_operator"
16129 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16130 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16131 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16132 && !COMMUTATIVE_ARITH_P (operands[3])
16133 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16134 "* return output_387_binary_op (insn, operands);"
16135 [(set (attr "type")
16136 (cond [(match_operand:DF 3 "mult_operator" "")
16137 (const_string "fmul")
16138 (match_operand:DF 3 "div_operator" "")
16139 (const_string "fdiv")
16141 (const_string "fop")))
16142 (set_attr "mode" "DF")])
16144 ;; ??? Add SSE splitters for these!
16145 (define_insn "*fop_df_2<mode>_i387"
16146 [(set (match_operand:DF 0 "register_operand" "=f,f")
16147 (match_operator:DF 3 "binary_fp_operator"
16148 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16149 (match_operand:DF 2 "register_operand" "0,0")]))]
16150 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16151 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16152 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16153 [(set (attr "type")
16154 (cond [(match_operand:DF 3 "mult_operator" "")
16155 (const_string "fmul")
16156 (match_operand:DF 3 "div_operator" "")
16157 (const_string "fdiv")
16159 (const_string "fop")))
16160 (set_attr "fp_int_src" "true")
16161 (set_attr "mode" "<MODE>")])
16163 (define_insn "*fop_df_3<mode>_i387"
16164 [(set (match_operand:DF 0 "register_operand" "=f,f")
16165 (match_operator:DF 3 "binary_fp_operator"
16166 [(match_operand:DF 1 "register_operand" "0,0")
16167 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16168 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16169 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16170 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16171 [(set (attr "type")
16172 (cond [(match_operand:DF 3 "mult_operator" "")
16173 (const_string "fmul")
16174 (match_operand:DF 3 "div_operator" "")
16175 (const_string "fdiv")
16177 (const_string "fop")))
16178 (set_attr "fp_int_src" "true")
16179 (set_attr "mode" "<MODE>")])
16181 (define_insn "*fop_df_4_i387"
16182 [(set (match_operand:DF 0 "register_operand" "=f,f")
16183 (match_operator:DF 3 "binary_fp_operator"
16184 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16185 (match_operand:DF 2 "register_operand" "0,f")]))]
16186 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16187 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16188 "* return output_387_binary_op (insn, operands);"
16189 [(set (attr "type")
16190 (cond [(match_operand:DF 3 "mult_operator" "")
16191 (const_string "fmul")
16192 (match_operand:DF 3 "div_operator" "")
16193 (const_string "fdiv")
16195 (const_string "fop")))
16196 (set_attr "mode" "SF")])
16198 (define_insn "*fop_df_5_i387"
16199 [(set (match_operand:DF 0 "register_operand" "=f,f")
16200 (match_operator:DF 3 "binary_fp_operator"
16201 [(match_operand:DF 1 "register_operand" "0,f")
16203 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16204 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16205 "* return output_387_binary_op (insn, operands);"
16206 [(set (attr "type")
16207 (cond [(match_operand:DF 3 "mult_operator" "")
16208 (const_string "fmul")
16209 (match_operand:DF 3 "div_operator" "")
16210 (const_string "fdiv")
16212 (const_string "fop")))
16213 (set_attr "mode" "SF")])
16215 (define_insn "*fop_df_6_i387"
16216 [(set (match_operand:DF 0 "register_operand" "=f,f")
16217 (match_operator:DF 3 "binary_fp_operator"
16219 (match_operand:SF 1 "register_operand" "0,f"))
16221 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16222 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16223 "* return output_387_binary_op (insn, operands);"
16224 [(set (attr "type")
16225 (cond [(match_operand:DF 3 "mult_operator" "")
16226 (const_string "fmul")
16227 (match_operand:DF 3 "div_operator" "")
16228 (const_string "fdiv")
16230 (const_string "fop")))
16231 (set_attr "mode" "SF")])
16233 (define_insn "*fop_xf_comm_i387"
16234 [(set (match_operand:XF 0 "register_operand" "=f")
16235 (match_operator:XF 3 "binary_fp_operator"
16236 [(match_operand:XF 1 "register_operand" "%0")
16237 (match_operand:XF 2 "register_operand" "f")]))]
16239 && COMMUTATIVE_ARITH_P (operands[3])"
16240 "* return output_387_binary_op (insn, operands);"
16241 [(set (attr "type")
16242 (if_then_else (match_operand:XF 3 "mult_operator" "")
16243 (const_string "fmul")
16244 (const_string "fop")))
16245 (set_attr "mode" "XF")])
16247 (define_insn "*fop_xf_1_i387"
16248 [(set (match_operand:XF 0 "register_operand" "=f,f")
16249 (match_operator:XF 3 "binary_fp_operator"
16250 [(match_operand:XF 1 "register_operand" "0,f")
16251 (match_operand:XF 2 "register_operand" "f,0")]))]
16253 && !COMMUTATIVE_ARITH_P (operands[3])"
16254 "* return output_387_binary_op (insn, operands);"
16255 [(set (attr "type")
16256 (cond [(match_operand:XF 3 "mult_operator" "")
16257 (const_string "fmul")
16258 (match_operand:XF 3 "div_operator" "")
16259 (const_string "fdiv")
16261 (const_string "fop")))
16262 (set_attr "mode" "XF")])
16264 (define_insn "*fop_xf_2<mode>_i387"
16265 [(set (match_operand:XF 0 "register_operand" "=f,f")
16266 (match_operator:XF 3 "binary_fp_operator"
16267 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16268 (match_operand:XF 2 "register_operand" "0,0")]))]
16269 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16270 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16271 [(set (attr "type")
16272 (cond [(match_operand:XF 3 "mult_operator" "")
16273 (const_string "fmul")
16274 (match_operand:XF 3 "div_operator" "")
16275 (const_string "fdiv")
16277 (const_string "fop")))
16278 (set_attr "fp_int_src" "true")
16279 (set_attr "mode" "<MODE>")])
16281 (define_insn "*fop_xf_3<mode>_i387"
16282 [(set (match_operand:XF 0 "register_operand" "=f,f")
16283 (match_operator:XF 3 "binary_fp_operator"
16284 [(match_operand:XF 1 "register_operand" "0,0")
16285 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16286 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16287 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16288 [(set (attr "type")
16289 (cond [(match_operand:XF 3 "mult_operator" "")
16290 (const_string "fmul")
16291 (match_operand:XF 3 "div_operator" "")
16292 (const_string "fdiv")
16294 (const_string "fop")))
16295 (set_attr "fp_int_src" "true")
16296 (set_attr "mode" "<MODE>")])
16298 (define_insn "*fop_xf_4_i387"
16299 [(set (match_operand:XF 0 "register_operand" "=f,f")
16300 (match_operator:XF 3 "binary_fp_operator"
16302 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16303 (match_operand:XF 2 "register_operand" "0,f")]))]
16305 "* return output_387_binary_op (insn, operands);"
16306 [(set (attr "type")
16307 (cond [(match_operand:XF 3 "mult_operator" "")
16308 (const_string "fmul")
16309 (match_operand:XF 3 "div_operator" "")
16310 (const_string "fdiv")
16312 (const_string "fop")))
16313 (set_attr "mode" "SF")])
16315 (define_insn "*fop_xf_5_i387"
16316 [(set (match_operand:XF 0 "register_operand" "=f,f")
16317 (match_operator:XF 3 "binary_fp_operator"
16318 [(match_operand:XF 1 "register_operand" "0,f")
16320 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16322 "* return output_387_binary_op (insn, operands);"
16323 [(set (attr "type")
16324 (cond [(match_operand:XF 3 "mult_operator" "")
16325 (const_string "fmul")
16326 (match_operand:XF 3 "div_operator" "")
16327 (const_string "fdiv")
16329 (const_string "fop")))
16330 (set_attr "mode" "SF")])
16332 (define_insn "*fop_xf_6_i387"
16333 [(set (match_operand:XF 0 "register_operand" "=f,f")
16334 (match_operator:XF 3 "binary_fp_operator"
16336 (match_operand:MODEF 1 "register_operand" "0,f"))
16338 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16340 "* return output_387_binary_op (insn, operands);"
16341 [(set (attr "type")
16342 (cond [(match_operand:XF 3 "mult_operator" "")
16343 (const_string "fmul")
16344 (match_operand:XF 3 "div_operator" "")
16345 (const_string "fdiv")
16347 (const_string "fop")))
16348 (set_attr "mode" "SF")])
16351 [(set (match_operand 0 "register_operand" "")
16352 (match_operator 3 "binary_fp_operator"
16353 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16354 (match_operand 2 "register_operand" "")]))]
16356 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16359 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16360 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16361 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16362 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16363 GET_MODE (operands[3]),
16366 ix86_free_from_memory (GET_MODE (operands[1]));
16371 [(set (match_operand 0 "register_operand" "")
16372 (match_operator 3 "binary_fp_operator"
16373 [(match_operand 1 "register_operand" "")
16374 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16376 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16379 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16380 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16381 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16382 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16383 GET_MODE (operands[3]),
16386 ix86_free_from_memory (GET_MODE (operands[2]));
16390 ;; FPU special functions.
16392 ;; This pattern implements a no-op XFmode truncation for
16393 ;; all fancy i386 XFmode math functions.
16395 (define_insn "truncxf<mode>2_i387_noop_unspec"
16396 [(set (match_operand:MODEF 0 "register_operand" "=f")
16397 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16398 UNSPEC_TRUNC_NOOP))]
16399 "TARGET_USE_FANCY_MATH_387"
16400 "* return output_387_reg_move (insn, operands);"
16401 [(set_attr "type" "fmov")
16402 (set_attr "mode" "<MODE>")])
16404 (define_insn "sqrtxf2"
16405 [(set (match_operand:XF 0 "register_operand" "=f")
16406 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16407 "TARGET_USE_FANCY_MATH_387"
16409 [(set_attr "type" "fpspc")
16410 (set_attr "mode" "XF")
16411 (set_attr "athlon_decode" "direct")
16412 (set_attr "amdfam10_decode" "direct")])
16414 (define_insn "sqrt_extend<mode>xf2_i387"
16415 [(set (match_operand:XF 0 "register_operand" "=f")
16418 (match_operand:MODEF 1 "register_operand" "0"))))]
16419 "TARGET_USE_FANCY_MATH_387"
16421 [(set_attr "type" "fpspc")
16422 (set_attr "mode" "XF")
16423 (set_attr "athlon_decode" "direct")
16424 (set_attr "amdfam10_decode" "direct")])
16426 (define_insn "*rsqrtsf2_sse"
16427 [(set (match_operand:SF 0 "register_operand" "=x")
16428 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16431 "rsqrtss\t{%1, %0|%0, %1}"
16432 [(set_attr "type" "sse")
16433 (set_attr "mode" "SF")])
16435 (define_expand "rsqrtsf2"
16436 [(set (match_operand:SF 0 "register_operand" "")
16437 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16439 "TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16440 && flag_finite_math_only && !flag_trapping_math
16441 && flag_unsafe_math_optimizations"
16443 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16447 (define_insn "*sqrt<mode>2_sse"
16448 [(set (match_operand:MODEF 0 "register_operand" "=x")
16450 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16451 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16452 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16453 [(set_attr "type" "sse")
16454 (set_attr "mode" "<MODE>")
16455 (set_attr "athlon_decode" "*")
16456 (set_attr "amdfam10_decode" "*")])
16458 (define_expand "sqrt<mode>2"
16459 [(set (match_operand:MODEF 0 "register_operand" "")
16461 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16462 "TARGET_USE_FANCY_MATH_387
16463 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16465 if (<MODE>mode == SFmode
16466 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16467 && flag_finite_math_only && !flag_trapping_math
16468 && flag_unsafe_math_optimizations)
16470 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16474 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16476 rtx op0 = gen_reg_rtx (XFmode);
16477 rtx op1 = force_reg (<MODE>mode, operands[1]);
16479 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16480 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16485 (define_insn "fpremxf4_i387"
16486 [(set (match_operand:XF 0 "register_operand" "=f")
16487 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16488 (match_operand:XF 3 "register_operand" "1")]
16490 (set (match_operand:XF 1 "register_operand" "=u")
16491 (unspec:XF [(match_dup 2) (match_dup 3)]
16493 (set (reg:CCFP FPSR_REG)
16494 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16496 "TARGET_USE_FANCY_MATH_387"
16498 [(set_attr "type" "fpspc")
16499 (set_attr "mode" "XF")])
16501 (define_expand "fmodxf3"
16502 [(use (match_operand:XF 0 "register_operand" ""))
16503 (use (match_operand:XF 1 "register_operand" ""))
16504 (use (match_operand:XF 2 "register_operand" ""))]
16505 "TARGET_USE_FANCY_MATH_387"
16507 rtx label = gen_label_rtx ();
16509 emit_label (label);
16511 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16512 operands[1], operands[2]));
16513 ix86_emit_fp_unordered_jump (label);
16514 LABEL_NUSES (label) = 1;
16516 emit_move_insn (operands[0], operands[1]);
16520 (define_expand "fmod<mode>3"
16521 [(use (match_operand:MODEF 0 "register_operand" ""))
16522 (use (match_operand:MODEF 1 "general_operand" ""))
16523 (use (match_operand:MODEF 2 "general_operand" ""))]
16524 "TARGET_USE_FANCY_MATH_387"
16526 rtx label = gen_label_rtx ();
16528 rtx op1 = gen_reg_rtx (XFmode);
16529 rtx op2 = gen_reg_rtx (XFmode);
16531 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16532 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16534 emit_label (label);
16535 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16536 ix86_emit_fp_unordered_jump (label);
16537 LABEL_NUSES (label) = 1;
16539 /* Truncate the result properly for strict SSE math. */
16540 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16541 && !TARGET_MIX_SSE_I387)
16542 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16544 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16549 (define_insn "fprem1xf4_i387"
16550 [(set (match_operand:XF 0 "register_operand" "=f")
16551 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16552 (match_operand:XF 3 "register_operand" "1")]
16554 (set (match_operand:XF 1 "register_operand" "=u")
16555 (unspec:XF [(match_dup 2) (match_dup 3)]
16557 (set (reg:CCFP FPSR_REG)
16558 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16560 "TARGET_USE_FANCY_MATH_387"
16562 [(set_attr "type" "fpspc")
16563 (set_attr "mode" "XF")])
16565 (define_expand "remainderxf3"
16566 [(use (match_operand:XF 0 "register_operand" ""))
16567 (use (match_operand:XF 1 "register_operand" ""))
16568 (use (match_operand:XF 2 "register_operand" ""))]
16569 "TARGET_USE_FANCY_MATH_387"
16571 rtx label = gen_label_rtx ();
16573 emit_label (label);
16575 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16576 operands[1], operands[2]));
16577 ix86_emit_fp_unordered_jump (label);
16578 LABEL_NUSES (label) = 1;
16580 emit_move_insn (operands[0], operands[1]);
16584 (define_expand "remainder<mode>3"
16585 [(use (match_operand:MODEF 0 "register_operand" ""))
16586 (use (match_operand:MODEF 1 "general_operand" ""))
16587 (use (match_operand:MODEF 2 "general_operand" ""))]
16588 "TARGET_USE_FANCY_MATH_387"
16590 rtx label = gen_label_rtx ();
16592 rtx op1 = gen_reg_rtx (XFmode);
16593 rtx op2 = gen_reg_rtx (XFmode);
16595 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16596 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16598 emit_label (label);
16600 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16601 ix86_emit_fp_unordered_jump (label);
16602 LABEL_NUSES (label) = 1;
16604 /* Truncate the result properly for strict SSE math. */
16605 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16606 && !TARGET_MIX_SSE_I387)
16607 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16609 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16614 (define_insn "*sinxf2_i387"
16615 [(set (match_operand:XF 0 "register_operand" "=f")
16616 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16617 "TARGET_USE_FANCY_MATH_387
16618 && flag_unsafe_math_optimizations"
16620 [(set_attr "type" "fpspc")
16621 (set_attr "mode" "XF")])
16623 (define_insn "*sin_extend<mode>xf2_i387"
16624 [(set (match_operand:XF 0 "register_operand" "=f")
16625 (unspec:XF [(float_extend:XF
16626 (match_operand:MODEF 1 "register_operand" "0"))]
16628 "TARGET_USE_FANCY_MATH_387
16629 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16630 || TARGET_MIX_SSE_I387)
16631 && flag_unsafe_math_optimizations"
16633 [(set_attr "type" "fpspc")
16634 (set_attr "mode" "XF")])
16636 (define_insn "*cosxf2_i387"
16637 [(set (match_operand:XF 0 "register_operand" "=f")
16638 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16639 "TARGET_USE_FANCY_MATH_387
16640 && flag_unsafe_math_optimizations"
16642 [(set_attr "type" "fpspc")
16643 (set_attr "mode" "XF")])
16645 (define_insn "*cos_extend<mode>xf2_i387"
16646 [(set (match_operand:XF 0 "register_operand" "=f")
16647 (unspec:XF [(float_extend:XF
16648 (match_operand:MODEF 1 "register_operand" "0"))]
16650 "TARGET_USE_FANCY_MATH_387
16651 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16652 || TARGET_MIX_SSE_I387)
16653 && flag_unsafe_math_optimizations"
16655 [(set_attr "type" "fpspc")
16656 (set_attr "mode" "XF")])
16658 ;; When sincos pattern is defined, sin and cos builtin functions will be
16659 ;; expanded to sincos pattern with one of its outputs left unused.
16660 ;; CSE pass will figure out if two sincos patterns can be combined,
16661 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16662 ;; depending on the unused output.
16664 (define_insn "sincosxf3"
16665 [(set (match_operand:XF 0 "register_operand" "=f")
16666 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16667 UNSPEC_SINCOS_COS))
16668 (set (match_operand:XF 1 "register_operand" "=u")
16669 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16670 "TARGET_USE_FANCY_MATH_387
16671 && flag_unsafe_math_optimizations"
16673 [(set_attr "type" "fpspc")
16674 (set_attr "mode" "XF")])
16677 [(set (match_operand:XF 0 "register_operand" "")
16678 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16679 UNSPEC_SINCOS_COS))
16680 (set (match_operand:XF 1 "register_operand" "")
16681 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16682 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16683 && !(reload_completed || reload_in_progress)"
16684 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16688 [(set (match_operand:XF 0 "register_operand" "")
16689 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16690 UNSPEC_SINCOS_COS))
16691 (set (match_operand:XF 1 "register_operand" "")
16692 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16693 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16694 && !(reload_completed || reload_in_progress)"
16695 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16698 (define_insn "sincos_extend<mode>xf3_i387"
16699 [(set (match_operand:XF 0 "register_operand" "=f")
16700 (unspec:XF [(float_extend:XF
16701 (match_operand:MODEF 2 "register_operand" "0"))]
16702 UNSPEC_SINCOS_COS))
16703 (set (match_operand:XF 1 "register_operand" "=u")
16704 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16705 "TARGET_USE_FANCY_MATH_387
16706 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16707 || TARGET_MIX_SSE_I387)
16708 && flag_unsafe_math_optimizations"
16710 [(set_attr "type" "fpspc")
16711 (set_attr "mode" "XF")])
16714 [(set (match_operand:XF 0 "register_operand" "")
16715 (unspec:XF [(float_extend:XF
16716 (match_operand:MODEF 2 "register_operand" ""))]
16717 UNSPEC_SINCOS_COS))
16718 (set (match_operand:XF 1 "register_operand" "")
16719 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16720 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16721 && !(reload_completed || reload_in_progress)"
16722 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16726 [(set (match_operand:XF 0 "register_operand" "")
16727 (unspec:XF [(float_extend:XF
16728 (match_operand:MODEF 2 "register_operand" ""))]
16729 UNSPEC_SINCOS_COS))
16730 (set (match_operand:XF 1 "register_operand" "")
16731 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16732 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16733 && !(reload_completed || reload_in_progress)"
16734 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16737 (define_expand "sincos<mode>3"
16738 [(use (match_operand:MODEF 0 "register_operand" ""))
16739 (use (match_operand:MODEF 1 "register_operand" ""))
16740 (use (match_operand:MODEF 2 "register_operand" ""))]
16741 "TARGET_USE_FANCY_MATH_387
16742 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16743 || TARGET_MIX_SSE_I387)
16744 && flag_unsafe_math_optimizations"
16746 rtx op0 = gen_reg_rtx (XFmode);
16747 rtx op1 = gen_reg_rtx (XFmode);
16749 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16750 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16751 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16755 (define_insn "fptanxf4_i387"
16756 [(set (match_operand:XF 0 "register_operand" "=f")
16757 (match_operand:XF 3 "const_double_operand" "F"))
16758 (set (match_operand:XF 1 "register_operand" "=u")
16759 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16761 "TARGET_USE_FANCY_MATH_387
16762 && flag_unsafe_math_optimizations
16763 && standard_80387_constant_p (operands[3]) == 2"
16765 [(set_attr "type" "fpspc")
16766 (set_attr "mode" "XF")])
16768 (define_insn "fptan_extend<mode>xf4_i387"
16769 [(set (match_operand:MODEF 0 "register_operand" "=f")
16770 (match_operand:MODEF 3 "const_double_operand" "F"))
16771 (set (match_operand:XF 1 "register_operand" "=u")
16772 (unspec:XF [(float_extend:XF
16773 (match_operand:MODEF 2 "register_operand" "0"))]
16775 "TARGET_USE_FANCY_MATH_387
16776 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16777 || TARGET_MIX_SSE_I387)
16778 && flag_unsafe_math_optimizations
16779 && standard_80387_constant_p (operands[3]) == 2"
16781 [(set_attr "type" "fpspc")
16782 (set_attr "mode" "XF")])
16784 (define_expand "tanxf2"
16785 [(use (match_operand:XF 0 "register_operand" ""))
16786 (use (match_operand:XF 1 "register_operand" ""))]
16787 "TARGET_USE_FANCY_MATH_387
16788 && flag_unsafe_math_optimizations"
16790 rtx one = gen_reg_rtx (XFmode);
16791 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16793 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16797 (define_expand "tan<mode>2"
16798 [(use (match_operand:MODEF 0 "register_operand" ""))
16799 (use (match_operand:MODEF 1 "register_operand" ""))]
16800 "TARGET_USE_FANCY_MATH_387
16801 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16802 || TARGET_MIX_SSE_I387)
16803 && flag_unsafe_math_optimizations"
16805 rtx op0 = gen_reg_rtx (XFmode);
16807 rtx one = gen_reg_rtx (<MODE>mode);
16808 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16810 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16811 operands[1], op2));
16812 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16816 (define_insn "*fpatanxf3_i387"
16817 [(set (match_operand:XF 0 "register_operand" "=f")
16818 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16819 (match_operand:XF 2 "register_operand" "u")]
16821 (clobber (match_scratch:XF 3 "=2"))]
16822 "TARGET_USE_FANCY_MATH_387
16823 && flag_unsafe_math_optimizations"
16825 [(set_attr "type" "fpspc")
16826 (set_attr "mode" "XF")])
16828 (define_insn "fpatan_extend<mode>xf3_i387"
16829 [(set (match_operand:XF 0 "register_operand" "=f")
16830 (unspec:XF [(float_extend:XF
16831 (match_operand:MODEF 1 "register_operand" "0"))
16833 (match_operand:MODEF 2 "register_operand" "u"))]
16835 (clobber (match_scratch:XF 3 "=2"))]
16836 "TARGET_USE_FANCY_MATH_387
16837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16838 || TARGET_MIX_SSE_I387)
16839 && flag_unsafe_math_optimizations"
16841 [(set_attr "type" "fpspc")
16842 (set_attr "mode" "XF")])
16844 (define_expand "atan2xf3"
16845 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16846 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16847 (match_operand:XF 1 "register_operand" "")]
16849 (clobber (match_scratch:XF 3 ""))])]
16850 "TARGET_USE_FANCY_MATH_387
16851 && flag_unsafe_math_optimizations"
16854 (define_expand "atan2<mode>3"
16855 [(use (match_operand:MODEF 0 "register_operand" ""))
16856 (use (match_operand:MODEF 1 "register_operand" ""))
16857 (use (match_operand:MODEF 2 "register_operand" ""))]
16858 "TARGET_USE_FANCY_MATH_387
16859 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16860 || TARGET_MIX_SSE_I387)
16861 && flag_unsafe_math_optimizations"
16863 rtx op0 = gen_reg_rtx (XFmode);
16865 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16866 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16870 (define_expand "atanxf2"
16871 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16872 (unspec:XF [(match_dup 2)
16873 (match_operand:XF 1 "register_operand" "")]
16875 (clobber (match_scratch:XF 3 ""))])]
16876 "TARGET_USE_FANCY_MATH_387
16877 && flag_unsafe_math_optimizations"
16879 operands[2] = gen_reg_rtx (XFmode);
16880 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16883 (define_expand "atan<mode>2"
16884 [(use (match_operand:MODEF 0 "register_operand" ""))
16885 (use (match_operand:MODEF 1 "register_operand" ""))]
16886 "TARGET_USE_FANCY_MATH_387
16887 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16888 || TARGET_MIX_SSE_I387)
16889 && flag_unsafe_math_optimizations"
16891 rtx op0 = gen_reg_rtx (XFmode);
16893 rtx op2 = gen_reg_rtx (<MODE>mode);
16894 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16896 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16897 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16901 (define_expand "asinxf2"
16902 [(set (match_dup 2)
16903 (mult:XF (match_operand:XF 1 "register_operand" "")
16905 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16906 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16907 (parallel [(set (match_operand:XF 0 "register_operand" "")
16908 (unspec:XF [(match_dup 5) (match_dup 1)]
16910 (clobber (match_scratch:XF 6 ""))])]
16911 "TARGET_USE_FANCY_MATH_387
16912 && flag_unsafe_math_optimizations && !optimize_size"
16916 for (i = 2; i < 6; i++)
16917 operands[i] = gen_reg_rtx (XFmode);
16919 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16922 (define_expand "asin<mode>2"
16923 [(use (match_operand:MODEF 0 "register_operand" ""))
16924 (use (match_operand:MODEF 1 "general_operand" ""))]
16925 "TARGET_USE_FANCY_MATH_387
16926 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16927 || TARGET_MIX_SSE_I387)
16928 && flag_unsafe_math_optimizations && !optimize_size"
16930 rtx op0 = gen_reg_rtx (XFmode);
16931 rtx op1 = gen_reg_rtx (XFmode);
16933 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16934 emit_insn (gen_asinxf2 (op0, op1));
16935 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16939 (define_expand "acosxf2"
16940 [(set (match_dup 2)
16941 (mult:XF (match_operand:XF 1 "register_operand" "")
16943 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16944 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16945 (parallel [(set (match_operand:XF 0 "register_operand" "")
16946 (unspec:XF [(match_dup 1) (match_dup 5)]
16948 (clobber (match_scratch:XF 6 ""))])]
16949 "TARGET_USE_FANCY_MATH_387
16950 && flag_unsafe_math_optimizations && !optimize_size"
16954 for (i = 2; i < 6; i++)
16955 operands[i] = gen_reg_rtx (XFmode);
16957 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16960 (define_expand "acos<mode>2"
16961 [(use (match_operand:MODEF 0 "register_operand" ""))
16962 (use (match_operand:MODEF 1 "general_operand" ""))]
16963 "TARGET_USE_FANCY_MATH_387
16964 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16965 || TARGET_MIX_SSE_I387)
16966 && flag_unsafe_math_optimizations && !optimize_size"
16968 rtx op0 = gen_reg_rtx (XFmode);
16969 rtx op1 = gen_reg_rtx (XFmode);
16971 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16972 emit_insn (gen_acosxf2 (op0, op1));
16973 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16977 (define_insn "fyl2xxf3_i387"
16978 [(set (match_operand:XF 0 "register_operand" "=f")
16979 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16980 (match_operand:XF 2 "register_operand" "u")]
16982 (clobber (match_scratch:XF 3 "=2"))]
16983 "TARGET_USE_FANCY_MATH_387
16984 && flag_unsafe_math_optimizations"
16986 [(set_attr "type" "fpspc")
16987 (set_attr "mode" "XF")])
16989 (define_insn "fyl2x_extend<mode>xf3_i387"
16990 [(set (match_operand:XF 0 "register_operand" "=f")
16991 (unspec:XF [(float_extend:XF
16992 (match_operand:MODEF 1 "register_operand" "0"))
16993 (match_operand:XF 2 "register_operand" "u")]
16995 (clobber (match_scratch:XF 3 "=2"))]
16996 "TARGET_USE_FANCY_MATH_387
16997 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16998 || TARGET_MIX_SSE_I387)
16999 && flag_unsafe_math_optimizations"
17001 [(set_attr "type" "fpspc")
17002 (set_attr "mode" "XF")])
17004 (define_expand "logxf2"
17005 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17006 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17007 (match_dup 2)] UNSPEC_FYL2X))
17008 (clobber (match_scratch:XF 3 ""))])]
17009 "TARGET_USE_FANCY_MATH_387
17010 && flag_unsafe_math_optimizations"
17012 operands[2] = gen_reg_rtx (XFmode);
17013 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17016 (define_expand "log<mode>2"
17017 [(use (match_operand:MODEF 0 "register_operand" ""))
17018 (use (match_operand:MODEF 1 "register_operand" ""))]
17019 "TARGET_USE_FANCY_MATH_387
17020 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17021 || TARGET_MIX_SSE_I387)
17022 && flag_unsafe_math_optimizations"
17024 rtx op0 = gen_reg_rtx (XFmode);
17026 rtx op2 = gen_reg_rtx (XFmode);
17027 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17029 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17030 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17034 (define_expand "log10xf2"
17035 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17036 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17037 (match_dup 2)] UNSPEC_FYL2X))
17038 (clobber (match_scratch:XF 3 ""))])]
17039 "TARGET_USE_FANCY_MATH_387
17040 && flag_unsafe_math_optimizations"
17042 operands[2] = gen_reg_rtx (XFmode);
17043 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17046 (define_expand "log10<mode>2"
17047 [(use (match_operand:MODEF 0 "register_operand" ""))
17048 (use (match_operand:MODEF 1 "register_operand" ""))]
17049 "TARGET_USE_FANCY_MATH_387
17050 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17051 || TARGET_MIX_SSE_I387)
17052 && flag_unsafe_math_optimizations"
17054 rtx op0 = gen_reg_rtx (XFmode);
17056 rtx op2 = gen_reg_rtx (XFmode);
17057 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17059 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17060 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17064 (define_expand "log2xf2"
17065 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17066 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17067 (match_dup 2)] UNSPEC_FYL2X))
17068 (clobber (match_scratch:XF 3 ""))])]
17069 "TARGET_USE_FANCY_MATH_387
17070 && flag_unsafe_math_optimizations"
17072 operands[2] = gen_reg_rtx (XFmode);
17073 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17076 (define_expand "log2<mode>2"
17077 [(use (match_operand:MODEF 0 "register_operand" ""))
17078 (use (match_operand:MODEF 1 "register_operand" ""))]
17079 "TARGET_USE_FANCY_MATH_387
17080 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17081 || TARGET_MIX_SSE_I387)
17082 && flag_unsafe_math_optimizations"
17084 rtx op0 = gen_reg_rtx (XFmode);
17086 rtx op2 = gen_reg_rtx (XFmode);
17087 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17089 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17090 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17094 (define_insn "fyl2xp1xf3_i387"
17095 [(set (match_operand:XF 0 "register_operand" "=f")
17096 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17097 (match_operand:XF 2 "register_operand" "u")]
17099 (clobber (match_scratch:XF 3 "=2"))]
17100 "TARGET_USE_FANCY_MATH_387
17101 && flag_unsafe_math_optimizations"
17103 [(set_attr "type" "fpspc")
17104 (set_attr "mode" "XF")])
17106 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17107 [(set (match_operand:XF 0 "register_operand" "=f")
17108 (unspec:XF [(float_extend:XF
17109 (match_operand:MODEF 1 "register_operand" "0"))
17110 (match_operand:XF 2 "register_operand" "u")]
17112 (clobber (match_scratch:XF 3 "=2"))]
17113 "TARGET_USE_FANCY_MATH_387
17114 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17115 || TARGET_MIX_SSE_I387)
17116 && flag_unsafe_math_optimizations"
17118 [(set_attr "type" "fpspc")
17119 (set_attr "mode" "XF")])
17121 (define_expand "log1pxf2"
17122 [(use (match_operand:XF 0 "register_operand" ""))
17123 (use (match_operand:XF 1 "register_operand" ""))]
17124 "TARGET_USE_FANCY_MATH_387
17125 && flag_unsafe_math_optimizations && !optimize_size"
17127 ix86_emit_i387_log1p (operands[0], operands[1]);
17131 (define_expand "log1p<mode>2"
17132 [(use (match_operand:MODEF 0 "register_operand" ""))
17133 (use (match_operand:MODEF 1 "register_operand" ""))]
17134 "TARGET_USE_FANCY_MATH_387
17135 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17136 || TARGET_MIX_SSE_I387)
17137 && flag_unsafe_math_optimizations && !optimize_size"
17139 rtx op0 = gen_reg_rtx (XFmode);
17141 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17143 ix86_emit_i387_log1p (op0, operands[1]);
17144 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17148 (define_insn "fxtractxf3_i387"
17149 [(set (match_operand:XF 0 "register_operand" "=f")
17150 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17151 UNSPEC_XTRACT_FRACT))
17152 (set (match_operand:XF 1 "register_operand" "=u")
17153 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17154 "TARGET_USE_FANCY_MATH_387
17155 && flag_unsafe_math_optimizations"
17157 [(set_attr "type" "fpspc")
17158 (set_attr "mode" "XF")])
17160 (define_insn "fxtract_extend<mode>xf3_i387"
17161 [(set (match_operand:XF 0 "register_operand" "=f")
17162 (unspec:XF [(float_extend:XF
17163 (match_operand:MODEF 2 "register_operand" "0"))]
17164 UNSPEC_XTRACT_FRACT))
17165 (set (match_operand:XF 1 "register_operand" "=u")
17166 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17167 "TARGET_USE_FANCY_MATH_387
17168 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17169 || TARGET_MIX_SSE_I387)
17170 && flag_unsafe_math_optimizations"
17172 [(set_attr "type" "fpspc")
17173 (set_attr "mode" "XF")])
17175 (define_expand "logbxf2"
17176 [(parallel [(set (match_dup 2)
17177 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17178 UNSPEC_XTRACT_FRACT))
17179 (set (match_operand:XF 0 "register_operand" "")
17180 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17181 "TARGET_USE_FANCY_MATH_387
17182 && flag_unsafe_math_optimizations"
17184 operands[2] = gen_reg_rtx (XFmode);
17187 (define_expand "logb<mode>2"
17188 [(use (match_operand:MODEF 0 "register_operand" ""))
17189 (use (match_operand:MODEF 1 "register_operand" ""))]
17190 "TARGET_USE_FANCY_MATH_387
17191 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17192 || TARGET_MIX_SSE_I387)
17193 && flag_unsafe_math_optimizations"
17195 rtx op0 = gen_reg_rtx (XFmode);
17196 rtx op1 = gen_reg_rtx (XFmode);
17198 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17199 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17203 (define_expand "ilogbxf2"
17204 [(use (match_operand:SI 0 "register_operand" ""))
17205 (use (match_operand:XF 1 "register_operand" ""))]
17206 "TARGET_USE_FANCY_MATH_387
17207 && flag_unsafe_math_optimizations && !optimize_size"
17209 rtx op0 = gen_reg_rtx (XFmode);
17210 rtx op1 = gen_reg_rtx (XFmode);
17212 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17213 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17217 (define_expand "ilogb<mode>2"
17218 [(use (match_operand:SI 0 "register_operand" ""))
17219 (use (match_operand:MODEF 1 "register_operand" ""))]
17220 "TARGET_USE_FANCY_MATH_387
17221 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17222 || TARGET_MIX_SSE_I387)
17223 && flag_unsafe_math_optimizations && !optimize_size"
17225 rtx op0 = gen_reg_rtx (XFmode);
17226 rtx op1 = gen_reg_rtx (XFmode);
17228 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17229 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17233 (define_insn "*f2xm1xf2_i387"
17234 [(set (match_operand:XF 0 "register_operand" "=f")
17235 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17237 "TARGET_USE_FANCY_MATH_387
17238 && flag_unsafe_math_optimizations"
17240 [(set_attr "type" "fpspc")
17241 (set_attr "mode" "XF")])
17243 (define_insn "*fscalexf4_i387"
17244 [(set (match_operand:XF 0 "register_operand" "=f")
17245 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17246 (match_operand:XF 3 "register_operand" "1")]
17247 UNSPEC_FSCALE_FRACT))
17248 (set (match_operand:XF 1 "register_operand" "=u")
17249 (unspec:XF [(match_dup 2) (match_dup 3)]
17250 UNSPEC_FSCALE_EXP))]
17251 "TARGET_USE_FANCY_MATH_387
17252 && flag_unsafe_math_optimizations"
17254 [(set_attr "type" "fpspc")
17255 (set_attr "mode" "XF")])
17257 (define_expand "expNcorexf3"
17258 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17259 (match_operand:XF 2 "register_operand" "")))
17260 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17261 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17262 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17263 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17264 (parallel [(set (match_operand:XF 0 "register_operand" "")
17265 (unspec:XF [(match_dup 8) (match_dup 4)]
17266 UNSPEC_FSCALE_FRACT))
17268 (unspec:XF [(match_dup 8) (match_dup 4)]
17269 UNSPEC_FSCALE_EXP))])]
17270 "TARGET_USE_FANCY_MATH_387
17271 && flag_unsafe_math_optimizations && !optimize_size"
17275 for (i = 3; i < 10; i++)
17276 operands[i] = gen_reg_rtx (XFmode);
17278 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17281 (define_expand "expxf2"
17282 [(use (match_operand:XF 0 "register_operand" ""))
17283 (use (match_operand:XF 1 "register_operand" ""))]
17284 "TARGET_USE_FANCY_MATH_387
17285 && flag_unsafe_math_optimizations && !optimize_size"
17287 rtx op2 = gen_reg_rtx (XFmode);
17288 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17290 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17294 (define_expand "exp<mode>2"
17295 [(use (match_operand:MODEF 0 "register_operand" ""))
17296 (use (match_operand:MODEF 1 "general_operand" ""))]
17297 "TARGET_USE_FANCY_MATH_387
17298 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17299 || TARGET_MIX_SSE_I387)
17300 && flag_unsafe_math_optimizations && !optimize_size"
17302 rtx op0 = gen_reg_rtx (XFmode);
17303 rtx op1 = gen_reg_rtx (XFmode);
17305 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17306 emit_insn (gen_expxf2 (op0, op1));
17307 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17311 (define_expand "exp10xf2"
17312 [(use (match_operand:XF 0 "register_operand" ""))
17313 (use (match_operand:XF 1 "register_operand" ""))]
17314 "TARGET_USE_FANCY_MATH_387
17315 && flag_unsafe_math_optimizations && !optimize_size"
17317 rtx op2 = gen_reg_rtx (XFmode);
17318 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17320 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17324 (define_expand "exp10<mode>2"
17325 [(use (match_operand:MODEF 0 "register_operand" ""))
17326 (use (match_operand:MODEF 1 "general_operand" ""))]
17327 "TARGET_USE_FANCY_MATH_387
17328 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17329 || TARGET_MIX_SSE_I387)
17330 && flag_unsafe_math_optimizations && !optimize_size"
17332 rtx op0 = gen_reg_rtx (XFmode);
17333 rtx op1 = gen_reg_rtx (XFmode);
17335 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17336 emit_insn (gen_exp10xf2 (op0, op1));
17337 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17341 (define_expand "exp2xf2"
17342 [(use (match_operand:XF 0 "register_operand" ""))
17343 (use (match_operand:XF 1 "register_operand" ""))]
17344 "TARGET_USE_FANCY_MATH_387
17345 && flag_unsafe_math_optimizations && !optimize_size"
17347 rtx op2 = gen_reg_rtx (XFmode);
17348 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17350 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17354 (define_expand "exp2<mode>2"
17355 [(use (match_operand:MODEF 0 "register_operand" ""))
17356 (use (match_operand:MODEF 1 "general_operand" ""))]
17357 "TARGET_USE_FANCY_MATH_387
17358 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17359 || TARGET_MIX_SSE_I387)
17360 && flag_unsafe_math_optimizations && !optimize_size"
17362 rtx op0 = gen_reg_rtx (XFmode);
17363 rtx op1 = gen_reg_rtx (XFmode);
17365 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17366 emit_insn (gen_exp2xf2 (op0, op1));
17367 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17371 (define_expand "expm1xf2"
17372 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17374 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17375 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17376 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17377 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17378 (parallel [(set (match_dup 7)
17379 (unspec:XF [(match_dup 6) (match_dup 4)]
17380 UNSPEC_FSCALE_FRACT))
17382 (unspec:XF [(match_dup 6) (match_dup 4)]
17383 UNSPEC_FSCALE_EXP))])
17384 (parallel [(set (match_dup 10)
17385 (unspec:XF [(match_dup 9) (match_dup 8)]
17386 UNSPEC_FSCALE_FRACT))
17387 (set (match_dup 11)
17388 (unspec:XF [(match_dup 9) (match_dup 8)]
17389 UNSPEC_FSCALE_EXP))])
17390 (set (match_dup 12) (minus:XF (match_dup 10)
17391 (float_extend:XF (match_dup 13))))
17392 (set (match_operand:XF 0 "register_operand" "")
17393 (plus:XF (match_dup 12) (match_dup 7)))]
17394 "TARGET_USE_FANCY_MATH_387
17395 && flag_unsafe_math_optimizations && !optimize_size"
17399 for (i = 2; i < 13; i++)
17400 operands[i] = gen_reg_rtx (XFmode);
17403 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17405 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17408 (define_expand "expm1<mode>2"
17409 [(use (match_operand:MODEF 0 "register_operand" ""))
17410 (use (match_operand:MODEF 1 "general_operand" ""))]
17411 "TARGET_USE_FANCY_MATH_387
17412 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17413 || TARGET_MIX_SSE_I387)
17414 && flag_unsafe_math_optimizations && !optimize_size"
17416 rtx op0 = gen_reg_rtx (XFmode);
17417 rtx op1 = gen_reg_rtx (XFmode);
17419 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17420 emit_insn (gen_expm1xf2 (op0, op1));
17421 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17425 (define_expand "ldexpxf3"
17426 [(set (match_dup 3)
17427 (float:XF (match_operand:SI 2 "register_operand" "")))
17428 (parallel [(set (match_operand:XF 0 " register_operand" "")
17429 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17431 UNSPEC_FSCALE_FRACT))
17433 (unspec:XF [(match_dup 1) (match_dup 3)]
17434 UNSPEC_FSCALE_EXP))])]
17435 "TARGET_USE_FANCY_MATH_387
17436 && flag_unsafe_math_optimizations && !optimize_size"
17438 operands[3] = gen_reg_rtx (XFmode);
17439 operands[4] = gen_reg_rtx (XFmode);
17442 (define_expand "ldexp<mode>3"
17443 [(use (match_operand:MODEF 0 "register_operand" ""))
17444 (use (match_operand:MODEF 1 "general_operand" ""))
17445 (use (match_operand:SI 2 "register_operand" ""))]
17446 "TARGET_USE_FANCY_MATH_387
17447 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17448 || TARGET_MIX_SSE_I387)
17449 && flag_unsafe_math_optimizations && !optimize_size"
17451 rtx op0 = gen_reg_rtx (XFmode);
17452 rtx op1 = gen_reg_rtx (XFmode);
17454 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17455 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17456 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17460 (define_expand "scalbxf3"
17461 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17462 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17463 (match_operand:XF 2 "register_operand" "")]
17464 UNSPEC_FSCALE_FRACT))
17466 (unspec:XF [(match_dup 1) (match_dup 2)]
17467 UNSPEC_FSCALE_EXP))])]
17468 "TARGET_USE_FANCY_MATH_387
17469 && flag_unsafe_math_optimizations && !optimize_size"
17471 operands[3] = gen_reg_rtx (XFmode);
17474 (define_expand "scalb<mode>3"
17475 [(use (match_operand:MODEF 0 "register_operand" ""))
17476 (use (match_operand:MODEF 1 "general_operand" ""))
17477 (use (match_operand:MODEF 2 "register_operand" ""))]
17478 "TARGET_USE_FANCY_MATH_387
17479 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17480 || TARGET_MIX_SSE_I387)
17481 && flag_unsafe_math_optimizations && !optimize_size"
17483 rtx op0 = gen_reg_rtx (XFmode);
17484 rtx op1 = gen_reg_rtx (XFmode);
17485 rtx op2 = gen_reg_rtx (XFmode);
17487 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17488 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17489 emit_insn (gen_scalbxf3 (op0, op1, op2));
17490 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17495 (define_insn "sse4_1_round<mode>2"
17496 [(set (match_operand:MODEF 0 "register_operand" "=x")
17497 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17498 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17501 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17502 [(set_attr "type" "ssecvt")
17503 (set_attr "prefix_extra" "1")
17504 (set_attr "mode" "<MODE>")])
17506 (define_insn "rintxf2"
17507 [(set (match_operand:XF 0 "register_operand" "=f")
17508 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17510 "TARGET_USE_FANCY_MATH_387
17511 && flag_unsafe_math_optimizations"
17513 [(set_attr "type" "fpspc")
17514 (set_attr "mode" "XF")])
17516 (define_expand "rint<mode>2"
17517 [(use (match_operand:MODEF 0 "register_operand" ""))
17518 (use (match_operand:MODEF 1 "register_operand" ""))]
17519 "(TARGET_USE_FANCY_MATH_387
17520 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17521 || TARGET_MIX_SSE_I387)
17522 && flag_unsafe_math_optimizations)
17523 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17524 && !flag_trapping_math
17525 && (TARGET_SSE4_1 || !optimize_size))"
17527 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17528 && !flag_trapping_math
17529 && (TARGET_SSE4_1 || !optimize_size))
17532 emit_insn (gen_sse4_1_round<mode>2
17533 (operands[0], operands[1], GEN_INT (0x04)));
17535 ix86_expand_rint (operand0, operand1);
17539 rtx op0 = gen_reg_rtx (XFmode);
17540 rtx op1 = gen_reg_rtx (XFmode);
17542 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17543 emit_insn (gen_rintxf2 (op0, op1));
17545 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17550 (define_expand "round<mode>2"
17551 [(match_operand:MODEF 0 "register_operand" "")
17552 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17553 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17554 && !flag_trapping_math && !flag_rounding_math
17557 if (TARGET_64BIT || (<MODE>mode != DFmode))
17558 ix86_expand_round (operand0, operand1);
17560 ix86_expand_rounddf_32 (operand0, operand1);
17564 (define_insn_and_split "*fistdi2_1"
17565 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17566 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17568 "TARGET_USE_FANCY_MATH_387
17569 && !(reload_completed || reload_in_progress)"
17574 if (memory_operand (operands[0], VOIDmode))
17575 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17578 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17579 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17584 [(set_attr "type" "fpspc")
17585 (set_attr "mode" "DI")])
17587 (define_insn "fistdi2"
17588 [(set (match_operand:DI 0 "memory_operand" "=m")
17589 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17591 (clobber (match_scratch:XF 2 "=&1f"))]
17592 "TARGET_USE_FANCY_MATH_387"
17593 "* return output_fix_trunc (insn, operands, 0);"
17594 [(set_attr "type" "fpspc")
17595 (set_attr "mode" "DI")])
17597 (define_insn "fistdi2_with_temp"
17598 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17599 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17601 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17602 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17603 "TARGET_USE_FANCY_MATH_387"
17605 [(set_attr "type" "fpspc")
17606 (set_attr "mode" "DI")])
17609 [(set (match_operand:DI 0 "register_operand" "")
17610 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17612 (clobber (match_operand:DI 2 "memory_operand" ""))
17613 (clobber (match_scratch 3 ""))]
17615 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17616 (clobber (match_dup 3))])
17617 (set (match_dup 0) (match_dup 2))]
17621 [(set (match_operand:DI 0 "memory_operand" "")
17622 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17624 (clobber (match_operand:DI 2 "memory_operand" ""))
17625 (clobber (match_scratch 3 ""))]
17627 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17628 (clobber (match_dup 3))])]
17631 (define_insn_and_split "*fist<mode>2_1"
17632 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17633 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17635 "TARGET_USE_FANCY_MATH_387
17636 && !(reload_completed || reload_in_progress)"
17641 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17642 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17646 [(set_attr "type" "fpspc")
17647 (set_attr "mode" "<MODE>")])
17649 (define_insn "fist<mode>2"
17650 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17651 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17653 "TARGET_USE_FANCY_MATH_387"
17654 "* return output_fix_trunc (insn, operands, 0);"
17655 [(set_attr "type" "fpspc")
17656 (set_attr "mode" "<MODE>")])
17658 (define_insn "fist<mode>2_with_temp"
17659 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17660 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17662 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17663 "TARGET_USE_FANCY_MATH_387"
17665 [(set_attr "type" "fpspc")
17666 (set_attr "mode" "<MODE>")])
17669 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17670 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17672 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17674 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17675 (set (match_dup 0) (match_dup 2))]
17679 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17680 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17682 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17684 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17687 (define_expand "lrintxf<mode>2"
17688 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17689 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17691 "TARGET_USE_FANCY_MATH_387"
17694 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17695 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17696 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17697 UNSPEC_FIX_NOTRUNC))]
17698 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17699 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17702 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17703 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17704 (match_operand:MODEF 1 "register_operand" "")]
17705 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17706 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17707 && !flag_trapping_math && !flag_rounding_math
17710 ix86_expand_lround (operand0, operand1);
17714 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17715 (define_insn_and_split "frndintxf2_floor"
17716 [(set (match_operand:XF 0 "register_operand" "")
17717 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17718 UNSPEC_FRNDINT_FLOOR))
17719 (clobber (reg:CC FLAGS_REG))]
17720 "TARGET_USE_FANCY_MATH_387
17721 && flag_unsafe_math_optimizations
17722 && !(reload_completed || reload_in_progress)"
17727 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17729 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17730 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17732 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17733 operands[2], operands[3]));
17736 [(set_attr "type" "frndint")
17737 (set_attr "i387_cw" "floor")
17738 (set_attr "mode" "XF")])
17740 (define_insn "frndintxf2_floor_i387"
17741 [(set (match_operand:XF 0 "register_operand" "=f")
17742 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17743 UNSPEC_FRNDINT_FLOOR))
17744 (use (match_operand:HI 2 "memory_operand" "m"))
17745 (use (match_operand:HI 3 "memory_operand" "m"))]
17746 "TARGET_USE_FANCY_MATH_387
17747 && flag_unsafe_math_optimizations"
17748 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17749 [(set_attr "type" "frndint")
17750 (set_attr "i387_cw" "floor")
17751 (set_attr "mode" "XF")])
17753 (define_expand "floorxf2"
17754 [(use (match_operand:XF 0 "register_operand" ""))
17755 (use (match_operand:XF 1 "register_operand" ""))]
17756 "TARGET_USE_FANCY_MATH_387
17757 && flag_unsafe_math_optimizations && !optimize_size"
17759 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17763 (define_expand "floor<mode>2"
17764 [(use (match_operand:MODEF 0 "register_operand" ""))
17765 (use (match_operand:MODEF 1 "register_operand" ""))]
17766 "(TARGET_USE_FANCY_MATH_387
17767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17768 || TARGET_MIX_SSE_I387)
17769 && flag_unsafe_math_optimizations && !optimize_size)
17770 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17771 && !flag_trapping_math
17772 && (TARGET_SSE4_1 || !optimize_size))"
17774 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17775 && !flag_trapping_math
17776 && (TARGET_SSE4_1 || !optimize_size))
17779 emit_insn (gen_sse4_1_round<mode>2
17780 (operands[0], operands[1], GEN_INT (0x01)));
17781 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17782 ix86_expand_floorceil (operand0, operand1, true);
17784 ix86_expand_floorceildf_32 (operand0, operand1, true);
17788 rtx op0 = gen_reg_rtx (XFmode);
17789 rtx op1 = gen_reg_rtx (XFmode);
17791 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17792 emit_insn (gen_frndintxf2_floor (op0, op1));
17794 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17799 (define_insn_and_split "*fist<mode>2_floor_1"
17800 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17801 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17802 UNSPEC_FIST_FLOOR))
17803 (clobber (reg:CC FLAGS_REG))]
17804 "TARGET_USE_FANCY_MATH_387
17805 && flag_unsafe_math_optimizations
17806 && !(reload_completed || reload_in_progress)"
17811 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17813 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17814 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17815 if (memory_operand (operands[0], VOIDmode))
17816 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17817 operands[2], operands[3]));
17820 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17821 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17822 operands[2], operands[3],
17827 [(set_attr "type" "fistp")
17828 (set_attr "i387_cw" "floor")
17829 (set_attr "mode" "<MODE>")])
17831 (define_insn "fistdi2_floor"
17832 [(set (match_operand:DI 0 "memory_operand" "=m")
17833 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17834 UNSPEC_FIST_FLOOR))
17835 (use (match_operand:HI 2 "memory_operand" "m"))
17836 (use (match_operand:HI 3 "memory_operand" "m"))
17837 (clobber (match_scratch:XF 4 "=&1f"))]
17838 "TARGET_USE_FANCY_MATH_387
17839 && flag_unsafe_math_optimizations"
17840 "* return output_fix_trunc (insn, operands, 0);"
17841 [(set_attr "type" "fistp")
17842 (set_attr "i387_cw" "floor")
17843 (set_attr "mode" "DI")])
17845 (define_insn "fistdi2_floor_with_temp"
17846 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17847 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17848 UNSPEC_FIST_FLOOR))
17849 (use (match_operand:HI 2 "memory_operand" "m,m"))
17850 (use (match_operand:HI 3 "memory_operand" "m,m"))
17851 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17852 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17853 "TARGET_USE_FANCY_MATH_387
17854 && flag_unsafe_math_optimizations"
17856 [(set_attr "type" "fistp")
17857 (set_attr "i387_cw" "floor")
17858 (set_attr "mode" "DI")])
17861 [(set (match_operand:DI 0 "register_operand" "")
17862 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17863 UNSPEC_FIST_FLOOR))
17864 (use (match_operand:HI 2 "memory_operand" ""))
17865 (use (match_operand:HI 3 "memory_operand" ""))
17866 (clobber (match_operand:DI 4 "memory_operand" ""))
17867 (clobber (match_scratch 5 ""))]
17869 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17870 (use (match_dup 2))
17871 (use (match_dup 3))
17872 (clobber (match_dup 5))])
17873 (set (match_dup 0) (match_dup 4))]
17877 [(set (match_operand:DI 0 "memory_operand" "")
17878 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17879 UNSPEC_FIST_FLOOR))
17880 (use (match_operand:HI 2 "memory_operand" ""))
17881 (use (match_operand:HI 3 "memory_operand" ""))
17882 (clobber (match_operand:DI 4 "memory_operand" ""))
17883 (clobber (match_scratch 5 ""))]
17885 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17886 (use (match_dup 2))
17887 (use (match_dup 3))
17888 (clobber (match_dup 5))])]
17891 (define_insn "fist<mode>2_floor"
17892 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17893 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17894 UNSPEC_FIST_FLOOR))
17895 (use (match_operand:HI 2 "memory_operand" "m"))
17896 (use (match_operand:HI 3 "memory_operand" "m"))]
17897 "TARGET_USE_FANCY_MATH_387
17898 && flag_unsafe_math_optimizations"
17899 "* return output_fix_trunc (insn, operands, 0);"
17900 [(set_attr "type" "fistp")
17901 (set_attr "i387_cw" "floor")
17902 (set_attr "mode" "<MODE>")])
17904 (define_insn "fist<mode>2_floor_with_temp"
17905 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17906 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17907 UNSPEC_FIST_FLOOR))
17908 (use (match_operand:HI 2 "memory_operand" "m,m"))
17909 (use (match_operand:HI 3 "memory_operand" "m,m"))
17910 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17911 "TARGET_USE_FANCY_MATH_387
17912 && flag_unsafe_math_optimizations"
17914 [(set_attr "type" "fistp")
17915 (set_attr "i387_cw" "floor")
17916 (set_attr "mode" "<MODE>")])
17919 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17920 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17921 UNSPEC_FIST_FLOOR))
17922 (use (match_operand:HI 2 "memory_operand" ""))
17923 (use (match_operand:HI 3 "memory_operand" ""))
17924 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17926 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17927 UNSPEC_FIST_FLOOR))
17928 (use (match_dup 2))
17929 (use (match_dup 3))])
17930 (set (match_dup 0) (match_dup 4))]
17934 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17935 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17936 UNSPEC_FIST_FLOOR))
17937 (use (match_operand:HI 2 "memory_operand" ""))
17938 (use (match_operand:HI 3 "memory_operand" ""))
17939 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17941 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17942 UNSPEC_FIST_FLOOR))
17943 (use (match_dup 2))
17944 (use (match_dup 3))])]
17947 (define_expand "lfloorxf<mode>2"
17948 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17949 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17950 UNSPEC_FIST_FLOOR))
17951 (clobber (reg:CC FLAGS_REG))])]
17952 "TARGET_USE_FANCY_MATH_387
17953 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17954 && flag_unsafe_math_optimizations"
17957 (define_expand "lfloor<mode>di2"
17958 [(match_operand:DI 0 "nonimmediate_operand" "")
17959 (match_operand:MODEF 1 "register_operand" "")]
17960 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17961 && !flag_trapping_math
17964 ix86_expand_lfloorceil (operand0, operand1, true);
17968 (define_expand "lfloor<mode>si2"
17969 [(match_operand:SI 0 "nonimmediate_operand" "")
17970 (match_operand:MODEF 1 "register_operand" "")]
17971 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17972 && !flag_trapping_math
17973 && (!optimize_size || !TARGET_64BIT)"
17975 ix86_expand_lfloorceil (operand0, operand1, true);
17979 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17980 (define_insn_and_split "frndintxf2_ceil"
17981 [(set (match_operand:XF 0 "register_operand" "")
17982 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17983 UNSPEC_FRNDINT_CEIL))
17984 (clobber (reg:CC FLAGS_REG))]
17985 "TARGET_USE_FANCY_MATH_387
17986 && flag_unsafe_math_optimizations
17987 && !(reload_completed || reload_in_progress)"
17992 ix86_optimize_mode_switching[I387_CEIL] = 1;
17994 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17995 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17997 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17998 operands[2], operands[3]));
18001 [(set_attr "type" "frndint")
18002 (set_attr "i387_cw" "ceil")
18003 (set_attr "mode" "XF")])
18005 (define_insn "frndintxf2_ceil_i387"
18006 [(set (match_operand:XF 0 "register_operand" "=f")
18007 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18008 UNSPEC_FRNDINT_CEIL))
18009 (use (match_operand:HI 2 "memory_operand" "m"))
18010 (use (match_operand:HI 3 "memory_operand" "m"))]
18011 "TARGET_USE_FANCY_MATH_387
18012 && flag_unsafe_math_optimizations"
18013 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18014 [(set_attr "type" "frndint")
18015 (set_attr "i387_cw" "ceil")
18016 (set_attr "mode" "XF")])
18018 (define_expand "ceilxf2"
18019 [(use (match_operand:XF 0 "register_operand" ""))
18020 (use (match_operand:XF 1 "register_operand" ""))]
18021 "TARGET_USE_FANCY_MATH_387
18022 && flag_unsafe_math_optimizations && !optimize_size"
18024 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18028 (define_expand "ceil<mode>2"
18029 [(use (match_operand:MODEF 0 "register_operand" ""))
18030 (use (match_operand:MODEF 1 "register_operand" ""))]
18031 "(TARGET_USE_FANCY_MATH_387
18032 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18033 || TARGET_MIX_SSE_I387)
18034 && flag_unsafe_math_optimizations && !optimize_size)
18035 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18036 && !flag_trapping_math
18037 && (TARGET_SSE4_1 || !optimize_size))"
18039 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18040 && !flag_trapping_math
18041 && (TARGET_SSE4_1 || !optimize_size))
18044 emit_insn (gen_sse4_1_round<mode>2
18045 (operands[0], operands[1], GEN_INT (0x02)));
18046 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18047 ix86_expand_floorceil (operand0, operand1, false);
18049 ix86_expand_floorceildf_32 (operand0, operand1, false);
18053 rtx op0 = gen_reg_rtx (XFmode);
18054 rtx op1 = gen_reg_rtx (XFmode);
18056 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18057 emit_insn (gen_frndintxf2_ceil (op0, op1));
18059 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18064 (define_insn_and_split "*fist<mode>2_ceil_1"
18065 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18066 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18068 (clobber (reg:CC FLAGS_REG))]
18069 "TARGET_USE_FANCY_MATH_387
18070 && flag_unsafe_math_optimizations
18071 && !(reload_completed || reload_in_progress)"
18076 ix86_optimize_mode_switching[I387_CEIL] = 1;
18078 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18079 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18080 if (memory_operand (operands[0], VOIDmode))
18081 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18082 operands[2], operands[3]));
18085 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18086 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18087 operands[2], operands[3],
18092 [(set_attr "type" "fistp")
18093 (set_attr "i387_cw" "ceil")
18094 (set_attr "mode" "<MODE>")])
18096 (define_insn "fistdi2_ceil"
18097 [(set (match_operand:DI 0 "memory_operand" "=m")
18098 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18100 (use (match_operand:HI 2 "memory_operand" "m"))
18101 (use (match_operand:HI 3 "memory_operand" "m"))
18102 (clobber (match_scratch:XF 4 "=&1f"))]
18103 "TARGET_USE_FANCY_MATH_387
18104 && flag_unsafe_math_optimizations"
18105 "* return output_fix_trunc (insn, operands, 0);"
18106 [(set_attr "type" "fistp")
18107 (set_attr "i387_cw" "ceil")
18108 (set_attr "mode" "DI")])
18110 (define_insn "fistdi2_ceil_with_temp"
18111 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18112 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18114 (use (match_operand:HI 2 "memory_operand" "m,m"))
18115 (use (match_operand:HI 3 "memory_operand" "m,m"))
18116 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18117 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18118 "TARGET_USE_FANCY_MATH_387
18119 && flag_unsafe_math_optimizations"
18121 [(set_attr "type" "fistp")
18122 (set_attr "i387_cw" "ceil")
18123 (set_attr "mode" "DI")])
18126 [(set (match_operand:DI 0 "register_operand" "")
18127 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18129 (use (match_operand:HI 2 "memory_operand" ""))
18130 (use (match_operand:HI 3 "memory_operand" ""))
18131 (clobber (match_operand:DI 4 "memory_operand" ""))
18132 (clobber (match_scratch 5 ""))]
18134 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18135 (use (match_dup 2))
18136 (use (match_dup 3))
18137 (clobber (match_dup 5))])
18138 (set (match_dup 0) (match_dup 4))]
18142 [(set (match_operand:DI 0 "memory_operand" "")
18143 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18145 (use (match_operand:HI 2 "memory_operand" ""))
18146 (use (match_operand:HI 3 "memory_operand" ""))
18147 (clobber (match_operand:DI 4 "memory_operand" ""))
18148 (clobber (match_scratch 5 ""))]
18150 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18151 (use (match_dup 2))
18152 (use (match_dup 3))
18153 (clobber (match_dup 5))])]
18156 (define_insn "fist<mode>2_ceil"
18157 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18158 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18160 (use (match_operand:HI 2 "memory_operand" "m"))
18161 (use (match_operand:HI 3 "memory_operand" "m"))]
18162 "TARGET_USE_FANCY_MATH_387
18163 && flag_unsafe_math_optimizations"
18164 "* return output_fix_trunc (insn, operands, 0);"
18165 [(set_attr "type" "fistp")
18166 (set_attr "i387_cw" "ceil")
18167 (set_attr "mode" "<MODE>")])
18169 (define_insn "fist<mode>2_ceil_with_temp"
18170 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18171 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18173 (use (match_operand:HI 2 "memory_operand" "m,m"))
18174 (use (match_operand:HI 3 "memory_operand" "m,m"))
18175 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18176 "TARGET_USE_FANCY_MATH_387
18177 && flag_unsafe_math_optimizations"
18179 [(set_attr "type" "fistp")
18180 (set_attr "i387_cw" "ceil")
18181 (set_attr "mode" "<MODE>")])
18184 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18185 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18187 (use (match_operand:HI 2 "memory_operand" ""))
18188 (use (match_operand:HI 3 "memory_operand" ""))
18189 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18191 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18193 (use (match_dup 2))
18194 (use (match_dup 3))])
18195 (set (match_dup 0) (match_dup 4))]
18199 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18200 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18202 (use (match_operand:HI 2 "memory_operand" ""))
18203 (use (match_operand:HI 3 "memory_operand" ""))
18204 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18206 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18208 (use (match_dup 2))
18209 (use (match_dup 3))])]
18212 (define_expand "lceilxf<mode>2"
18213 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18214 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18216 (clobber (reg:CC FLAGS_REG))])]
18217 "TARGET_USE_FANCY_MATH_387
18218 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18219 && flag_unsafe_math_optimizations"
18222 (define_expand "lceil<mode>di2"
18223 [(match_operand:DI 0 "nonimmediate_operand" "")
18224 (match_operand:MODEF 1 "register_operand" "")]
18225 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18226 && !flag_trapping_math"
18228 ix86_expand_lfloorceil (operand0, operand1, false);
18232 (define_expand "lceil<mode>si2"
18233 [(match_operand:SI 0 "nonimmediate_operand" "")
18234 (match_operand:MODEF 1 "register_operand" "")]
18235 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18236 && !flag_trapping_math"
18238 ix86_expand_lfloorceil (operand0, operand1, false);
18242 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18243 (define_insn_and_split "frndintxf2_trunc"
18244 [(set (match_operand:XF 0 "register_operand" "")
18245 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18246 UNSPEC_FRNDINT_TRUNC))
18247 (clobber (reg:CC FLAGS_REG))]
18248 "TARGET_USE_FANCY_MATH_387
18249 && flag_unsafe_math_optimizations
18250 && !(reload_completed || reload_in_progress)"
18255 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18257 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18258 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18260 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18261 operands[2], operands[3]));
18264 [(set_attr "type" "frndint")
18265 (set_attr "i387_cw" "trunc")
18266 (set_attr "mode" "XF")])
18268 (define_insn "frndintxf2_trunc_i387"
18269 [(set (match_operand:XF 0 "register_operand" "=f")
18270 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18271 UNSPEC_FRNDINT_TRUNC))
18272 (use (match_operand:HI 2 "memory_operand" "m"))
18273 (use (match_operand:HI 3 "memory_operand" "m"))]
18274 "TARGET_USE_FANCY_MATH_387
18275 && flag_unsafe_math_optimizations"
18276 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18277 [(set_attr "type" "frndint")
18278 (set_attr "i387_cw" "trunc")
18279 (set_attr "mode" "XF")])
18281 (define_expand "btruncxf2"
18282 [(use (match_operand:XF 0 "register_operand" ""))
18283 (use (match_operand:XF 1 "register_operand" ""))]
18284 "TARGET_USE_FANCY_MATH_387
18285 && flag_unsafe_math_optimizations && !optimize_size"
18287 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18291 (define_expand "btrunc<mode>2"
18292 [(use (match_operand:MODEF 0 "register_operand" ""))
18293 (use (match_operand:MODEF 1 "register_operand" ""))]
18294 "(TARGET_USE_FANCY_MATH_387
18295 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18296 || TARGET_MIX_SSE_I387)
18297 && flag_unsafe_math_optimizations && !optimize_size)
18298 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18299 && !flag_trapping_math
18300 && (TARGET_SSE4_1 || !optimize_size))"
18302 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18303 && !flag_trapping_math
18304 && (TARGET_SSE4_1 || !optimize_size))
18307 emit_insn (gen_sse4_1_round<mode>2
18308 (operands[0], operands[1], GEN_INT (0x03)));
18309 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18310 ix86_expand_trunc (operand0, operand1);
18312 ix86_expand_truncdf_32 (operand0, operand1);
18316 rtx op0 = gen_reg_rtx (XFmode);
18317 rtx op1 = gen_reg_rtx (XFmode);
18319 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18320 emit_insn (gen_frndintxf2_trunc (op0, op1));
18322 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18327 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18328 (define_insn_and_split "frndintxf2_mask_pm"
18329 [(set (match_operand:XF 0 "register_operand" "")
18330 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18331 UNSPEC_FRNDINT_MASK_PM))
18332 (clobber (reg:CC FLAGS_REG))]
18333 "TARGET_USE_FANCY_MATH_387
18334 && flag_unsafe_math_optimizations
18335 && !(reload_completed || reload_in_progress)"
18340 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18342 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18343 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18345 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18346 operands[2], operands[3]));
18349 [(set_attr "type" "frndint")
18350 (set_attr "i387_cw" "mask_pm")
18351 (set_attr "mode" "XF")])
18353 (define_insn "frndintxf2_mask_pm_i387"
18354 [(set (match_operand:XF 0 "register_operand" "=f")
18355 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18356 UNSPEC_FRNDINT_MASK_PM))
18357 (use (match_operand:HI 2 "memory_operand" "m"))
18358 (use (match_operand:HI 3 "memory_operand" "m"))]
18359 "TARGET_USE_FANCY_MATH_387
18360 && flag_unsafe_math_optimizations"
18361 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18362 [(set_attr "type" "frndint")
18363 (set_attr "i387_cw" "mask_pm")
18364 (set_attr "mode" "XF")])
18366 (define_expand "nearbyintxf2"
18367 [(use (match_operand:XF 0 "register_operand" ""))
18368 (use (match_operand:XF 1 "register_operand" ""))]
18369 "TARGET_USE_FANCY_MATH_387
18370 && flag_unsafe_math_optimizations"
18372 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18377 (define_expand "nearbyint<mode>2"
18378 [(use (match_operand:MODEF 0 "register_operand" ""))
18379 (use (match_operand:MODEF 1 "register_operand" ""))]
18380 "TARGET_USE_FANCY_MATH_387
18381 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18382 || TARGET_MIX_SSE_I387)
18383 && flag_unsafe_math_optimizations"
18385 rtx op0 = gen_reg_rtx (XFmode);
18386 rtx op1 = gen_reg_rtx (XFmode);
18388 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18389 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18391 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18395 (define_insn "fxam<mode>2_i387"
18396 [(set (match_operand:HI 0 "register_operand" "=a")
18398 [(match_operand:X87MODEF 1 "register_operand" "f")]
18400 "TARGET_USE_FANCY_MATH_387"
18401 "fxam\n\tfnstsw\t%0"
18402 [(set_attr "type" "multi")
18403 (set_attr "unit" "i387")
18404 (set_attr "mode" "<MODE>")])
18406 (define_expand "isinf<mode>2"
18407 [(use (match_operand:SI 0 "register_operand" ""))
18408 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18409 "TARGET_USE_FANCY_MATH_387
18410 && TARGET_C99_FUNCTIONS
18411 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18413 rtx mask = GEN_INT (0x45);
18414 rtx val = GEN_INT (0x05);
18418 rtx scratch = gen_reg_rtx (HImode);
18419 rtx res = gen_reg_rtx (QImode);
18421 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18422 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18423 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18424 cond = gen_rtx_fmt_ee (EQ, QImode,
18425 gen_rtx_REG (CCmode, FLAGS_REG),
18427 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18428 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18432 (define_expand "signbit<mode>2"
18433 [(use (match_operand:SI 0 "register_operand" ""))
18434 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18435 "TARGET_USE_FANCY_MATH_387
18436 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18438 rtx mask = GEN_INT (0x0200);
18440 rtx scratch = gen_reg_rtx (HImode);
18442 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18443 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18447 ;; Block operation instructions
18449 (define_expand "movmemsi"
18450 [(use (match_operand:BLK 0 "memory_operand" ""))
18451 (use (match_operand:BLK 1 "memory_operand" ""))
18452 (use (match_operand:SI 2 "nonmemory_operand" ""))
18453 (use (match_operand:SI 3 "const_int_operand" ""))
18454 (use (match_operand:SI 4 "const_int_operand" ""))
18455 (use (match_operand:SI 5 "const_int_operand" ""))]
18458 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18459 operands[4], operands[5]))
18465 (define_expand "movmemdi"
18466 [(use (match_operand:BLK 0 "memory_operand" ""))
18467 (use (match_operand:BLK 1 "memory_operand" ""))
18468 (use (match_operand:DI 2 "nonmemory_operand" ""))
18469 (use (match_operand:DI 3 "const_int_operand" ""))
18470 (use (match_operand:SI 4 "const_int_operand" ""))
18471 (use (match_operand:SI 5 "const_int_operand" ""))]
18474 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18475 operands[4], operands[5]))
18481 ;; Most CPUs don't like single string operations
18482 ;; Handle this case here to simplify previous expander.
18484 (define_expand "strmov"
18485 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18486 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18487 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18488 (clobber (reg:CC FLAGS_REG))])
18489 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18490 (clobber (reg:CC FLAGS_REG))])]
18493 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18495 /* If .md ever supports :P for Pmode, these can be directly
18496 in the pattern above. */
18497 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18498 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18500 if (TARGET_SINGLE_STRINGOP || optimize_size)
18502 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18503 operands[2], operands[3],
18504 operands[5], operands[6]));
18508 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18511 (define_expand "strmov_singleop"
18512 [(parallel [(set (match_operand 1 "memory_operand" "")
18513 (match_operand 3 "memory_operand" ""))
18514 (set (match_operand 0 "register_operand" "")
18515 (match_operand 4 "" ""))
18516 (set (match_operand 2 "register_operand" "")
18517 (match_operand 5 "" ""))])]
18518 "TARGET_SINGLE_STRINGOP || optimize_size"
18521 (define_insn "*strmovdi_rex_1"
18522 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18523 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18524 (set (match_operand:DI 0 "register_operand" "=D")
18525 (plus:DI (match_dup 2)
18527 (set (match_operand:DI 1 "register_operand" "=S")
18528 (plus:DI (match_dup 3)
18530 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18532 [(set_attr "type" "str")
18533 (set_attr "mode" "DI")
18534 (set_attr "memory" "both")])
18536 (define_insn "*strmovsi_1"
18537 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18538 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18539 (set (match_operand:SI 0 "register_operand" "=D")
18540 (plus:SI (match_dup 2)
18542 (set (match_operand:SI 1 "register_operand" "=S")
18543 (plus:SI (match_dup 3)
18545 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18547 [(set_attr "type" "str")
18548 (set_attr "mode" "SI")
18549 (set_attr "memory" "both")])
18551 (define_insn "*strmovsi_rex_1"
18552 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18553 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18554 (set (match_operand:DI 0 "register_operand" "=D")
18555 (plus:DI (match_dup 2)
18557 (set (match_operand:DI 1 "register_operand" "=S")
18558 (plus:DI (match_dup 3)
18560 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18562 [(set_attr "type" "str")
18563 (set_attr "mode" "SI")
18564 (set_attr "memory" "both")])
18566 (define_insn "*strmovhi_1"
18567 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18568 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18569 (set (match_operand:SI 0 "register_operand" "=D")
18570 (plus:SI (match_dup 2)
18572 (set (match_operand:SI 1 "register_operand" "=S")
18573 (plus:SI (match_dup 3)
18575 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18577 [(set_attr "type" "str")
18578 (set_attr "memory" "both")
18579 (set_attr "mode" "HI")])
18581 (define_insn "*strmovhi_rex_1"
18582 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18583 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18584 (set (match_operand:DI 0 "register_operand" "=D")
18585 (plus:DI (match_dup 2)
18587 (set (match_operand:DI 1 "register_operand" "=S")
18588 (plus:DI (match_dup 3)
18590 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18592 [(set_attr "type" "str")
18593 (set_attr "memory" "both")
18594 (set_attr "mode" "HI")])
18596 (define_insn "*strmovqi_1"
18597 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18598 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18599 (set (match_operand:SI 0 "register_operand" "=D")
18600 (plus:SI (match_dup 2)
18602 (set (match_operand:SI 1 "register_operand" "=S")
18603 (plus:SI (match_dup 3)
18605 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18607 [(set_attr "type" "str")
18608 (set_attr "memory" "both")
18609 (set_attr "mode" "QI")])
18611 (define_insn "*strmovqi_rex_1"
18612 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18613 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18614 (set (match_operand:DI 0 "register_operand" "=D")
18615 (plus:DI (match_dup 2)
18617 (set (match_operand:DI 1 "register_operand" "=S")
18618 (plus:DI (match_dup 3)
18620 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18622 [(set_attr "type" "str")
18623 (set_attr "memory" "both")
18624 (set_attr "mode" "QI")])
18626 (define_expand "rep_mov"
18627 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18628 (set (match_operand 0 "register_operand" "")
18629 (match_operand 5 "" ""))
18630 (set (match_operand 2 "register_operand" "")
18631 (match_operand 6 "" ""))
18632 (set (match_operand 1 "memory_operand" "")
18633 (match_operand 3 "memory_operand" ""))
18634 (use (match_dup 4))])]
18638 (define_insn "*rep_movdi_rex64"
18639 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18640 (set (match_operand:DI 0 "register_operand" "=D")
18641 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18643 (match_operand:DI 3 "register_operand" "0")))
18644 (set (match_operand:DI 1 "register_operand" "=S")
18645 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18646 (match_operand:DI 4 "register_operand" "1")))
18647 (set (mem:BLK (match_dup 3))
18648 (mem:BLK (match_dup 4)))
18649 (use (match_dup 5))]
18652 [(set_attr "type" "str")
18653 (set_attr "prefix_rep" "1")
18654 (set_attr "memory" "both")
18655 (set_attr "mode" "DI")])
18657 (define_insn "*rep_movsi"
18658 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18659 (set (match_operand:SI 0 "register_operand" "=D")
18660 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18662 (match_operand:SI 3 "register_operand" "0")))
18663 (set (match_operand:SI 1 "register_operand" "=S")
18664 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18665 (match_operand:SI 4 "register_operand" "1")))
18666 (set (mem:BLK (match_dup 3))
18667 (mem:BLK (match_dup 4)))
18668 (use (match_dup 5))]
18671 [(set_attr "type" "str")
18672 (set_attr "prefix_rep" "1")
18673 (set_attr "memory" "both")
18674 (set_attr "mode" "SI")])
18676 (define_insn "*rep_movsi_rex64"
18677 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18678 (set (match_operand:DI 0 "register_operand" "=D")
18679 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18681 (match_operand:DI 3 "register_operand" "0")))
18682 (set (match_operand:DI 1 "register_operand" "=S")
18683 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18684 (match_operand:DI 4 "register_operand" "1")))
18685 (set (mem:BLK (match_dup 3))
18686 (mem:BLK (match_dup 4)))
18687 (use (match_dup 5))]
18690 [(set_attr "type" "str")
18691 (set_attr "prefix_rep" "1")
18692 (set_attr "memory" "both")
18693 (set_attr "mode" "SI")])
18695 (define_insn "*rep_movqi"
18696 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18697 (set (match_operand:SI 0 "register_operand" "=D")
18698 (plus:SI (match_operand:SI 3 "register_operand" "0")
18699 (match_operand:SI 5 "register_operand" "2")))
18700 (set (match_operand:SI 1 "register_operand" "=S")
18701 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18702 (set (mem:BLK (match_dup 3))
18703 (mem:BLK (match_dup 4)))
18704 (use (match_dup 5))]
18707 [(set_attr "type" "str")
18708 (set_attr "prefix_rep" "1")
18709 (set_attr "memory" "both")
18710 (set_attr "mode" "SI")])
18712 (define_insn "*rep_movqi_rex64"
18713 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18714 (set (match_operand:DI 0 "register_operand" "=D")
18715 (plus:DI (match_operand:DI 3 "register_operand" "0")
18716 (match_operand:DI 5 "register_operand" "2")))
18717 (set (match_operand:DI 1 "register_operand" "=S")
18718 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18719 (set (mem:BLK (match_dup 3))
18720 (mem:BLK (match_dup 4)))
18721 (use (match_dup 5))]
18724 [(set_attr "type" "str")
18725 (set_attr "prefix_rep" "1")
18726 (set_attr "memory" "both")
18727 (set_attr "mode" "SI")])
18729 (define_expand "setmemsi"
18730 [(use (match_operand:BLK 0 "memory_operand" ""))
18731 (use (match_operand:SI 1 "nonmemory_operand" ""))
18732 (use (match_operand 2 "const_int_operand" ""))
18733 (use (match_operand 3 "const_int_operand" ""))
18734 (use (match_operand:SI 4 "const_int_operand" ""))
18735 (use (match_operand:SI 5 "const_int_operand" ""))]
18738 if (ix86_expand_setmem (operands[0], operands[1],
18739 operands[2], operands[3],
18740 operands[4], operands[5]))
18746 (define_expand "setmemdi"
18747 [(use (match_operand:BLK 0 "memory_operand" ""))
18748 (use (match_operand:DI 1 "nonmemory_operand" ""))
18749 (use (match_operand 2 "const_int_operand" ""))
18750 (use (match_operand 3 "const_int_operand" ""))
18751 (use (match_operand 4 "const_int_operand" ""))
18752 (use (match_operand 5 "const_int_operand" ""))]
18755 if (ix86_expand_setmem (operands[0], operands[1],
18756 operands[2], operands[3],
18757 operands[4], operands[5]))
18763 ;; Most CPUs don't like single string operations
18764 ;; Handle this case here to simplify previous expander.
18766 (define_expand "strset"
18767 [(set (match_operand 1 "memory_operand" "")
18768 (match_operand 2 "register_operand" ""))
18769 (parallel [(set (match_operand 0 "register_operand" "")
18771 (clobber (reg:CC FLAGS_REG))])]
18774 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18775 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18777 /* If .md ever supports :P for Pmode, this can be directly
18778 in the pattern above. */
18779 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18780 GEN_INT (GET_MODE_SIZE (GET_MODE
18782 if (TARGET_SINGLE_STRINGOP || optimize_size)
18784 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18790 (define_expand "strset_singleop"
18791 [(parallel [(set (match_operand 1 "memory_operand" "")
18792 (match_operand 2 "register_operand" ""))
18793 (set (match_operand 0 "register_operand" "")
18794 (match_operand 3 "" ""))])]
18795 "TARGET_SINGLE_STRINGOP || optimize_size"
18798 (define_insn "*strsetdi_rex_1"
18799 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18800 (match_operand:DI 2 "register_operand" "a"))
18801 (set (match_operand:DI 0 "register_operand" "=D")
18802 (plus:DI (match_dup 1)
18804 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18806 [(set_attr "type" "str")
18807 (set_attr "memory" "store")
18808 (set_attr "mode" "DI")])
18810 (define_insn "*strsetsi_1"
18811 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18812 (match_operand:SI 2 "register_operand" "a"))
18813 (set (match_operand:SI 0 "register_operand" "=D")
18814 (plus:SI (match_dup 1)
18816 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18818 [(set_attr "type" "str")
18819 (set_attr "memory" "store")
18820 (set_attr "mode" "SI")])
18822 (define_insn "*strsetsi_rex_1"
18823 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18824 (match_operand:SI 2 "register_operand" "a"))
18825 (set (match_operand:DI 0 "register_operand" "=D")
18826 (plus:DI (match_dup 1)
18828 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18830 [(set_attr "type" "str")
18831 (set_attr "memory" "store")
18832 (set_attr "mode" "SI")])
18834 (define_insn "*strsethi_1"
18835 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18836 (match_operand:HI 2 "register_operand" "a"))
18837 (set (match_operand:SI 0 "register_operand" "=D")
18838 (plus:SI (match_dup 1)
18840 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18842 [(set_attr "type" "str")
18843 (set_attr "memory" "store")
18844 (set_attr "mode" "HI")])
18846 (define_insn "*strsethi_rex_1"
18847 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18848 (match_operand:HI 2 "register_operand" "a"))
18849 (set (match_operand:DI 0 "register_operand" "=D")
18850 (plus:DI (match_dup 1)
18852 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18854 [(set_attr "type" "str")
18855 (set_attr "memory" "store")
18856 (set_attr "mode" "HI")])
18858 (define_insn "*strsetqi_1"
18859 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18860 (match_operand:QI 2 "register_operand" "a"))
18861 (set (match_operand:SI 0 "register_operand" "=D")
18862 (plus:SI (match_dup 1)
18864 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18866 [(set_attr "type" "str")
18867 (set_attr "memory" "store")
18868 (set_attr "mode" "QI")])
18870 (define_insn "*strsetqi_rex_1"
18871 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18872 (match_operand:QI 2 "register_operand" "a"))
18873 (set (match_operand:DI 0 "register_operand" "=D")
18874 (plus:DI (match_dup 1)
18876 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18878 [(set_attr "type" "str")
18879 (set_attr "memory" "store")
18880 (set_attr "mode" "QI")])
18882 (define_expand "rep_stos"
18883 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18884 (set (match_operand 0 "register_operand" "")
18885 (match_operand 4 "" ""))
18886 (set (match_operand 2 "memory_operand" "") (const_int 0))
18887 (use (match_operand 3 "register_operand" ""))
18888 (use (match_dup 1))])]
18892 (define_insn "*rep_stosdi_rex64"
18893 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18894 (set (match_operand:DI 0 "register_operand" "=D")
18895 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18897 (match_operand:DI 3 "register_operand" "0")))
18898 (set (mem:BLK (match_dup 3))
18900 (use (match_operand:DI 2 "register_operand" "a"))
18901 (use (match_dup 4))]
18904 [(set_attr "type" "str")
18905 (set_attr "prefix_rep" "1")
18906 (set_attr "memory" "store")
18907 (set_attr "mode" "DI")])
18909 (define_insn "*rep_stossi"
18910 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18911 (set (match_operand:SI 0 "register_operand" "=D")
18912 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18914 (match_operand:SI 3 "register_operand" "0")))
18915 (set (mem:BLK (match_dup 3))
18917 (use (match_operand:SI 2 "register_operand" "a"))
18918 (use (match_dup 4))]
18921 [(set_attr "type" "str")
18922 (set_attr "prefix_rep" "1")
18923 (set_attr "memory" "store")
18924 (set_attr "mode" "SI")])
18926 (define_insn "*rep_stossi_rex64"
18927 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18928 (set (match_operand:DI 0 "register_operand" "=D")
18929 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18931 (match_operand:DI 3 "register_operand" "0")))
18932 (set (mem:BLK (match_dup 3))
18934 (use (match_operand:SI 2 "register_operand" "a"))
18935 (use (match_dup 4))]
18938 [(set_attr "type" "str")
18939 (set_attr "prefix_rep" "1")
18940 (set_attr "memory" "store")
18941 (set_attr "mode" "SI")])
18943 (define_insn "*rep_stosqi"
18944 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18945 (set (match_operand:SI 0 "register_operand" "=D")
18946 (plus:SI (match_operand:SI 3 "register_operand" "0")
18947 (match_operand:SI 4 "register_operand" "1")))
18948 (set (mem:BLK (match_dup 3))
18950 (use (match_operand:QI 2 "register_operand" "a"))
18951 (use (match_dup 4))]
18954 [(set_attr "type" "str")
18955 (set_attr "prefix_rep" "1")
18956 (set_attr "memory" "store")
18957 (set_attr "mode" "QI")])
18959 (define_insn "*rep_stosqi_rex64"
18960 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18961 (set (match_operand:DI 0 "register_operand" "=D")
18962 (plus:DI (match_operand:DI 3 "register_operand" "0")
18963 (match_operand:DI 4 "register_operand" "1")))
18964 (set (mem:BLK (match_dup 3))
18966 (use (match_operand:QI 2 "register_operand" "a"))
18967 (use (match_dup 4))]
18970 [(set_attr "type" "str")
18971 (set_attr "prefix_rep" "1")
18972 (set_attr "memory" "store")
18973 (set_attr "mode" "QI")])
18975 (define_expand "cmpstrnsi"
18976 [(set (match_operand:SI 0 "register_operand" "")
18977 (compare:SI (match_operand:BLK 1 "general_operand" "")
18978 (match_operand:BLK 2 "general_operand" "")))
18979 (use (match_operand 3 "general_operand" ""))
18980 (use (match_operand 4 "immediate_operand" ""))]
18981 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18983 rtx addr1, addr2, out, outlow, count, countreg, align;
18985 /* Can't use this if the user has appropriated esi or edi. */
18986 if (global_regs[4] || global_regs[5])
18991 out = gen_reg_rtx (SImode);
18993 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18994 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18995 if (addr1 != XEXP (operands[1], 0))
18996 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18997 if (addr2 != XEXP (operands[2], 0))
18998 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19000 count = operands[3];
19001 countreg = ix86_zero_extend_to_Pmode (count);
19003 /* %%% Iff we are testing strict equality, we can use known alignment
19004 to good advantage. This may be possible with combine, particularly
19005 once cc0 is dead. */
19006 align = operands[4];
19008 if (CONST_INT_P (count))
19010 if (INTVAL (count) == 0)
19012 emit_move_insn (operands[0], const0_rtx);
19015 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19016 operands[1], operands[2]));
19021 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19023 emit_insn (gen_cmpsi_1 (countreg, countreg));
19024 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19025 operands[1], operands[2]));
19028 outlow = gen_lowpart (QImode, out);
19029 emit_insn (gen_cmpintqi (outlow));
19030 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19032 if (operands[0] != out)
19033 emit_move_insn (operands[0], out);
19038 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19040 (define_expand "cmpintqi"
19041 [(set (match_dup 1)
19042 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19044 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19045 (parallel [(set (match_operand:QI 0 "register_operand" "")
19046 (minus:QI (match_dup 1)
19048 (clobber (reg:CC FLAGS_REG))])]
19050 "operands[1] = gen_reg_rtx (QImode);
19051 operands[2] = gen_reg_rtx (QImode);")
19053 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19054 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19056 (define_expand "cmpstrnqi_nz_1"
19057 [(parallel [(set (reg:CC FLAGS_REG)
19058 (compare:CC (match_operand 4 "memory_operand" "")
19059 (match_operand 5 "memory_operand" "")))
19060 (use (match_operand 2 "register_operand" ""))
19061 (use (match_operand:SI 3 "immediate_operand" ""))
19062 (clobber (match_operand 0 "register_operand" ""))
19063 (clobber (match_operand 1 "register_operand" ""))
19064 (clobber (match_dup 2))])]
19068 (define_insn "*cmpstrnqi_nz_1"
19069 [(set (reg:CC FLAGS_REG)
19070 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19071 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19072 (use (match_operand:SI 6 "register_operand" "2"))
19073 (use (match_operand:SI 3 "immediate_operand" "i"))
19074 (clobber (match_operand:SI 0 "register_operand" "=S"))
19075 (clobber (match_operand:SI 1 "register_operand" "=D"))
19076 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19079 [(set_attr "type" "str")
19080 (set_attr "mode" "QI")
19081 (set_attr "prefix_rep" "1")])
19083 (define_insn "*cmpstrnqi_nz_rex_1"
19084 [(set (reg:CC FLAGS_REG)
19085 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19086 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19087 (use (match_operand:DI 6 "register_operand" "2"))
19088 (use (match_operand:SI 3 "immediate_operand" "i"))
19089 (clobber (match_operand:DI 0 "register_operand" "=S"))
19090 (clobber (match_operand:DI 1 "register_operand" "=D"))
19091 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19094 [(set_attr "type" "str")
19095 (set_attr "mode" "QI")
19096 (set_attr "prefix_rep" "1")])
19098 ;; The same, but the count is not known to not be zero.
19100 (define_expand "cmpstrnqi_1"
19101 [(parallel [(set (reg:CC FLAGS_REG)
19102 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19104 (compare:CC (match_operand 4 "memory_operand" "")
19105 (match_operand 5 "memory_operand" ""))
19107 (use (match_operand:SI 3 "immediate_operand" ""))
19108 (use (reg:CC FLAGS_REG))
19109 (clobber (match_operand 0 "register_operand" ""))
19110 (clobber (match_operand 1 "register_operand" ""))
19111 (clobber (match_dup 2))])]
19115 (define_insn "*cmpstrnqi_1"
19116 [(set (reg:CC FLAGS_REG)
19117 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19119 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19120 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19122 (use (match_operand:SI 3 "immediate_operand" "i"))
19123 (use (reg:CC FLAGS_REG))
19124 (clobber (match_operand:SI 0 "register_operand" "=S"))
19125 (clobber (match_operand:SI 1 "register_operand" "=D"))
19126 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19129 [(set_attr "type" "str")
19130 (set_attr "mode" "QI")
19131 (set_attr "prefix_rep" "1")])
19133 (define_insn "*cmpstrnqi_rex_1"
19134 [(set (reg:CC FLAGS_REG)
19135 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19137 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19138 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19140 (use (match_operand:SI 3 "immediate_operand" "i"))
19141 (use (reg:CC FLAGS_REG))
19142 (clobber (match_operand:DI 0 "register_operand" "=S"))
19143 (clobber (match_operand:DI 1 "register_operand" "=D"))
19144 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19147 [(set_attr "type" "str")
19148 (set_attr "mode" "QI")
19149 (set_attr "prefix_rep" "1")])
19151 (define_expand "strlensi"
19152 [(set (match_operand:SI 0 "register_operand" "")
19153 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19154 (match_operand:QI 2 "immediate_operand" "")
19155 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19158 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19164 (define_expand "strlendi"
19165 [(set (match_operand:DI 0 "register_operand" "")
19166 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19167 (match_operand:QI 2 "immediate_operand" "")
19168 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19171 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19177 (define_expand "strlenqi_1"
19178 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19179 (clobber (match_operand 1 "register_operand" ""))
19180 (clobber (reg:CC FLAGS_REG))])]
19184 (define_insn "*strlenqi_1"
19185 [(set (match_operand:SI 0 "register_operand" "=&c")
19186 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19187 (match_operand:QI 2 "register_operand" "a")
19188 (match_operand:SI 3 "immediate_operand" "i")
19189 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19190 (clobber (match_operand:SI 1 "register_operand" "=D"))
19191 (clobber (reg:CC FLAGS_REG))]
19194 [(set_attr "type" "str")
19195 (set_attr "mode" "QI")
19196 (set_attr "prefix_rep" "1")])
19198 (define_insn "*strlenqi_rex_1"
19199 [(set (match_operand:DI 0 "register_operand" "=&c")
19200 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19201 (match_operand:QI 2 "register_operand" "a")
19202 (match_operand:DI 3 "immediate_operand" "i")
19203 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19204 (clobber (match_operand:DI 1 "register_operand" "=D"))
19205 (clobber (reg:CC FLAGS_REG))]
19208 [(set_attr "type" "str")
19209 (set_attr "mode" "QI")
19210 (set_attr "prefix_rep" "1")])
19212 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19213 ;; handled in combine, but it is not currently up to the task.
19214 ;; When used for their truth value, the cmpstrn* expanders generate
19223 ;; The intermediate three instructions are unnecessary.
19225 ;; This one handles cmpstrn*_nz_1...
19228 (set (reg:CC FLAGS_REG)
19229 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19230 (mem:BLK (match_operand 5 "register_operand" ""))))
19231 (use (match_operand 6 "register_operand" ""))
19232 (use (match_operand:SI 3 "immediate_operand" ""))
19233 (clobber (match_operand 0 "register_operand" ""))
19234 (clobber (match_operand 1 "register_operand" ""))
19235 (clobber (match_operand 2 "register_operand" ""))])
19236 (set (match_operand:QI 7 "register_operand" "")
19237 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19238 (set (match_operand:QI 8 "register_operand" "")
19239 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19240 (set (reg FLAGS_REG)
19241 (compare (match_dup 7) (match_dup 8)))
19243 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19245 (set (reg:CC FLAGS_REG)
19246 (compare:CC (mem:BLK (match_dup 4))
19247 (mem:BLK (match_dup 5))))
19248 (use (match_dup 6))
19249 (use (match_dup 3))
19250 (clobber (match_dup 0))
19251 (clobber (match_dup 1))
19252 (clobber (match_dup 2))])]
19255 ;; ...and this one handles cmpstrn*_1.
19258 (set (reg:CC FLAGS_REG)
19259 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19261 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19262 (mem:BLK (match_operand 5 "register_operand" "")))
19264 (use (match_operand:SI 3 "immediate_operand" ""))
19265 (use (reg:CC FLAGS_REG))
19266 (clobber (match_operand 0 "register_operand" ""))
19267 (clobber (match_operand 1 "register_operand" ""))
19268 (clobber (match_operand 2 "register_operand" ""))])
19269 (set (match_operand:QI 7 "register_operand" "")
19270 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19271 (set (match_operand:QI 8 "register_operand" "")
19272 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19273 (set (reg FLAGS_REG)
19274 (compare (match_dup 7) (match_dup 8)))
19276 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19278 (set (reg:CC FLAGS_REG)
19279 (if_then_else:CC (ne (match_dup 6)
19281 (compare:CC (mem:BLK (match_dup 4))
19282 (mem:BLK (match_dup 5)))
19284 (use (match_dup 3))
19285 (use (reg:CC FLAGS_REG))
19286 (clobber (match_dup 0))
19287 (clobber (match_dup 1))
19288 (clobber (match_dup 2))])]
19293 ;; Conditional move instructions.
19295 (define_expand "movdicc"
19296 [(set (match_operand:DI 0 "register_operand" "")
19297 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19298 (match_operand:DI 2 "general_operand" "")
19299 (match_operand:DI 3 "general_operand" "")))]
19301 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19303 (define_insn "x86_movdicc_0_m1_rex64"
19304 [(set (match_operand:DI 0 "register_operand" "=r")
19305 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19308 (clobber (reg:CC FLAGS_REG))]
19311 ; Since we don't have the proper number of operands for an alu insn,
19312 ; fill in all the blanks.
19313 [(set_attr "type" "alu")
19314 (set_attr "pent_pair" "pu")
19315 (set_attr "memory" "none")
19316 (set_attr "imm_disp" "false")
19317 (set_attr "mode" "DI")
19318 (set_attr "length_immediate" "0")])
19320 (define_insn "*movdicc_c_rex64"
19321 [(set (match_operand:DI 0 "register_operand" "=r,r")
19322 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19323 [(reg FLAGS_REG) (const_int 0)])
19324 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19325 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19326 "TARGET_64BIT && TARGET_CMOVE
19327 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19329 cmov%O2%C1\t{%2, %0|%0, %2}
19330 cmov%O2%c1\t{%3, %0|%0, %3}"
19331 [(set_attr "type" "icmov")
19332 (set_attr "mode" "DI")])
19334 (define_expand "movsicc"
19335 [(set (match_operand:SI 0 "register_operand" "")
19336 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19337 (match_operand:SI 2 "general_operand" "")
19338 (match_operand:SI 3 "general_operand" "")))]
19340 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19342 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19343 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19344 ;; So just document what we're doing explicitly.
19346 (define_insn "x86_movsicc_0_m1"
19347 [(set (match_operand:SI 0 "register_operand" "=r")
19348 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19351 (clobber (reg:CC FLAGS_REG))]
19354 ; Since we don't have the proper number of operands for an alu insn,
19355 ; fill in all the blanks.
19356 [(set_attr "type" "alu")
19357 (set_attr "pent_pair" "pu")
19358 (set_attr "memory" "none")
19359 (set_attr "imm_disp" "false")
19360 (set_attr "mode" "SI")
19361 (set_attr "length_immediate" "0")])
19363 (define_insn "*movsicc_noc"
19364 [(set (match_operand:SI 0 "register_operand" "=r,r")
19365 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19366 [(reg FLAGS_REG) (const_int 0)])
19367 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19368 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19370 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19372 cmov%O2%C1\t{%2, %0|%0, %2}
19373 cmov%O2%c1\t{%3, %0|%0, %3}"
19374 [(set_attr "type" "icmov")
19375 (set_attr "mode" "SI")])
19377 (define_expand "movhicc"
19378 [(set (match_operand:HI 0 "register_operand" "")
19379 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19380 (match_operand:HI 2 "general_operand" "")
19381 (match_operand:HI 3 "general_operand" "")))]
19382 "TARGET_HIMODE_MATH"
19383 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19385 (define_insn "*movhicc_noc"
19386 [(set (match_operand:HI 0 "register_operand" "=r,r")
19387 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19388 [(reg FLAGS_REG) (const_int 0)])
19389 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19390 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19392 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19394 cmov%O2%C1\t{%2, %0|%0, %2}
19395 cmov%O2%c1\t{%3, %0|%0, %3}"
19396 [(set_attr "type" "icmov")
19397 (set_attr "mode" "HI")])
19399 (define_expand "movqicc"
19400 [(set (match_operand:QI 0 "register_operand" "")
19401 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19402 (match_operand:QI 2 "general_operand" "")
19403 (match_operand:QI 3 "general_operand" "")))]
19404 "TARGET_QIMODE_MATH"
19405 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19407 (define_insn_and_split "*movqicc_noc"
19408 [(set (match_operand:QI 0 "register_operand" "=r,r")
19409 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19410 [(match_operand 4 "flags_reg_operand" "")
19412 (match_operand:QI 2 "register_operand" "r,0")
19413 (match_operand:QI 3 "register_operand" "0,r")))]
19414 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19416 "&& reload_completed"
19417 [(set (match_dup 0)
19418 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19421 "operands[0] = gen_lowpart (SImode, operands[0]);
19422 operands[2] = gen_lowpart (SImode, operands[2]);
19423 operands[3] = gen_lowpart (SImode, operands[3]);"
19424 [(set_attr "type" "icmov")
19425 (set_attr "mode" "SI")])
19427 (define_expand "movsfcc"
19428 [(set (match_operand:SF 0 "register_operand" "")
19429 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19430 (match_operand:SF 2 "register_operand" "")
19431 (match_operand:SF 3 "register_operand" "")))]
19432 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19433 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19435 (define_insn "*movsfcc_1_387"
19436 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19437 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19438 [(reg FLAGS_REG) (const_int 0)])
19439 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19440 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19441 "TARGET_80387 && TARGET_CMOVE
19442 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19444 fcmov%F1\t{%2, %0|%0, %2}
19445 fcmov%f1\t{%3, %0|%0, %3}
19446 cmov%O2%C1\t{%2, %0|%0, %2}
19447 cmov%O2%c1\t{%3, %0|%0, %3}"
19448 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19449 (set_attr "mode" "SF,SF,SI,SI")])
19451 (define_expand "movdfcc"
19452 [(set (match_operand:DF 0 "register_operand" "")
19453 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19454 (match_operand:DF 2 "register_operand" "")
19455 (match_operand:DF 3 "register_operand" "")))]
19456 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19457 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19459 (define_insn "*movdfcc_1"
19460 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19461 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19462 [(reg FLAGS_REG) (const_int 0)])
19463 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19464 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19465 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19466 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19468 fcmov%F1\t{%2, %0|%0, %2}
19469 fcmov%f1\t{%3, %0|%0, %3}
19472 [(set_attr "type" "fcmov,fcmov,multi,multi")
19473 (set_attr "mode" "DF")])
19475 (define_insn "*movdfcc_1_rex64"
19476 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19477 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19478 [(reg FLAGS_REG) (const_int 0)])
19479 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19480 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19481 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19482 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19484 fcmov%F1\t{%2, %0|%0, %2}
19485 fcmov%f1\t{%3, %0|%0, %3}
19486 cmov%O2%C1\t{%2, %0|%0, %2}
19487 cmov%O2%c1\t{%3, %0|%0, %3}"
19488 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19489 (set_attr "mode" "DF")])
19492 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19493 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19494 [(match_operand 4 "flags_reg_operand" "")
19496 (match_operand:DF 2 "nonimmediate_operand" "")
19497 (match_operand:DF 3 "nonimmediate_operand" "")))]
19498 "!TARGET_64BIT && reload_completed"
19499 [(set (match_dup 2)
19500 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19504 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19507 "split_di (operands+2, 1, operands+5, operands+6);
19508 split_di (operands+3, 1, operands+7, operands+8);
19509 split_di (operands, 1, operands+2, operands+3);")
19511 (define_expand "movxfcc"
19512 [(set (match_operand:XF 0 "register_operand" "")
19513 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19514 (match_operand:XF 2 "register_operand" "")
19515 (match_operand:XF 3 "register_operand" "")))]
19516 "TARGET_80387 && TARGET_CMOVE"
19517 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19519 (define_insn "*movxfcc_1"
19520 [(set (match_operand:XF 0 "register_operand" "=f,f")
19521 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19522 [(reg FLAGS_REG) (const_int 0)])
19523 (match_operand:XF 2 "register_operand" "f,0")
19524 (match_operand:XF 3 "register_operand" "0,f")))]
19525 "TARGET_80387 && TARGET_CMOVE"
19527 fcmov%F1\t{%2, %0|%0, %2}
19528 fcmov%f1\t{%3, %0|%0, %3}"
19529 [(set_attr "type" "fcmov")
19530 (set_attr "mode" "XF")])
19532 ;; These versions of the min/max patterns are intentionally ignorant of
19533 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19534 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19535 ;; are undefined in this condition, we're certain this is correct.
19537 (define_insn "sminsf3"
19538 [(set (match_operand:SF 0 "register_operand" "=x")
19539 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19540 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19542 "minss\t{%2, %0|%0, %2}"
19543 [(set_attr "type" "sseadd")
19544 (set_attr "mode" "SF")])
19546 (define_insn "smaxsf3"
19547 [(set (match_operand:SF 0 "register_operand" "=x")
19548 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19549 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19551 "maxss\t{%2, %0|%0, %2}"
19552 [(set_attr "type" "sseadd")
19553 (set_attr "mode" "SF")])
19555 (define_insn "smindf3"
19556 [(set (match_operand:DF 0 "register_operand" "=x")
19557 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19558 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19559 "TARGET_SSE2 && TARGET_SSE_MATH"
19560 "minsd\t{%2, %0|%0, %2}"
19561 [(set_attr "type" "sseadd")
19562 (set_attr "mode" "DF")])
19564 (define_insn "smaxdf3"
19565 [(set (match_operand:DF 0 "register_operand" "=x")
19566 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19567 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19568 "TARGET_SSE2 && TARGET_SSE_MATH"
19569 "maxsd\t{%2, %0|%0, %2}"
19570 [(set_attr "type" "sseadd")
19571 (set_attr "mode" "DF")])
19573 ;; These versions of the min/max patterns implement exactly the operations
19574 ;; min = (op1 < op2 ? op1 : op2)
19575 ;; max = (!(op1 < op2) ? op1 : op2)
19576 ;; Their operands are not commutative, and thus they may be used in the
19577 ;; presence of -0.0 and NaN.
19579 (define_insn "*ieee_sminsf3"
19580 [(set (match_operand:SF 0 "register_operand" "=x")
19581 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19582 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19585 "minss\t{%2, %0|%0, %2}"
19586 [(set_attr "type" "sseadd")
19587 (set_attr "mode" "SF")])
19589 (define_insn "*ieee_smaxsf3"
19590 [(set (match_operand:SF 0 "register_operand" "=x")
19591 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19592 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19595 "maxss\t{%2, %0|%0, %2}"
19596 [(set_attr "type" "sseadd")
19597 (set_attr "mode" "SF")])
19599 (define_insn "*ieee_smindf3"
19600 [(set (match_operand:DF 0 "register_operand" "=x")
19601 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19602 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19604 "TARGET_SSE2 && TARGET_SSE_MATH"
19605 "minsd\t{%2, %0|%0, %2}"
19606 [(set_attr "type" "sseadd")
19607 (set_attr "mode" "DF")])
19609 (define_insn "*ieee_smaxdf3"
19610 [(set (match_operand:DF 0 "register_operand" "=x")
19611 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19612 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19614 "TARGET_SSE2 && TARGET_SSE_MATH"
19615 "maxsd\t{%2, %0|%0, %2}"
19616 [(set_attr "type" "sseadd")
19617 (set_attr "mode" "DF")])
19619 ;; Make two stack loads independent:
19621 ;; fld %st(0) -> fld bb
19622 ;; fmul bb fmul %st(1), %st
19624 ;; Actually we only match the last two instructions for simplicity.
19626 [(set (match_operand 0 "fp_register_operand" "")
19627 (match_operand 1 "fp_register_operand" ""))
19629 (match_operator 2 "binary_fp_operator"
19631 (match_operand 3 "memory_operand" "")]))]
19632 "REGNO (operands[0]) != REGNO (operands[1])"
19633 [(set (match_dup 0) (match_dup 3))
19634 (set (match_dup 0) (match_dup 4))]
19636 ;; The % modifier is not operational anymore in peephole2's, so we have to
19637 ;; swap the operands manually in the case of addition and multiplication.
19638 "if (COMMUTATIVE_ARITH_P (operands[2]))
19639 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19640 operands[0], operands[1]);
19642 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19643 operands[1], operands[0]);")
19645 ;; Conditional addition patterns
19646 (define_expand "addqicc"
19647 [(match_operand:QI 0 "register_operand" "")
19648 (match_operand 1 "comparison_operator" "")
19649 (match_operand:QI 2 "register_operand" "")
19650 (match_operand:QI 3 "const_int_operand" "")]
19652 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19654 (define_expand "addhicc"
19655 [(match_operand:HI 0 "register_operand" "")
19656 (match_operand 1 "comparison_operator" "")
19657 (match_operand:HI 2 "register_operand" "")
19658 (match_operand:HI 3 "const_int_operand" "")]
19660 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19662 (define_expand "addsicc"
19663 [(match_operand:SI 0 "register_operand" "")
19664 (match_operand 1 "comparison_operator" "")
19665 (match_operand:SI 2 "register_operand" "")
19666 (match_operand:SI 3 "const_int_operand" "")]
19668 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19670 (define_expand "adddicc"
19671 [(match_operand:DI 0 "register_operand" "")
19672 (match_operand 1 "comparison_operator" "")
19673 (match_operand:DI 2 "register_operand" "")
19674 (match_operand:DI 3 "const_int_operand" "")]
19676 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19679 ;; Misc patterns (?)
19681 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19682 ;; Otherwise there will be nothing to keep
19684 ;; [(set (reg ebp) (reg esp))]
19685 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19686 ;; (clobber (eflags)]
19687 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19689 ;; in proper program order.
19690 (define_insn "pro_epilogue_adjust_stack_1"
19691 [(set (match_operand:SI 0 "register_operand" "=r,r")
19692 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19693 (match_operand:SI 2 "immediate_operand" "i,i")))
19694 (clobber (reg:CC FLAGS_REG))
19695 (clobber (mem:BLK (scratch)))]
19698 switch (get_attr_type (insn))
19701 return "mov{l}\t{%1, %0|%0, %1}";
19704 if (CONST_INT_P (operands[2])
19705 && (INTVAL (operands[2]) == 128
19706 || (INTVAL (operands[2]) < 0
19707 && INTVAL (operands[2]) != -128)))
19709 operands[2] = GEN_INT (-INTVAL (operands[2]));
19710 return "sub{l}\t{%2, %0|%0, %2}";
19712 return "add{l}\t{%2, %0|%0, %2}";
19715 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19716 return "lea{l}\t{%a2, %0|%0, %a2}";
19719 gcc_unreachable ();
19722 [(set (attr "type")
19723 (cond [(eq_attr "alternative" "0")
19724 (const_string "alu")
19725 (match_operand:SI 2 "const0_operand" "")
19726 (const_string "imov")
19728 (const_string "lea")))
19729 (set_attr "mode" "SI")])
19731 (define_insn "pro_epilogue_adjust_stack_rex64"
19732 [(set (match_operand:DI 0 "register_operand" "=r,r")
19733 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19734 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19735 (clobber (reg:CC FLAGS_REG))
19736 (clobber (mem:BLK (scratch)))]
19739 switch (get_attr_type (insn))
19742 return "mov{q}\t{%1, %0|%0, %1}";
19745 if (CONST_INT_P (operands[2])
19746 /* Avoid overflows. */
19747 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19748 && (INTVAL (operands[2]) == 128
19749 || (INTVAL (operands[2]) < 0
19750 && INTVAL (operands[2]) != -128)))
19752 operands[2] = GEN_INT (-INTVAL (operands[2]));
19753 return "sub{q}\t{%2, %0|%0, %2}";
19755 return "add{q}\t{%2, %0|%0, %2}";
19758 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19759 return "lea{q}\t{%a2, %0|%0, %a2}";
19762 gcc_unreachable ();
19765 [(set (attr "type")
19766 (cond [(eq_attr "alternative" "0")
19767 (const_string "alu")
19768 (match_operand:DI 2 "const0_operand" "")
19769 (const_string "imov")
19771 (const_string "lea")))
19772 (set_attr "mode" "DI")])
19774 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19775 [(set (match_operand:DI 0 "register_operand" "=r,r")
19776 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19777 (match_operand:DI 3 "immediate_operand" "i,i")))
19778 (use (match_operand:DI 2 "register_operand" "r,r"))
19779 (clobber (reg:CC FLAGS_REG))
19780 (clobber (mem:BLK (scratch)))]
19783 switch (get_attr_type (insn))
19786 return "add{q}\t{%2, %0|%0, %2}";
19789 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19790 return "lea{q}\t{%a2, %0|%0, %a2}";
19793 gcc_unreachable ();
19796 [(set_attr "type" "alu,lea")
19797 (set_attr "mode" "DI")])
19799 (define_insn "allocate_stack_worker_32"
19800 [(set (match_operand:SI 0 "register_operand" "+a")
19801 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19802 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19803 (clobber (reg:CC FLAGS_REG))]
19804 "!TARGET_64BIT && TARGET_STACK_PROBE"
19806 [(set_attr "type" "multi")
19807 (set_attr "length" "5")])
19809 (define_insn "allocate_stack_worker_64"
19810 [(set (match_operand:DI 0 "register_operand" "=a")
19811 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19812 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19813 (clobber (reg:DI R10_REG))
19814 (clobber (reg:DI R11_REG))
19815 (clobber (reg:CC FLAGS_REG))]
19816 "TARGET_64BIT && TARGET_STACK_PROBE"
19818 [(set_attr "type" "multi")
19819 (set_attr "length" "5")])
19821 (define_expand "allocate_stack"
19822 [(match_operand 0 "register_operand" "")
19823 (match_operand 1 "general_operand" "")]
19824 "TARGET_STACK_PROBE"
19828 #ifndef CHECK_STACK_LIMIT
19829 #define CHECK_STACK_LIMIT 0
19832 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19833 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19835 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19836 stack_pointer_rtx, 0, OPTAB_DIRECT);
19837 if (x != stack_pointer_rtx)
19838 emit_move_insn (stack_pointer_rtx, x);
19842 x = copy_to_mode_reg (Pmode, operands[1]);
19844 x = gen_allocate_stack_worker_64 (x);
19846 x = gen_allocate_stack_worker_32 (x);
19850 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19854 (define_expand "builtin_setjmp_receiver"
19855 [(label_ref (match_operand 0 "" ""))]
19856 "!TARGET_64BIT && flag_pic"
19861 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19862 rtx label_rtx = gen_label_rtx ();
19863 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19864 xops[0] = xops[1] = picreg;
19865 xops[2] = gen_rtx_CONST (SImode,
19866 gen_rtx_MINUS (SImode,
19867 gen_rtx_LABEL_REF (SImode, label_rtx),
19868 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19869 ix86_expand_binary_operator (MINUS, SImode, xops);
19872 emit_insn (gen_set_got (pic_offset_table_rtx));
19876 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19879 [(set (match_operand 0 "register_operand" "")
19880 (match_operator 3 "promotable_binary_operator"
19881 [(match_operand 1 "register_operand" "")
19882 (match_operand 2 "aligned_operand" "")]))
19883 (clobber (reg:CC FLAGS_REG))]
19884 "! TARGET_PARTIAL_REG_STALL && reload_completed
19885 && ((GET_MODE (operands[0]) == HImode
19886 && ((!optimize_size && !TARGET_FAST_PREFIX)
19887 /* ??? next two lines just !satisfies_constraint_K (...) */
19888 || !CONST_INT_P (operands[2])
19889 || satisfies_constraint_K (operands[2])))
19890 || (GET_MODE (operands[0]) == QImode
19891 && (TARGET_PROMOTE_QImode || optimize_size)))"
19892 [(parallel [(set (match_dup 0)
19893 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19894 (clobber (reg:CC FLAGS_REG))])]
19895 "operands[0] = gen_lowpart (SImode, operands[0]);
19896 operands[1] = gen_lowpart (SImode, operands[1]);
19897 if (GET_CODE (operands[3]) != ASHIFT)
19898 operands[2] = gen_lowpart (SImode, operands[2]);
19899 PUT_MODE (operands[3], SImode);")
19901 ; Promote the QImode tests, as i386 has encoding of the AND
19902 ; instruction with 32-bit sign-extended immediate and thus the
19903 ; instruction size is unchanged, except in the %eax case for
19904 ; which it is increased by one byte, hence the ! optimize_size.
19906 [(set (match_operand 0 "flags_reg_operand" "")
19907 (match_operator 2 "compare_operator"
19908 [(and (match_operand 3 "aligned_operand" "")
19909 (match_operand 4 "const_int_operand" ""))
19911 (set (match_operand 1 "register_operand" "")
19912 (and (match_dup 3) (match_dup 4)))]
19913 "! TARGET_PARTIAL_REG_STALL && reload_completed
19915 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19916 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19917 /* Ensure that the operand will remain sign-extended immediate. */
19918 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19919 [(parallel [(set (match_dup 0)
19920 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19923 (and:SI (match_dup 3) (match_dup 4)))])]
19926 = gen_int_mode (INTVAL (operands[4])
19927 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19928 operands[1] = gen_lowpart (SImode, operands[1]);
19929 operands[3] = gen_lowpart (SImode, operands[3]);
19932 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19933 ; the TEST instruction with 32-bit sign-extended immediate and thus
19934 ; the instruction size would at least double, which is not what we
19935 ; want even with ! optimize_size.
19937 [(set (match_operand 0 "flags_reg_operand" "")
19938 (match_operator 1 "compare_operator"
19939 [(and (match_operand:HI 2 "aligned_operand" "")
19940 (match_operand:HI 3 "const_int_operand" ""))
19942 "! TARGET_PARTIAL_REG_STALL && reload_completed
19943 && ! TARGET_FAST_PREFIX
19945 /* Ensure that the operand will remain sign-extended immediate. */
19946 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19947 [(set (match_dup 0)
19948 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19952 = gen_int_mode (INTVAL (operands[3])
19953 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19954 operands[2] = gen_lowpart (SImode, operands[2]);
19958 [(set (match_operand 0 "register_operand" "")
19959 (neg (match_operand 1 "register_operand" "")))
19960 (clobber (reg:CC FLAGS_REG))]
19961 "! TARGET_PARTIAL_REG_STALL && reload_completed
19962 && (GET_MODE (operands[0]) == HImode
19963 || (GET_MODE (operands[0]) == QImode
19964 && (TARGET_PROMOTE_QImode || optimize_size)))"
19965 [(parallel [(set (match_dup 0)
19966 (neg:SI (match_dup 1)))
19967 (clobber (reg:CC FLAGS_REG))])]
19968 "operands[0] = gen_lowpart (SImode, operands[0]);
19969 operands[1] = gen_lowpart (SImode, operands[1]);")
19972 [(set (match_operand 0 "register_operand" "")
19973 (not (match_operand 1 "register_operand" "")))]
19974 "! TARGET_PARTIAL_REG_STALL && reload_completed
19975 && (GET_MODE (operands[0]) == HImode
19976 || (GET_MODE (operands[0]) == QImode
19977 && (TARGET_PROMOTE_QImode || optimize_size)))"
19978 [(set (match_dup 0)
19979 (not:SI (match_dup 1)))]
19980 "operands[0] = gen_lowpart (SImode, operands[0]);
19981 operands[1] = gen_lowpart (SImode, operands[1]);")
19984 [(set (match_operand 0 "register_operand" "")
19985 (if_then_else (match_operator 1 "comparison_operator"
19986 [(reg FLAGS_REG) (const_int 0)])
19987 (match_operand 2 "register_operand" "")
19988 (match_operand 3 "register_operand" "")))]
19989 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19990 && (GET_MODE (operands[0]) == HImode
19991 || (GET_MODE (operands[0]) == QImode
19992 && (TARGET_PROMOTE_QImode || optimize_size)))"
19993 [(set (match_dup 0)
19994 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19995 "operands[0] = gen_lowpart (SImode, operands[0]);
19996 operands[2] = gen_lowpart (SImode, operands[2]);
19997 operands[3] = gen_lowpart (SImode, operands[3]);")
20000 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20001 ;; transform a complex memory operation into two memory to register operations.
20003 ;; Don't push memory operands
20005 [(set (match_operand:SI 0 "push_operand" "")
20006 (match_operand:SI 1 "memory_operand" ""))
20007 (match_scratch:SI 2 "r")]
20008 "!optimize_size && !TARGET_PUSH_MEMORY
20009 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20010 [(set (match_dup 2) (match_dup 1))
20011 (set (match_dup 0) (match_dup 2))]
20015 [(set (match_operand:DI 0 "push_operand" "")
20016 (match_operand:DI 1 "memory_operand" ""))
20017 (match_scratch:DI 2 "r")]
20018 "!optimize_size && !TARGET_PUSH_MEMORY
20019 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20020 [(set (match_dup 2) (match_dup 1))
20021 (set (match_dup 0) (match_dup 2))]
20024 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20027 [(set (match_operand:SF 0 "push_operand" "")
20028 (match_operand:SF 1 "memory_operand" ""))
20029 (match_scratch:SF 2 "r")]
20030 "!optimize_size && !TARGET_PUSH_MEMORY
20031 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20032 [(set (match_dup 2) (match_dup 1))
20033 (set (match_dup 0) (match_dup 2))]
20037 [(set (match_operand:HI 0 "push_operand" "")
20038 (match_operand:HI 1 "memory_operand" ""))
20039 (match_scratch:HI 2 "r")]
20040 "!optimize_size && !TARGET_PUSH_MEMORY
20041 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20042 [(set (match_dup 2) (match_dup 1))
20043 (set (match_dup 0) (match_dup 2))]
20047 [(set (match_operand:QI 0 "push_operand" "")
20048 (match_operand:QI 1 "memory_operand" ""))
20049 (match_scratch:QI 2 "q")]
20050 "!optimize_size && !TARGET_PUSH_MEMORY
20051 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20052 [(set (match_dup 2) (match_dup 1))
20053 (set (match_dup 0) (match_dup 2))]
20056 ;; Don't move an immediate directly to memory when the instruction
20059 [(match_scratch:SI 1 "r")
20060 (set (match_operand:SI 0 "memory_operand" "")
20063 && ! TARGET_USE_MOV0
20064 && TARGET_SPLIT_LONG_MOVES
20065 && get_attr_length (insn) >= ix86_cost->large_insn
20066 && peep2_regno_dead_p (0, FLAGS_REG)"
20067 [(parallel [(set (match_dup 1) (const_int 0))
20068 (clobber (reg:CC FLAGS_REG))])
20069 (set (match_dup 0) (match_dup 1))]
20073 [(match_scratch:HI 1 "r")
20074 (set (match_operand:HI 0 "memory_operand" "")
20077 && ! TARGET_USE_MOV0
20078 && TARGET_SPLIT_LONG_MOVES
20079 && get_attr_length (insn) >= ix86_cost->large_insn
20080 && peep2_regno_dead_p (0, FLAGS_REG)"
20081 [(parallel [(set (match_dup 2) (const_int 0))
20082 (clobber (reg:CC FLAGS_REG))])
20083 (set (match_dup 0) (match_dup 1))]
20084 "operands[2] = gen_lowpart (SImode, operands[1]);")
20087 [(match_scratch:QI 1 "q")
20088 (set (match_operand:QI 0 "memory_operand" "")
20091 && ! TARGET_USE_MOV0
20092 && TARGET_SPLIT_LONG_MOVES
20093 && get_attr_length (insn) >= ix86_cost->large_insn
20094 && peep2_regno_dead_p (0, FLAGS_REG)"
20095 [(parallel [(set (match_dup 2) (const_int 0))
20096 (clobber (reg:CC FLAGS_REG))])
20097 (set (match_dup 0) (match_dup 1))]
20098 "operands[2] = gen_lowpart (SImode, operands[1]);")
20101 [(match_scratch:SI 2 "r")
20102 (set (match_operand:SI 0 "memory_operand" "")
20103 (match_operand:SI 1 "immediate_operand" ""))]
20105 && TARGET_SPLIT_LONG_MOVES
20106 && get_attr_length (insn) >= ix86_cost->large_insn"
20107 [(set (match_dup 2) (match_dup 1))
20108 (set (match_dup 0) (match_dup 2))]
20112 [(match_scratch:HI 2 "r")
20113 (set (match_operand:HI 0 "memory_operand" "")
20114 (match_operand:HI 1 "immediate_operand" ""))]
20116 && TARGET_SPLIT_LONG_MOVES
20117 && get_attr_length (insn) >= ix86_cost->large_insn"
20118 [(set (match_dup 2) (match_dup 1))
20119 (set (match_dup 0) (match_dup 2))]
20123 [(match_scratch:QI 2 "q")
20124 (set (match_operand:QI 0 "memory_operand" "")
20125 (match_operand:QI 1 "immediate_operand" ""))]
20127 && TARGET_SPLIT_LONG_MOVES
20128 && get_attr_length (insn) >= ix86_cost->large_insn"
20129 [(set (match_dup 2) (match_dup 1))
20130 (set (match_dup 0) (match_dup 2))]
20133 ;; Don't compare memory with zero, load and use a test instead.
20135 [(set (match_operand 0 "flags_reg_operand" "")
20136 (match_operator 1 "compare_operator"
20137 [(match_operand:SI 2 "memory_operand" "")
20139 (match_scratch:SI 3 "r")]
20140 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20141 [(set (match_dup 3) (match_dup 2))
20142 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20145 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20146 ;; Don't split NOTs with a displacement operand, because resulting XOR
20147 ;; will not be pairable anyway.
20149 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20150 ;; represented using a modRM byte. The XOR replacement is long decoded,
20151 ;; so this split helps here as well.
20153 ;; Note: Can't do this as a regular split because we can't get proper
20154 ;; lifetime information then.
20157 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20158 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20160 && ((TARGET_NOT_UNPAIRABLE
20161 && (!MEM_P (operands[0])
20162 || !memory_displacement_operand (operands[0], SImode)))
20163 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20164 && peep2_regno_dead_p (0, FLAGS_REG)"
20165 [(parallel [(set (match_dup 0)
20166 (xor:SI (match_dup 1) (const_int -1)))
20167 (clobber (reg:CC FLAGS_REG))])]
20171 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20172 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20174 && ((TARGET_NOT_UNPAIRABLE
20175 && (!MEM_P (operands[0])
20176 || !memory_displacement_operand (operands[0], HImode)))
20177 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20178 && peep2_regno_dead_p (0, FLAGS_REG)"
20179 [(parallel [(set (match_dup 0)
20180 (xor:HI (match_dup 1) (const_int -1)))
20181 (clobber (reg:CC FLAGS_REG))])]
20185 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20186 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20188 && ((TARGET_NOT_UNPAIRABLE
20189 && (!MEM_P (operands[0])
20190 || !memory_displacement_operand (operands[0], QImode)))
20191 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20192 && peep2_regno_dead_p (0, FLAGS_REG)"
20193 [(parallel [(set (match_dup 0)
20194 (xor:QI (match_dup 1) (const_int -1)))
20195 (clobber (reg:CC FLAGS_REG))])]
20198 ;; Non pairable "test imm, reg" instructions can be translated to
20199 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20200 ;; byte opcode instead of two, have a short form for byte operands),
20201 ;; so do it for other CPUs as well. Given that the value was dead,
20202 ;; this should not create any new dependencies. Pass on the sub-word
20203 ;; versions if we're concerned about partial register stalls.
20206 [(set (match_operand 0 "flags_reg_operand" "")
20207 (match_operator 1 "compare_operator"
20208 [(and:SI (match_operand:SI 2 "register_operand" "")
20209 (match_operand:SI 3 "immediate_operand" ""))
20211 "ix86_match_ccmode (insn, CCNOmode)
20212 && (true_regnum (operands[2]) != 0
20213 || satisfies_constraint_K (operands[3]))
20214 && peep2_reg_dead_p (1, operands[2])"
20216 [(set (match_dup 0)
20217 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20220 (and:SI (match_dup 2) (match_dup 3)))])]
20223 ;; We don't need to handle HImode case, because it will be promoted to SImode
20224 ;; on ! TARGET_PARTIAL_REG_STALL
20227 [(set (match_operand 0 "flags_reg_operand" "")
20228 (match_operator 1 "compare_operator"
20229 [(and:QI (match_operand:QI 2 "register_operand" "")
20230 (match_operand:QI 3 "immediate_operand" ""))
20232 "! TARGET_PARTIAL_REG_STALL
20233 && ix86_match_ccmode (insn, CCNOmode)
20234 && true_regnum (operands[2]) != 0
20235 && peep2_reg_dead_p (1, operands[2])"
20237 [(set (match_dup 0)
20238 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20241 (and:QI (match_dup 2) (match_dup 3)))])]
20245 [(set (match_operand 0 "flags_reg_operand" "")
20246 (match_operator 1 "compare_operator"
20249 (match_operand 2 "ext_register_operand" "")
20252 (match_operand 3 "const_int_operand" ""))
20254 "! TARGET_PARTIAL_REG_STALL
20255 && ix86_match_ccmode (insn, CCNOmode)
20256 && true_regnum (operands[2]) != 0
20257 && peep2_reg_dead_p (1, operands[2])"
20258 [(parallel [(set (match_dup 0)
20267 (set (zero_extract:SI (match_dup 2)
20278 ;; Don't do logical operations with memory inputs.
20280 [(match_scratch:SI 2 "r")
20281 (parallel [(set (match_operand:SI 0 "register_operand" "")
20282 (match_operator:SI 3 "arith_or_logical_operator"
20284 (match_operand:SI 1 "memory_operand" "")]))
20285 (clobber (reg:CC FLAGS_REG))])]
20286 "! optimize_size && ! TARGET_READ_MODIFY"
20287 [(set (match_dup 2) (match_dup 1))
20288 (parallel [(set (match_dup 0)
20289 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20290 (clobber (reg:CC FLAGS_REG))])]
20294 [(match_scratch:SI 2 "r")
20295 (parallel [(set (match_operand:SI 0 "register_operand" "")
20296 (match_operator:SI 3 "arith_or_logical_operator"
20297 [(match_operand:SI 1 "memory_operand" "")
20299 (clobber (reg:CC FLAGS_REG))])]
20300 "! optimize_size && ! TARGET_READ_MODIFY"
20301 [(set (match_dup 2) (match_dup 1))
20302 (parallel [(set (match_dup 0)
20303 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20304 (clobber (reg:CC FLAGS_REG))])]
20307 ; Don't do logical operations with memory outputs
20309 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20310 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20311 ; the same decoder scheduling characteristics as the original.
20314 [(match_scratch:SI 2 "r")
20315 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20316 (match_operator:SI 3 "arith_or_logical_operator"
20318 (match_operand:SI 1 "nonmemory_operand" "")]))
20319 (clobber (reg:CC FLAGS_REG))])]
20320 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20321 [(set (match_dup 2) (match_dup 0))
20322 (parallel [(set (match_dup 2)
20323 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20324 (clobber (reg:CC FLAGS_REG))])
20325 (set (match_dup 0) (match_dup 2))]
20329 [(match_scratch:SI 2 "r")
20330 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20331 (match_operator:SI 3 "arith_or_logical_operator"
20332 [(match_operand:SI 1 "nonmemory_operand" "")
20334 (clobber (reg:CC FLAGS_REG))])]
20335 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20336 [(set (match_dup 2) (match_dup 0))
20337 (parallel [(set (match_dup 2)
20338 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20339 (clobber (reg:CC FLAGS_REG))])
20340 (set (match_dup 0) (match_dup 2))]
20343 ;; Attempt to always use XOR for zeroing registers.
20345 [(set (match_operand 0 "register_operand" "")
20346 (match_operand 1 "const0_operand" ""))]
20347 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20348 && (! TARGET_USE_MOV0 || optimize_size)
20349 && GENERAL_REG_P (operands[0])
20350 && peep2_regno_dead_p (0, FLAGS_REG)"
20351 [(parallel [(set (match_dup 0) (const_int 0))
20352 (clobber (reg:CC FLAGS_REG))])]
20354 operands[0] = gen_lowpart (word_mode, operands[0]);
20358 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20360 "(GET_MODE (operands[0]) == QImode
20361 || GET_MODE (operands[0]) == HImode)
20362 && (! TARGET_USE_MOV0 || optimize_size)
20363 && peep2_regno_dead_p (0, FLAGS_REG)"
20364 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20365 (clobber (reg:CC FLAGS_REG))])])
20367 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20369 [(set (match_operand 0 "register_operand" "")
20371 "(GET_MODE (operands[0]) == HImode
20372 || GET_MODE (operands[0]) == SImode
20373 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20374 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20375 && peep2_regno_dead_p (0, FLAGS_REG)"
20376 [(parallel [(set (match_dup 0) (const_int -1))
20377 (clobber (reg:CC FLAGS_REG))])]
20378 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20381 ;; Attempt to convert simple leas to adds. These can be created by
20384 [(set (match_operand:SI 0 "register_operand" "")
20385 (plus:SI (match_dup 0)
20386 (match_operand:SI 1 "nonmemory_operand" "")))]
20387 "peep2_regno_dead_p (0, FLAGS_REG)"
20388 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20389 (clobber (reg:CC FLAGS_REG))])]
20393 [(set (match_operand:SI 0 "register_operand" "")
20394 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20395 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20396 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20397 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20398 (clobber (reg:CC FLAGS_REG))])]
20399 "operands[2] = gen_lowpart (SImode, operands[2]);")
20402 [(set (match_operand:DI 0 "register_operand" "")
20403 (plus:DI (match_dup 0)
20404 (match_operand:DI 1 "x86_64_general_operand" "")))]
20405 "peep2_regno_dead_p (0, FLAGS_REG)"
20406 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20407 (clobber (reg:CC FLAGS_REG))])]
20411 [(set (match_operand:SI 0 "register_operand" "")
20412 (mult:SI (match_dup 0)
20413 (match_operand:SI 1 "const_int_operand" "")))]
20414 "exact_log2 (INTVAL (operands[1])) >= 0
20415 && peep2_regno_dead_p (0, FLAGS_REG)"
20416 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20417 (clobber (reg:CC FLAGS_REG))])]
20418 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20421 [(set (match_operand:DI 0 "register_operand" "")
20422 (mult:DI (match_dup 0)
20423 (match_operand:DI 1 "const_int_operand" "")))]
20424 "exact_log2 (INTVAL (operands[1])) >= 0
20425 && peep2_regno_dead_p (0, FLAGS_REG)"
20426 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20427 (clobber (reg:CC FLAGS_REG))])]
20428 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20431 [(set (match_operand:SI 0 "register_operand" "")
20432 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20433 (match_operand:DI 2 "const_int_operand" "")) 0))]
20434 "exact_log2 (INTVAL (operands[2])) >= 0
20435 && REGNO (operands[0]) == REGNO (operands[1])
20436 && peep2_regno_dead_p (0, FLAGS_REG)"
20437 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20438 (clobber (reg:CC FLAGS_REG))])]
20439 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20441 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20442 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20443 ;; many CPUs it is also faster, since special hardware to avoid esp
20444 ;; dependencies is present.
20446 ;; While some of these conversions may be done using splitters, we use peepholes
20447 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20449 ;; Convert prologue esp subtractions to push.
20450 ;; We need register to push. In order to keep verify_flow_info happy we have
20452 ;; - use scratch and clobber it in order to avoid dependencies
20453 ;; - use already live register
20454 ;; We can't use the second way right now, since there is no reliable way how to
20455 ;; verify that given register is live. First choice will also most likely in
20456 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20457 ;; call clobbered registers are dead. We may want to use base pointer as an
20458 ;; alternative when no register is available later.
20461 [(match_scratch:SI 0 "r")
20462 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20463 (clobber (reg:CC FLAGS_REG))
20464 (clobber (mem:BLK (scratch)))])]
20465 "optimize_size || !TARGET_SUB_ESP_4"
20466 [(clobber (match_dup 0))
20467 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20468 (clobber (mem:BLK (scratch)))])])
20471 [(match_scratch:SI 0 "r")
20472 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20473 (clobber (reg:CC FLAGS_REG))
20474 (clobber (mem:BLK (scratch)))])]
20475 "optimize_size || !TARGET_SUB_ESP_8"
20476 [(clobber (match_dup 0))
20477 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20478 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20479 (clobber (mem:BLK (scratch)))])])
20481 ;; Convert esp subtractions to push.
20483 [(match_scratch:SI 0 "r")
20484 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20485 (clobber (reg:CC FLAGS_REG))])]
20486 "optimize_size || !TARGET_SUB_ESP_4"
20487 [(clobber (match_dup 0))
20488 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20491 [(match_scratch:SI 0 "r")
20492 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20493 (clobber (reg:CC FLAGS_REG))])]
20494 "optimize_size || !TARGET_SUB_ESP_8"
20495 [(clobber (match_dup 0))
20496 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20497 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20499 ;; Convert epilogue deallocator to pop.
20501 [(match_scratch:SI 0 "r")
20502 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20503 (clobber (reg:CC FLAGS_REG))
20504 (clobber (mem:BLK (scratch)))])]
20505 "optimize_size || !TARGET_ADD_ESP_4"
20506 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20507 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20508 (clobber (mem:BLK (scratch)))])]
20511 ;; Two pops case is tricky, since pop causes dependency on destination register.
20512 ;; We use two registers if available.
20514 [(match_scratch:SI 0 "r")
20515 (match_scratch:SI 1 "r")
20516 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20517 (clobber (reg:CC FLAGS_REG))
20518 (clobber (mem:BLK (scratch)))])]
20519 "optimize_size || !TARGET_ADD_ESP_8"
20520 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20521 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20522 (clobber (mem:BLK (scratch)))])
20523 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20524 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20528 [(match_scratch:SI 0 "r")
20529 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20530 (clobber (reg:CC FLAGS_REG))
20531 (clobber (mem:BLK (scratch)))])]
20533 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20534 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20535 (clobber (mem:BLK (scratch)))])
20536 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20537 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20540 ;; Convert esp additions to pop.
20542 [(match_scratch:SI 0 "r")
20543 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20544 (clobber (reg:CC FLAGS_REG))])]
20546 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20547 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20550 ;; Two pops case is tricky, since pop causes dependency on destination register.
20551 ;; We use two registers if available.
20553 [(match_scratch:SI 0 "r")
20554 (match_scratch:SI 1 "r")
20555 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20556 (clobber (reg:CC FLAGS_REG))])]
20558 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20559 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20560 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20561 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20565 [(match_scratch:SI 0 "r")
20566 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20567 (clobber (reg:CC FLAGS_REG))])]
20569 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20570 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20571 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20572 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20575 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20576 ;; required and register dies. Similarly for 128 to plus -128.
20578 [(set (match_operand 0 "flags_reg_operand" "")
20579 (match_operator 1 "compare_operator"
20580 [(match_operand 2 "register_operand" "")
20581 (match_operand 3 "const_int_operand" "")]))]
20582 "(INTVAL (operands[3]) == -1
20583 || INTVAL (operands[3]) == 1
20584 || INTVAL (operands[3]) == 128)
20585 && ix86_match_ccmode (insn, CCGCmode)
20586 && peep2_reg_dead_p (1, operands[2])"
20587 [(parallel [(set (match_dup 0)
20588 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20589 (clobber (match_dup 2))])]
20593 [(match_scratch:DI 0 "r")
20594 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20595 (clobber (reg:CC FLAGS_REG))
20596 (clobber (mem:BLK (scratch)))])]
20597 "optimize_size || !TARGET_SUB_ESP_4"
20598 [(clobber (match_dup 0))
20599 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20600 (clobber (mem:BLK (scratch)))])])
20603 [(match_scratch:DI 0 "r")
20604 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20605 (clobber (reg:CC FLAGS_REG))
20606 (clobber (mem:BLK (scratch)))])]
20607 "optimize_size || !TARGET_SUB_ESP_8"
20608 [(clobber (match_dup 0))
20609 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20610 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20611 (clobber (mem:BLK (scratch)))])])
20613 ;; Convert esp subtractions to push.
20615 [(match_scratch:DI 0 "r")
20616 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20617 (clobber (reg:CC FLAGS_REG))])]
20618 "optimize_size || !TARGET_SUB_ESP_4"
20619 [(clobber (match_dup 0))
20620 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20623 [(match_scratch:DI 0 "r")
20624 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20625 (clobber (reg:CC FLAGS_REG))])]
20626 "optimize_size || !TARGET_SUB_ESP_8"
20627 [(clobber (match_dup 0))
20628 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20629 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20631 ;; Convert epilogue deallocator to pop.
20633 [(match_scratch:DI 0 "r")
20634 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20635 (clobber (reg:CC FLAGS_REG))
20636 (clobber (mem:BLK (scratch)))])]
20637 "optimize_size || !TARGET_ADD_ESP_4"
20638 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20639 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20640 (clobber (mem:BLK (scratch)))])]
20643 ;; Two pops case is tricky, since pop causes dependency on destination register.
20644 ;; We use two registers if available.
20646 [(match_scratch:DI 0 "r")
20647 (match_scratch:DI 1 "r")
20648 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20649 (clobber (reg:CC FLAGS_REG))
20650 (clobber (mem:BLK (scratch)))])]
20651 "optimize_size || !TARGET_ADD_ESP_8"
20652 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20653 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20654 (clobber (mem:BLK (scratch)))])
20655 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20656 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20660 [(match_scratch:DI 0 "r")
20661 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20662 (clobber (reg:CC FLAGS_REG))
20663 (clobber (mem:BLK (scratch)))])]
20665 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20666 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20667 (clobber (mem:BLK (scratch)))])
20668 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20669 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20672 ;; Convert esp additions to pop.
20674 [(match_scratch:DI 0 "r")
20675 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20676 (clobber (reg:CC FLAGS_REG))])]
20678 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20679 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20682 ;; Two pops case is tricky, since pop causes dependency on destination register.
20683 ;; We use two registers if available.
20685 [(match_scratch:DI 0 "r")
20686 (match_scratch:DI 1 "r")
20687 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20688 (clobber (reg:CC FLAGS_REG))])]
20690 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20691 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20692 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20693 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20697 [(match_scratch:DI 0 "r")
20698 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20699 (clobber (reg:CC FLAGS_REG))])]
20701 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20702 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20703 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20704 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20707 ;; Convert imul by three, five and nine into lea
20710 [(set (match_operand:SI 0 "register_operand" "")
20711 (mult:SI (match_operand:SI 1 "register_operand" "")
20712 (match_operand:SI 2 "const_int_operand" "")))
20713 (clobber (reg:CC FLAGS_REG))])]
20714 "INTVAL (operands[2]) == 3
20715 || INTVAL (operands[2]) == 5
20716 || INTVAL (operands[2]) == 9"
20717 [(set (match_dup 0)
20718 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20720 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20724 [(set (match_operand:SI 0 "register_operand" "")
20725 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20726 (match_operand:SI 2 "const_int_operand" "")))
20727 (clobber (reg:CC FLAGS_REG))])]
20729 && (INTVAL (operands[2]) == 3
20730 || INTVAL (operands[2]) == 5
20731 || INTVAL (operands[2]) == 9)"
20732 [(set (match_dup 0) (match_dup 1))
20734 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20736 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20740 [(set (match_operand:DI 0 "register_operand" "")
20741 (mult:DI (match_operand:DI 1 "register_operand" "")
20742 (match_operand:DI 2 "const_int_operand" "")))
20743 (clobber (reg:CC FLAGS_REG))])]
20745 && (INTVAL (operands[2]) == 3
20746 || INTVAL (operands[2]) == 5
20747 || INTVAL (operands[2]) == 9)"
20748 [(set (match_dup 0)
20749 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20751 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20755 [(set (match_operand:DI 0 "register_operand" "")
20756 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20757 (match_operand:DI 2 "const_int_operand" "")))
20758 (clobber (reg:CC FLAGS_REG))])]
20761 && (INTVAL (operands[2]) == 3
20762 || INTVAL (operands[2]) == 5
20763 || INTVAL (operands[2]) == 9)"
20764 [(set (match_dup 0) (match_dup 1))
20766 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20768 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20770 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20771 ;; imul $32bit_imm, reg, reg is direct decoded.
20773 [(match_scratch:DI 3 "r")
20774 (parallel [(set (match_operand:DI 0 "register_operand" "")
20775 (mult:DI (match_operand:DI 1 "memory_operand" "")
20776 (match_operand:DI 2 "immediate_operand" "")))
20777 (clobber (reg:CC FLAGS_REG))])]
20778 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20779 && !satisfies_constraint_K (operands[2])"
20780 [(set (match_dup 3) (match_dup 1))
20781 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20782 (clobber (reg:CC FLAGS_REG))])]
20786 [(match_scratch:SI 3 "r")
20787 (parallel [(set (match_operand:SI 0 "register_operand" "")
20788 (mult:SI (match_operand:SI 1 "memory_operand" "")
20789 (match_operand:SI 2 "immediate_operand" "")))
20790 (clobber (reg:CC FLAGS_REG))])]
20791 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20792 && !satisfies_constraint_K (operands[2])"
20793 [(set (match_dup 3) (match_dup 1))
20794 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20795 (clobber (reg:CC FLAGS_REG))])]
20799 [(match_scratch:SI 3 "r")
20800 (parallel [(set (match_operand:DI 0 "register_operand" "")
20802 (mult:SI (match_operand:SI 1 "memory_operand" "")
20803 (match_operand:SI 2 "immediate_operand" ""))))
20804 (clobber (reg:CC FLAGS_REG))])]
20805 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20806 && !satisfies_constraint_K (operands[2])"
20807 [(set (match_dup 3) (match_dup 1))
20808 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20809 (clobber (reg:CC FLAGS_REG))])]
20812 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20813 ;; Convert it into imul reg, reg
20814 ;; It would be better to force assembler to encode instruction using long
20815 ;; immediate, but there is apparently no way to do so.
20817 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20818 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20819 (match_operand:DI 2 "const_int_operand" "")))
20820 (clobber (reg:CC FLAGS_REG))])
20821 (match_scratch:DI 3 "r")]
20822 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20823 && satisfies_constraint_K (operands[2])"
20824 [(set (match_dup 3) (match_dup 2))
20825 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20826 (clobber (reg:CC FLAGS_REG))])]
20828 if (!rtx_equal_p (operands[0], operands[1]))
20829 emit_move_insn (operands[0], operands[1]);
20833 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20834 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20835 (match_operand:SI 2 "const_int_operand" "")))
20836 (clobber (reg:CC FLAGS_REG))])
20837 (match_scratch:SI 3 "r")]
20838 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20839 && satisfies_constraint_K (operands[2])"
20840 [(set (match_dup 3) (match_dup 2))
20841 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20842 (clobber (reg:CC FLAGS_REG))])]
20844 if (!rtx_equal_p (operands[0], operands[1]))
20845 emit_move_insn (operands[0], operands[1]);
20849 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20850 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20851 (match_operand:HI 2 "immediate_operand" "")))
20852 (clobber (reg:CC FLAGS_REG))])
20853 (match_scratch:HI 3 "r")]
20854 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20855 [(set (match_dup 3) (match_dup 2))
20856 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20857 (clobber (reg:CC FLAGS_REG))])]
20859 if (!rtx_equal_p (operands[0], operands[1]))
20860 emit_move_insn (operands[0], operands[1]);
20863 ;; After splitting up read-modify operations, array accesses with memory
20864 ;; operands might end up in form:
20866 ;; movl 4(%esp), %edx
20868 ;; instead of pre-splitting:
20870 ;; addl 4(%esp), %eax
20872 ;; movl 4(%esp), %edx
20873 ;; leal (%edx,%eax,4), %eax
20876 [(parallel [(set (match_operand 0 "register_operand" "")
20877 (ashift (match_operand 1 "register_operand" "")
20878 (match_operand 2 "const_int_operand" "")))
20879 (clobber (reg:CC FLAGS_REG))])
20880 (set (match_operand 3 "register_operand")
20881 (match_operand 4 "x86_64_general_operand" ""))
20882 (parallel [(set (match_operand 5 "register_operand" "")
20883 (plus (match_operand 6 "register_operand" "")
20884 (match_operand 7 "register_operand" "")))
20885 (clobber (reg:CC FLAGS_REG))])]
20886 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20887 /* Validate MODE for lea. */
20888 && ((!TARGET_PARTIAL_REG_STALL
20889 && (GET_MODE (operands[0]) == QImode
20890 || GET_MODE (operands[0]) == HImode))
20891 || GET_MODE (operands[0]) == SImode
20892 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20893 /* We reorder load and the shift. */
20894 && !rtx_equal_p (operands[1], operands[3])
20895 && !reg_overlap_mentioned_p (operands[0], operands[4])
20896 /* Last PLUS must consist of operand 0 and 3. */
20897 && !rtx_equal_p (operands[0], operands[3])
20898 && (rtx_equal_p (operands[3], operands[6])
20899 || rtx_equal_p (operands[3], operands[7]))
20900 && (rtx_equal_p (operands[0], operands[6])
20901 || rtx_equal_p (operands[0], operands[7]))
20902 /* The intermediate operand 0 must die or be same as output. */
20903 && (rtx_equal_p (operands[0], operands[5])
20904 || peep2_reg_dead_p (3, operands[0]))"
20905 [(set (match_dup 3) (match_dup 4))
20906 (set (match_dup 0) (match_dup 1))]
20908 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20909 int scale = 1 << INTVAL (operands[2]);
20910 rtx index = gen_lowpart (Pmode, operands[1]);
20911 rtx base = gen_lowpart (Pmode, operands[3]);
20912 rtx dest = gen_lowpart (mode, operands[5]);
20914 operands[1] = gen_rtx_PLUS (Pmode, base,
20915 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20917 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20918 operands[0] = dest;
20921 ;; Call-value patterns last so that the wildcard operand does not
20922 ;; disrupt insn-recog's switch tables.
20924 (define_insn "*call_value_pop_0"
20925 [(set (match_operand 0 "" "")
20926 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20927 (match_operand:SI 2 "" "")))
20928 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20929 (match_operand:SI 3 "immediate_operand" "")))]
20932 if (SIBLING_CALL_P (insn))
20935 return "call\t%P1";
20937 [(set_attr "type" "callv")])
20939 (define_insn "*call_value_pop_1"
20940 [(set (match_operand 0 "" "")
20941 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20942 (match_operand:SI 2 "" "")))
20943 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20944 (match_operand:SI 3 "immediate_operand" "i")))]
20947 if (constant_call_address_operand (operands[1], Pmode))
20949 if (SIBLING_CALL_P (insn))
20952 return "call\t%P1";
20954 if (SIBLING_CALL_P (insn))
20957 return "call\t%A1";
20959 [(set_attr "type" "callv")])
20961 (define_insn "*call_value_0"
20962 [(set (match_operand 0 "" "")
20963 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20964 (match_operand:SI 2 "" "")))]
20967 if (SIBLING_CALL_P (insn))
20970 return "call\t%P1";
20972 [(set_attr "type" "callv")])
20974 (define_insn "*call_value_0_rex64"
20975 [(set (match_operand 0 "" "")
20976 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20977 (match_operand:DI 2 "const_int_operand" "")))]
20980 if (SIBLING_CALL_P (insn))
20983 return "call\t%P1";
20985 [(set_attr "type" "callv")])
20987 (define_insn "*call_value_1"
20988 [(set (match_operand 0 "" "")
20989 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20990 (match_operand:SI 2 "" "")))]
20991 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20993 if (constant_call_address_operand (operands[1], Pmode))
20994 return "call\t%P1";
20995 return "call\t%A1";
20997 [(set_attr "type" "callv")])
20999 (define_insn "*sibcall_value_1"
21000 [(set (match_operand 0 "" "")
21001 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21002 (match_operand:SI 2 "" "")))]
21003 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21005 if (constant_call_address_operand (operands[1], Pmode))
21009 [(set_attr "type" "callv")])
21011 (define_insn "*call_value_1_rex64"
21012 [(set (match_operand 0 "" "")
21013 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21014 (match_operand:DI 2 "" "")))]
21015 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21016 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21018 if (constant_call_address_operand (operands[1], Pmode))
21019 return "call\t%P1";
21020 return "call\t%A1";
21022 [(set_attr "type" "callv")])
21024 (define_insn "*call_value_1_rex64_large"
21025 [(set (match_operand 0 "" "")
21026 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21027 (match_operand:DI 2 "" "")))]
21028 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21030 [(set_attr "type" "callv")])
21032 (define_insn "*sibcall_value_1_rex64"
21033 [(set (match_operand 0 "" "")
21034 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21035 (match_operand:DI 2 "" "")))]
21036 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21038 [(set_attr "type" "callv")])
21040 (define_insn "*sibcall_value_1_rex64_v"
21041 [(set (match_operand 0 "" "")
21042 (call (mem:QI (reg:DI R11_REG))
21043 (match_operand:DI 1 "" "")))]
21044 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21046 [(set_attr "type" "callv")])
21048 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21049 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21050 ;; caught for use by garbage collectors and the like. Using an insn that
21051 ;; maps to SIGILL makes it more likely the program will rightfully die.
21052 ;; Keeping with tradition, "6" is in honor of #UD.
21053 (define_insn "trap"
21054 [(trap_if (const_int 1) (const_int 6))]
21056 { return ASM_SHORT "0x0b0f"; }
21057 [(set_attr "length" "2")])
21059 (define_expand "sse_prologue_save"
21060 [(parallel [(set (match_operand:BLK 0 "" "")
21061 (unspec:BLK [(reg:DI 21)
21068 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21069 (use (match_operand:DI 1 "register_operand" ""))
21070 (use (match_operand:DI 2 "immediate_operand" ""))
21071 (use (label_ref:DI (match_operand 3 "" "")))])]
21075 (define_insn "*sse_prologue_save_insn"
21076 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21077 (match_operand:DI 4 "const_int_operand" "n")))
21078 (unspec:BLK [(reg:DI 21)
21085 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21086 (use (match_operand:DI 1 "register_operand" "r"))
21087 (use (match_operand:DI 2 "const_int_operand" "i"))
21088 (use (label_ref:DI (match_operand 3 "" "X")))]
21090 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21091 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21095 operands[0] = gen_rtx_MEM (Pmode,
21096 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21097 output_asm_insn (\"jmp\\t%A1\", operands);
21098 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21100 operands[4] = adjust_address (operands[0], DImode, i*16);
21101 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21102 PUT_MODE (operands[4], TImode);
21103 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21104 output_asm_insn (\"rex\", operands);
21105 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21107 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21108 CODE_LABEL_NUMBER (operands[3]));
21112 [(set_attr "type" "other")
21113 (set_attr "length_immediate" "0")
21114 (set_attr "length_address" "0")
21115 (set_attr "length" "135")
21116 (set_attr "memory" "store")
21117 (set_attr "modrm" "0")
21118 (set_attr "mode" "DI")])
21120 (define_expand "prefetch"
21121 [(prefetch (match_operand 0 "address_operand" "")
21122 (match_operand:SI 1 "const_int_operand" "")
21123 (match_operand:SI 2 "const_int_operand" ""))]
21124 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21126 int rw = INTVAL (operands[1]);
21127 int locality = INTVAL (operands[2]);
21129 gcc_assert (rw == 0 || rw == 1);
21130 gcc_assert (locality >= 0 && locality <= 3);
21131 gcc_assert (GET_MODE (operands[0]) == Pmode
21132 || GET_MODE (operands[0]) == VOIDmode);
21134 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21135 supported by SSE counterpart or the SSE prefetch is not available
21136 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21138 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21139 operands[2] = GEN_INT (3);
21141 operands[1] = const0_rtx;
21144 (define_insn "*prefetch_sse"
21145 [(prefetch (match_operand:SI 0 "address_operand" "p")
21147 (match_operand:SI 1 "const_int_operand" ""))]
21148 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21150 static const char * const patterns[4] = {
21151 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21154 int locality = INTVAL (operands[1]);
21155 gcc_assert (locality >= 0 && locality <= 3);
21157 return patterns[locality];
21159 [(set_attr "type" "sse")
21160 (set_attr "memory" "none")])
21162 (define_insn "*prefetch_sse_rex"
21163 [(prefetch (match_operand:DI 0 "address_operand" "p")
21165 (match_operand:SI 1 "const_int_operand" ""))]
21166 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21168 static const char * const patterns[4] = {
21169 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21172 int locality = INTVAL (operands[1]);
21173 gcc_assert (locality >= 0 && locality <= 3);
21175 return patterns[locality];
21177 [(set_attr "type" "sse")
21178 (set_attr "memory" "none")])
21180 (define_insn "*prefetch_3dnow"
21181 [(prefetch (match_operand:SI 0 "address_operand" "p")
21182 (match_operand:SI 1 "const_int_operand" "n")
21184 "TARGET_3DNOW && !TARGET_64BIT"
21186 if (INTVAL (operands[1]) == 0)
21187 return "prefetch\t%a0";
21189 return "prefetchw\t%a0";
21191 [(set_attr "type" "mmx")
21192 (set_attr "memory" "none")])
21194 (define_insn "*prefetch_3dnow_rex"
21195 [(prefetch (match_operand:DI 0 "address_operand" "p")
21196 (match_operand:SI 1 "const_int_operand" "n")
21198 "TARGET_3DNOW && TARGET_64BIT"
21200 if (INTVAL (operands[1]) == 0)
21201 return "prefetch\t%a0";
21203 return "prefetchw\t%a0";
21205 [(set_attr "type" "mmx")
21206 (set_attr "memory" "none")])
21208 (define_expand "stack_protect_set"
21209 [(match_operand 0 "memory_operand" "")
21210 (match_operand 1 "memory_operand" "")]
21213 #ifdef TARGET_THREAD_SSP_OFFSET
21215 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21216 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21218 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21219 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21222 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21224 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21229 (define_insn "stack_protect_set_si"
21230 [(set (match_operand:SI 0 "memory_operand" "=m")
21231 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21232 (set (match_scratch:SI 2 "=&r") (const_int 0))
21233 (clobber (reg:CC FLAGS_REG))]
21235 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21236 [(set_attr "type" "multi")])
21238 (define_insn "stack_protect_set_di"
21239 [(set (match_operand:DI 0 "memory_operand" "=m")
21240 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21241 (set (match_scratch:DI 2 "=&r") (const_int 0))
21242 (clobber (reg:CC FLAGS_REG))]
21244 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21245 [(set_attr "type" "multi")])
21247 (define_insn "stack_tls_protect_set_si"
21248 [(set (match_operand:SI 0 "memory_operand" "=m")
21249 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21250 (set (match_scratch:SI 2 "=&r") (const_int 0))
21251 (clobber (reg:CC FLAGS_REG))]
21253 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21254 [(set_attr "type" "multi")])
21256 (define_insn "stack_tls_protect_set_di"
21257 [(set (match_operand:DI 0 "memory_operand" "=m")
21258 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21259 (set (match_scratch:DI 2 "=&r") (const_int 0))
21260 (clobber (reg:CC FLAGS_REG))]
21263 /* The kernel uses a different segment register for performance reasons; a
21264 system call would not have to trash the userspace segment register,
21265 which would be expensive */
21266 if (ix86_cmodel != CM_KERNEL)
21267 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21269 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21271 [(set_attr "type" "multi")])
21273 (define_expand "stack_protect_test"
21274 [(match_operand 0 "memory_operand" "")
21275 (match_operand 1 "memory_operand" "")
21276 (match_operand 2 "" "")]
21279 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21280 ix86_compare_op0 = operands[0];
21281 ix86_compare_op1 = operands[1];
21282 ix86_compare_emitted = flags;
21284 #ifdef TARGET_THREAD_SSP_OFFSET
21286 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21287 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21289 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21290 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21293 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21295 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21297 emit_jump_insn (gen_beq (operands[2]));
21301 (define_insn "stack_protect_test_si"
21302 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21303 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21304 (match_operand:SI 2 "memory_operand" "m")]
21306 (clobber (match_scratch:SI 3 "=&r"))]
21308 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21309 [(set_attr "type" "multi")])
21311 (define_insn "stack_protect_test_di"
21312 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21313 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21314 (match_operand:DI 2 "memory_operand" "m")]
21316 (clobber (match_scratch:DI 3 "=&r"))]
21318 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21319 [(set_attr "type" "multi")])
21321 (define_insn "stack_tls_protect_test_si"
21322 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21323 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21324 (match_operand:SI 2 "const_int_operand" "i")]
21325 UNSPEC_SP_TLS_TEST))
21326 (clobber (match_scratch:SI 3 "=r"))]
21328 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21329 [(set_attr "type" "multi")])
21331 (define_insn "stack_tls_protect_test_di"
21332 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21333 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21334 (match_operand:DI 2 "const_int_operand" "i")]
21335 UNSPEC_SP_TLS_TEST))
21336 (clobber (match_scratch:DI 3 "=r"))]
21339 /* The kernel uses a different segment register for performance reasons; a
21340 system call would not have to trash the userspace segment register,
21341 which would be expensive */
21342 if (ix86_cmodel != CM_KERNEL)
21343 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21345 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21347 [(set_attr "type" "multi")])
21349 (define_mode_iterator CRC32MODE [QI HI SI])
21350 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21351 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21353 (define_insn "sse4_2_crc32<mode>"
21354 [(set (match_operand:SI 0 "register_operand" "=r")
21356 [(match_operand:SI 1 "register_operand" "0")
21357 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21360 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21361 [(set_attr "type" "sselog1")
21362 (set_attr "prefix_rep" "1")
21363 (set_attr "prefix_extra" "1")
21364 (set_attr "mode" "SI")])
21366 (define_insn "sse4_2_crc32di"
21367 [(set (match_operand:DI 0 "register_operand" "=r")
21369 [(match_operand:DI 1 "register_operand" "0")
21370 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21372 "TARGET_SSE4_2 && TARGET_64BIT"
21373 "crc32q\t{%2, %0|%0, %2}"
21374 [(set_attr "type" "sselog1")
21375 (set_attr "prefix_rep" "1")
21376 (set_attr "prefix_extra" "1")
21377 (set_attr "mode" "DI")])
21381 (include "sync.md")