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 || TARGET_GENERIC) && !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 || TARGET_GENERIC) && !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
4779 && TARGET_USE_VECTOR_CONVERTS && !optimize_size && TARGET_SSE_MATH
4780 && SSE_FLOAT_MODE_P (DFmode))
4781 operands[1] = force_reg (SImode, operands[1]);
4782 else if (GET_MODE (operands[0]) == SFmode
4783 && !optimize_size && TARGET_USE_VECTOR_CONVERTS && TARGET_SSE_MATH
4784 && SSE_FLOAT_MODE_P (SFmode))
4786 /* When !flag_trapping_math, we handle SImode->SFmode vector
4787 conversions same way as SImode->DFmode.
4789 For flat_trapping_math we can't safely use vector conversion without
4790 clearing upper half, otherwise precision exception might occur.
4791 However we can still generate the common sequence converting value
4792 from general register to XMM register as:
4798 because we know that movd clears the upper half.
4800 Sadly in this case we can't rely on reload moving the value to XMM
4801 register, since we need to know if upper half is OK, so we need
4802 to do reloading by hand. We force operand to memory unless target
4803 supports inter unit moves. */
4804 if (!flag_trapping_math)
4805 operands[1] = force_reg (SImode, operands[1]);
4806 else if (!MEM_P (operands[1]))
4808 rtx tmp = assign_386_stack_local (SImode, SLOT_VIRTUAL);
4809 emit_move_insn (tmp, operands[1]);
4813 /* Offload operand of cvtsi2ss and cvtsi2sd into memory for
4814 !TARGET_INTER_UNIT_CONVERSIONS
4815 It is neccesary for the patterns to not accept nonemmory operands
4816 as we would optimize out later. */
4817 else if (!TARGET_INTER_UNIT_CONVERSIONS
4818 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
4820 && !MEM_P (operands[1]))
4822 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), SLOT_VIRTUAL);
4823 emit_move_insn (tmp, operands[1]);
4828 (define_insn "*floatsisf2_mixed_vector"
4829 [(set (match_operand:SF 0 "register_operand" "=x,f,?f")
4830 (float:SF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4831 "TARGET_MIX_SSE_I387 && !flag_trapping_math
4832 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4834 cvtdq2ps\t{%1, %0|%0, %1}
4837 [(set_attr "type" "sseicvt,fmov,multi")
4838 (set_attr "mode" "SF")
4839 (set_attr "unit" "*,i387,*")
4840 (set_attr "athlon_decode" "double,*,*")
4841 (set_attr "amdfam10_decode" "double,*,*")
4842 (set_attr "fp_int_src" "false,true,true")])
4844 (define_insn "*floatsisf2_mixed"
4845 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4846 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4847 "TARGET_MIX_SSE_I387
4848 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4853 cvtsi2ss\t{%1, %0|%0, %1}
4854 cvtsi2ss\t{%1, %0|%0, %1}"
4855 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4856 (set_attr "mode" "SF")
4857 (set_attr "unit" "*,i387,*,*")
4858 (set_attr "athlon_decode" "*,*,vector,double")
4859 (set_attr "amdfam10_decode" "*,*,vector,double")
4860 (set_attr "fp_int_src" "true")])
4862 (define_insn "*floatsisf2_mixed_memory"
4863 [(set (match_operand:SF 0 "register_operand" "=f,x")
4864 (float:SF (match_operand:SI 1 "memory_operand" "m,m")))]
4865 "TARGET_MIX_SSE_I387
4866 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4869 cvtsi2ss\t{%1, %0|%0, %1}"
4870 [(set_attr "type" "fmov,sseicvt")
4871 (set_attr "mode" "SF")
4872 (set_attr "athlon_decode" "*,double")
4873 (set_attr "amdfam10_decode" "*,double")
4874 (set_attr "fp_int_src" "true")])
4876 (define_insn "*floatsisf2_sse_vector_nointernunit"
4877 [(set (match_operand:SF 0 "register_operand" "=x")
4878 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4879 "TARGET_SSE_MATH && flag_trapping_math
4880 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4881 && !TARGET_INTER_UNIT_MOVES"
4883 [(set_attr "type" "multi")])
4885 (define_insn "*floatsisf2_sse_vector_internunit"
4886 [(set (match_operand:SF 0 "register_operand" "=x,x")
4887 (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm,x")))]
4888 "TARGET_SSE_MATH && flag_trapping_math
4889 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4890 && TARGET_INTER_UNIT_MOVES"
4892 [(set_attr "type" "multi")])
4895 [(set (match_operand:SF 0 "register_operand" "")
4896 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4898 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4899 && (TARGET_INTER_UNIT_MOVES || MEM_P (operands[1]))
4900 && !SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4902 (float:V4SF (match_dup 2)))]
4904 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4905 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4906 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
4910 [(set (match_operand:SF 0 "register_operand" "")
4911 (float:SF (match_operand:SI 1 "register_operand" "")))]
4913 && TARGET_USE_VECTOR_CONVERTS && reload_completed
4914 && SSE_REG_P (operands[1]) && SSE_REG_P (operands[0])"
4915 [(set (match_dup 2) (vec_duplicate:V4SI (match_dup 1)))
4917 (float:V4SF (match_dup 2)))]
4919 operands[2] = simplify_gen_subreg (V4SImode, operands[0], SFmode, 0);
4920 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4923 (define_insn "*floatsisf2_sse_vector"
4924 [(set (match_operand:SF 0 "register_operand" "=x")
4925 (float:SF (match_operand:SI 1 "register_operand" "x")))]
4926 "TARGET_SSE_MATH && !flag_trapping_math
4927 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4928 && !TARGET_INTER_UNIT_MOVES"
4929 "cvtdq2ps\t{%1, %0|%0, %1}"
4930 [(set_attr "type" "sseicvt")
4931 (set_attr "mode" "SF")
4932 (set_attr "athlon_decode" "double")
4933 (set_attr "amdfam10_decode" "double")
4934 (set_attr "fp_int_src" "true")])
4936 (define_insn "*floatsisf2_sse"
4937 [(set (match_operand:SF 0 "register_operand" "=x,x")
4938 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4940 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
4942 "cvtsi2ss\t{%1, %0|%0, %1}"
4943 [(set_attr "type" "sseicvt")
4944 (set_attr "mode" "SF")
4945 (set_attr "athlon_decode" "vector,double")
4946 (set_attr "amdfam10_decode" "vector,double")
4947 (set_attr "fp_int_src" "true")])
4949 (define_insn "*floatsisf2_sse_memory"
4950 [(set (match_operand:SF 0 "register_operand" "=x")
4951 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
4953 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
4954 "cvtsi2ss\t{%1, %0|%0, %1}"
4955 [(set_attr "type" "sseicvt")
4956 (set_attr "mode" "SF")
4957 (set_attr "athlon_decode" "double")
4958 (set_attr "amdfam10_decode" "double")
4959 (set_attr "fp_int_src" "true")])
4961 (define_insn "*floatsidf2_mixed_vector"
4962 [(set (match_operand:DF 0 "register_operand" "=x,f,f")
4963 (float:DF (match_operand:SI 1 "nonimmediate_operand" "x,m,r")))]
4964 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4965 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4967 cvtdq2pd\t{%1, %0|%0, %1}
4970 [(set_attr "type" "sseicvt,fmov,multi")
4971 (set_attr "mode" "V2DF,DF,DF")
4972 (set_attr "unit" "*,*,i387")
4973 (set_attr "athlon_decode" "double,*,*")
4974 (set_attr "amdfam10_decode" "double,*,*")
4975 (set_attr "fp_int_src" "false,true,true")])
4977 (define_insn "*floatsidf2_mixed"
4978 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x,!x")
4979 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m,x")))]
4980 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4981 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
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" "fmov,multi,sseicvt,sseicvt,sseicvt")
4990 (set_attr "mode" "DF,DF,DF,DF,V2DF")
4991 (set_attr "unit" "*,i387,*,*,*")
4992 (set_attr "athlon_decode" "*,*,double,direct,double")
4993 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4994 (set_attr "fp_int_src" "true,true,true,true,false")])
4996 (define_insn "*floatsidf2_mixed_memory"
4997 [(set (match_operand:DF 0 "register_operand" "=f,x")
4998 (float:DF (match_operand:SI 1 "memory_operand" "m,m")))]
4999 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5000 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5003 cvtsi2sd\t{%1, %0|%0, %1}"
5004 [(set_attr "type" "fmov,sseicvt")
5005 (set_attr "mode" "DF")
5006 (set_attr "athlon_decode" "*,direct")
5007 (set_attr "amdfam10_decode" "*,double")
5008 (set_attr "fp_int_src" "true")])
5010 (define_insn "*floatsidf2_sse_vector"
5011 [(set (match_operand:DF 0 "register_operand" "=x")
5012 (float:DF (match_operand:SI 1 "register_operand" "x")))]
5013 "TARGET_SSE2 && TARGET_SSE_MATH
5014 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5015 "cvtdq2pd\t{%1, %0|%0, %1}"
5016 [(set_attr "type" "sseicvt")
5017 (set_attr "mode" "V2DF")
5018 (set_attr "athlon_decode" "double")
5019 (set_attr "amdfam10_decode" "double")
5020 (set_attr "fp_int_src" "true")])
5023 [(set (match_operand:DF 0 "register_operand" "")
5024 (float:DF (match_operand:SI 1 "memory_operand" "")))]
5025 "TARGET_USE_VECTOR_CONVERTS && reload_completed
5026 && SSE_REG_P (operands[0])"
5031 (parallel [(const_int 0) (const_int 1)]))))]
5033 operands[2] = simplify_gen_subreg (V4SImode, operands[0], DFmode, 0);
5034 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
5035 emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), operands[1]));
5038 (define_insn "*floatsidf2_sse"
5039 [(set (match_operand:DF 0 "register_operand" "=x,x,!x")
5040 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m,x")))]
5041 "TARGET_SSE2 && TARGET_SSE_MATH
5042 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5045 cvtsi2sd\t{%1, %0|%0, %1}
5046 cvtsi2sd\t{%1, %0|%0, %1}
5047 cvtdq2pd\t{%1, %0|%0, %1}"
5048 [(set_attr "type" "sseicvt")
5049 (set_attr "mode" "DF,DF,V2DF")
5050 (set_attr "athlon_decode" "double,direct,double")
5051 (set_attr "amdfam10_decode" "vector,double,double")
5052 (set_attr "fp_int_src" "true")])
5054 (define_insn "*floatsidf2_memory"
5055 [(set (match_operand:DF 0 "register_operand" "=x")
5056 (float:DF (match_operand:SI 1 "memory_operand" "x")))]
5057 "TARGET_SSE2 && TARGET_SSE_MATH
5058 && ((!TARGET_USE_VECTOR_CONVERTS && TARGET_INTER_UNIT_CONVERSIONS)
5060 "cvtsi2sd\t{%1, %0|%0, %1}"
5061 [(set_attr "type" "sseicvt")
5062 (set_attr "mode" "DF")
5063 (set_attr "athlon_decode" "direct")
5064 (set_attr "amdfam10_decode" "double")
5065 (set_attr "fp_int_src" "true")])
5067 (define_insn "*floatsi<mode>2_i387"
5068 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5070 (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
5072 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5076 [(set_attr "type" "fmov,multi")
5077 (set_attr "mode" "<MODE>")
5078 (set_attr "unit" "*,i387")
5079 (set_attr "fp_int_src" "true")])
5081 (define_expand "floatdisf2"
5082 [(set (match_operand:SF 0 "register_operand" "")
5083 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
5084 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
5086 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5087 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (SFmode)
5089 && !MEM_P (operands[1]))
5091 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), SLOT_VIRTUAL);
5092 emit_move_insn (tmp, operands[1]);
5097 (define_insn "*floatdisf2_mixed"
5098 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
5099 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5100 "TARGET_64BIT && TARGET_MIX_SSE_I387
5101 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5105 cvtsi2ss{q}\t{%1, %0|%0, %1}
5106 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5107 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5108 (set_attr "mode" "SF")
5109 (set_attr "unit" "*,i387,*,*")
5110 (set_attr "athlon_decode" "*,*,vector,double")
5111 (set_attr "amdfam10_decode" "*,*,vector,double")
5112 (set_attr "fp_int_src" "true")])
5114 (define_insn "*floatdisf2_mixed"
5115 [(set (match_operand:SF 0 "register_operand" "=f,x")
5116 (float:SF (match_operand:DI 1 "memory_operand" "m,m")))]
5117 "TARGET_64BIT && TARGET_MIX_SSE_I387
5118 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5121 cvtsi2ss{q}\t{%1, %0|%0, %1}"
5122 [(set_attr "type" "fmov,sseicvt")
5123 (set_attr "mode" "SF")
5124 (set_attr "athlon_decode" "*,double")
5125 (set_attr "amdfam10_decode" "*,double")
5126 (set_attr "fp_int_src" "true")])
5128 (define_insn "*floatdisf2_sse"
5129 [(set (match_operand:SF 0 "register_operand" "=x,x")
5130 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5131 "TARGET_64BIT && TARGET_SSE_MATH
5132 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5133 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5134 [(set_attr "type" "sseicvt")
5135 (set_attr "mode" "SF")
5136 (set_attr "athlon_decode" "vector,double")
5137 (set_attr "amdfam10_decode" "vector,double")
5138 (set_attr "fp_int_src" "true")])
5140 (define_insn "*floatdisf2_memory"
5141 [(set (match_operand:SF 0 "register_operand" "=x")
5142 (float:SF (match_operand:DI 1 "memory_operand" "m")))]
5143 "TARGET_64BIT && TARGET_SSE_MATH
5144 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5145 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
5146 [(set_attr "type" "sseicvt")
5147 (set_attr "mode" "SF")
5148 (set_attr "athlon_decode" "double")
5149 (set_attr "amdfam10_decode" "double")
5150 (set_attr "fp_int_src" "true")])
5152 (define_expand "floatdidf2"
5153 [(set (match_operand:DF 0 "register_operand" "")
5154 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5155 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5157 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
5159 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
5162 if (!TARGET_INTER_UNIT_CONVERSIONS && TARGET_64BIT
5163 && TARGET_SSE_MATH && SSE_FLOAT_MODE_P (DFmode)
5165 && !MEM_P (operands[1]))
5167 rtx tmp = assign_386_stack_local (GET_MODE (operands[1]), SLOT_VIRTUAL);
5168 emit_move_insn (tmp, operands[1]);
5173 (define_insn "*floatdidf2_mixed"
5174 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
5175 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
5176 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5177 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5181 cvtsi2sd{q}\t{%1, %0|%0, %1}
5182 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5183 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5184 (set_attr "mode" "DF")
5185 (set_attr "unit" "*,i387,*,*")
5186 (set_attr "athlon_decode" "*,*,double,direct")
5187 (set_attr "amdfam10_decode" "*,*,vector,double")
5188 (set_attr "fp_int_src" "true")])
5190 (define_insn "*floatdidf2_mixed_memory"
5191 [(set (match_operand:DF 0 "register_operand" "=f,x")
5192 (float:DF (match_operand:DI 1 "memory_operand" "m,m")))]
5193 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387
5194 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5197 cvtsi2sd{q}\t{%1, %0|%0, %1}"
5198 [(set_attr "type" "fmov,sseicvt")
5199 (set_attr "mode" "DF")
5200 (set_attr "athlon_decode" "*,direct")
5201 (set_attr "amdfam10_decode" "*,double")
5202 (set_attr "fp_int_src" "true")])
5204 (define_insn "*floatdidf2_sse"
5205 [(set (match_operand:DF 0 "register_operand" "=x,x")
5206 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
5207 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5208 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5209 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5210 [(set_attr "type" "sseicvt")
5211 (set_attr "mode" "DF")
5212 (set_attr "athlon_decode" "double,direct")
5213 (set_attr "amdfam10_decode" "vector,double")
5214 (set_attr "fp_int_src" "true")])
5216 (define_insn "*floatdidf2_sse_memory"
5217 [(set (match_operand:DF 0 "register_operand" "=x")
5218 (float:DF (match_operand:DI 1 "memory_operand" "m")))]
5219 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5220 && !TARGET_INTER_UNIT_CONVERSIONS && !optimize_size"
5221 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5222 [(set_attr "type" "sseicvt")
5223 (set_attr "mode" "DF")
5224 (set_attr "athlon_decode" "direct")
5225 (set_attr "amdfam10_decode" "double")
5226 (set_attr "fp_int_src" "true")])
5228 (define_insn "*floatdi<mode>2_i387"
5229 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
5231 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
5233 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))"
5237 [(set_attr "type" "fmov,multi")
5238 (set_attr "mode" "<MODE>")
5239 (set_attr "unit" "*,i387")
5240 (set_attr "fp_int_src" "true")])
5242 (define_insn "float<mode>xf2"
5243 [(set (match_operand:XF 0 "register_operand" "=f,f")
5244 (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
5249 [(set_attr "type" "fmov,multi")
5250 (set_attr "mode" "XF")
5251 (set_attr "unit" "*,i387")
5252 (set_attr "fp_int_src" "true")])
5254 ;; %%% Kill these when reload knows how to do it.
5256 [(set (match_operand 0 "fp_register_operand" "")
5257 (float (match_operand 1 "register_operand" "")))]
5259 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
5262 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5263 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5264 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5265 ix86_free_from_memory (GET_MODE (operands[1]));
5269 (define_expand "floatunssisf2"
5270 [(use (match_operand:SF 0 "register_operand" ""))
5271 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5274 if (TARGET_SSE_MATH && TARGET_SSE2)
5275 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5277 x86_emit_floatuns (operands);
5281 (define_expand "floatunssidf2"
5282 [(use (match_operand:DF 0 "register_operand" ""))
5283 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5284 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5285 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5287 (define_expand "floatunsdisf2"
5288 [(use (match_operand:SF 0 "register_operand" ""))
5289 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5290 "TARGET_64BIT && TARGET_SSE_MATH"
5291 "x86_emit_floatuns (operands); DONE;")
5293 (define_expand "floatunsdidf2"
5294 [(use (match_operand:DF 0 "register_operand" ""))
5295 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5296 "TARGET_SSE_MATH && TARGET_SSE2
5297 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5300 x86_emit_floatuns (operands);
5302 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5308 ;; %%% splits for addditi3
5310 (define_expand "addti3"
5311 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5312 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5313 (match_operand:TI 2 "x86_64_general_operand" "")))
5314 (clobber (reg:CC FLAGS_REG))]
5316 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5318 (define_insn "*addti3_1"
5319 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5320 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5321 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5322 (clobber (reg:CC FLAGS_REG))]
5323 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5327 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5328 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5329 (match_operand:TI 2 "x86_64_general_operand" "")))
5330 (clobber (reg:CC FLAGS_REG))]
5331 "TARGET_64BIT && reload_completed"
5332 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5334 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5335 (parallel [(set (match_dup 3)
5336 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5339 (clobber (reg:CC FLAGS_REG))])]
5340 "split_ti (operands+0, 1, operands+0, operands+3);
5341 split_ti (operands+1, 1, operands+1, operands+4);
5342 split_ti (operands+2, 1, operands+2, operands+5);")
5344 ;; %%% splits for addsidi3
5345 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5346 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5347 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5349 (define_expand "adddi3"
5350 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5351 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5352 (match_operand:DI 2 "x86_64_general_operand" "")))
5353 (clobber (reg:CC FLAGS_REG))]
5355 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5357 (define_insn "*adddi3_1"
5358 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5359 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5360 (match_operand:DI 2 "general_operand" "roiF,riF")))
5361 (clobber (reg:CC FLAGS_REG))]
5362 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5366 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5367 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5368 (match_operand:DI 2 "general_operand" "")))
5369 (clobber (reg:CC FLAGS_REG))]
5370 "!TARGET_64BIT && reload_completed"
5371 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5373 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5374 (parallel [(set (match_dup 3)
5375 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5378 (clobber (reg:CC FLAGS_REG))])]
5379 "split_di (operands+0, 1, operands+0, operands+3);
5380 split_di (operands+1, 1, operands+1, operands+4);
5381 split_di (operands+2, 1, operands+2, operands+5);")
5383 (define_insn "adddi3_carry_rex64"
5384 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5385 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5386 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5387 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5388 (clobber (reg:CC FLAGS_REG))]
5389 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5390 "adc{q}\t{%2, %0|%0, %2}"
5391 [(set_attr "type" "alu")
5392 (set_attr "pent_pair" "pu")
5393 (set_attr "mode" "DI")])
5395 (define_insn "*adddi3_cc_rex64"
5396 [(set (reg:CC FLAGS_REG)
5397 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5398 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5400 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5401 (plus:DI (match_dup 1) (match_dup 2)))]
5402 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5403 "add{q}\t{%2, %0|%0, %2}"
5404 [(set_attr "type" "alu")
5405 (set_attr "mode" "DI")])
5407 (define_insn "*<addsub><mode>3_cc_overflow"
5408 [(set (reg:CCC FLAGS_REG)
5411 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5412 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5414 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5415 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5416 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5417 "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5418 [(set_attr "type" "alu")
5419 (set_attr "mode" "<MODE>")])
5421 (define_insn "*add<mode>3_cconly_overflow"
5422 [(set (reg:CCC FLAGS_REG)
5424 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5425 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5427 (clobber (match_scratch:SWI 0 "=<r>"))]
5428 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5429 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5430 [(set_attr "type" "alu")
5431 (set_attr "mode" "<MODE>")])
5433 (define_insn "*sub<mode>3_cconly_overflow"
5434 [(set (reg:CCC FLAGS_REG)
5436 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5437 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5440 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5441 [(set_attr "type" "icmp")
5442 (set_attr "mode" "<MODE>")])
5444 (define_insn "*<addsub>si3_zext_cc_overflow"
5445 [(set (reg:CCC FLAGS_REG)
5447 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5448 (match_operand:SI 2 "general_operand" "g"))
5450 (set (match_operand:DI 0 "register_operand" "=r")
5451 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5452 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5453 "<addsub>{l}\t{%2, %k0|%k0, %2}"
5454 [(set_attr "type" "alu")
5455 (set_attr "mode" "SI")])
5457 (define_insn "addqi3_carry"
5458 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5459 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5460 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5461 (match_operand:QI 2 "general_operand" "qi,qm")))
5462 (clobber (reg:CC FLAGS_REG))]
5463 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5464 "adc{b}\t{%2, %0|%0, %2}"
5465 [(set_attr "type" "alu")
5466 (set_attr "pent_pair" "pu")
5467 (set_attr "mode" "QI")])
5469 (define_insn "addhi3_carry"
5470 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5471 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5472 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5473 (match_operand:HI 2 "general_operand" "ri,rm")))
5474 (clobber (reg:CC FLAGS_REG))]
5475 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5476 "adc{w}\t{%2, %0|%0, %2}"
5477 [(set_attr "type" "alu")
5478 (set_attr "pent_pair" "pu")
5479 (set_attr "mode" "HI")])
5481 (define_insn "addsi3_carry"
5482 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5483 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5484 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5485 (match_operand:SI 2 "general_operand" "ri,rm")))
5486 (clobber (reg:CC FLAGS_REG))]
5487 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5488 "adc{l}\t{%2, %0|%0, %2}"
5489 [(set_attr "type" "alu")
5490 (set_attr "pent_pair" "pu")
5491 (set_attr "mode" "SI")])
5493 (define_insn "*addsi3_carry_zext"
5494 [(set (match_operand:DI 0 "register_operand" "=r")
5496 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5497 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5498 (match_operand:SI 2 "general_operand" "g"))))
5499 (clobber (reg:CC FLAGS_REG))]
5500 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5501 "adc{l}\t{%2, %k0|%k0, %2}"
5502 [(set_attr "type" "alu")
5503 (set_attr "pent_pair" "pu")
5504 (set_attr "mode" "SI")])
5506 (define_insn "*addsi3_cc"
5507 [(set (reg:CC FLAGS_REG)
5508 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5509 (match_operand:SI 2 "general_operand" "ri,rm")]
5511 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5512 (plus:SI (match_dup 1) (match_dup 2)))]
5513 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5514 "add{l}\t{%2, %0|%0, %2}"
5515 [(set_attr "type" "alu")
5516 (set_attr "mode" "SI")])
5518 (define_insn "addqi3_cc"
5519 [(set (reg:CC FLAGS_REG)
5520 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5521 (match_operand:QI 2 "general_operand" "qi,qm")]
5523 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5524 (plus:QI (match_dup 1) (match_dup 2)))]
5525 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5526 "add{b}\t{%2, %0|%0, %2}"
5527 [(set_attr "type" "alu")
5528 (set_attr "mode" "QI")])
5530 (define_expand "addsi3"
5531 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5532 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5533 (match_operand:SI 2 "general_operand" "")))
5534 (clobber (reg:CC FLAGS_REG))])]
5536 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5538 (define_insn "*lea_1"
5539 [(set (match_operand:SI 0 "register_operand" "=r")
5540 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5542 "lea{l}\t{%a1, %0|%0, %a1}"
5543 [(set_attr "type" "lea")
5544 (set_attr "mode" "SI")])
5546 (define_insn "*lea_1_rex64"
5547 [(set (match_operand:SI 0 "register_operand" "=r")
5548 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5550 "lea{l}\t{%a1, %0|%0, %a1}"
5551 [(set_attr "type" "lea")
5552 (set_attr "mode" "SI")])
5554 (define_insn "*lea_1_zext"
5555 [(set (match_operand:DI 0 "register_operand" "=r")
5557 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5559 "lea{l}\t{%a1, %k0|%k0, %a1}"
5560 [(set_attr "type" "lea")
5561 (set_attr "mode" "SI")])
5563 (define_insn "*lea_2_rex64"
5564 [(set (match_operand:DI 0 "register_operand" "=r")
5565 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5567 "lea{q}\t{%a1, %0|%0, %a1}"
5568 [(set_attr "type" "lea")
5569 (set_attr "mode" "DI")])
5571 ;; The lea patterns for non-Pmodes needs to be matched by several
5572 ;; insns converted to real lea by splitters.
5574 (define_insn_and_split "*lea_general_1"
5575 [(set (match_operand 0 "register_operand" "=r")
5576 (plus (plus (match_operand 1 "index_register_operand" "l")
5577 (match_operand 2 "register_operand" "r"))
5578 (match_operand 3 "immediate_operand" "i")))]
5579 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5580 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5581 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5582 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5583 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5584 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5585 || GET_MODE (operands[3]) == VOIDmode)"
5587 "&& reload_completed"
5591 operands[0] = gen_lowpart (SImode, operands[0]);
5592 operands[1] = gen_lowpart (Pmode, operands[1]);
5593 operands[2] = gen_lowpart (Pmode, operands[2]);
5594 operands[3] = gen_lowpart (Pmode, operands[3]);
5595 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5597 if (Pmode != SImode)
5598 pat = gen_rtx_SUBREG (SImode, pat, 0);
5599 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5602 [(set_attr "type" "lea")
5603 (set_attr "mode" "SI")])
5605 (define_insn_and_split "*lea_general_1_zext"
5606 [(set (match_operand:DI 0 "register_operand" "=r")
5608 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5609 (match_operand:SI 2 "register_operand" "r"))
5610 (match_operand:SI 3 "immediate_operand" "i"))))]
5613 "&& reload_completed"
5615 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5617 (match_dup 3)) 0)))]
5619 operands[1] = gen_lowpart (Pmode, operands[1]);
5620 operands[2] = gen_lowpart (Pmode, operands[2]);
5621 operands[3] = gen_lowpart (Pmode, operands[3]);
5623 [(set_attr "type" "lea")
5624 (set_attr "mode" "SI")])
5626 (define_insn_and_split "*lea_general_2"
5627 [(set (match_operand 0 "register_operand" "=r")
5628 (plus (mult (match_operand 1 "index_register_operand" "l")
5629 (match_operand 2 "const248_operand" "i"))
5630 (match_operand 3 "nonmemory_operand" "ri")))]
5631 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5632 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5633 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5634 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5635 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5636 || GET_MODE (operands[3]) == VOIDmode)"
5638 "&& reload_completed"
5642 operands[0] = gen_lowpart (SImode, operands[0]);
5643 operands[1] = gen_lowpart (Pmode, operands[1]);
5644 operands[3] = gen_lowpart (Pmode, operands[3]);
5645 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5647 if (Pmode != SImode)
5648 pat = gen_rtx_SUBREG (SImode, pat, 0);
5649 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5652 [(set_attr "type" "lea")
5653 (set_attr "mode" "SI")])
5655 (define_insn_and_split "*lea_general_2_zext"
5656 [(set (match_operand:DI 0 "register_operand" "=r")
5658 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5659 (match_operand:SI 2 "const248_operand" "n"))
5660 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5663 "&& reload_completed"
5665 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5667 (match_dup 3)) 0)))]
5669 operands[1] = gen_lowpart (Pmode, operands[1]);
5670 operands[3] = gen_lowpart (Pmode, operands[3]);
5672 [(set_attr "type" "lea")
5673 (set_attr "mode" "SI")])
5675 (define_insn_and_split "*lea_general_3"
5676 [(set (match_operand 0 "register_operand" "=r")
5677 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5678 (match_operand 2 "const248_operand" "i"))
5679 (match_operand 3 "register_operand" "r"))
5680 (match_operand 4 "immediate_operand" "i")))]
5681 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5682 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5683 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5684 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5685 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5687 "&& reload_completed"
5691 operands[0] = gen_lowpart (SImode, operands[0]);
5692 operands[1] = gen_lowpart (Pmode, operands[1]);
5693 operands[3] = gen_lowpart (Pmode, operands[3]);
5694 operands[4] = gen_lowpart (Pmode, operands[4]);
5695 pat = gen_rtx_PLUS (Pmode,
5696 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5700 if (Pmode != SImode)
5701 pat = gen_rtx_SUBREG (SImode, pat, 0);
5702 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5705 [(set_attr "type" "lea")
5706 (set_attr "mode" "SI")])
5708 (define_insn_and_split "*lea_general_3_zext"
5709 [(set (match_operand:DI 0 "register_operand" "=r")
5711 (plus:SI (plus:SI (mult:SI
5712 (match_operand:SI 1 "index_register_operand" "l")
5713 (match_operand:SI 2 "const248_operand" "n"))
5714 (match_operand:SI 3 "register_operand" "r"))
5715 (match_operand:SI 4 "immediate_operand" "i"))))]
5718 "&& reload_completed"
5720 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5723 (match_dup 4)) 0)))]
5725 operands[1] = gen_lowpart (Pmode, operands[1]);
5726 operands[3] = gen_lowpart (Pmode, operands[3]);
5727 operands[4] = gen_lowpart (Pmode, operands[4]);
5729 [(set_attr "type" "lea")
5730 (set_attr "mode" "SI")])
5732 (define_insn "*adddi_1_rex64"
5733 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5734 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5735 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5736 (clobber (reg:CC FLAGS_REG))]
5737 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5739 switch (get_attr_type (insn))
5742 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5743 return "lea{q}\t{%a2, %0|%0, %a2}";
5746 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5747 if (operands[2] == const1_rtx)
5748 return "inc{q}\t%0";
5751 gcc_assert (operands[2] == constm1_rtx);
5752 return "dec{q}\t%0";
5756 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5758 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5759 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5760 if (CONST_INT_P (operands[2])
5761 /* Avoid overflows. */
5762 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5763 && (INTVAL (operands[2]) == 128
5764 || (INTVAL (operands[2]) < 0
5765 && INTVAL (operands[2]) != -128)))
5767 operands[2] = GEN_INT (-INTVAL (operands[2]));
5768 return "sub{q}\t{%2, %0|%0, %2}";
5770 return "add{q}\t{%2, %0|%0, %2}";
5774 (cond [(eq_attr "alternative" "2")
5775 (const_string "lea")
5776 ; Current assemblers are broken and do not allow @GOTOFF in
5777 ; ought but a memory context.
5778 (match_operand:DI 2 "pic_symbolic_operand" "")
5779 (const_string "lea")
5780 (match_operand:DI 2 "incdec_operand" "")
5781 (const_string "incdec")
5783 (const_string "alu")))
5784 (set_attr "mode" "DI")])
5786 ;; Convert lea to the lea pattern to avoid flags dependency.
5788 [(set (match_operand:DI 0 "register_operand" "")
5789 (plus:DI (match_operand:DI 1 "register_operand" "")
5790 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5791 (clobber (reg:CC FLAGS_REG))]
5792 "TARGET_64BIT && reload_completed
5793 && true_regnum (operands[0]) != true_regnum (operands[1])"
5795 (plus:DI (match_dup 1)
5799 (define_insn "*adddi_2_rex64"
5800 [(set (reg FLAGS_REG)
5802 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5803 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5805 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5806 (plus:DI (match_dup 1) (match_dup 2)))]
5807 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5808 && ix86_binary_operator_ok (PLUS, DImode, operands)
5809 /* Current assemblers are broken and do not allow @GOTOFF in
5810 ought but a memory context. */
5811 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5813 switch (get_attr_type (insn))
5816 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5817 if (operands[2] == const1_rtx)
5818 return "inc{q}\t%0";
5821 gcc_assert (operands[2] == constm1_rtx);
5822 return "dec{q}\t%0";
5826 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5827 /* ???? We ought to handle there the 32bit case too
5828 - do we need new constraint? */
5829 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5830 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5831 if (CONST_INT_P (operands[2])
5832 /* Avoid overflows. */
5833 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5834 && (INTVAL (operands[2]) == 128
5835 || (INTVAL (operands[2]) < 0
5836 && INTVAL (operands[2]) != -128)))
5838 operands[2] = GEN_INT (-INTVAL (operands[2]));
5839 return "sub{q}\t{%2, %0|%0, %2}";
5841 return "add{q}\t{%2, %0|%0, %2}";
5845 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5846 (const_string "incdec")
5847 (const_string "alu")))
5848 (set_attr "mode" "DI")])
5850 (define_insn "*adddi_3_rex64"
5851 [(set (reg FLAGS_REG)
5852 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5853 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5854 (clobber (match_scratch:DI 0 "=r"))]
5856 && ix86_match_ccmode (insn, CCZmode)
5857 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5858 /* Current assemblers are broken and do not allow @GOTOFF in
5859 ought but a memory context. */
5860 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5862 switch (get_attr_type (insn))
5865 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5866 if (operands[2] == const1_rtx)
5867 return "inc{q}\t%0";
5870 gcc_assert (operands[2] == constm1_rtx);
5871 return "dec{q}\t%0";
5875 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5876 /* ???? We ought to handle there the 32bit case too
5877 - do we need new constraint? */
5878 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5879 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5880 if (CONST_INT_P (operands[2])
5881 /* Avoid overflows. */
5882 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5883 && (INTVAL (operands[2]) == 128
5884 || (INTVAL (operands[2]) < 0
5885 && INTVAL (operands[2]) != -128)))
5887 operands[2] = GEN_INT (-INTVAL (operands[2]));
5888 return "sub{q}\t{%2, %0|%0, %2}";
5890 return "add{q}\t{%2, %0|%0, %2}";
5894 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5895 (const_string "incdec")
5896 (const_string "alu")))
5897 (set_attr "mode" "DI")])
5899 ; For comparisons against 1, -1 and 128, we may generate better code
5900 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5901 ; is matched then. We can't accept general immediate, because for
5902 ; case of overflows, the result is messed up.
5903 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5905 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5906 ; only for comparisons not depending on it.
5907 (define_insn "*adddi_4_rex64"
5908 [(set (reg FLAGS_REG)
5909 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5910 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5911 (clobber (match_scratch:DI 0 "=rm"))]
5913 && ix86_match_ccmode (insn, CCGCmode)"
5915 switch (get_attr_type (insn))
5918 if (operands[2] == constm1_rtx)
5919 return "inc{q}\t%0";
5922 gcc_assert (operands[2] == const1_rtx);
5923 return "dec{q}\t%0";
5927 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5928 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5929 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5930 if ((INTVAL (operands[2]) == -128
5931 || (INTVAL (operands[2]) > 0
5932 && INTVAL (operands[2]) != 128))
5933 /* Avoid overflows. */
5934 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5935 return "sub{q}\t{%2, %0|%0, %2}";
5936 operands[2] = GEN_INT (-INTVAL (operands[2]));
5937 return "add{q}\t{%2, %0|%0, %2}";
5941 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5942 (const_string "incdec")
5943 (const_string "alu")))
5944 (set_attr "mode" "DI")])
5946 (define_insn "*adddi_5_rex64"
5947 [(set (reg FLAGS_REG)
5949 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5950 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5952 (clobber (match_scratch:DI 0 "=r"))]
5954 && ix86_match_ccmode (insn, CCGOCmode)
5955 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5956 /* Current assemblers are broken and do not allow @GOTOFF in
5957 ought but a memory context. */
5958 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5960 switch (get_attr_type (insn))
5963 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5964 if (operands[2] == const1_rtx)
5965 return "inc{q}\t%0";
5968 gcc_assert (operands[2] == constm1_rtx);
5969 return "dec{q}\t%0";
5973 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5974 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5975 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5976 if (CONST_INT_P (operands[2])
5977 /* Avoid overflows. */
5978 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5979 && (INTVAL (operands[2]) == 128
5980 || (INTVAL (operands[2]) < 0
5981 && INTVAL (operands[2]) != -128)))
5983 operands[2] = GEN_INT (-INTVAL (operands[2]));
5984 return "sub{q}\t{%2, %0|%0, %2}";
5986 return "add{q}\t{%2, %0|%0, %2}";
5990 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5991 (const_string "incdec")
5992 (const_string "alu")))
5993 (set_attr "mode" "DI")])
5996 (define_insn "*addsi_1"
5997 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5998 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5999 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6000 (clobber (reg:CC FLAGS_REG))]
6001 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6003 switch (get_attr_type (insn))
6006 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6007 return "lea{l}\t{%a2, %0|%0, %a2}";
6010 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6011 if (operands[2] == const1_rtx)
6012 return "inc{l}\t%0";
6015 gcc_assert (operands[2] == constm1_rtx);
6016 return "dec{l}\t%0";
6020 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6022 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6023 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6024 if (CONST_INT_P (operands[2])
6025 && (INTVAL (operands[2]) == 128
6026 || (INTVAL (operands[2]) < 0
6027 && INTVAL (operands[2]) != -128)))
6029 operands[2] = GEN_INT (-INTVAL (operands[2]));
6030 return "sub{l}\t{%2, %0|%0, %2}";
6032 return "add{l}\t{%2, %0|%0, %2}";
6036 (cond [(eq_attr "alternative" "2")
6037 (const_string "lea")
6038 ; Current assemblers are broken and do not allow @GOTOFF in
6039 ; ought but a memory context.
6040 (match_operand:SI 2 "pic_symbolic_operand" "")
6041 (const_string "lea")
6042 (match_operand:SI 2 "incdec_operand" "")
6043 (const_string "incdec")
6045 (const_string "alu")))
6046 (set_attr "mode" "SI")])
6048 ;; Convert lea to the lea pattern to avoid flags dependency.
6050 [(set (match_operand 0 "register_operand" "")
6051 (plus (match_operand 1 "register_operand" "")
6052 (match_operand 2 "nonmemory_operand" "")))
6053 (clobber (reg:CC FLAGS_REG))]
6055 && true_regnum (operands[0]) != true_regnum (operands[1])"
6059 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6060 may confuse gen_lowpart. */
6061 if (GET_MODE (operands[0]) != Pmode)
6063 operands[1] = gen_lowpart (Pmode, operands[1]);
6064 operands[2] = gen_lowpart (Pmode, operands[2]);
6066 operands[0] = gen_lowpart (SImode, operands[0]);
6067 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6068 if (Pmode != SImode)
6069 pat = gen_rtx_SUBREG (SImode, pat, 0);
6070 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6074 ;; It may seem that nonimmediate operand is proper one for operand 1.
6075 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6076 ;; we take care in ix86_binary_operator_ok to not allow two memory
6077 ;; operands so proper swapping will be done in reload. This allow
6078 ;; patterns constructed from addsi_1 to match.
6079 (define_insn "addsi_1_zext"
6080 [(set (match_operand:DI 0 "register_operand" "=r,r")
6082 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6083 (match_operand:SI 2 "general_operand" "rmni,lni"))))
6084 (clobber (reg:CC FLAGS_REG))]
6085 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6087 switch (get_attr_type (insn))
6090 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6091 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6094 if (operands[2] == const1_rtx)
6095 return "inc{l}\t%k0";
6098 gcc_assert (operands[2] == constm1_rtx);
6099 return "dec{l}\t%k0";
6103 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6104 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6105 if (CONST_INT_P (operands[2])
6106 && (INTVAL (operands[2]) == 128
6107 || (INTVAL (operands[2]) < 0
6108 && INTVAL (operands[2]) != -128)))
6110 operands[2] = GEN_INT (-INTVAL (operands[2]));
6111 return "sub{l}\t{%2, %k0|%k0, %2}";
6113 return "add{l}\t{%2, %k0|%k0, %2}";
6117 (cond [(eq_attr "alternative" "1")
6118 (const_string "lea")
6119 ; Current assemblers are broken and do not allow @GOTOFF in
6120 ; ought but a memory context.
6121 (match_operand:SI 2 "pic_symbolic_operand" "")
6122 (const_string "lea")
6123 (match_operand:SI 2 "incdec_operand" "")
6124 (const_string "incdec")
6126 (const_string "alu")))
6127 (set_attr "mode" "SI")])
6129 ;; Convert lea to the lea pattern to avoid flags dependency.
6131 [(set (match_operand:DI 0 "register_operand" "")
6133 (plus:SI (match_operand:SI 1 "register_operand" "")
6134 (match_operand:SI 2 "nonmemory_operand" ""))))
6135 (clobber (reg:CC FLAGS_REG))]
6136 "TARGET_64BIT && reload_completed
6137 && true_regnum (operands[0]) != true_regnum (operands[1])"
6139 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6141 operands[1] = gen_lowpart (Pmode, operands[1]);
6142 operands[2] = gen_lowpart (Pmode, operands[2]);
6145 (define_insn "*addsi_2"
6146 [(set (reg FLAGS_REG)
6148 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6149 (match_operand:SI 2 "general_operand" "rmni,rni"))
6151 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6152 (plus:SI (match_dup 1) (match_dup 2)))]
6153 "ix86_match_ccmode (insn, CCGOCmode)
6154 && ix86_binary_operator_ok (PLUS, SImode, operands)
6155 /* Current assemblers are broken and do not allow @GOTOFF in
6156 ought but a memory context. */
6157 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6159 switch (get_attr_type (insn))
6162 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6163 if (operands[2] == const1_rtx)
6164 return "inc{l}\t%0";
6167 gcc_assert (operands[2] == constm1_rtx);
6168 return "dec{l}\t%0";
6172 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6173 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6174 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6175 if (CONST_INT_P (operands[2])
6176 && (INTVAL (operands[2]) == 128
6177 || (INTVAL (operands[2]) < 0
6178 && INTVAL (operands[2]) != -128)))
6180 operands[2] = GEN_INT (-INTVAL (operands[2]));
6181 return "sub{l}\t{%2, %0|%0, %2}";
6183 return "add{l}\t{%2, %0|%0, %2}";
6187 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6188 (const_string "incdec")
6189 (const_string "alu")))
6190 (set_attr "mode" "SI")])
6192 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6193 (define_insn "*addsi_2_zext"
6194 [(set (reg FLAGS_REG)
6196 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6197 (match_operand:SI 2 "general_operand" "rmni"))
6199 (set (match_operand:DI 0 "register_operand" "=r")
6200 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6201 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6202 && ix86_binary_operator_ok (PLUS, SImode, operands)
6203 /* Current assemblers are broken and do not allow @GOTOFF in
6204 ought but a memory context. */
6205 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6207 switch (get_attr_type (insn))
6210 if (operands[2] == const1_rtx)
6211 return "inc{l}\t%k0";
6214 gcc_assert (operands[2] == constm1_rtx);
6215 return "dec{l}\t%k0";
6219 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6220 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6221 if (CONST_INT_P (operands[2])
6222 && (INTVAL (operands[2]) == 128
6223 || (INTVAL (operands[2]) < 0
6224 && INTVAL (operands[2]) != -128)))
6226 operands[2] = GEN_INT (-INTVAL (operands[2]));
6227 return "sub{l}\t{%2, %k0|%k0, %2}";
6229 return "add{l}\t{%2, %k0|%k0, %2}";
6233 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6234 (const_string "incdec")
6235 (const_string "alu")))
6236 (set_attr "mode" "SI")])
6238 (define_insn "*addsi_3"
6239 [(set (reg FLAGS_REG)
6240 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6241 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6242 (clobber (match_scratch:SI 0 "=r"))]
6243 "ix86_match_ccmode (insn, CCZmode)
6244 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6245 /* Current assemblers are broken and do not allow @GOTOFF in
6246 ought but a memory context. */
6247 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6249 switch (get_attr_type (insn))
6252 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6253 if (operands[2] == const1_rtx)
6254 return "inc{l}\t%0";
6257 gcc_assert (operands[2] == constm1_rtx);
6258 return "dec{l}\t%0";
6262 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6263 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6264 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6265 if (CONST_INT_P (operands[2])
6266 && (INTVAL (operands[2]) == 128
6267 || (INTVAL (operands[2]) < 0
6268 && INTVAL (operands[2]) != -128)))
6270 operands[2] = GEN_INT (-INTVAL (operands[2]));
6271 return "sub{l}\t{%2, %0|%0, %2}";
6273 return "add{l}\t{%2, %0|%0, %2}";
6277 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6278 (const_string "incdec")
6279 (const_string "alu")))
6280 (set_attr "mode" "SI")])
6282 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6283 (define_insn "*addsi_3_zext"
6284 [(set (reg FLAGS_REG)
6285 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6286 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6287 (set (match_operand:DI 0 "register_operand" "=r")
6288 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6289 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6290 && ix86_binary_operator_ok (PLUS, SImode, operands)
6291 /* Current assemblers are broken and do not allow @GOTOFF in
6292 ought but a memory context. */
6293 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6295 switch (get_attr_type (insn))
6298 if (operands[2] == const1_rtx)
6299 return "inc{l}\t%k0";
6302 gcc_assert (operands[2] == constm1_rtx);
6303 return "dec{l}\t%k0";
6307 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6308 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6309 if (CONST_INT_P (operands[2])
6310 && (INTVAL (operands[2]) == 128
6311 || (INTVAL (operands[2]) < 0
6312 && INTVAL (operands[2]) != -128)))
6314 operands[2] = GEN_INT (-INTVAL (operands[2]));
6315 return "sub{l}\t{%2, %k0|%k0, %2}";
6317 return "add{l}\t{%2, %k0|%k0, %2}";
6321 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6322 (const_string "incdec")
6323 (const_string "alu")))
6324 (set_attr "mode" "SI")])
6326 ; For comparisons against 1, -1 and 128, we may generate better code
6327 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6328 ; is matched then. We can't accept general immediate, because for
6329 ; case of overflows, the result is messed up.
6330 ; This pattern also don't hold of 0x80000000, since the value overflows
6332 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6333 ; only for comparisons not depending on it.
6334 (define_insn "*addsi_4"
6335 [(set (reg FLAGS_REG)
6336 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6337 (match_operand:SI 2 "const_int_operand" "n")))
6338 (clobber (match_scratch:SI 0 "=rm"))]
6339 "ix86_match_ccmode (insn, CCGCmode)
6340 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6342 switch (get_attr_type (insn))
6345 if (operands[2] == constm1_rtx)
6346 return "inc{l}\t%0";
6349 gcc_assert (operands[2] == const1_rtx);
6350 return "dec{l}\t%0";
6354 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6355 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6356 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6357 if ((INTVAL (operands[2]) == -128
6358 || (INTVAL (operands[2]) > 0
6359 && INTVAL (operands[2]) != 128)))
6360 return "sub{l}\t{%2, %0|%0, %2}";
6361 operands[2] = GEN_INT (-INTVAL (operands[2]));
6362 return "add{l}\t{%2, %0|%0, %2}";
6366 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6367 (const_string "incdec")
6368 (const_string "alu")))
6369 (set_attr "mode" "SI")])
6371 (define_insn "*addsi_5"
6372 [(set (reg FLAGS_REG)
6374 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6375 (match_operand:SI 2 "general_operand" "rmni"))
6377 (clobber (match_scratch:SI 0 "=r"))]
6378 "ix86_match_ccmode (insn, CCGOCmode)
6379 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6380 /* Current assemblers are broken and do not allow @GOTOFF in
6381 ought but a memory context. */
6382 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6384 switch (get_attr_type (insn))
6387 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6388 if (operands[2] == const1_rtx)
6389 return "inc{l}\t%0";
6392 gcc_assert (operands[2] == constm1_rtx);
6393 return "dec{l}\t%0";
6397 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6398 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6399 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6400 if (CONST_INT_P (operands[2])
6401 && (INTVAL (operands[2]) == 128
6402 || (INTVAL (operands[2]) < 0
6403 && INTVAL (operands[2]) != -128)))
6405 operands[2] = GEN_INT (-INTVAL (operands[2]));
6406 return "sub{l}\t{%2, %0|%0, %2}";
6408 return "add{l}\t{%2, %0|%0, %2}";
6412 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6413 (const_string "incdec")
6414 (const_string "alu")))
6415 (set_attr "mode" "SI")])
6417 (define_expand "addhi3"
6418 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6419 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6420 (match_operand:HI 2 "general_operand" "")))
6421 (clobber (reg:CC FLAGS_REG))])]
6422 "TARGET_HIMODE_MATH"
6423 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6425 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6426 ;; type optimizations enabled by define-splits. This is not important
6427 ;; for PII, and in fact harmful because of partial register stalls.
6429 (define_insn "*addhi_1_lea"
6430 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6431 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6432 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6433 (clobber (reg:CC FLAGS_REG))]
6434 "!TARGET_PARTIAL_REG_STALL
6435 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6437 switch (get_attr_type (insn))
6442 if (operands[2] == const1_rtx)
6443 return "inc{w}\t%0";
6446 gcc_assert (operands[2] == constm1_rtx);
6447 return "dec{w}\t%0";
6451 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6452 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6453 if (CONST_INT_P (operands[2])
6454 && (INTVAL (operands[2]) == 128
6455 || (INTVAL (operands[2]) < 0
6456 && INTVAL (operands[2]) != -128)))
6458 operands[2] = GEN_INT (-INTVAL (operands[2]));
6459 return "sub{w}\t{%2, %0|%0, %2}";
6461 return "add{w}\t{%2, %0|%0, %2}";
6465 (if_then_else (eq_attr "alternative" "2")
6466 (const_string "lea")
6467 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6468 (const_string "incdec")
6469 (const_string "alu"))))
6470 (set_attr "mode" "HI,HI,SI")])
6472 (define_insn "*addhi_1"
6473 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6474 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6475 (match_operand:HI 2 "general_operand" "ri,rm")))
6476 (clobber (reg:CC FLAGS_REG))]
6477 "TARGET_PARTIAL_REG_STALL
6478 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6480 switch (get_attr_type (insn))
6483 if (operands[2] == const1_rtx)
6484 return "inc{w}\t%0";
6487 gcc_assert (operands[2] == constm1_rtx);
6488 return "dec{w}\t%0";
6492 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6493 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6494 if (CONST_INT_P (operands[2])
6495 && (INTVAL (operands[2]) == 128
6496 || (INTVAL (operands[2]) < 0
6497 && INTVAL (operands[2]) != -128)))
6499 operands[2] = GEN_INT (-INTVAL (operands[2]));
6500 return "sub{w}\t{%2, %0|%0, %2}";
6502 return "add{w}\t{%2, %0|%0, %2}";
6506 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6507 (const_string "incdec")
6508 (const_string "alu")))
6509 (set_attr "mode" "HI")])
6511 (define_insn "*addhi_2"
6512 [(set (reg FLAGS_REG)
6514 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6515 (match_operand:HI 2 "general_operand" "rmni,rni"))
6517 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6518 (plus:HI (match_dup 1) (match_dup 2)))]
6519 "ix86_match_ccmode (insn, CCGOCmode)
6520 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6522 switch (get_attr_type (insn))
6525 if (operands[2] == const1_rtx)
6526 return "inc{w}\t%0";
6529 gcc_assert (operands[2] == constm1_rtx);
6530 return "dec{w}\t%0";
6534 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6535 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6536 if (CONST_INT_P (operands[2])
6537 && (INTVAL (operands[2]) == 128
6538 || (INTVAL (operands[2]) < 0
6539 && INTVAL (operands[2]) != -128)))
6541 operands[2] = GEN_INT (-INTVAL (operands[2]));
6542 return "sub{w}\t{%2, %0|%0, %2}";
6544 return "add{w}\t{%2, %0|%0, %2}";
6548 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6549 (const_string "incdec")
6550 (const_string "alu")))
6551 (set_attr "mode" "HI")])
6553 (define_insn "*addhi_3"
6554 [(set (reg FLAGS_REG)
6555 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6556 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6557 (clobber (match_scratch:HI 0 "=r"))]
6558 "ix86_match_ccmode (insn, CCZmode)
6559 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6561 switch (get_attr_type (insn))
6564 if (operands[2] == const1_rtx)
6565 return "inc{w}\t%0";
6568 gcc_assert (operands[2] == constm1_rtx);
6569 return "dec{w}\t%0";
6573 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6574 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6575 if (CONST_INT_P (operands[2])
6576 && (INTVAL (operands[2]) == 128
6577 || (INTVAL (operands[2]) < 0
6578 && INTVAL (operands[2]) != -128)))
6580 operands[2] = GEN_INT (-INTVAL (operands[2]));
6581 return "sub{w}\t{%2, %0|%0, %2}";
6583 return "add{w}\t{%2, %0|%0, %2}";
6587 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6588 (const_string "incdec")
6589 (const_string "alu")))
6590 (set_attr "mode" "HI")])
6592 ; See comments above addsi_4 for details.
6593 (define_insn "*addhi_4"
6594 [(set (reg FLAGS_REG)
6595 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6596 (match_operand:HI 2 "const_int_operand" "n")))
6597 (clobber (match_scratch:HI 0 "=rm"))]
6598 "ix86_match_ccmode (insn, CCGCmode)
6599 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6601 switch (get_attr_type (insn))
6604 if (operands[2] == constm1_rtx)
6605 return "inc{w}\t%0";
6608 gcc_assert (operands[2] == const1_rtx);
6609 return "dec{w}\t%0";
6613 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6614 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6615 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6616 if ((INTVAL (operands[2]) == -128
6617 || (INTVAL (operands[2]) > 0
6618 && INTVAL (operands[2]) != 128)))
6619 return "sub{w}\t{%2, %0|%0, %2}";
6620 operands[2] = GEN_INT (-INTVAL (operands[2]));
6621 return "add{w}\t{%2, %0|%0, %2}";
6625 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6626 (const_string "incdec")
6627 (const_string "alu")))
6628 (set_attr "mode" "SI")])
6631 (define_insn "*addhi_5"
6632 [(set (reg FLAGS_REG)
6634 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6635 (match_operand:HI 2 "general_operand" "rmni"))
6637 (clobber (match_scratch:HI 0 "=r"))]
6638 "ix86_match_ccmode (insn, CCGOCmode)
6639 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6641 switch (get_attr_type (insn))
6644 if (operands[2] == const1_rtx)
6645 return "inc{w}\t%0";
6648 gcc_assert (operands[2] == constm1_rtx);
6649 return "dec{w}\t%0";
6653 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6654 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6655 if (CONST_INT_P (operands[2])
6656 && (INTVAL (operands[2]) == 128
6657 || (INTVAL (operands[2]) < 0
6658 && INTVAL (operands[2]) != -128)))
6660 operands[2] = GEN_INT (-INTVAL (operands[2]));
6661 return "sub{w}\t{%2, %0|%0, %2}";
6663 return "add{w}\t{%2, %0|%0, %2}";
6667 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6668 (const_string "incdec")
6669 (const_string "alu")))
6670 (set_attr "mode" "HI")])
6672 (define_expand "addqi3"
6673 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6674 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6675 (match_operand:QI 2 "general_operand" "")))
6676 (clobber (reg:CC FLAGS_REG))])]
6677 "TARGET_QIMODE_MATH"
6678 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6680 ;; %%% Potential partial reg stall on alternative 2. What to do?
6681 (define_insn "*addqi_1_lea"
6682 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6683 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6684 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6685 (clobber (reg:CC FLAGS_REG))]
6686 "!TARGET_PARTIAL_REG_STALL
6687 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6689 int widen = (which_alternative == 2);
6690 switch (get_attr_type (insn))
6695 if (operands[2] == const1_rtx)
6696 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6699 gcc_assert (operands[2] == constm1_rtx);
6700 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6704 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6705 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6706 if (CONST_INT_P (operands[2])
6707 && (INTVAL (operands[2]) == 128
6708 || (INTVAL (operands[2]) < 0
6709 && INTVAL (operands[2]) != -128)))
6711 operands[2] = GEN_INT (-INTVAL (operands[2]));
6713 return "sub{l}\t{%2, %k0|%k0, %2}";
6715 return "sub{b}\t{%2, %0|%0, %2}";
6718 return "add{l}\t{%k2, %k0|%k0, %k2}";
6720 return "add{b}\t{%2, %0|%0, %2}";
6724 (if_then_else (eq_attr "alternative" "3")
6725 (const_string "lea")
6726 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6727 (const_string "incdec")
6728 (const_string "alu"))))
6729 (set_attr "mode" "QI,QI,SI,SI")])
6731 (define_insn "*addqi_1"
6732 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6733 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6734 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6735 (clobber (reg:CC FLAGS_REG))]
6736 "TARGET_PARTIAL_REG_STALL
6737 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6739 int widen = (which_alternative == 2);
6740 switch (get_attr_type (insn))
6743 if (operands[2] == const1_rtx)
6744 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6747 gcc_assert (operands[2] == constm1_rtx);
6748 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6752 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6753 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6754 if (CONST_INT_P (operands[2])
6755 && (INTVAL (operands[2]) == 128
6756 || (INTVAL (operands[2]) < 0
6757 && INTVAL (operands[2]) != -128)))
6759 operands[2] = GEN_INT (-INTVAL (operands[2]));
6761 return "sub{l}\t{%2, %k0|%k0, %2}";
6763 return "sub{b}\t{%2, %0|%0, %2}";
6766 return "add{l}\t{%k2, %k0|%k0, %k2}";
6768 return "add{b}\t{%2, %0|%0, %2}";
6772 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6773 (const_string "incdec")
6774 (const_string "alu")))
6775 (set_attr "mode" "QI,QI,SI")])
6777 (define_insn "*addqi_1_slp"
6778 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6779 (plus:QI (match_dup 0)
6780 (match_operand:QI 1 "general_operand" "qn,qnm")))
6781 (clobber (reg:CC FLAGS_REG))]
6782 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6783 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6785 switch (get_attr_type (insn))
6788 if (operands[1] == const1_rtx)
6789 return "inc{b}\t%0";
6792 gcc_assert (operands[1] == constm1_rtx);
6793 return "dec{b}\t%0";
6797 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6798 if (CONST_INT_P (operands[1])
6799 && INTVAL (operands[1]) < 0)
6801 operands[1] = GEN_INT (-INTVAL (operands[1]));
6802 return "sub{b}\t{%1, %0|%0, %1}";
6804 return "add{b}\t{%1, %0|%0, %1}";
6808 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6809 (const_string "incdec")
6810 (const_string "alu1")))
6811 (set (attr "memory")
6812 (if_then_else (match_operand 1 "memory_operand" "")
6813 (const_string "load")
6814 (const_string "none")))
6815 (set_attr "mode" "QI")])
6817 (define_insn "*addqi_2"
6818 [(set (reg FLAGS_REG)
6820 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6821 (match_operand:QI 2 "general_operand" "qmni,qni"))
6823 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6824 (plus:QI (match_dup 1) (match_dup 2)))]
6825 "ix86_match_ccmode (insn, CCGOCmode)
6826 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6828 switch (get_attr_type (insn))
6831 if (operands[2] == const1_rtx)
6832 return "inc{b}\t%0";
6835 gcc_assert (operands[2] == constm1_rtx
6836 || (CONST_INT_P (operands[2])
6837 && INTVAL (operands[2]) == 255));
6838 return "dec{b}\t%0";
6842 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6843 if (CONST_INT_P (operands[2])
6844 && INTVAL (operands[2]) < 0)
6846 operands[2] = GEN_INT (-INTVAL (operands[2]));
6847 return "sub{b}\t{%2, %0|%0, %2}";
6849 return "add{b}\t{%2, %0|%0, %2}";
6853 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6854 (const_string "incdec")
6855 (const_string "alu")))
6856 (set_attr "mode" "QI")])
6858 (define_insn "*addqi_3"
6859 [(set (reg FLAGS_REG)
6860 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6861 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6862 (clobber (match_scratch:QI 0 "=q"))]
6863 "ix86_match_ccmode (insn, CCZmode)
6864 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6866 switch (get_attr_type (insn))
6869 if (operands[2] == const1_rtx)
6870 return "inc{b}\t%0";
6873 gcc_assert (operands[2] == constm1_rtx
6874 || (CONST_INT_P (operands[2])
6875 && INTVAL (operands[2]) == 255));
6876 return "dec{b}\t%0";
6880 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6881 if (CONST_INT_P (operands[2])
6882 && INTVAL (operands[2]) < 0)
6884 operands[2] = GEN_INT (-INTVAL (operands[2]));
6885 return "sub{b}\t{%2, %0|%0, %2}";
6887 return "add{b}\t{%2, %0|%0, %2}";
6891 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6892 (const_string "incdec")
6893 (const_string "alu")))
6894 (set_attr "mode" "QI")])
6896 ; See comments above addsi_4 for details.
6897 (define_insn "*addqi_4"
6898 [(set (reg FLAGS_REG)
6899 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6900 (match_operand:QI 2 "const_int_operand" "n")))
6901 (clobber (match_scratch:QI 0 "=qm"))]
6902 "ix86_match_ccmode (insn, CCGCmode)
6903 && (INTVAL (operands[2]) & 0xff) != 0x80"
6905 switch (get_attr_type (insn))
6908 if (operands[2] == constm1_rtx
6909 || (CONST_INT_P (operands[2])
6910 && INTVAL (operands[2]) == 255))
6911 return "inc{b}\t%0";
6914 gcc_assert (operands[2] == const1_rtx);
6915 return "dec{b}\t%0";
6919 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6920 if (INTVAL (operands[2]) < 0)
6922 operands[2] = GEN_INT (-INTVAL (operands[2]));
6923 return "add{b}\t{%2, %0|%0, %2}";
6925 return "sub{b}\t{%2, %0|%0, %2}";
6929 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6930 (const_string "incdec")
6931 (const_string "alu")))
6932 (set_attr "mode" "QI")])
6935 (define_insn "*addqi_5"
6936 [(set (reg FLAGS_REG)
6938 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6939 (match_operand:QI 2 "general_operand" "qmni"))
6941 (clobber (match_scratch:QI 0 "=q"))]
6942 "ix86_match_ccmode (insn, CCGOCmode)
6943 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6945 switch (get_attr_type (insn))
6948 if (operands[2] == const1_rtx)
6949 return "inc{b}\t%0";
6952 gcc_assert (operands[2] == constm1_rtx
6953 || (CONST_INT_P (operands[2])
6954 && INTVAL (operands[2]) == 255));
6955 return "dec{b}\t%0";
6959 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6960 if (CONST_INT_P (operands[2])
6961 && INTVAL (operands[2]) < 0)
6963 operands[2] = GEN_INT (-INTVAL (operands[2]));
6964 return "sub{b}\t{%2, %0|%0, %2}";
6966 return "add{b}\t{%2, %0|%0, %2}";
6970 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6971 (const_string "incdec")
6972 (const_string "alu")))
6973 (set_attr "mode" "QI")])
6976 (define_insn "addqi_ext_1"
6977 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6982 (match_operand 1 "ext_register_operand" "0")
6985 (match_operand:QI 2 "general_operand" "Qmn")))
6986 (clobber (reg:CC FLAGS_REG))]
6989 switch (get_attr_type (insn))
6992 if (operands[2] == const1_rtx)
6993 return "inc{b}\t%h0";
6996 gcc_assert (operands[2] == constm1_rtx
6997 || (CONST_INT_P (operands[2])
6998 && INTVAL (operands[2]) == 255));
6999 return "dec{b}\t%h0";
7003 return "add{b}\t{%2, %h0|%h0, %2}";
7007 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7008 (const_string "incdec")
7009 (const_string "alu")))
7010 (set_attr "mode" "QI")])
7012 (define_insn "*addqi_ext_1_rex64"
7013 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7018 (match_operand 1 "ext_register_operand" "0")
7021 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7022 (clobber (reg:CC FLAGS_REG))]
7025 switch (get_attr_type (insn))
7028 if (operands[2] == const1_rtx)
7029 return "inc{b}\t%h0";
7032 gcc_assert (operands[2] == constm1_rtx
7033 || (CONST_INT_P (operands[2])
7034 && INTVAL (operands[2]) == 255));
7035 return "dec{b}\t%h0";
7039 return "add{b}\t{%2, %h0|%h0, %2}";
7043 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7044 (const_string "incdec")
7045 (const_string "alu")))
7046 (set_attr "mode" "QI")])
7048 (define_insn "*addqi_ext_2"
7049 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7054 (match_operand 1 "ext_register_operand" "%0")
7058 (match_operand 2 "ext_register_operand" "Q")
7061 (clobber (reg:CC FLAGS_REG))]
7063 "add{b}\t{%h2, %h0|%h0, %h2}"
7064 [(set_attr "type" "alu")
7065 (set_attr "mode" "QI")])
7067 ;; The patterns that match these are at the end of this file.
7069 (define_expand "addxf3"
7070 [(set (match_operand:XF 0 "register_operand" "")
7071 (plus:XF (match_operand:XF 1 "register_operand" "")
7072 (match_operand:XF 2 "register_operand" "")))]
7076 (define_expand "add<mode>3"
7077 [(set (match_operand:MODEF 0 "register_operand" "")
7078 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7079 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7080 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7083 ;; Subtract instructions
7085 ;; %%% splits for subditi3
7087 (define_expand "subti3"
7088 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7089 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7090 (match_operand:TI 2 "x86_64_general_operand" "")))
7091 (clobber (reg:CC FLAGS_REG))])]
7093 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7095 (define_insn "*subti3_1"
7096 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7097 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7098 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7099 (clobber (reg:CC FLAGS_REG))]
7100 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7104 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7105 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7106 (match_operand:TI 2 "x86_64_general_operand" "")))
7107 (clobber (reg:CC FLAGS_REG))]
7108 "TARGET_64BIT && reload_completed"
7109 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7110 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7111 (parallel [(set (match_dup 3)
7112 (minus:DI (match_dup 4)
7113 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7115 (clobber (reg:CC FLAGS_REG))])]
7116 "split_ti (operands+0, 1, operands+0, operands+3);
7117 split_ti (operands+1, 1, operands+1, operands+4);
7118 split_ti (operands+2, 1, operands+2, operands+5);")
7120 ;; %%% splits for subsidi3
7122 (define_expand "subdi3"
7123 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7124 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7125 (match_operand:DI 2 "x86_64_general_operand" "")))
7126 (clobber (reg:CC FLAGS_REG))])]
7128 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7130 (define_insn "*subdi3_1"
7131 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7132 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7133 (match_operand:DI 2 "general_operand" "roiF,riF")))
7134 (clobber (reg:CC FLAGS_REG))]
7135 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7139 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7140 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7141 (match_operand:DI 2 "general_operand" "")))
7142 (clobber (reg:CC FLAGS_REG))]
7143 "!TARGET_64BIT && reload_completed"
7144 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7145 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7146 (parallel [(set (match_dup 3)
7147 (minus:SI (match_dup 4)
7148 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7150 (clobber (reg:CC FLAGS_REG))])]
7151 "split_di (operands+0, 1, operands+0, operands+3);
7152 split_di (operands+1, 1, operands+1, operands+4);
7153 split_di (operands+2, 1, operands+2, operands+5);")
7155 (define_insn "subdi3_carry_rex64"
7156 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7157 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7158 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7159 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7160 (clobber (reg:CC FLAGS_REG))]
7161 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7162 "sbb{q}\t{%2, %0|%0, %2}"
7163 [(set_attr "type" "alu")
7164 (set_attr "pent_pair" "pu")
7165 (set_attr "mode" "DI")])
7167 (define_insn "*subdi_1_rex64"
7168 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7169 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7170 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7171 (clobber (reg:CC FLAGS_REG))]
7172 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7173 "sub{q}\t{%2, %0|%0, %2}"
7174 [(set_attr "type" "alu")
7175 (set_attr "mode" "DI")])
7177 (define_insn "*subdi_2_rex64"
7178 [(set (reg FLAGS_REG)
7180 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7181 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7183 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7184 (minus:DI (match_dup 1) (match_dup 2)))]
7185 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7186 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7187 "sub{q}\t{%2, %0|%0, %2}"
7188 [(set_attr "type" "alu")
7189 (set_attr "mode" "DI")])
7191 (define_insn "*subdi_3_rex63"
7192 [(set (reg FLAGS_REG)
7193 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7194 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7195 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7196 (minus:DI (match_dup 1) (match_dup 2)))]
7197 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7198 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7199 "sub{q}\t{%2, %0|%0, %2}"
7200 [(set_attr "type" "alu")
7201 (set_attr "mode" "DI")])
7203 (define_insn "subqi3_carry"
7204 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7205 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7206 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7207 (match_operand:QI 2 "general_operand" "qi,qm"))))
7208 (clobber (reg:CC FLAGS_REG))]
7209 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7210 "sbb{b}\t{%2, %0|%0, %2}"
7211 [(set_attr "type" "alu")
7212 (set_attr "pent_pair" "pu")
7213 (set_attr "mode" "QI")])
7215 (define_insn "subhi3_carry"
7216 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7217 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7218 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7219 (match_operand:HI 2 "general_operand" "ri,rm"))))
7220 (clobber (reg:CC FLAGS_REG))]
7221 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7222 "sbb{w}\t{%2, %0|%0, %2}"
7223 [(set_attr "type" "alu")
7224 (set_attr "pent_pair" "pu")
7225 (set_attr "mode" "HI")])
7227 (define_insn "subsi3_carry"
7228 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7229 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7230 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7231 (match_operand:SI 2 "general_operand" "ri,rm"))))
7232 (clobber (reg:CC FLAGS_REG))]
7233 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7234 "sbb{l}\t{%2, %0|%0, %2}"
7235 [(set_attr "type" "alu")
7236 (set_attr "pent_pair" "pu")
7237 (set_attr "mode" "SI")])
7239 (define_insn "subsi3_carry_zext"
7240 [(set (match_operand:DI 0 "register_operand" "=r")
7242 (minus:SI (match_operand:SI 1 "register_operand" "0")
7243 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7244 (match_operand:SI 2 "general_operand" "g")))))
7245 (clobber (reg:CC FLAGS_REG))]
7246 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7247 "sbb{l}\t{%2, %k0|%k0, %2}"
7248 [(set_attr "type" "alu")
7249 (set_attr "pent_pair" "pu")
7250 (set_attr "mode" "SI")])
7252 (define_expand "subsi3"
7253 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7254 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7255 (match_operand:SI 2 "general_operand" "")))
7256 (clobber (reg:CC FLAGS_REG))])]
7258 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7260 (define_insn "*subsi_1"
7261 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7262 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7263 (match_operand:SI 2 "general_operand" "ri,rm")))
7264 (clobber (reg:CC FLAGS_REG))]
7265 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7266 "sub{l}\t{%2, %0|%0, %2}"
7267 [(set_attr "type" "alu")
7268 (set_attr "mode" "SI")])
7270 (define_insn "*subsi_1_zext"
7271 [(set (match_operand:DI 0 "register_operand" "=r")
7273 (minus:SI (match_operand:SI 1 "register_operand" "0")
7274 (match_operand:SI 2 "general_operand" "g"))))
7275 (clobber (reg:CC FLAGS_REG))]
7276 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7277 "sub{l}\t{%2, %k0|%k0, %2}"
7278 [(set_attr "type" "alu")
7279 (set_attr "mode" "SI")])
7281 (define_insn "*subsi_2"
7282 [(set (reg FLAGS_REG)
7284 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7285 (match_operand:SI 2 "general_operand" "ri,rm"))
7287 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7288 (minus:SI (match_dup 1) (match_dup 2)))]
7289 "ix86_match_ccmode (insn, CCGOCmode)
7290 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7291 "sub{l}\t{%2, %0|%0, %2}"
7292 [(set_attr "type" "alu")
7293 (set_attr "mode" "SI")])
7295 (define_insn "*subsi_2_zext"
7296 [(set (reg FLAGS_REG)
7298 (minus:SI (match_operand:SI 1 "register_operand" "0")
7299 (match_operand:SI 2 "general_operand" "g"))
7301 (set (match_operand:DI 0 "register_operand" "=r")
7303 (minus:SI (match_dup 1)
7305 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7306 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7307 "sub{l}\t{%2, %k0|%k0, %2}"
7308 [(set_attr "type" "alu")
7309 (set_attr "mode" "SI")])
7311 (define_insn "*subsi_3"
7312 [(set (reg FLAGS_REG)
7313 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7314 (match_operand:SI 2 "general_operand" "ri,rm")))
7315 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7316 (minus:SI (match_dup 1) (match_dup 2)))]
7317 "ix86_match_ccmode (insn, CCmode)
7318 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7319 "sub{l}\t{%2, %0|%0, %2}"
7320 [(set_attr "type" "alu")
7321 (set_attr "mode" "SI")])
7323 (define_insn "*subsi_3_zext"
7324 [(set (reg FLAGS_REG)
7325 (compare (match_operand:SI 1 "register_operand" "0")
7326 (match_operand:SI 2 "general_operand" "g")))
7327 (set (match_operand:DI 0 "register_operand" "=r")
7329 (minus:SI (match_dup 1)
7331 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7332 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7333 "sub{l}\t{%2, %1|%1, %2}"
7334 [(set_attr "type" "alu")
7335 (set_attr "mode" "DI")])
7337 (define_expand "subhi3"
7338 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7339 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7340 (match_operand:HI 2 "general_operand" "")))
7341 (clobber (reg:CC FLAGS_REG))])]
7342 "TARGET_HIMODE_MATH"
7343 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7345 (define_insn "*subhi_1"
7346 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7347 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7348 (match_operand:HI 2 "general_operand" "ri,rm")))
7349 (clobber (reg:CC FLAGS_REG))]
7350 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7351 "sub{w}\t{%2, %0|%0, %2}"
7352 [(set_attr "type" "alu")
7353 (set_attr "mode" "HI")])
7355 (define_insn "*subhi_2"
7356 [(set (reg FLAGS_REG)
7358 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7359 (match_operand:HI 2 "general_operand" "ri,rm"))
7361 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7362 (minus:HI (match_dup 1) (match_dup 2)))]
7363 "ix86_match_ccmode (insn, CCGOCmode)
7364 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7365 "sub{w}\t{%2, %0|%0, %2}"
7366 [(set_attr "type" "alu")
7367 (set_attr "mode" "HI")])
7369 (define_insn "*subhi_3"
7370 [(set (reg FLAGS_REG)
7371 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7372 (match_operand:HI 2 "general_operand" "ri,rm")))
7373 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7374 (minus:HI (match_dup 1) (match_dup 2)))]
7375 "ix86_match_ccmode (insn, CCmode)
7376 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7377 "sub{w}\t{%2, %0|%0, %2}"
7378 [(set_attr "type" "alu")
7379 (set_attr "mode" "HI")])
7381 (define_expand "subqi3"
7382 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7383 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7384 (match_operand:QI 2 "general_operand" "")))
7385 (clobber (reg:CC FLAGS_REG))])]
7386 "TARGET_QIMODE_MATH"
7387 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7389 (define_insn "*subqi_1"
7390 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7391 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7392 (match_operand:QI 2 "general_operand" "qn,qmn")))
7393 (clobber (reg:CC FLAGS_REG))]
7394 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7395 "sub{b}\t{%2, %0|%0, %2}"
7396 [(set_attr "type" "alu")
7397 (set_attr "mode" "QI")])
7399 (define_insn "*subqi_1_slp"
7400 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7401 (minus:QI (match_dup 0)
7402 (match_operand:QI 1 "general_operand" "qn,qmn")))
7403 (clobber (reg:CC FLAGS_REG))]
7404 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7405 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7406 "sub{b}\t{%1, %0|%0, %1}"
7407 [(set_attr "type" "alu1")
7408 (set_attr "mode" "QI")])
7410 (define_insn "*subqi_2"
7411 [(set (reg FLAGS_REG)
7413 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7414 (match_operand:QI 2 "general_operand" "qi,qm"))
7416 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7417 (minus:HI (match_dup 1) (match_dup 2)))]
7418 "ix86_match_ccmode (insn, CCGOCmode)
7419 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7420 "sub{b}\t{%2, %0|%0, %2}"
7421 [(set_attr "type" "alu")
7422 (set_attr "mode" "QI")])
7424 (define_insn "*subqi_3"
7425 [(set (reg FLAGS_REG)
7426 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7427 (match_operand:QI 2 "general_operand" "qi,qm")))
7428 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7429 (minus:HI (match_dup 1) (match_dup 2)))]
7430 "ix86_match_ccmode (insn, CCmode)
7431 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7432 "sub{b}\t{%2, %0|%0, %2}"
7433 [(set_attr "type" "alu")
7434 (set_attr "mode" "QI")])
7436 ;; The patterns that match these are at the end of this file.
7438 (define_expand "subxf3"
7439 [(set (match_operand:XF 0 "register_operand" "")
7440 (minus:XF (match_operand:XF 1 "register_operand" "")
7441 (match_operand:XF 2 "register_operand" "")))]
7445 (define_expand "sub<mode>3"
7446 [(set (match_operand:MODEF 0 "register_operand" "")
7447 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7448 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7449 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7452 ;; Multiply instructions
7454 (define_expand "muldi3"
7455 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7456 (mult:DI (match_operand:DI 1 "register_operand" "")
7457 (match_operand:DI 2 "x86_64_general_operand" "")))
7458 (clobber (reg:CC FLAGS_REG))])]
7463 ;; IMUL reg64, reg64, imm8 Direct
7464 ;; IMUL reg64, mem64, imm8 VectorPath
7465 ;; IMUL reg64, reg64, imm32 Direct
7466 ;; IMUL reg64, mem64, imm32 VectorPath
7467 ;; IMUL reg64, reg64 Direct
7468 ;; IMUL reg64, mem64 Direct
7470 (define_insn "*muldi3_1_rex64"
7471 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7472 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7473 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7474 (clobber (reg:CC FLAGS_REG))]
7476 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7478 imul{q}\t{%2, %1, %0|%0, %1, %2}
7479 imul{q}\t{%2, %1, %0|%0, %1, %2}
7480 imul{q}\t{%2, %0|%0, %2}"
7481 [(set_attr "type" "imul")
7482 (set_attr "prefix_0f" "0,0,1")
7483 (set (attr "athlon_decode")
7484 (cond [(eq_attr "cpu" "athlon")
7485 (const_string "vector")
7486 (eq_attr "alternative" "1")
7487 (const_string "vector")
7488 (and (eq_attr "alternative" "2")
7489 (match_operand 1 "memory_operand" ""))
7490 (const_string "vector")]
7491 (const_string "direct")))
7492 (set (attr "amdfam10_decode")
7493 (cond [(and (eq_attr "alternative" "0,1")
7494 (match_operand 1 "memory_operand" ""))
7495 (const_string "vector")]
7496 (const_string "direct")))
7497 (set_attr "mode" "DI")])
7499 (define_expand "mulsi3"
7500 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7501 (mult:SI (match_operand:SI 1 "register_operand" "")
7502 (match_operand:SI 2 "general_operand" "")))
7503 (clobber (reg:CC FLAGS_REG))])]
7508 ;; IMUL reg32, reg32, imm8 Direct
7509 ;; IMUL reg32, mem32, imm8 VectorPath
7510 ;; IMUL reg32, reg32, imm32 Direct
7511 ;; IMUL reg32, mem32, imm32 VectorPath
7512 ;; IMUL reg32, reg32 Direct
7513 ;; IMUL reg32, mem32 Direct
7515 (define_insn "*mulsi3_1"
7516 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7517 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7518 (match_operand:SI 2 "general_operand" "K,i,mr")))
7519 (clobber (reg:CC FLAGS_REG))]
7520 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7522 imul{l}\t{%2, %1, %0|%0, %1, %2}
7523 imul{l}\t{%2, %1, %0|%0, %1, %2}
7524 imul{l}\t{%2, %0|%0, %2}"
7525 [(set_attr "type" "imul")
7526 (set_attr "prefix_0f" "0,0,1")
7527 (set (attr "athlon_decode")
7528 (cond [(eq_attr "cpu" "athlon")
7529 (const_string "vector")
7530 (eq_attr "alternative" "1")
7531 (const_string "vector")
7532 (and (eq_attr "alternative" "2")
7533 (match_operand 1 "memory_operand" ""))
7534 (const_string "vector")]
7535 (const_string "direct")))
7536 (set (attr "amdfam10_decode")
7537 (cond [(and (eq_attr "alternative" "0,1")
7538 (match_operand 1 "memory_operand" ""))
7539 (const_string "vector")]
7540 (const_string "direct")))
7541 (set_attr "mode" "SI")])
7543 (define_insn "*mulsi3_1_zext"
7544 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7546 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7547 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7548 (clobber (reg:CC FLAGS_REG))]
7550 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7552 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7553 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7554 imul{l}\t{%2, %k0|%k0, %2}"
7555 [(set_attr "type" "imul")
7556 (set_attr "prefix_0f" "0,0,1")
7557 (set (attr "athlon_decode")
7558 (cond [(eq_attr "cpu" "athlon")
7559 (const_string "vector")
7560 (eq_attr "alternative" "1")
7561 (const_string "vector")
7562 (and (eq_attr "alternative" "2")
7563 (match_operand 1 "memory_operand" ""))
7564 (const_string "vector")]
7565 (const_string "direct")))
7566 (set (attr "amdfam10_decode")
7567 (cond [(and (eq_attr "alternative" "0,1")
7568 (match_operand 1 "memory_operand" ""))
7569 (const_string "vector")]
7570 (const_string "direct")))
7571 (set_attr "mode" "SI")])
7573 (define_expand "mulhi3"
7574 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7575 (mult:HI (match_operand:HI 1 "register_operand" "")
7576 (match_operand:HI 2 "general_operand" "")))
7577 (clobber (reg:CC FLAGS_REG))])]
7578 "TARGET_HIMODE_MATH"
7582 ;; IMUL reg16, reg16, imm8 VectorPath
7583 ;; IMUL reg16, mem16, imm8 VectorPath
7584 ;; IMUL reg16, reg16, imm16 VectorPath
7585 ;; IMUL reg16, mem16, imm16 VectorPath
7586 ;; IMUL reg16, reg16 Direct
7587 ;; IMUL reg16, mem16 Direct
7588 (define_insn "*mulhi3_1"
7589 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7590 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7591 (match_operand:HI 2 "general_operand" "K,i,mr")))
7592 (clobber (reg:CC FLAGS_REG))]
7593 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7595 imul{w}\t{%2, %1, %0|%0, %1, %2}
7596 imul{w}\t{%2, %1, %0|%0, %1, %2}
7597 imul{w}\t{%2, %0|%0, %2}"
7598 [(set_attr "type" "imul")
7599 (set_attr "prefix_0f" "0,0,1")
7600 (set (attr "athlon_decode")
7601 (cond [(eq_attr "cpu" "athlon")
7602 (const_string "vector")
7603 (eq_attr "alternative" "1,2")
7604 (const_string "vector")]
7605 (const_string "direct")))
7606 (set (attr "amdfam10_decode")
7607 (cond [(eq_attr "alternative" "0,1")
7608 (const_string "vector")]
7609 (const_string "direct")))
7610 (set_attr "mode" "HI")])
7612 (define_expand "mulqi3"
7613 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7614 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7615 (match_operand:QI 2 "register_operand" "")))
7616 (clobber (reg:CC FLAGS_REG))])]
7617 "TARGET_QIMODE_MATH"
7624 (define_insn "*mulqi3_1"
7625 [(set (match_operand:QI 0 "register_operand" "=a")
7626 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7627 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7628 (clobber (reg:CC FLAGS_REG))]
7630 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7632 [(set_attr "type" "imul")
7633 (set_attr "length_immediate" "0")
7634 (set (attr "athlon_decode")
7635 (if_then_else (eq_attr "cpu" "athlon")
7636 (const_string "vector")
7637 (const_string "direct")))
7638 (set_attr "amdfam10_decode" "direct")
7639 (set_attr "mode" "QI")])
7641 (define_expand "umulqihi3"
7642 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7643 (mult:HI (zero_extend:HI
7644 (match_operand:QI 1 "nonimmediate_operand" ""))
7646 (match_operand:QI 2 "register_operand" ""))))
7647 (clobber (reg:CC FLAGS_REG))])]
7648 "TARGET_QIMODE_MATH"
7651 (define_insn "*umulqihi3_1"
7652 [(set (match_operand:HI 0 "register_operand" "=a")
7653 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7654 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7655 (clobber (reg:CC FLAGS_REG))]
7657 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7659 [(set_attr "type" "imul")
7660 (set_attr "length_immediate" "0")
7661 (set (attr "athlon_decode")
7662 (if_then_else (eq_attr "cpu" "athlon")
7663 (const_string "vector")
7664 (const_string "direct")))
7665 (set_attr "amdfam10_decode" "direct")
7666 (set_attr "mode" "QI")])
7668 (define_expand "mulqihi3"
7669 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7670 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7671 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7672 (clobber (reg:CC FLAGS_REG))])]
7673 "TARGET_QIMODE_MATH"
7676 (define_insn "*mulqihi3_insn"
7677 [(set (match_operand:HI 0 "register_operand" "=a")
7678 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7679 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7680 (clobber (reg:CC FLAGS_REG))]
7682 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7684 [(set_attr "type" "imul")
7685 (set_attr "length_immediate" "0")
7686 (set (attr "athlon_decode")
7687 (if_then_else (eq_attr "cpu" "athlon")
7688 (const_string "vector")
7689 (const_string "direct")))
7690 (set_attr "amdfam10_decode" "direct")
7691 (set_attr "mode" "QI")])
7693 (define_expand "umulditi3"
7694 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7695 (mult:TI (zero_extend:TI
7696 (match_operand:DI 1 "nonimmediate_operand" ""))
7698 (match_operand:DI 2 "register_operand" ""))))
7699 (clobber (reg:CC FLAGS_REG))])]
7703 (define_insn "*umulditi3_insn"
7704 [(set (match_operand:TI 0 "register_operand" "=A")
7705 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7706 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7707 (clobber (reg:CC FLAGS_REG))]
7709 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7711 [(set_attr "type" "imul")
7712 (set_attr "length_immediate" "0")
7713 (set (attr "athlon_decode")
7714 (if_then_else (eq_attr "cpu" "athlon")
7715 (const_string "vector")
7716 (const_string "double")))
7717 (set_attr "amdfam10_decode" "double")
7718 (set_attr "mode" "DI")])
7720 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7721 (define_expand "umulsidi3"
7722 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7723 (mult:DI (zero_extend:DI
7724 (match_operand:SI 1 "nonimmediate_operand" ""))
7726 (match_operand:SI 2 "register_operand" ""))))
7727 (clobber (reg:CC FLAGS_REG))])]
7731 (define_insn "*umulsidi3_insn"
7732 [(set (match_operand:DI 0 "register_operand" "=A")
7733 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7734 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7735 (clobber (reg:CC FLAGS_REG))]
7737 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7739 [(set_attr "type" "imul")
7740 (set_attr "length_immediate" "0")
7741 (set (attr "athlon_decode")
7742 (if_then_else (eq_attr "cpu" "athlon")
7743 (const_string "vector")
7744 (const_string "double")))
7745 (set_attr "amdfam10_decode" "double")
7746 (set_attr "mode" "SI")])
7748 (define_expand "mulditi3"
7749 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7750 (mult:TI (sign_extend:TI
7751 (match_operand:DI 1 "nonimmediate_operand" ""))
7753 (match_operand:DI 2 "register_operand" ""))))
7754 (clobber (reg:CC FLAGS_REG))])]
7758 (define_insn "*mulditi3_insn"
7759 [(set (match_operand:TI 0 "register_operand" "=A")
7760 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7761 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7762 (clobber (reg:CC FLAGS_REG))]
7764 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7766 [(set_attr "type" "imul")
7767 (set_attr "length_immediate" "0")
7768 (set (attr "athlon_decode")
7769 (if_then_else (eq_attr "cpu" "athlon")
7770 (const_string "vector")
7771 (const_string "double")))
7772 (set_attr "amdfam10_decode" "double")
7773 (set_attr "mode" "DI")])
7775 (define_expand "mulsidi3"
7776 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7777 (mult:DI (sign_extend:DI
7778 (match_operand:SI 1 "nonimmediate_operand" ""))
7780 (match_operand:SI 2 "register_operand" ""))))
7781 (clobber (reg:CC FLAGS_REG))])]
7785 (define_insn "*mulsidi3_insn"
7786 [(set (match_operand:DI 0 "register_operand" "=A")
7787 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7788 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7789 (clobber (reg:CC FLAGS_REG))]
7791 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7793 [(set_attr "type" "imul")
7794 (set_attr "length_immediate" "0")
7795 (set (attr "athlon_decode")
7796 (if_then_else (eq_attr "cpu" "athlon")
7797 (const_string "vector")
7798 (const_string "double")))
7799 (set_attr "amdfam10_decode" "double")
7800 (set_attr "mode" "SI")])
7802 (define_expand "umuldi3_highpart"
7803 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7806 (mult:TI (zero_extend:TI
7807 (match_operand:DI 1 "nonimmediate_operand" ""))
7809 (match_operand:DI 2 "register_operand" "")))
7811 (clobber (match_scratch:DI 3 ""))
7812 (clobber (reg:CC FLAGS_REG))])]
7816 (define_insn "*umuldi3_highpart_rex64"
7817 [(set (match_operand:DI 0 "register_operand" "=d")
7820 (mult:TI (zero_extend:TI
7821 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7823 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7825 (clobber (match_scratch:DI 3 "=1"))
7826 (clobber (reg:CC FLAGS_REG))]
7828 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7830 [(set_attr "type" "imul")
7831 (set_attr "length_immediate" "0")
7832 (set (attr "athlon_decode")
7833 (if_then_else (eq_attr "cpu" "athlon")
7834 (const_string "vector")
7835 (const_string "double")))
7836 (set_attr "amdfam10_decode" "double")
7837 (set_attr "mode" "DI")])
7839 (define_expand "umulsi3_highpart"
7840 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7843 (mult:DI (zero_extend:DI
7844 (match_operand:SI 1 "nonimmediate_operand" ""))
7846 (match_operand:SI 2 "register_operand" "")))
7848 (clobber (match_scratch:SI 3 ""))
7849 (clobber (reg:CC FLAGS_REG))])]
7853 (define_insn "*umulsi3_highpart_insn"
7854 [(set (match_operand:SI 0 "register_operand" "=d")
7857 (mult:DI (zero_extend:DI
7858 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7860 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7862 (clobber (match_scratch:SI 3 "=1"))
7863 (clobber (reg:CC FLAGS_REG))]
7864 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7866 [(set_attr "type" "imul")
7867 (set_attr "length_immediate" "0")
7868 (set (attr "athlon_decode")
7869 (if_then_else (eq_attr "cpu" "athlon")
7870 (const_string "vector")
7871 (const_string "double")))
7872 (set_attr "amdfam10_decode" "double")
7873 (set_attr "mode" "SI")])
7875 (define_insn "*umulsi3_highpart_zext"
7876 [(set (match_operand:DI 0 "register_operand" "=d")
7877 (zero_extend:DI (truncate:SI
7879 (mult:DI (zero_extend:DI
7880 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7882 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7884 (clobber (match_scratch:SI 3 "=1"))
7885 (clobber (reg:CC FLAGS_REG))]
7887 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7889 [(set_attr "type" "imul")
7890 (set_attr "length_immediate" "0")
7891 (set (attr "athlon_decode")
7892 (if_then_else (eq_attr "cpu" "athlon")
7893 (const_string "vector")
7894 (const_string "double")))
7895 (set_attr "amdfam10_decode" "double")
7896 (set_attr "mode" "SI")])
7898 (define_expand "smuldi3_highpart"
7899 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7902 (mult:TI (sign_extend:TI
7903 (match_operand:DI 1 "nonimmediate_operand" ""))
7905 (match_operand:DI 2 "register_operand" "")))
7907 (clobber (match_scratch:DI 3 ""))
7908 (clobber (reg:CC FLAGS_REG))])]
7912 (define_insn "*smuldi3_highpart_rex64"
7913 [(set (match_operand:DI 0 "register_operand" "=d")
7916 (mult:TI (sign_extend:TI
7917 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7919 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7921 (clobber (match_scratch:DI 3 "=1"))
7922 (clobber (reg:CC FLAGS_REG))]
7924 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7926 [(set_attr "type" "imul")
7927 (set (attr "athlon_decode")
7928 (if_then_else (eq_attr "cpu" "athlon")
7929 (const_string "vector")
7930 (const_string "double")))
7931 (set_attr "amdfam10_decode" "double")
7932 (set_attr "mode" "DI")])
7934 (define_expand "smulsi3_highpart"
7935 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7938 (mult:DI (sign_extend:DI
7939 (match_operand:SI 1 "nonimmediate_operand" ""))
7941 (match_operand:SI 2 "register_operand" "")))
7943 (clobber (match_scratch:SI 3 ""))
7944 (clobber (reg:CC FLAGS_REG))])]
7948 (define_insn "*smulsi3_highpart_insn"
7949 [(set (match_operand:SI 0 "register_operand" "=d")
7952 (mult:DI (sign_extend:DI
7953 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7955 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7957 (clobber (match_scratch:SI 3 "=1"))
7958 (clobber (reg:CC FLAGS_REG))]
7959 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7961 [(set_attr "type" "imul")
7962 (set (attr "athlon_decode")
7963 (if_then_else (eq_attr "cpu" "athlon")
7964 (const_string "vector")
7965 (const_string "double")))
7966 (set_attr "amdfam10_decode" "double")
7967 (set_attr "mode" "SI")])
7969 (define_insn "*smulsi3_highpart_zext"
7970 [(set (match_operand:DI 0 "register_operand" "=d")
7971 (zero_extend:DI (truncate:SI
7973 (mult:DI (sign_extend:DI
7974 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7976 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7978 (clobber (match_scratch:SI 3 "=1"))
7979 (clobber (reg:CC FLAGS_REG))]
7981 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7983 [(set_attr "type" "imul")
7984 (set (attr "athlon_decode")
7985 (if_then_else (eq_attr "cpu" "athlon")
7986 (const_string "vector")
7987 (const_string "double")))
7988 (set_attr "amdfam10_decode" "double")
7989 (set_attr "mode" "SI")])
7991 ;; The patterns that match these are at the end of this file.
7993 (define_expand "mulxf3"
7994 [(set (match_operand:XF 0 "register_operand" "")
7995 (mult:XF (match_operand:XF 1 "register_operand" "")
7996 (match_operand:XF 2 "register_operand" "")))]
8000 (define_expand "mul<mode>3"
8001 [(set (match_operand:MODEF 0 "register_operand" "")
8002 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8003 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8004 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8007 ;; Divide instructions
8009 (define_insn "divqi3"
8010 [(set (match_operand:QI 0 "register_operand" "=a")
8011 (div:QI (match_operand:HI 1 "register_operand" "0")
8012 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8013 (clobber (reg:CC FLAGS_REG))]
8014 "TARGET_QIMODE_MATH"
8016 [(set_attr "type" "idiv")
8017 (set_attr "mode" "QI")])
8019 (define_insn "udivqi3"
8020 [(set (match_operand:QI 0 "register_operand" "=a")
8021 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8022 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8023 (clobber (reg:CC FLAGS_REG))]
8024 "TARGET_QIMODE_MATH"
8026 [(set_attr "type" "idiv")
8027 (set_attr "mode" "QI")])
8029 ;; The patterns that match these are at the end of this file.
8031 (define_expand "divxf3"
8032 [(set (match_operand:XF 0 "register_operand" "")
8033 (div:XF (match_operand:XF 1 "register_operand" "")
8034 (match_operand:XF 2 "register_operand" "")))]
8038 (define_expand "divdf3"
8039 [(set (match_operand:DF 0 "register_operand" "")
8040 (div:DF (match_operand:DF 1 "register_operand" "")
8041 (match_operand:DF 2 "nonimmediate_operand" "")))]
8042 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8045 (define_expand "divsf3"
8046 [(set (match_operand:SF 0 "register_operand" "")
8047 (div:SF (match_operand:SF 1 "register_operand" "")
8048 (match_operand:SF 2 "nonimmediate_operand" "")))]
8049 "TARGET_80387 || TARGET_SSE_MATH"
8051 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8052 && flag_finite_math_only && !flag_trapping_math
8053 && flag_unsafe_math_optimizations)
8055 ix86_emit_swdivsf (operands[0], operands[1],
8056 operands[2], SFmode);
8061 ;; Remainder instructions.
8063 (define_expand "divmoddi4"
8064 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8065 (div:DI (match_operand:DI 1 "register_operand" "")
8066 (match_operand:DI 2 "nonimmediate_operand" "")))
8067 (set (match_operand:DI 3 "register_operand" "")
8068 (mod:DI (match_dup 1) (match_dup 2)))
8069 (clobber (reg:CC FLAGS_REG))])]
8073 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8074 ;; Penalize eax case slightly because it results in worse scheduling
8076 (define_insn "*divmoddi4_nocltd_rex64"
8077 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8078 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8079 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8080 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8081 (mod:DI (match_dup 2) (match_dup 3)))
8082 (clobber (reg:CC FLAGS_REG))]
8083 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8085 [(set_attr "type" "multi")])
8087 (define_insn "*divmoddi4_cltd_rex64"
8088 [(set (match_operand:DI 0 "register_operand" "=a")
8089 (div:DI (match_operand:DI 2 "register_operand" "a")
8090 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8091 (set (match_operand:DI 1 "register_operand" "=&d")
8092 (mod:DI (match_dup 2) (match_dup 3)))
8093 (clobber (reg:CC FLAGS_REG))]
8094 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8096 [(set_attr "type" "multi")])
8098 (define_insn "*divmoddi_noext_rex64"
8099 [(set (match_operand:DI 0 "register_operand" "=a")
8100 (div:DI (match_operand:DI 1 "register_operand" "0")
8101 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8102 (set (match_operand:DI 3 "register_operand" "=d")
8103 (mod:DI (match_dup 1) (match_dup 2)))
8104 (use (match_operand:DI 4 "register_operand" "3"))
8105 (clobber (reg:CC FLAGS_REG))]
8108 [(set_attr "type" "idiv")
8109 (set_attr "mode" "DI")])
8112 [(set (match_operand:DI 0 "register_operand" "")
8113 (div:DI (match_operand:DI 1 "register_operand" "")
8114 (match_operand:DI 2 "nonimmediate_operand" "")))
8115 (set (match_operand:DI 3 "register_operand" "")
8116 (mod:DI (match_dup 1) (match_dup 2)))
8117 (clobber (reg:CC FLAGS_REG))]
8118 "TARGET_64BIT && reload_completed"
8119 [(parallel [(set (match_dup 3)
8120 (ashiftrt:DI (match_dup 4) (const_int 63)))
8121 (clobber (reg:CC FLAGS_REG))])
8122 (parallel [(set (match_dup 0)
8123 (div:DI (reg:DI 0) (match_dup 2)))
8125 (mod:DI (reg:DI 0) (match_dup 2)))
8127 (clobber (reg:CC FLAGS_REG))])]
8129 /* Avoid use of cltd in favor of a mov+shift. */
8130 if (!TARGET_USE_CLTD && !optimize_size)
8132 if (true_regnum (operands[1]))
8133 emit_move_insn (operands[0], operands[1]);
8135 emit_move_insn (operands[3], operands[1]);
8136 operands[4] = operands[3];
8140 gcc_assert (!true_regnum (operands[1]));
8141 operands[4] = operands[1];
8146 (define_expand "divmodsi4"
8147 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8148 (div:SI (match_operand:SI 1 "register_operand" "")
8149 (match_operand:SI 2 "nonimmediate_operand" "")))
8150 (set (match_operand:SI 3 "register_operand" "")
8151 (mod:SI (match_dup 1) (match_dup 2)))
8152 (clobber (reg:CC FLAGS_REG))])]
8156 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8157 ;; Penalize eax case slightly because it results in worse scheduling
8159 (define_insn "*divmodsi4_nocltd"
8160 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8161 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8162 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8163 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8164 (mod:SI (match_dup 2) (match_dup 3)))
8165 (clobber (reg:CC FLAGS_REG))]
8166 "!optimize_size && !TARGET_USE_CLTD"
8168 [(set_attr "type" "multi")])
8170 (define_insn "*divmodsi4_cltd"
8171 [(set (match_operand:SI 0 "register_operand" "=a")
8172 (div:SI (match_operand:SI 2 "register_operand" "a")
8173 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8174 (set (match_operand:SI 1 "register_operand" "=&d")
8175 (mod:SI (match_dup 2) (match_dup 3)))
8176 (clobber (reg:CC FLAGS_REG))]
8177 "optimize_size || TARGET_USE_CLTD"
8179 [(set_attr "type" "multi")])
8181 (define_insn "*divmodsi_noext"
8182 [(set (match_operand:SI 0 "register_operand" "=a")
8183 (div:SI (match_operand:SI 1 "register_operand" "0")
8184 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8185 (set (match_operand:SI 3 "register_operand" "=d")
8186 (mod:SI (match_dup 1) (match_dup 2)))
8187 (use (match_operand:SI 4 "register_operand" "3"))
8188 (clobber (reg:CC FLAGS_REG))]
8191 [(set_attr "type" "idiv")
8192 (set_attr "mode" "SI")])
8195 [(set (match_operand:SI 0 "register_operand" "")
8196 (div:SI (match_operand:SI 1 "register_operand" "")
8197 (match_operand:SI 2 "nonimmediate_operand" "")))
8198 (set (match_operand:SI 3 "register_operand" "")
8199 (mod:SI (match_dup 1) (match_dup 2)))
8200 (clobber (reg:CC FLAGS_REG))]
8202 [(parallel [(set (match_dup 3)
8203 (ashiftrt:SI (match_dup 4) (const_int 31)))
8204 (clobber (reg:CC FLAGS_REG))])
8205 (parallel [(set (match_dup 0)
8206 (div:SI (reg:SI 0) (match_dup 2)))
8208 (mod:SI (reg:SI 0) (match_dup 2)))
8210 (clobber (reg:CC FLAGS_REG))])]
8212 /* Avoid use of cltd in favor of a mov+shift. */
8213 if (!TARGET_USE_CLTD && !optimize_size)
8215 if (true_regnum (operands[1]))
8216 emit_move_insn (operands[0], operands[1]);
8218 emit_move_insn (operands[3], operands[1]);
8219 operands[4] = operands[3];
8223 gcc_assert (!true_regnum (operands[1]));
8224 operands[4] = operands[1];
8228 (define_insn "divmodhi4"
8229 [(set (match_operand:HI 0 "register_operand" "=a")
8230 (div:HI (match_operand:HI 1 "register_operand" "0")
8231 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8232 (set (match_operand:HI 3 "register_operand" "=&d")
8233 (mod:HI (match_dup 1) (match_dup 2)))
8234 (clobber (reg:CC FLAGS_REG))]
8235 "TARGET_HIMODE_MATH"
8237 [(set_attr "type" "multi")
8238 (set_attr "length_immediate" "0")
8239 (set_attr "mode" "SI")])
8241 (define_insn "udivmoddi4"
8242 [(set (match_operand:DI 0 "register_operand" "=a")
8243 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8244 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8245 (set (match_operand:DI 3 "register_operand" "=&d")
8246 (umod:DI (match_dup 1) (match_dup 2)))
8247 (clobber (reg:CC FLAGS_REG))]
8249 "xor{q}\t%3, %3\;div{q}\t%2"
8250 [(set_attr "type" "multi")
8251 (set_attr "length_immediate" "0")
8252 (set_attr "mode" "DI")])
8254 (define_insn "*udivmoddi4_noext"
8255 [(set (match_operand:DI 0 "register_operand" "=a")
8256 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8257 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8258 (set (match_operand:DI 3 "register_operand" "=d")
8259 (umod:DI (match_dup 1) (match_dup 2)))
8261 (clobber (reg:CC FLAGS_REG))]
8264 [(set_attr "type" "idiv")
8265 (set_attr "mode" "DI")])
8268 [(set (match_operand:DI 0 "register_operand" "")
8269 (udiv:DI (match_operand:DI 1 "register_operand" "")
8270 (match_operand:DI 2 "nonimmediate_operand" "")))
8271 (set (match_operand:DI 3 "register_operand" "")
8272 (umod:DI (match_dup 1) (match_dup 2)))
8273 (clobber (reg:CC FLAGS_REG))]
8274 "TARGET_64BIT && reload_completed"
8275 [(set (match_dup 3) (const_int 0))
8276 (parallel [(set (match_dup 0)
8277 (udiv:DI (match_dup 1) (match_dup 2)))
8279 (umod:DI (match_dup 1) (match_dup 2)))
8281 (clobber (reg:CC FLAGS_REG))])]
8284 (define_insn "udivmodsi4"
8285 [(set (match_operand:SI 0 "register_operand" "=a")
8286 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8287 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8288 (set (match_operand:SI 3 "register_operand" "=&d")
8289 (umod:SI (match_dup 1) (match_dup 2)))
8290 (clobber (reg:CC FLAGS_REG))]
8292 "xor{l}\t%3, %3\;div{l}\t%2"
8293 [(set_attr "type" "multi")
8294 (set_attr "length_immediate" "0")
8295 (set_attr "mode" "SI")])
8297 (define_insn "*udivmodsi4_noext"
8298 [(set (match_operand:SI 0 "register_operand" "=a")
8299 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8300 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8301 (set (match_operand:SI 3 "register_operand" "=d")
8302 (umod:SI (match_dup 1) (match_dup 2)))
8304 (clobber (reg:CC FLAGS_REG))]
8307 [(set_attr "type" "idiv")
8308 (set_attr "mode" "SI")])
8311 [(set (match_operand:SI 0 "register_operand" "")
8312 (udiv:SI (match_operand:SI 1 "register_operand" "")
8313 (match_operand:SI 2 "nonimmediate_operand" "")))
8314 (set (match_operand:SI 3 "register_operand" "")
8315 (umod:SI (match_dup 1) (match_dup 2)))
8316 (clobber (reg:CC FLAGS_REG))]
8318 [(set (match_dup 3) (const_int 0))
8319 (parallel [(set (match_dup 0)
8320 (udiv:SI (match_dup 1) (match_dup 2)))
8322 (umod:SI (match_dup 1) (match_dup 2)))
8324 (clobber (reg:CC FLAGS_REG))])]
8327 (define_expand "udivmodhi4"
8328 [(set (match_dup 4) (const_int 0))
8329 (parallel [(set (match_operand:HI 0 "register_operand" "")
8330 (udiv:HI (match_operand:HI 1 "register_operand" "")
8331 (match_operand:HI 2 "nonimmediate_operand" "")))
8332 (set (match_operand:HI 3 "register_operand" "")
8333 (umod:HI (match_dup 1) (match_dup 2)))
8335 (clobber (reg:CC FLAGS_REG))])]
8336 "TARGET_HIMODE_MATH"
8337 "operands[4] = gen_reg_rtx (HImode);")
8339 (define_insn "*udivmodhi_noext"
8340 [(set (match_operand:HI 0 "register_operand" "=a")
8341 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8342 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8343 (set (match_operand:HI 3 "register_operand" "=d")
8344 (umod:HI (match_dup 1) (match_dup 2)))
8345 (use (match_operand:HI 4 "register_operand" "3"))
8346 (clobber (reg:CC FLAGS_REG))]
8349 [(set_attr "type" "idiv")
8350 (set_attr "mode" "HI")])
8352 ;; We cannot use div/idiv for double division, because it causes
8353 ;; "division by zero" on the overflow and that's not what we expect
8354 ;; from truncate. Because true (non truncating) double division is
8355 ;; never generated, we can't create this insn anyway.
8358 ; [(set (match_operand:SI 0 "register_operand" "=a")
8360 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8362 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8363 ; (set (match_operand:SI 3 "register_operand" "=d")
8365 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8366 ; (clobber (reg:CC FLAGS_REG))]
8368 ; "div{l}\t{%2, %0|%0, %2}"
8369 ; [(set_attr "type" "idiv")])
8371 ;;- Logical AND instructions
8373 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8374 ;; Note that this excludes ah.
8376 (define_insn "*testdi_1_rex64"
8377 [(set (reg FLAGS_REG)
8379 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8380 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8382 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8383 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8385 test{l}\t{%k1, %k0|%k0, %k1}
8386 test{l}\t{%k1, %k0|%k0, %k1}
8387 test{q}\t{%1, %0|%0, %1}
8388 test{q}\t{%1, %0|%0, %1}
8389 test{q}\t{%1, %0|%0, %1}"
8390 [(set_attr "type" "test")
8391 (set_attr "modrm" "0,1,0,1,1")
8392 (set_attr "mode" "SI,SI,DI,DI,DI")
8393 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8395 (define_insn "testsi_1"
8396 [(set (reg FLAGS_REG)
8398 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8399 (match_operand:SI 1 "general_operand" "in,in,rin"))
8401 "ix86_match_ccmode (insn, CCNOmode)
8402 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8403 "test{l}\t{%1, %0|%0, %1}"
8404 [(set_attr "type" "test")
8405 (set_attr "modrm" "0,1,1")
8406 (set_attr "mode" "SI")
8407 (set_attr "pent_pair" "uv,np,uv")])
8409 (define_expand "testsi_ccno_1"
8410 [(set (reg:CCNO FLAGS_REG)
8412 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8413 (match_operand:SI 1 "nonmemory_operand" ""))
8418 (define_insn "*testhi_1"
8419 [(set (reg FLAGS_REG)
8420 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8421 (match_operand:HI 1 "general_operand" "n,n,rn"))
8423 "ix86_match_ccmode (insn, CCNOmode)
8424 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8425 "test{w}\t{%1, %0|%0, %1}"
8426 [(set_attr "type" "test")
8427 (set_attr "modrm" "0,1,1")
8428 (set_attr "mode" "HI")
8429 (set_attr "pent_pair" "uv,np,uv")])
8431 (define_expand "testqi_ccz_1"
8432 [(set (reg:CCZ FLAGS_REG)
8433 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8434 (match_operand:QI 1 "nonmemory_operand" ""))
8439 (define_insn "*testqi_1_maybe_si"
8440 [(set (reg FLAGS_REG)
8443 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8444 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8446 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8447 && ix86_match_ccmode (insn,
8448 CONST_INT_P (operands[1])
8449 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8451 if (which_alternative == 3)
8453 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8454 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8455 return "test{l}\t{%1, %k0|%k0, %1}";
8457 return "test{b}\t{%1, %0|%0, %1}";
8459 [(set_attr "type" "test")
8460 (set_attr "modrm" "0,1,1,1")
8461 (set_attr "mode" "QI,QI,QI,SI")
8462 (set_attr "pent_pair" "uv,np,uv,np")])
8464 (define_insn "*testqi_1"
8465 [(set (reg FLAGS_REG)
8468 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8469 (match_operand:QI 1 "general_operand" "n,n,qn"))
8471 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8472 && ix86_match_ccmode (insn, CCNOmode)"
8473 "test{b}\t{%1, %0|%0, %1}"
8474 [(set_attr "type" "test")
8475 (set_attr "modrm" "0,1,1")
8476 (set_attr "mode" "QI")
8477 (set_attr "pent_pair" "uv,np,uv")])
8479 (define_expand "testqi_ext_ccno_0"
8480 [(set (reg:CCNO FLAGS_REG)
8484 (match_operand 0 "ext_register_operand" "")
8487 (match_operand 1 "const_int_operand" ""))
8492 (define_insn "*testqi_ext_0"
8493 [(set (reg FLAGS_REG)
8497 (match_operand 0 "ext_register_operand" "Q")
8500 (match_operand 1 "const_int_operand" "n"))
8502 "ix86_match_ccmode (insn, CCNOmode)"
8503 "test{b}\t{%1, %h0|%h0, %1}"
8504 [(set_attr "type" "test")
8505 (set_attr "mode" "QI")
8506 (set_attr "length_immediate" "1")
8507 (set_attr "pent_pair" "np")])
8509 (define_insn "*testqi_ext_1"
8510 [(set (reg FLAGS_REG)
8514 (match_operand 0 "ext_register_operand" "Q")
8518 (match_operand:QI 1 "general_operand" "Qm")))
8520 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8521 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8522 "test{b}\t{%1, %h0|%h0, %1}"
8523 [(set_attr "type" "test")
8524 (set_attr "mode" "QI")])
8526 (define_insn "*testqi_ext_1_rex64"
8527 [(set (reg FLAGS_REG)
8531 (match_operand 0 "ext_register_operand" "Q")
8535 (match_operand:QI 1 "register_operand" "Q")))
8537 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8538 "test{b}\t{%1, %h0|%h0, %1}"
8539 [(set_attr "type" "test")
8540 (set_attr "mode" "QI")])
8542 (define_insn "*testqi_ext_2"
8543 [(set (reg FLAGS_REG)
8547 (match_operand 0 "ext_register_operand" "Q")
8551 (match_operand 1 "ext_register_operand" "Q")
8555 "ix86_match_ccmode (insn, CCNOmode)"
8556 "test{b}\t{%h1, %h0|%h0, %h1}"
8557 [(set_attr "type" "test")
8558 (set_attr "mode" "QI")])
8560 ;; Combine likes to form bit extractions for some tests. Humor it.
8561 (define_insn "*testqi_ext_3"
8562 [(set (reg FLAGS_REG)
8563 (compare (zero_extract:SI
8564 (match_operand 0 "nonimmediate_operand" "rm")
8565 (match_operand:SI 1 "const_int_operand" "")
8566 (match_operand:SI 2 "const_int_operand" ""))
8568 "ix86_match_ccmode (insn, CCNOmode)
8569 && INTVAL (operands[1]) > 0
8570 && INTVAL (operands[2]) >= 0
8571 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8572 && (GET_MODE (operands[0]) == SImode
8573 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8574 || GET_MODE (operands[0]) == HImode
8575 || GET_MODE (operands[0]) == QImode)"
8578 (define_insn "*testqi_ext_3_rex64"
8579 [(set (reg FLAGS_REG)
8580 (compare (zero_extract:DI
8581 (match_operand 0 "nonimmediate_operand" "rm")
8582 (match_operand:DI 1 "const_int_operand" "")
8583 (match_operand:DI 2 "const_int_operand" ""))
8586 && ix86_match_ccmode (insn, CCNOmode)
8587 && INTVAL (operands[1]) > 0
8588 && INTVAL (operands[2]) >= 0
8589 /* Ensure that resulting mask is zero or sign extended operand. */
8590 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8591 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8592 && INTVAL (operands[1]) > 32))
8593 && (GET_MODE (operands[0]) == SImode
8594 || GET_MODE (operands[0]) == DImode
8595 || GET_MODE (operands[0]) == HImode
8596 || GET_MODE (operands[0]) == QImode)"
8600 [(set (match_operand 0 "flags_reg_operand" "")
8601 (match_operator 1 "compare_operator"
8603 (match_operand 2 "nonimmediate_operand" "")
8604 (match_operand 3 "const_int_operand" "")
8605 (match_operand 4 "const_int_operand" ""))
8607 "ix86_match_ccmode (insn, CCNOmode)"
8608 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8610 rtx val = operands[2];
8611 HOST_WIDE_INT len = INTVAL (operands[3]);
8612 HOST_WIDE_INT pos = INTVAL (operands[4]);
8614 enum machine_mode mode, submode;
8616 mode = GET_MODE (val);
8619 /* ??? Combine likes to put non-volatile mem extractions in QImode
8620 no matter the size of the test. So find a mode that works. */
8621 if (! MEM_VOLATILE_P (val))
8623 mode = smallest_mode_for_size (pos + len, MODE_INT);
8624 val = adjust_address (val, mode, 0);
8627 else if (GET_CODE (val) == SUBREG
8628 && (submode = GET_MODE (SUBREG_REG (val)),
8629 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8630 && pos + len <= GET_MODE_BITSIZE (submode))
8632 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8634 val = SUBREG_REG (val);
8636 else if (mode == HImode && pos + len <= 8)
8638 /* Small HImode tests can be converted to QImode. */
8640 val = gen_lowpart (QImode, val);
8643 if (len == HOST_BITS_PER_WIDE_INT)
8646 mask = ((HOST_WIDE_INT)1 << len) - 1;
8649 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8652 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8653 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8654 ;; this is relatively important trick.
8655 ;; Do the conversion only post-reload to avoid limiting of the register class
8658 [(set (match_operand 0 "flags_reg_operand" "")
8659 (match_operator 1 "compare_operator"
8660 [(and (match_operand 2 "register_operand" "")
8661 (match_operand 3 "const_int_operand" ""))
8664 && QI_REG_P (operands[2])
8665 && GET_MODE (operands[2]) != QImode
8666 && ((ix86_match_ccmode (insn, CCZmode)
8667 && !(INTVAL (operands[3]) & ~(255 << 8)))
8668 || (ix86_match_ccmode (insn, CCNOmode)
8669 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8672 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8675 "operands[2] = gen_lowpart (SImode, operands[2]);
8676 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8679 [(set (match_operand 0 "flags_reg_operand" "")
8680 (match_operator 1 "compare_operator"
8681 [(and (match_operand 2 "nonimmediate_operand" "")
8682 (match_operand 3 "const_int_operand" ""))
8685 && GET_MODE (operands[2]) != QImode
8686 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8687 && ((ix86_match_ccmode (insn, CCZmode)
8688 && !(INTVAL (operands[3]) & ~255))
8689 || (ix86_match_ccmode (insn, CCNOmode)
8690 && !(INTVAL (operands[3]) & ~127)))"
8692 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8694 "operands[2] = gen_lowpart (QImode, operands[2]);
8695 operands[3] = gen_lowpart (QImode, operands[3]);")
8698 ;; %%% This used to optimize known byte-wide and operations to memory,
8699 ;; and sometimes to QImode registers. If this is considered useful,
8700 ;; it should be done with splitters.
8702 (define_expand "anddi3"
8703 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8704 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8705 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8706 (clobber (reg:CC FLAGS_REG))]
8708 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8710 (define_insn "*anddi_1_rex64"
8711 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8712 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8713 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8714 (clobber (reg:CC FLAGS_REG))]
8715 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8717 switch (get_attr_type (insn))
8721 enum machine_mode mode;
8723 gcc_assert (CONST_INT_P (operands[2]));
8724 if (INTVAL (operands[2]) == 0xff)
8728 gcc_assert (INTVAL (operands[2]) == 0xffff);
8732 operands[1] = gen_lowpart (mode, operands[1]);
8734 return "movz{bq|x}\t{%1,%0|%0, %1}";
8736 return "movz{wq|x}\t{%1,%0|%0, %1}";
8740 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8741 if (get_attr_mode (insn) == MODE_SI)
8742 return "and{l}\t{%k2, %k0|%k0, %k2}";
8744 return "and{q}\t{%2, %0|%0, %2}";
8747 [(set_attr "type" "alu,alu,alu,imovx")
8748 (set_attr "length_immediate" "*,*,*,0")
8749 (set_attr "mode" "SI,DI,DI,DI")])
8751 (define_insn "*anddi_2"
8752 [(set (reg FLAGS_REG)
8753 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8754 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8756 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8757 (and:DI (match_dup 1) (match_dup 2)))]
8758 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8759 && ix86_binary_operator_ok (AND, DImode, operands)"
8761 and{l}\t{%k2, %k0|%k0, %k2}
8762 and{q}\t{%2, %0|%0, %2}
8763 and{q}\t{%2, %0|%0, %2}"
8764 [(set_attr "type" "alu")
8765 (set_attr "mode" "SI,DI,DI")])
8767 (define_expand "andsi3"
8768 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8769 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8770 (match_operand:SI 2 "general_operand" "")))
8771 (clobber (reg:CC FLAGS_REG))]
8773 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8775 (define_insn "*andsi_1"
8776 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8777 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8778 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8779 (clobber (reg:CC FLAGS_REG))]
8780 "ix86_binary_operator_ok (AND, SImode, operands)"
8782 switch (get_attr_type (insn))
8786 enum machine_mode mode;
8788 gcc_assert (CONST_INT_P (operands[2]));
8789 if (INTVAL (operands[2]) == 0xff)
8793 gcc_assert (INTVAL (operands[2]) == 0xffff);
8797 operands[1] = gen_lowpart (mode, operands[1]);
8799 return "movz{bl|x}\t{%1,%0|%0, %1}";
8801 return "movz{wl|x}\t{%1,%0|%0, %1}";
8805 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8806 return "and{l}\t{%2, %0|%0, %2}";
8809 [(set_attr "type" "alu,alu,imovx")
8810 (set_attr "length_immediate" "*,*,0")
8811 (set_attr "mode" "SI")])
8814 [(set (match_operand 0 "register_operand" "")
8816 (const_int -65536)))
8817 (clobber (reg:CC FLAGS_REG))]
8818 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8819 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8820 "operands[1] = gen_lowpart (HImode, operands[0]);")
8823 [(set (match_operand 0 "ext_register_operand" "")
8826 (clobber (reg:CC FLAGS_REG))]
8827 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8828 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8829 "operands[1] = gen_lowpart (QImode, operands[0]);")
8832 [(set (match_operand 0 "ext_register_operand" "")
8834 (const_int -65281)))
8835 (clobber (reg:CC FLAGS_REG))]
8836 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8837 [(parallel [(set (zero_extract:SI (match_dup 0)
8841 (zero_extract:SI (match_dup 0)
8844 (zero_extract:SI (match_dup 0)
8847 (clobber (reg:CC FLAGS_REG))])]
8848 "operands[0] = gen_lowpart (SImode, operands[0]);")
8850 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8851 (define_insn "*andsi_1_zext"
8852 [(set (match_operand:DI 0 "register_operand" "=r")
8854 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8855 (match_operand:SI 2 "general_operand" "g"))))
8856 (clobber (reg:CC FLAGS_REG))]
8857 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8858 "and{l}\t{%2, %k0|%k0, %2}"
8859 [(set_attr "type" "alu")
8860 (set_attr "mode" "SI")])
8862 (define_insn "*andsi_2"
8863 [(set (reg FLAGS_REG)
8864 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8865 (match_operand:SI 2 "general_operand" "g,ri"))
8867 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8868 (and:SI (match_dup 1) (match_dup 2)))]
8869 "ix86_match_ccmode (insn, CCNOmode)
8870 && ix86_binary_operator_ok (AND, SImode, operands)"
8871 "and{l}\t{%2, %0|%0, %2}"
8872 [(set_attr "type" "alu")
8873 (set_attr "mode" "SI")])
8875 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8876 (define_insn "*andsi_2_zext"
8877 [(set (reg FLAGS_REG)
8878 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8879 (match_operand:SI 2 "general_operand" "g"))
8881 (set (match_operand:DI 0 "register_operand" "=r")
8882 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8883 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8884 && ix86_binary_operator_ok (AND, SImode, operands)"
8885 "and{l}\t{%2, %k0|%k0, %2}"
8886 [(set_attr "type" "alu")
8887 (set_attr "mode" "SI")])
8889 (define_expand "andhi3"
8890 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8891 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8892 (match_operand:HI 2 "general_operand" "")))
8893 (clobber (reg:CC FLAGS_REG))]
8894 "TARGET_HIMODE_MATH"
8895 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8897 (define_insn "*andhi_1"
8898 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8899 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8900 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8901 (clobber (reg:CC FLAGS_REG))]
8902 "ix86_binary_operator_ok (AND, HImode, operands)"
8904 switch (get_attr_type (insn))
8907 gcc_assert (CONST_INT_P (operands[2]));
8908 gcc_assert (INTVAL (operands[2]) == 0xff);
8909 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8912 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8914 return "and{w}\t{%2, %0|%0, %2}";
8917 [(set_attr "type" "alu,alu,imovx")
8918 (set_attr "length_immediate" "*,*,0")
8919 (set_attr "mode" "HI,HI,SI")])
8921 (define_insn "*andhi_2"
8922 [(set (reg FLAGS_REG)
8923 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8924 (match_operand:HI 2 "general_operand" "g,ri"))
8926 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8927 (and:HI (match_dup 1) (match_dup 2)))]
8928 "ix86_match_ccmode (insn, CCNOmode)
8929 && ix86_binary_operator_ok (AND, HImode, operands)"
8930 "and{w}\t{%2, %0|%0, %2}"
8931 [(set_attr "type" "alu")
8932 (set_attr "mode" "HI")])
8934 (define_expand "andqi3"
8935 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8936 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8937 (match_operand:QI 2 "general_operand" "")))
8938 (clobber (reg:CC FLAGS_REG))]
8939 "TARGET_QIMODE_MATH"
8940 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8942 ;; %%% Potential partial reg stall on alternative 2. What to do?
8943 (define_insn "*andqi_1"
8944 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8945 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8946 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8947 (clobber (reg:CC FLAGS_REG))]
8948 "ix86_binary_operator_ok (AND, QImode, operands)"
8950 and{b}\t{%2, %0|%0, %2}
8951 and{b}\t{%2, %0|%0, %2}
8952 and{l}\t{%k2, %k0|%k0, %k2}"
8953 [(set_attr "type" "alu")
8954 (set_attr "mode" "QI,QI,SI")])
8956 (define_insn "*andqi_1_slp"
8957 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8958 (and:QI (match_dup 0)
8959 (match_operand:QI 1 "general_operand" "qi,qmi")))
8960 (clobber (reg:CC FLAGS_REG))]
8961 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8962 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8963 "and{b}\t{%1, %0|%0, %1}"
8964 [(set_attr "type" "alu1")
8965 (set_attr "mode" "QI")])
8967 (define_insn "*andqi_2_maybe_si"
8968 [(set (reg FLAGS_REG)
8970 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8971 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8973 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8974 (and:QI (match_dup 1) (match_dup 2)))]
8975 "ix86_binary_operator_ok (AND, QImode, operands)
8976 && ix86_match_ccmode (insn,
8977 CONST_INT_P (operands[2])
8978 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8980 if (which_alternative == 2)
8982 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8983 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8984 return "and{l}\t{%2, %k0|%k0, %2}";
8986 return "and{b}\t{%2, %0|%0, %2}";
8988 [(set_attr "type" "alu")
8989 (set_attr "mode" "QI,QI,SI")])
8991 (define_insn "*andqi_2"
8992 [(set (reg FLAGS_REG)
8994 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8995 (match_operand:QI 2 "general_operand" "qim,qi"))
8997 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8998 (and:QI (match_dup 1) (match_dup 2)))]
8999 "ix86_match_ccmode (insn, CCNOmode)
9000 && ix86_binary_operator_ok (AND, QImode, operands)"
9001 "and{b}\t{%2, %0|%0, %2}"
9002 [(set_attr "type" "alu")
9003 (set_attr "mode" "QI")])
9005 (define_insn "*andqi_2_slp"
9006 [(set (reg FLAGS_REG)
9008 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9009 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9011 (set (strict_low_part (match_dup 0))
9012 (and:QI (match_dup 0) (match_dup 1)))]
9013 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9014 && ix86_match_ccmode (insn, CCNOmode)
9015 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9016 "and{b}\t{%1, %0|%0, %1}"
9017 [(set_attr "type" "alu1")
9018 (set_attr "mode" "QI")])
9020 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9021 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9022 ;; for a QImode operand, which of course failed.
9024 (define_insn "andqi_ext_0"
9025 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9030 (match_operand 1 "ext_register_operand" "0")
9033 (match_operand 2 "const_int_operand" "n")))
9034 (clobber (reg:CC FLAGS_REG))]
9036 "and{b}\t{%2, %h0|%h0, %2}"
9037 [(set_attr "type" "alu")
9038 (set_attr "length_immediate" "1")
9039 (set_attr "mode" "QI")])
9041 ;; Generated by peephole translating test to and. This shows up
9042 ;; often in fp comparisons.
9044 (define_insn "*andqi_ext_0_cc"
9045 [(set (reg FLAGS_REG)
9049 (match_operand 1 "ext_register_operand" "0")
9052 (match_operand 2 "const_int_operand" "n"))
9054 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9063 "ix86_match_ccmode (insn, CCNOmode)"
9064 "and{b}\t{%2, %h0|%h0, %2}"
9065 [(set_attr "type" "alu")
9066 (set_attr "length_immediate" "1")
9067 (set_attr "mode" "QI")])
9069 (define_insn "*andqi_ext_1"
9070 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9075 (match_operand 1 "ext_register_operand" "0")
9079 (match_operand:QI 2 "general_operand" "Qm"))))
9080 (clobber (reg:CC FLAGS_REG))]
9082 "and{b}\t{%2, %h0|%h0, %2}"
9083 [(set_attr "type" "alu")
9084 (set_attr "length_immediate" "0")
9085 (set_attr "mode" "QI")])
9087 (define_insn "*andqi_ext_1_rex64"
9088 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9093 (match_operand 1 "ext_register_operand" "0")
9097 (match_operand 2 "ext_register_operand" "Q"))))
9098 (clobber (reg:CC FLAGS_REG))]
9100 "and{b}\t{%2, %h0|%h0, %2}"
9101 [(set_attr "type" "alu")
9102 (set_attr "length_immediate" "0")
9103 (set_attr "mode" "QI")])
9105 (define_insn "*andqi_ext_2"
9106 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9111 (match_operand 1 "ext_register_operand" "%0")
9115 (match_operand 2 "ext_register_operand" "Q")
9118 (clobber (reg:CC FLAGS_REG))]
9120 "and{b}\t{%h2, %h0|%h0, %h2}"
9121 [(set_attr "type" "alu")
9122 (set_attr "length_immediate" "0")
9123 (set_attr "mode" "QI")])
9125 ;; Convert wide AND instructions with immediate operand to shorter QImode
9126 ;; equivalents when possible.
9127 ;; Don't do the splitting with memory operands, since it introduces risk
9128 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9129 ;; for size, but that can (should?) be handled by generic code instead.
9131 [(set (match_operand 0 "register_operand" "")
9132 (and (match_operand 1 "register_operand" "")
9133 (match_operand 2 "const_int_operand" "")))
9134 (clobber (reg:CC FLAGS_REG))]
9136 && QI_REG_P (operands[0])
9137 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9138 && !(~INTVAL (operands[2]) & ~(255 << 8))
9139 && GET_MODE (operands[0]) != QImode"
9140 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9141 (and:SI (zero_extract:SI (match_dup 1)
9142 (const_int 8) (const_int 8))
9144 (clobber (reg:CC FLAGS_REG))])]
9145 "operands[0] = gen_lowpart (SImode, operands[0]);
9146 operands[1] = gen_lowpart (SImode, operands[1]);
9147 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9149 ;; Since AND can be encoded with sign extended immediate, this is only
9150 ;; profitable when 7th bit is not set.
9152 [(set (match_operand 0 "register_operand" "")
9153 (and (match_operand 1 "general_operand" "")
9154 (match_operand 2 "const_int_operand" "")))
9155 (clobber (reg:CC FLAGS_REG))]
9157 && ANY_QI_REG_P (operands[0])
9158 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9159 && !(~INTVAL (operands[2]) & ~255)
9160 && !(INTVAL (operands[2]) & 128)
9161 && GET_MODE (operands[0]) != QImode"
9162 [(parallel [(set (strict_low_part (match_dup 0))
9163 (and:QI (match_dup 1)
9165 (clobber (reg:CC FLAGS_REG))])]
9166 "operands[0] = gen_lowpart (QImode, operands[0]);
9167 operands[1] = gen_lowpart (QImode, operands[1]);
9168 operands[2] = gen_lowpart (QImode, operands[2]);")
9170 ;; Logical inclusive OR instructions
9172 ;; %%% This used to optimize known byte-wide and operations to memory.
9173 ;; If this is considered useful, it should be done with splitters.
9175 (define_expand "iordi3"
9176 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9177 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9178 (match_operand:DI 2 "x86_64_general_operand" "")))
9179 (clobber (reg:CC FLAGS_REG))]
9181 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9183 (define_insn "*iordi_1_rex64"
9184 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9185 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9186 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9187 (clobber (reg:CC FLAGS_REG))]
9189 && ix86_binary_operator_ok (IOR, DImode, operands)"
9190 "or{q}\t{%2, %0|%0, %2}"
9191 [(set_attr "type" "alu")
9192 (set_attr "mode" "DI")])
9194 (define_insn "*iordi_2_rex64"
9195 [(set (reg FLAGS_REG)
9196 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9197 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9199 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9200 (ior:DI (match_dup 1) (match_dup 2)))]
9202 && ix86_match_ccmode (insn, CCNOmode)
9203 && ix86_binary_operator_ok (IOR, DImode, operands)"
9204 "or{q}\t{%2, %0|%0, %2}"
9205 [(set_attr "type" "alu")
9206 (set_attr "mode" "DI")])
9208 (define_insn "*iordi_3_rex64"
9209 [(set (reg FLAGS_REG)
9210 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9211 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9213 (clobber (match_scratch:DI 0 "=r"))]
9215 && ix86_match_ccmode (insn, CCNOmode)
9216 && ix86_binary_operator_ok (IOR, DImode, operands)"
9217 "or{q}\t{%2, %0|%0, %2}"
9218 [(set_attr "type" "alu")
9219 (set_attr "mode" "DI")])
9222 (define_expand "iorsi3"
9223 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9224 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9225 (match_operand:SI 2 "general_operand" "")))
9226 (clobber (reg:CC FLAGS_REG))]
9228 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9230 (define_insn "*iorsi_1"
9231 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9232 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9233 (match_operand:SI 2 "general_operand" "ri,g")))
9234 (clobber (reg:CC FLAGS_REG))]
9235 "ix86_binary_operator_ok (IOR, SImode, operands)"
9236 "or{l}\t{%2, %0|%0, %2}"
9237 [(set_attr "type" "alu")
9238 (set_attr "mode" "SI")])
9240 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9241 (define_insn "*iorsi_1_zext"
9242 [(set (match_operand:DI 0 "register_operand" "=r")
9244 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9245 (match_operand:SI 2 "general_operand" "g"))))
9246 (clobber (reg:CC FLAGS_REG))]
9247 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9248 "or{l}\t{%2, %k0|%k0, %2}"
9249 [(set_attr "type" "alu")
9250 (set_attr "mode" "SI")])
9252 (define_insn "*iorsi_1_zext_imm"
9253 [(set (match_operand:DI 0 "register_operand" "=r")
9254 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9255 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9256 (clobber (reg:CC FLAGS_REG))]
9258 "or{l}\t{%2, %k0|%k0, %2}"
9259 [(set_attr "type" "alu")
9260 (set_attr "mode" "SI")])
9262 (define_insn "*iorsi_2"
9263 [(set (reg FLAGS_REG)
9264 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9265 (match_operand:SI 2 "general_operand" "g,ri"))
9267 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9268 (ior:SI (match_dup 1) (match_dup 2)))]
9269 "ix86_match_ccmode (insn, CCNOmode)
9270 && ix86_binary_operator_ok (IOR, SImode, operands)"
9271 "or{l}\t{%2, %0|%0, %2}"
9272 [(set_attr "type" "alu")
9273 (set_attr "mode" "SI")])
9275 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9276 ;; ??? Special case for immediate operand is missing - it is tricky.
9277 (define_insn "*iorsi_2_zext"
9278 [(set (reg FLAGS_REG)
9279 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9280 (match_operand:SI 2 "general_operand" "g"))
9282 (set (match_operand:DI 0 "register_operand" "=r")
9283 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9284 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9285 && ix86_binary_operator_ok (IOR, SImode, operands)"
9286 "or{l}\t{%2, %k0|%k0, %2}"
9287 [(set_attr "type" "alu")
9288 (set_attr "mode" "SI")])
9290 (define_insn "*iorsi_2_zext_imm"
9291 [(set (reg FLAGS_REG)
9292 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9293 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9295 (set (match_operand:DI 0 "register_operand" "=r")
9296 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9297 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9298 && ix86_binary_operator_ok (IOR, SImode, operands)"
9299 "or{l}\t{%2, %k0|%k0, %2}"
9300 [(set_attr "type" "alu")
9301 (set_attr "mode" "SI")])
9303 (define_insn "*iorsi_3"
9304 [(set (reg FLAGS_REG)
9305 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9306 (match_operand:SI 2 "general_operand" "g"))
9308 (clobber (match_scratch:SI 0 "=r"))]
9309 "ix86_match_ccmode (insn, CCNOmode)
9310 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9311 "or{l}\t{%2, %0|%0, %2}"
9312 [(set_attr "type" "alu")
9313 (set_attr "mode" "SI")])
9315 (define_expand "iorhi3"
9316 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9317 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9318 (match_operand:HI 2 "general_operand" "")))
9319 (clobber (reg:CC FLAGS_REG))]
9320 "TARGET_HIMODE_MATH"
9321 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9323 (define_insn "*iorhi_1"
9324 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9325 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9326 (match_operand:HI 2 "general_operand" "g,ri")))
9327 (clobber (reg:CC FLAGS_REG))]
9328 "ix86_binary_operator_ok (IOR, HImode, operands)"
9329 "or{w}\t{%2, %0|%0, %2}"
9330 [(set_attr "type" "alu")
9331 (set_attr "mode" "HI")])
9333 (define_insn "*iorhi_2"
9334 [(set (reg FLAGS_REG)
9335 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9336 (match_operand:HI 2 "general_operand" "g,ri"))
9338 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9339 (ior:HI (match_dup 1) (match_dup 2)))]
9340 "ix86_match_ccmode (insn, CCNOmode)
9341 && ix86_binary_operator_ok (IOR, HImode, operands)"
9342 "or{w}\t{%2, %0|%0, %2}"
9343 [(set_attr "type" "alu")
9344 (set_attr "mode" "HI")])
9346 (define_insn "*iorhi_3"
9347 [(set (reg FLAGS_REG)
9348 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9349 (match_operand:HI 2 "general_operand" "g"))
9351 (clobber (match_scratch:HI 0 "=r"))]
9352 "ix86_match_ccmode (insn, CCNOmode)
9353 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9354 "or{w}\t{%2, %0|%0, %2}"
9355 [(set_attr "type" "alu")
9356 (set_attr "mode" "HI")])
9358 (define_expand "iorqi3"
9359 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9360 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9361 (match_operand:QI 2 "general_operand" "")))
9362 (clobber (reg:CC FLAGS_REG))]
9363 "TARGET_QIMODE_MATH"
9364 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9366 ;; %%% Potential partial reg stall on alternative 2. What to do?
9367 (define_insn "*iorqi_1"
9368 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9369 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9370 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9371 (clobber (reg:CC FLAGS_REG))]
9372 "ix86_binary_operator_ok (IOR, QImode, operands)"
9374 or{b}\t{%2, %0|%0, %2}
9375 or{b}\t{%2, %0|%0, %2}
9376 or{l}\t{%k2, %k0|%k0, %k2}"
9377 [(set_attr "type" "alu")
9378 (set_attr "mode" "QI,QI,SI")])
9380 (define_insn "*iorqi_1_slp"
9381 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9382 (ior:QI (match_dup 0)
9383 (match_operand:QI 1 "general_operand" "qmi,qi")))
9384 (clobber (reg:CC FLAGS_REG))]
9385 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9386 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9387 "or{b}\t{%1, %0|%0, %1}"
9388 [(set_attr "type" "alu1")
9389 (set_attr "mode" "QI")])
9391 (define_insn "*iorqi_2"
9392 [(set (reg FLAGS_REG)
9393 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9394 (match_operand:QI 2 "general_operand" "qim,qi"))
9396 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9397 (ior:QI (match_dup 1) (match_dup 2)))]
9398 "ix86_match_ccmode (insn, CCNOmode)
9399 && ix86_binary_operator_ok (IOR, QImode, operands)"
9400 "or{b}\t{%2, %0|%0, %2}"
9401 [(set_attr "type" "alu")
9402 (set_attr "mode" "QI")])
9404 (define_insn "*iorqi_2_slp"
9405 [(set (reg FLAGS_REG)
9406 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9407 (match_operand:QI 1 "general_operand" "qim,qi"))
9409 (set (strict_low_part (match_dup 0))
9410 (ior:QI (match_dup 0) (match_dup 1)))]
9411 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9412 && ix86_match_ccmode (insn, CCNOmode)
9413 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9414 "or{b}\t{%1, %0|%0, %1}"
9415 [(set_attr "type" "alu1")
9416 (set_attr "mode" "QI")])
9418 (define_insn "*iorqi_3"
9419 [(set (reg FLAGS_REG)
9420 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9421 (match_operand:QI 2 "general_operand" "qim"))
9423 (clobber (match_scratch:QI 0 "=q"))]
9424 "ix86_match_ccmode (insn, CCNOmode)
9425 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9426 "or{b}\t{%2, %0|%0, %2}"
9427 [(set_attr "type" "alu")
9428 (set_attr "mode" "QI")])
9430 (define_insn "iorqi_ext_0"
9431 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9436 (match_operand 1 "ext_register_operand" "0")
9439 (match_operand 2 "const_int_operand" "n")))
9440 (clobber (reg:CC FLAGS_REG))]
9441 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9442 "or{b}\t{%2, %h0|%h0, %2}"
9443 [(set_attr "type" "alu")
9444 (set_attr "length_immediate" "1")
9445 (set_attr "mode" "QI")])
9447 (define_insn "*iorqi_ext_1"
9448 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9453 (match_operand 1 "ext_register_operand" "0")
9457 (match_operand:QI 2 "general_operand" "Qm"))))
9458 (clobber (reg:CC FLAGS_REG))]
9460 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9461 "or{b}\t{%2, %h0|%h0, %2}"
9462 [(set_attr "type" "alu")
9463 (set_attr "length_immediate" "0")
9464 (set_attr "mode" "QI")])
9466 (define_insn "*iorqi_ext_1_rex64"
9467 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9472 (match_operand 1 "ext_register_operand" "0")
9476 (match_operand 2 "ext_register_operand" "Q"))))
9477 (clobber (reg:CC FLAGS_REG))]
9479 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9480 "or{b}\t{%2, %h0|%h0, %2}"
9481 [(set_attr "type" "alu")
9482 (set_attr "length_immediate" "0")
9483 (set_attr "mode" "QI")])
9485 (define_insn "*iorqi_ext_2"
9486 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9490 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9493 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9496 (clobber (reg:CC FLAGS_REG))]
9497 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9498 "ior{b}\t{%h2, %h0|%h0, %h2}"
9499 [(set_attr "type" "alu")
9500 (set_attr "length_immediate" "0")
9501 (set_attr "mode" "QI")])
9504 [(set (match_operand 0 "register_operand" "")
9505 (ior (match_operand 1 "register_operand" "")
9506 (match_operand 2 "const_int_operand" "")))
9507 (clobber (reg:CC FLAGS_REG))]
9509 && QI_REG_P (operands[0])
9510 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9511 && !(INTVAL (operands[2]) & ~(255 << 8))
9512 && GET_MODE (operands[0]) != QImode"
9513 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9514 (ior:SI (zero_extract:SI (match_dup 1)
9515 (const_int 8) (const_int 8))
9517 (clobber (reg:CC FLAGS_REG))])]
9518 "operands[0] = gen_lowpart (SImode, operands[0]);
9519 operands[1] = gen_lowpart (SImode, operands[1]);
9520 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9522 ;; Since OR can be encoded with sign extended immediate, this is only
9523 ;; profitable when 7th bit is set.
9525 [(set (match_operand 0 "register_operand" "")
9526 (ior (match_operand 1 "general_operand" "")
9527 (match_operand 2 "const_int_operand" "")))
9528 (clobber (reg:CC FLAGS_REG))]
9530 && ANY_QI_REG_P (operands[0])
9531 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9532 && !(INTVAL (operands[2]) & ~255)
9533 && (INTVAL (operands[2]) & 128)
9534 && GET_MODE (operands[0]) != QImode"
9535 [(parallel [(set (strict_low_part (match_dup 0))
9536 (ior:QI (match_dup 1)
9538 (clobber (reg:CC FLAGS_REG))])]
9539 "operands[0] = gen_lowpart (QImode, operands[0]);
9540 operands[1] = gen_lowpart (QImode, operands[1]);
9541 operands[2] = gen_lowpart (QImode, operands[2]);")
9543 ;; Logical XOR instructions
9545 ;; %%% This used to optimize known byte-wide and operations to memory.
9546 ;; If this is considered useful, it should be done with splitters.
9548 (define_expand "xordi3"
9549 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9550 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9551 (match_operand:DI 2 "x86_64_general_operand" "")))
9552 (clobber (reg:CC FLAGS_REG))]
9554 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9556 (define_insn "*xordi_1_rex64"
9557 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9558 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9559 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9560 (clobber (reg:CC FLAGS_REG))]
9562 && ix86_binary_operator_ok (XOR, DImode, operands)"
9564 xor{q}\t{%2, %0|%0, %2}
9565 xor{q}\t{%2, %0|%0, %2}"
9566 [(set_attr "type" "alu")
9567 (set_attr "mode" "DI,DI")])
9569 (define_insn "*xordi_2_rex64"
9570 [(set (reg FLAGS_REG)
9571 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9572 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9574 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9575 (xor:DI (match_dup 1) (match_dup 2)))]
9577 && ix86_match_ccmode (insn, CCNOmode)
9578 && ix86_binary_operator_ok (XOR, DImode, operands)"
9580 xor{q}\t{%2, %0|%0, %2}
9581 xor{q}\t{%2, %0|%0, %2}"
9582 [(set_attr "type" "alu")
9583 (set_attr "mode" "DI,DI")])
9585 (define_insn "*xordi_3_rex64"
9586 [(set (reg FLAGS_REG)
9587 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9588 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9590 (clobber (match_scratch:DI 0 "=r"))]
9592 && ix86_match_ccmode (insn, CCNOmode)
9593 && ix86_binary_operator_ok (XOR, DImode, operands)"
9594 "xor{q}\t{%2, %0|%0, %2}"
9595 [(set_attr "type" "alu")
9596 (set_attr "mode" "DI")])
9598 (define_expand "xorsi3"
9599 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9600 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9601 (match_operand:SI 2 "general_operand" "")))
9602 (clobber (reg:CC FLAGS_REG))]
9604 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9606 (define_insn "*xorsi_1"
9607 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9608 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9609 (match_operand:SI 2 "general_operand" "ri,rm")))
9610 (clobber (reg:CC FLAGS_REG))]
9611 "ix86_binary_operator_ok (XOR, SImode, operands)"
9612 "xor{l}\t{%2, %0|%0, %2}"
9613 [(set_attr "type" "alu")
9614 (set_attr "mode" "SI")])
9616 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9617 ;; Add speccase for immediates
9618 (define_insn "*xorsi_1_zext"
9619 [(set (match_operand:DI 0 "register_operand" "=r")
9621 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9622 (match_operand:SI 2 "general_operand" "g"))))
9623 (clobber (reg:CC FLAGS_REG))]
9624 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9625 "xor{l}\t{%2, %k0|%k0, %2}"
9626 [(set_attr "type" "alu")
9627 (set_attr "mode" "SI")])
9629 (define_insn "*xorsi_1_zext_imm"
9630 [(set (match_operand:DI 0 "register_operand" "=r")
9631 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9632 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9633 (clobber (reg:CC FLAGS_REG))]
9634 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9635 "xor{l}\t{%2, %k0|%k0, %2}"
9636 [(set_attr "type" "alu")
9637 (set_attr "mode" "SI")])
9639 (define_insn "*xorsi_2"
9640 [(set (reg FLAGS_REG)
9641 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9642 (match_operand:SI 2 "general_operand" "g,ri"))
9644 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9645 (xor:SI (match_dup 1) (match_dup 2)))]
9646 "ix86_match_ccmode (insn, CCNOmode)
9647 && ix86_binary_operator_ok (XOR, SImode, operands)"
9648 "xor{l}\t{%2, %0|%0, %2}"
9649 [(set_attr "type" "alu")
9650 (set_attr "mode" "SI")])
9652 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9653 ;; ??? Special case for immediate operand is missing - it is tricky.
9654 (define_insn "*xorsi_2_zext"
9655 [(set (reg FLAGS_REG)
9656 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9657 (match_operand:SI 2 "general_operand" "g"))
9659 (set (match_operand:DI 0 "register_operand" "=r")
9660 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9661 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9662 && ix86_binary_operator_ok (XOR, SImode, operands)"
9663 "xor{l}\t{%2, %k0|%k0, %2}"
9664 [(set_attr "type" "alu")
9665 (set_attr "mode" "SI")])
9667 (define_insn "*xorsi_2_zext_imm"
9668 [(set (reg FLAGS_REG)
9669 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9670 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9672 (set (match_operand:DI 0 "register_operand" "=r")
9673 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9674 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9675 && ix86_binary_operator_ok (XOR, SImode, operands)"
9676 "xor{l}\t{%2, %k0|%k0, %2}"
9677 [(set_attr "type" "alu")
9678 (set_attr "mode" "SI")])
9680 (define_insn "*xorsi_3"
9681 [(set (reg FLAGS_REG)
9682 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9683 (match_operand:SI 2 "general_operand" "g"))
9685 (clobber (match_scratch:SI 0 "=r"))]
9686 "ix86_match_ccmode (insn, CCNOmode)
9687 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9688 "xor{l}\t{%2, %0|%0, %2}"
9689 [(set_attr "type" "alu")
9690 (set_attr "mode" "SI")])
9692 (define_expand "xorhi3"
9693 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9694 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9695 (match_operand:HI 2 "general_operand" "")))
9696 (clobber (reg:CC FLAGS_REG))]
9697 "TARGET_HIMODE_MATH"
9698 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9700 (define_insn "*xorhi_1"
9701 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9702 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9703 (match_operand:HI 2 "general_operand" "g,ri")))
9704 (clobber (reg:CC FLAGS_REG))]
9705 "ix86_binary_operator_ok (XOR, HImode, operands)"
9706 "xor{w}\t{%2, %0|%0, %2}"
9707 [(set_attr "type" "alu")
9708 (set_attr "mode" "HI")])
9710 (define_insn "*xorhi_2"
9711 [(set (reg FLAGS_REG)
9712 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9713 (match_operand:HI 2 "general_operand" "g,ri"))
9715 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9716 (xor:HI (match_dup 1) (match_dup 2)))]
9717 "ix86_match_ccmode (insn, CCNOmode)
9718 && ix86_binary_operator_ok (XOR, HImode, operands)"
9719 "xor{w}\t{%2, %0|%0, %2}"
9720 [(set_attr "type" "alu")
9721 (set_attr "mode" "HI")])
9723 (define_insn "*xorhi_3"
9724 [(set (reg FLAGS_REG)
9725 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9726 (match_operand:HI 2 "general_operand" "g"))
9728 (clobber (match_scratch:HI 0 "=r"))]
9729 "ix86_match_ccmode (insn, CCNOmode)
9730 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9731 "xor{w}\t{%2, %0|%0, %2}"
9732 [(set_attr "type" "alu")
9733 (set_attr "mode" "HI")])
9735 (define_expand "xorqi3"
9736 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9737 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9738 (match_operand:QI 2 "general_operand" "")))
9739 (clobber (reg:CC FLAGS_REG))]
9740 "TARGET_QIMODE_MATH"
9741 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9743 ;; %%% Potential partial reg stall on alternative 2. What to do?
9744 (define_insn "*xorqi_1"
9745 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9746 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9747 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9748 (clobber (reg:CC FLAGS_REG))]
9749 "ix86_binary_operator_ok (XOR, QImode, operands)"
9751 xor{b}\t{%2, %0|%0, %2}
9752 xor{b}\t{%2, %0|%0, %2}
9753 xor{l}\t{%k2, %k0|%k0, %k2}"
9754 [(set_attr "type" "alu")
9755 (set_attr "mode" "QI,QI,SI")])
9757 (define_insn "*xorqi_1_slp"
9758 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9759 (xor:QI (match_dup 0)
9760 (match_operand:QI 1 "general_operand" "qi,qmi")))
9761 (clobber (reg:CC FLAGS_REG))]
9762 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9763 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9764 "xor{b}\t{%1, %0|%0, %1}"
9765 [(set_attr "type" "alu1")
9766 (set_attr "mode" "QI")])
9768 (define_insn "xorqi_ext_0"
9769 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9774 (match_operand 1 "ext_register_operand" "0")
9777 (match_operand 2 "const_int_operand" "n")))
9778 (clobber (reg:CC FLAGS_REG))]
9779 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9780 "xor{b}\t{%2, %h0|%h0, %2}"
9781 [(set_attr "type" "alu")
9782 (set_attr "length_immediate" "1")
9783 (set_attr "mode" "QI")])
9785 (define_insn "*xorqi_ext_1"
9786 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9791 (match_operand 1 "ext_register_operand" "0")
9795 (match_operand:QI 2 "general_operand" "Qm"))))
9796 (clobber (reg:CC FLAGS_REG))]
9798 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9799 "xor{b}\t{%2, %h0|%h0, %2}"
9800 [(set_attr "type" "alu")
9801 (set_attr "length_immediate" "0")
9802 (set_attr "mode" "QI")])
9804 (define_insn "*xorqi_ext_1_rex64"
9805 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9810 (match_operand 1 "ext_register_operand" "0")
9814 (match_operand 2 "ext_register_operand" "Q"))))
9815 (clobber (reg:CC FLAGS_REG))]
9817 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9818 "xor{b}\t{%2, %h0|%h0, %2}"
9819 [(set_attr "type" "alu")
9820 (set_attr "length_immediate" "0")
9821 (set_attr "mode" "QI")])
9823 (define_insn "*xorqi_ext_2"
9824 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9828 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9831 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9834 (clobber (reg:CC FLAGS_REG))]
9835 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9836 "xor{b}\t{%h2, %h0|%h0, %h2}"
9837 [(set_attr "type" "alu")
9838 (set_attr "length_immediate" "0")
9839 (set_attr "mode" "QI")])
9841 (define_insn "*xorqi_cc_1"
9842 [(set (reg FLAGS_REG)
9844 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9845 (match_operand:QI 2 "general_operand" "qim,qi"))
9847 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9848 (xor:QI (match_dup 1) (match_dup 2)))]
9849 "ix86_match_ccmode (insn, CCNOmode)
9850 && ix86_binary_operator_ok (XOR, QImode, operands)"
9851 "xor{b}\t{%2, %0|%0, %2}"
9852 [(set_attr "type" "alu")
9853 (set_attr "mode" "QI")])
9855 (define_insn "*xorqi_2_slp"
9856 [(set (reg FLAGS_REG)
9857 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9858 (match_operand:QI 1 "general_operand" "qim,qi"))
9860 (set (strict_low_part (match_dup 0))
9861 (xor:QI (match_dup 0) (match_dup 1)))]
9862 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9863 && ix86_match_ccmode (insn, CCNOmode)
9864 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9865 "xor{b}\t{%1, %0|%0, %1}"
9866 [(set_attr "type" "alu1")
9867 (set_attr "mode" "QI")])
9869 (define_insn "*xorqi_cc_2"
9870 [(set (reg FLAGS_REG)
9872 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9873 (match_operand:QI 2 "general_operand" "qim"))
9875 (clobber (match_scratch:QI 0 "=q"))]
9876 "ix86_match_ccmode (insn, CCNOmode)
9877 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9878 "xor{b}\t{%2, %0|%0, %2}"
9879 [(set_attr "type" "alu")
9880 (set_attr "mode" "QI")])
9882 (define_insn "*xorqi_cc_ext_1"
9883 [(set (reg FLAGS_REG)
9887 (match_operand 1 "ext_register_operand" "0")
9890 (match_operand:QI 2 "general_operand" "qmn"))
9892 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9896 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9898 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9899 "xor{b}\t{%2, %h0|%h0, %2}"
9900 [(set_attr "type" "alu")
9901 (set_attr "mode" "QI")])
9903 (define_insn "*xorqi_cc_ext_1_rex64"
9904 [(set (reg FLAGS_REG)
9908 (match_operand 1 "ext_register_operand" "0")
9911 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9913 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9917 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9919 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9920 "xor{b}\t{%2, %h0|%h0, %2}"
9921 [(set_attr "type" "alu")
9922 (set_attr "mode" "QI")])
9924 (define_expand "xorqi_cc_ext_1"
9926 (set (reg:CCNO FLAGS_REG)
9930 (match_operand 1 "ext_register_operand" "")
9933 (match_operand:QI 2 "general_operand" ""))
9935 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9939 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9945 [(set (match_operand 0 "register_operand" "")
9946 (xor (match_operand 1 "register_operand" "")
9947 (match_operand 2 "const_int_operand" "")))
9948 (clobber (reg:CC FLAGS_REG))]
9950 && QI_REG_P (operands[0])
9951 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9952 && !(INTVAL (operands[2]) & ~(255 << 8))
9953 && GET_MODE (operands[0]) != QImode"
9954 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9955 (xor:SI (zero_extract:SI (match_dup 1)
9956 (const_int 8) (const_int 8))
9958 (clobber (reg:CC FLAGS_REG))])]
9959 "operands[0] = gen_lowpart (SImode, operands[0]);
9960 operands[1] = gen_lowpart (SImode, operands[1]);
9961 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9963 ;; Since XOR can be encoded with sign extended immediate, this is only
9964 ;; profitable when 7th bit is set.
9966 [(set (match_operand 0 "register_operand" "")
9967 (xor (match_operand 1 "general_operand" "")
9968 (match_operand 2 "const_int_operand" "")))
9969 (clobber (reg:CC FLAGS_REG))]
9971 && ANY_QI_REG_P (operands[0])
9972 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9973 && !(INTVAL (operands[2]) & ~255)
9974 && (INTVAL (operands[2]) & 128)
9975 && GET_MODE (operands[0]) != QImode"
9976 [(parallel [(set (strict_low_part (match_dup 0))
9977 (xor:QI (match_dup 1)
9979 (clobber (reg:CC FLAGS_REG))])]
9980 "operands[0] = gen_lowpart (QImode, operands[0]);
9981 operands[1] = gen_lowpart (QImode, operands[1]);
9982 operands[2] = gen_lowpart (QImode, operands[2]);")
9984 ;; Negation instructions
9986 (define_expand "negti2"
9987 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9988 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9989 (clobber (reg:CC FLAGS_REG))])]
9991 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9993 (define_insn "*negti2_1"
9994 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9995 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9996 (clobber (reg:CC FLAGS_REG))]
9998 && ix86_unary_operator_ok (NEG, TImode, operands)"
10002 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10003 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10004 (clobber (reg:CC FLAGS_REG))]
10005 "TARGET_64BIT && reload_completed"
10007 [(set (reg:CCZ FLAGS_REG)
10008 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
10009 (set (match_dup 0) (neg:DI (match_dup 2)))])
10011 [(set (match_dup 1)
10012 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10015 (clobber (reg:CC FLAGS_REG))])
10017 [(set (match_dup 1)
10018 (neg:DI (match_dup 1)))
10019 (clobber (reg:CC FLAGS_REG))])]
10020 "split_ti (operands+1, 1, operands+2, operands+3);
10021 split_ti (operands+0, 1, operands+0, operands+1);")
10023 (define_expand "negdi2"
10024 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10025 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10026 (clobber (reg:CC FLAGS_REG))])]
10028 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10030 (define_insn "*negdi2_1"
10031 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10032 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10033 (clobber (reg:CC FLAGS_REG))]
10035 && ix86_unary_operator_ok (NEG, DImode, operands)"
10039 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10040 (neg:DI (match_operand:DI 1 "general_operand" "")))
10041 (clobber (reg:CC FLAGS_REG))]
10042 "!TARGET_64BIT && reload_completed"
10044 [(set (reg:CCZ FLAGS_REG)
10045 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
10046 (set (match_dup 0) (neg:SI (match_dup 2)))])
10048 [(set (match_dup 1)
10049 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10052 (clobber (reg:CC FLAGS_REG))])
10054 [(set (match_dup 1)
10055 (neg:SI (match_dup 1)))
10056 (clobber (reg:CC FLAGS_REG))])]
10057 "split_di (operands+1, 1, operands+2, operands+3);
10058 split_di (operands+0, 1, operands+0, operands+1);")
10060 (define_insn "*negdi2_1_rex64"
10061 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10062 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10063 (clobber (reg:CC FLAGS_REG))]
10064 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10066 [(set_attr "type" "negnot")
10067 (set_attr "mode" "DI")])
10069 ;; The problem with neg is that it does not perform (compare x 0),
10070 ;; it really performs (compare 0 x), which leaves us with the zero
10071 ;; flag being the only useful item.
10073 (define_insn "*negdi2_cmpz_rex64"
10074 [(set (reg:CCZ FLAGS_REG)
10075 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10077 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10078 (neg:DI (match_dup 1)))]
10079 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10081 [(set_attr "type" "negnot")
10082 (set_attr "mode" "DI")])
10085 (define_expand "negsi2"
10086 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10087 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10088 (clobber (reg:CC FLAGS_REG))])]
10090 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10092 (define_insn "*negsi2_1"
10093 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10094 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10095 (clobber (reg:CC FLAGS_REG))]
10096 "ix86_unary_operator_ok (NEG, SImode, operands)"
10098 [(set_attr "type" "negnot")
10099 (set_attr "mode" "SI")])
10101 ;; Combine is quite creative about this pattern.
10102 (define_insn "*negsi2_1_zext"
10103 [(set (match_operand:DI 0 "register_operand" "=r")
10104 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10107 (clobber (reg:CC FLAGS_REG))]
10108 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10110 [(set_attr "type" "negnot")
10111 (set_attr "mode" "SI")])
10113 ;; The problem with neg is that it does not perform (compare x 0),
10114 ;; it really performs (compare 0 x), which leaves us with the zero
10115 ;; flag being the only useful item.
10117 (define_insn "*negsi2_cmpz"
10118 [(set (reg:CCZ FLAGS_REG)
10119 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10121 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10122 (neg:SI (match_dup 1)))]
10123 "ix86_unary_operator_ok (NEG, SImode, operands)"
10125 [(set_attr "type" "negnot")
10126 (set_attr "mode" "SI")])
10128 (define_insn "*negsi2_cmpz_zext"
10129 [(set (reg:CCZ FLAGS_REG)
10130 (compare:CCZ (lshiftrt:DI
10132 (match_operand:DI 1 "register_operand" "0")
10136 (set (match_operand:DI 0 "register_operand" "=r")
10137 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10140 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10142 [(set_attr "type" "negnot")
10143 (set_attr "mode" "SI")])
10145 (define_expand "neghi2"
10146 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10147 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10148 (clobber (reg:CC FLAGS_REG))])]
10149 "TARGET_HIMODE_MATH"
10150 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10152 (define_insn "*neghi2_1"
10153 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10154 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10155 (clobber (reg:CC FLAGS_REG))]
10156 "ix86_unary_operator_ok (NEG, HImode, operands)"
10158 [(set_attr "type" "negnot")
10159 (set_attr "mode" "HI")])
10161 (define_insn "*neghi2_cmpz"
10162 [(set (reg:CCZ FLAGS_REG)
10163 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10165 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10166 (neg:HI (match_dup 1)))]
10167 "ix86_unary_operator_ok (NEG, HImode, operands)"
10169 [(set_attr "type" "negnot")
10170 (set_attr "mode" "HI")])
10172 (define_expand "negqi2"
10173 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10174 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10175 (clobber (reg:CC FLAGS_REG))])]
10176 "TARGET_QIMODE_MATH"
10177 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10179 (define_insn "*negqi2_1"
10180 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10181 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10182 (clobber (reg:CC FLAGS_REG))]
10183 "ix86_unary_operator_ok (NEG, QImode, operands)"
10185 [(set_attr "type" "negnot")
10186 (set_attr "mode" "QI")])
10188 (define_insn "*negqi2_cmpz"
10189 [(set (reg:CCZ FLAGS_REG)
10190 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10192 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10193 (neg:QI (match_dup 1)))]
10194 "ix86_unary_operator_ok (NEG, QImode, operands)"
10196 [(set_attr "type" "negnot")
10197 (set_attr "mode" "QI")])
10199 ;; Changing of sign for FP values is doable using integer unit too.
10201 (define_expand "negsf2"
10202 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10203 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10204 "TARGET_80387 || TARGET_SSE_MATH"
10205 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
10207 (define_expand "abssf2"
10208 [(set (match_operand:SF 0 "nonimmediate_operand" "")
10209 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
10210 "TARGET_80387 || TARGET_SSE_MATH"
10211 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
10213 (define_insn "*absnegsf2_mixed"
10214 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
10215 (match_operator:SF 3 "absneg_operator"
10216 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
10217 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
10218 (clobber (reg:CC FLAGS_REG))]
10219 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10220 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10223 (define_insn "*absnegsf2_sse"
10224 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
10225 (match_operator:SF 3 "absneg_operator"
10226 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
10227 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
10228 (clobber (reg:CC FLAGS_REG))]
10230 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10233 (define_insn "*absnegsf2_i387"
10234 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
10235 (match_operator:SF 3 "absneg_operator"
10236 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
10237 (use (match_operand 2 "" ""))
10238 (clobber (reg:CC FLAGS_REG))]
10239 "TARGET_80387 && !TARGET_SSE_MATH
10240 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
10243 (define_expand "negdf2"
10244 [(set (match_operand:DF 0 "nonimmediate_operand" "")
10245 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10246 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10247 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
10249 (define_expand "absdf2"
10250 [(set (match_operand:DF 0 "nonimmediate_operand" "")
10251 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10252 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10253 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
10255 (define_insn "*absnegdf2_mixed"
10256 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
10257 (match_operator:DF 3 "absneg_operator"
10258 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
10259 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
10260 (clobber (reg:CC FLAGS_REG))]
10261 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10262 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10265 (define_insn "*absnegdf2_sse"
10266 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
10267 (match_operator:DF 3 "absneg_operator"
10268 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10269 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
10270 (clobber (reg:CC FLAGS_REG))]
10271 "TARGET_SSE2 && TARGET_SSE_MATH
10272 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10275 (define_insn "*absnegdf2_i387"
10276 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10277 (match_operator:DF 3 "absneg_operator"
10278 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10279 (use (match_operand 2 "" ""))
10280 (clobber (reg:CC FLAGS_REG))]
10281 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10282 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10285 (define_expand "negxf2"
10286 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10287 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10289 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10291 (define_expand "absxf2"
10292 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10293 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10295 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10297 (define_insn "*absnegxf2_i387"
10298 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10299 (match_operator:XF 3 "absneg_operator"
10300 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10301 (use (match_operand 2 "" ""))
10302 (clobber (reg:CC FLAGS_REG))]
10304 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10307 (define_expand "negtf2"
10308 [(set (match_operand:TF 0 "nonimmediate_operand" "")
10309 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
10311 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
10313 (define_expand "abstf2"
10314 [(set (match_operand:TF 0 "nonimmediate_operand" "")
10315 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
10317 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
10319 (define_insn "*absnegtf2_sse"
10320 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x,m")
10321 (match_operator:TF 3 "absneg_operator"
10322 [(match_operand:TF 1 "nonimmediate_operand" "0, x,0")]))
10323 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0,X"))
10324 (clobber (reg:CC FLAGS_REG))]
10326 && ix86_unary_operator_ok (GET_CODE (operands[3]), TFmode, operands)"
10329 ;; Splitters for fp abs and neg.
10332 [(set (match_operand 0 "fp_register_operand" "")
10333 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10334 (use (match_operand 2 "" ""))
10335 (clobber (reg:CC FLAGS_REG))]
10337 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10340 [(set (match_operand 0 "register_operand" "")
10341 (match_operator 3 "absneg_operator"
10342 [(match_operand 1 "register_operand" "")]))
10343 (use (match_operand 2 "nonimmediate_operand" ""))
10344 (clobber (reg:CC FLAGS_REG))]
10345 "reload_completed && SSE_REG_P (operands[0])"
10346 [(set (match_dup 0) (match_dup 3))]
10348 enum machine_mode mode = GET_MODE (operands[0]);
10349 enum machine_mode vmode = GET_MODE (operands[2]);
10352 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10353 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10354 if (operands_match_p (operands[0], operands[2]))
10357 operands[1] = operands[2];
10360 if (GET_CODE (operands[3]) == ABS)
10361 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10363 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10368 [(set (match_operand:SF 0 "register_operand" "")
10369 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10370 (use (match_operand:V4SF 2 "" ""))
10371 (clobber (reg:CC FLAGS_REG))]
10373 [(parallel [(set (match_dup 0) (match_dup 1))
10374 (clobber (reg:CC FLAGS_REG))])]
10377 operands[0] = gen_lowpart (SImode, operands[0]);
10378 if (GET_CODE (operands[1]) == ABS)
10380 tmp = gen_int_mode (0x7fffffff, SImode);
10381 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10385 tmp = gen_int_mode (0x80000000, SImode);
10386 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10392 [(set (match_operand:DF 0 "register_operand" "")
10393 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10394 (use (match_operand 2 "" ""))
10395 (clobber (reg:CC FLAGS_REG))]
10397 [(parallel [(set (match_dup 0) (match_dup 1))
10398 (clobber (reg:CC FLAGS_REG))])]
10403 tmp = gen_lowpart (DImode, operands[0]);
10404 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10407 if (GET_CODE (operands[1]) == ABS)
10410 tmp = gen_rtx_NOT (DImode, tmp);
10414 operands[0] = gen_highpart (SImode, operands[0]);
10415 if (GET_CODE (operands[1]) == ABS)
10417 tmp = gen_int_mode (0x7fffffff, SImode);
10418 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10422 tmp = gen_int_mode (0x80000000, SImode);
10423 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10430 [(set (match_operand:XF 0 "register_operand" "")
10431 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10432 (use (match_operand 2 "" ""))
10433 (clobber (reg:CC FLAGS_REG))]
10435 [(parallel [(set (match_dup 0) (match_dup 1))
10436 (clobber (reg:CC FLAGS_REG))])]
10439 operands[0] = gen_rtx_REG (SImode,
10440 true_regnum (operands[0])
10441 + (TARGET_64BIT ? 1 : 2));
10442 if (GET_CODE (operands[1]) == ABS)
10444 tmp = GEN_INT (0x7fff);
10445 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10449 tmp = GEN_INT (0x8000);
10450 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10456 [(set (match_operand 0 "memory_operand" "")
10457 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10458 (use (match_operand 2 "" ""))
10459 (clobber (reg:CC FLAGS_REG))]
10461 [(parallel [(set (match_dup 0) (match_dup 1))
10462 (clobber (reg:CC FLAGS_REG))])]
10464 enum machine_mode mode = GET_MODE (operands[0]);
10465 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10468 operands[0] = adjust_address (operands[0], QImode, size - 1);
10469 if (GET_CODE (operands[1]) == ABS)
10471 tmp = gen_int_mode (0x7f, QImode);
10472 tmp = gen_rtx_AND (QImode, operands[0], tmp);
10476 tmp = gen_int_mode (0x80, QImode);
10477 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10482 ;; Conditionalize these after reload. If they match before reload, we
10483 ;; lose the clobber and ability to use integer instructions.
10485 (define_insn "*negsf2_1"
10486 [(set (match_operand:SF 0 "register_operand" "=f")
10487 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10488 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10490 [(set_attr "type" "fsgn")
10491 (set_attr "mode" "SF")])
10493 (define_insn "*negdf2_1"
10494 [(set (match_operand:DF 0 "register_operand" "=f")
10495 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10496 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10498 [(set_attr "type" "fsgn")
10499 (set_attr "mode" "DF")])
10501 (define_insn "*negxf2_1"
10502 [(set (match_operand:XF 0 "register_operand" "=f")
10503 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10506 [(set_attr "type" "fsgn")
10507 (set_attr "mode" "XF")])
10509 (define_insn "*abssf2_1"
10510 [(set (match_operand:SF 0 "register_operand" "=f")
10511 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10512 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10514 [(set_attr "type" "fsgn")
10515 (set_attr "mode" "SF")])
10517 (define_insn "*absdf2_1"
10518 [(set (match_operand:DF 0 "register_operand" "=f")
10519 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10520 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10522 [(set_attr "type" "fsgn")
10523 (set_attr "mode" "DF")])
10525 (define_insn "*absxf2_1"
10526 [(set (match_operand:XF 0 "register_operand" "=f")
10527 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10530 [(set_attr "type" "fsgn")
10531 (set_attr "mode" "DF")])
10533 (define_insn "*negextendsfdf2"
10534 [(set (match_operand:DF 0 "register_operand" "=f")
10535 (neg:DF (float_extend:DF
10536 (match_operand:SF 1 "register_operand" "0"))))]
10537 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10539 [(set_attr "type" "fsgn")
10540 (set_attr "mode" "DF")])
10542 (define_insn "*negextenddfxf2"
10543 [(set (match_operand:XF 0 "register_operand" "=f")
10544 (neg:XF (float_extend:XF
10545 (match_operand:DF 1 "register_operand" "0"))))]
10548 [(set_attr "type" "fsgn")
10549 (set_attr "mode" "XF")])
10551 (define_insn "*negextendsfxf2"
10552 [(set (match_operand:XF 0 "register_operand" "=f")
10553 (neg:XF (float_extend:XF
10554 (match_operand:SF 1 "register_operand" "0"))))]
10557 [(set_attr "type" "fsgn")
10558 (set_attr "mode" "XF")])
10560 (define_insn "*absextendsfdf2"
10561 [(set (match_operand:DF 0 "register_operand" "=f")
10562 (abs:DF (float_extend:DF
10563 (match_operand:SF 1 "register_operand" "0"))))]
10564 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10566 [(set_attr "type" "fsgn")
10567 (set_attr "mode" "DF")])
10569 (define_insn "*absextenddfxf2"
10570 [(set (match_operand:XF 0 "register_operand" "=f")
10571 (abs:XF (float_extend:XF
10572 (match_operand:DF 1 "register_operand" "0"))))]
10575 [(set_attr "type" "fsgn")
10576 (set_attr "mode" "XF")])
10578 (define_insn "*absextendsfxf2"
10579 [(set (match_operand:XF 0 "register_operand" "=f")
10580 (abs:XF (float_extend:XF
10581 (match_operand:SF 1 "register_operand" "0"))))]
10584 [(set_attr "type" "fsgn")
10585 (set_attr "mode" "XF")])
10587 ;; Copysign instructions
10589 (define_mode_iterator CSGNMODE [SF DF TF])
10590 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10592 (define_expand "copysign<mode>3"
10593 [(match_operand:CSGNMODE 0 "register_operand" "")
10594 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10595 (match_operand:CSGNMODE 2 "register_operand" "")]
10596 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10597 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10599 ix86_expand_copysign (operands);
10603 (define_insn_and_split "copysign<mode>3_const"
10604 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10606 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10607 (match_operand:CSGNMODE 2 "register_operand" "0")
10608 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10610 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10611 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10613 "&& reload_completed"
10616 ix86_split_copysign_const (operands);
10620 (define_insn "copysign<mode>3_var"
10621 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10623 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10624 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10625 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10626 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10628 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10629 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10630 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10634 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10636 [(match_operand:CSGNMODE 2 "register_operand" "")
10637 (match_operand:CSGNMODE 3 "register_operand" "")
10638 (match_operand:<CSGNVMODE> 4 "" "")
10639 (match_operand:<CSGNVMODE> 5 "" "")]
10641 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10642 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10643 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10644 && reload_completed"
10647 ix86_split_copysign_var (operands);
10651 ;; One complement instructions
10653 (define_expand "one_cmpldi2"
10654 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10655 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10657 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10659 (define_insn "*one_cmpldi2_1_rex64"
10660 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10661 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10662 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10664 [(set_attr "type" "negnot")
10665 (set_attr "mode" "DI")])
10667 (define_insn "*one_cmpldi2_2_rex64"
10668 [(set (reg FLAGS_REG)
10669 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10671 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10672 (not:DI (match_dup 1)))]
10673 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10674 && ix86_unary_operator_ok (NOT, DImode, operands)"
10676 [(set_attr "type" "alu1")
10677 (set_attr "mode" "DI")])
10680 [(set (match_operand 0 "flags_reg_operand" "")
10681 (match_operator 2 "compare_operator"
10682 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10684 (set (match_operand:DI 1 "nonimmediate_operand" "")
10685 (not:DI (match_dup 3)))]
10686 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10687 [(parallel [(set (match_dup 0)
10689 [(xor:DI (match_dup 3) (const_int -1))
10692 (xor:DI (match_dup 3) (const_int -1)))])]
10695 (define_expand "one_cmplsi2"
10696 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10697 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10699 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10701 (define_insn "*one_cmplsi2_1"
10702 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10703 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10704 "ix86_unary_operator_ok (NOT, SImode, operands)"
10706 [(set_attr "type" "negnot")
10707 (set_attr "mode" "SI")])
10709 ;; ??? Currently never generated - xor is used instead.
10710 (define_insn "*one_cmplsi2_1_zext"
10711 [(set (match_operand:DI 0 "register_operand" "=r")
10712 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10713 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10715 [(set_attr "type" "negnot")
10716 (set_attr "mode" "SI")])
10718 (define_insn "*one_cmplsi2_2"
10719 [(set (reg FLAGS_REG)
10720 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10722 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10723 (not:SI (match_dup 1)))]
10724 "ix86_match_ccmode (insn, CCNOmode)
10725 && ix86_unary_operator_ok (NOT, SImode, operands)"
10727 [(set_attr "type" "alu1")
10728 (set_attr "mode" "SI")])
10731 [(set (match_operand 0 "flags_reg_operand" "")
10732 (match_operator 2 "compare_operator"
10733 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10735 (set (match_operand:SI 1 "nonimmediate_operand" "")
10736 (not:SI (match_dup 3)))]
10737 "ix86_match_ccmode (insn, CCNOmode)"
10738 [(parallel [(set (match_dup 0)
10739 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10742 (xor:SI (match_dup 3) (const_int -1)))])]
10745 ;; ??? Currently never generated - xor is used instead.
10746 (define_insn "*one_cmplsi2_2_zext"
10747 [(set (reg FLAGS_REG)
10748 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10750 (set (match_operand:DI 0 "register_operand" "=r")
10751 (zero_extend:DI (not:SI (match_dup 1))))]
10752 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10753 && ix86_unary_operator_ok (NOT, SImode, operands)"
10755 [(set_attr "type" "alu1")
10756 (set_attr "mode" "SI")])
10759 [(set (match_operand 0 "flags_reg_operand" "")
10760 (match_operator 2 "compare_operator"
10761 [(not:SI (match_operand:SI 3 "register_operand" ""))
10763 (set (match_operand:DI 1 "register_operand" "")
10764 (zero_extend:DI (not:SI (match_dup 3))))]
10765 "ix86_match_ccmode (insn, CCNOmode)"
10766 [(parallel [(set (match_dup 0)
10767 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10770 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10773 (define_expand "one_cmplhi2"
10774 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10775 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10776 "TARGET_HIMODE_MATH"
10777 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10779 (define_insn "*one_cmplhi2_1"
10780 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10781 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10782 "ix86_unary_operator_ok (NOT, HImode, operands)"
10784 [(set_attr "type" "negnot")
10785 (set_attr "mode" "HI")])
10787 (define_insn "*one_cmplhi2_2"
10788 [(set (reg FLAGS_REG)
10789 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10791 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10792 (not:HI (match_dup 1)))]
10793 "ix86_match_ccmode (insn, CCNOmode)
10794 && ix86_unary_operator_ok (NEG, HImode, operands)"
10796 [(set_attr "type" "alu1")
10797 (set_attr "mode" "HI")])
10800 [(set (match_operand 0 "flags_reg_operand" "")
10801 (match_operator 2 "compare_operator"
10802 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10804 (set (match_operand:HI 1 "nonimmediate_operand" "")
10805 (not:HI (match_dup 3)))]
10806 "ix86_match_ccmode (insn, CCNOmode)"
10807 [(parallel [(set (match_dup 0)
10808 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10811 (xor:HI (match_dup 3) (const_int -1)))])]
10814 ;; %%% Potential partial reg stall on alternative 1. What to do?
10815 (define_expand "one_cmplqi2"
10816 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10817 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10818 "TARGET_QIMODE_MATH"
10819 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10821 (define_insn "*one_cmplqi2_1"
10822 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10823 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10824 "ix86_unary_operator_ok (NOT, QImode, operands)"
10828 [(set_attr "type" "negnot")
10829 (set_attr "mode" "QI,SI")])
10831 (define_insn "*one_cmplqi2_2"
10832 [(set (reg FLAGS_REG)
10833 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10835 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10836 (not:QI (match_dup 1)))]
10837 "ix86_match_ccmode (insn, CCNOmode)
10838 && ix86_unary_operator_ok (NOT, QImode, operands)"
10840 [(set_attr "type" "alu1")
10841 (set_attr "mode" "QI")])
10844 [(set (match_operand 0 "flags_reg_operand" "")
10845 (match_operator 2 "compare_operator"
10846 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10848 (set (match_operand:QI 1 "nonimmediate_operand" "")
10849 (not:QI (match_dup 3)))]
10850 "ix86_match_ccmode (insn, CCNOmode)"
10851 [(parallel [(set (match_dup 0)
10852 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10855 (xor:QI (match_dup 3) (const_int -1)))])]
10858 ;; Arithmetic shift instructions
10860 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10861 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10862 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10863 ;; from the assembler input.
10865 ;; This instruction shifts the target reg/mem as usual, but instead of
10866 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10867 ;; is a left shift double, bits are taken from the high order bits of
10868 ;; reg, else if the insn is a shift right double, bits are taken from the
10869 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10870 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10872 ;; Since sh[lr]d does not change the `reg' operand, that is done
10873 ;; separately, making all shifts emit pairs of shift double and normal
10874 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10875 ;; support a 63 bit shift, each shift where the count is in a reg expands
10876 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10878 ;; If the shift count is a constant, we need never emit more than one
10879 ;; shift pair, instead using moves and sign extension for counts greater
10882 (define_expand "ashlti3"
10883 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10884 (ashift:TI (match_operand:TI 1 "register_operand" "")
10885 (match_operand:QI 2 "nonmemory_operand" "")))
10886 (clobber (reg:CC FLAGS_REG))])]
10889 if (! immediate_operand (operands[2], QImode))
10891 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10894 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10898 (define_insn "ashlti3_1"
10899 [(set (match_operand:TI 0 "register_operand" "=r")
10900 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10901 (match_operand:QI 2 "register_operand" "c")))
10902 (clobber (match_scratch:DI 3 "=&r"))
10903 (clobber (reg:CC FLAGS_REG))]
10906 [(set_attr "type" "multi")])
10908 ;; This pattern must be defined before *ashlti3_2 to prevent
10909 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10911 (define_insn "sse2_ashlti3"
10912 [(set (match_operand:TI 0 "register_operand" "=x")
10913 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10914 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10917 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10918 return "pslldq\t{%2, %0|%0, %2}";
10920 [(set_attr "type" "sseishft")
10921 (set_attr "prefix_data16" "1")
10922 (set_attr "mode" "TI")])
10924 (define_insn "*ashlti3_2"
10925 [(set (match_operand:TI 0 "register_operand" "=r")
10926 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10927 (match_operand:QI 2 "immediate_operand" "O")))
10928 (clobber (reg:CC FLAGS_REG))]
10931 [(set_attr "type" "multi")])
10934 [(set (match_operand:TI 0 "register_operand" "")
10935 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10936 (match_operand:QI 2 "register_operand" "")))
10937 (clobber (match_scratch:DI 3 ""))
10938 (clobber (reg:CC FLAGS_REG))]
10939 "TARGET_64BIT && reload_completed"
10941 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10944 [(set (match_operand:TI 0 "register_operand" "")
10945 (ashift:TI (match_operand:TI 1 "register_operand" "")
10946 (match_operand:QI 2 "immediate_operand" "")))
10947 (clobber (reg:CC FLAGS_REG))]
10948 "TARGET_64BIT && reload_completed"
10950 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10952 (define_insn "x86_64_shld"
10953 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10954 (ior:DI (ashift:DI (match_dup 0)
10955 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10956 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10957 (minus:QI (const_int 64) (match_dup 2)))))
10958 (clobber (reg:CC FLAGS_REG))]
10961 shld{q}\t{%2, %1, %0|%0, %1, %2}
10962 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10963 [(set_attr "type" "ishift")
10964 (set_attr "prefix_0f" "1")
10965 (set_attr "mode" "DI")
10966 (set_attr "athlon_decode" "vector")
10967 (set_attr "amdfam10_decode" "vector")])
10969 (define_expand "x86_64_shift_adj"
10970 [(set (reg:CCZ FLAGS_REG)
10971 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10974 (set (match_operand:DI 0 "register_operand" "")
10975 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10976 (match_operand:DI 1 "register_operand" "")
10979 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10980 (match_operand:DI 3 "register_operand" "r")
10985 (define_expand "ashldi3"
10986 [(set (match_operand:DI 0 "shiftdi_operand" "")
10987 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10988 (match_operand:QI 2 "nonmemory_operand" "")))]
10990 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10992 (define_insn "*ashldi3_1_rex64"
10993 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10994 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10995 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10996 (clobber (reg:CC FLAGS_REG))]
10997 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10999 switch (get_attr_type (insn))
11002 gcc_assert (operands[2] == const1_rtx);
11003 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11004 return "add{q}\t%0, %0";
11007 gcc_assert (CONST_INT_P (operands[2]));
11008 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11009 operands[1] = gen_rtx_MULT (DImode, operands[1],
11010 GEN_INT (1 << INTVAL (operands[2])));
11011 return "lea{q}\t{%a1, %0|%0, %a1}";
11014 if (REG_P (operands[2]))
11015 return "sal{q}\t{%b2, %0|%0, %b2}";
11016 else if (operands[2] == const1_rtx
11017 && (TARGET_SHIFT1 || optimize_size))
11018 return "sal{q}\t%0";
11020 return "sal{q}\t{%2, %0|%0, %2}";
11023 [(set (attr "type")
11024 (cond [(eq_attr "alternative" "1")
11025 (const_string "lea")
11026 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11028 (match_operand 0 "register_operand" ""))
11029 (match_operand 2 "const1_operand" ""))
11030 (const_string "alu")
11032 (const_string "ishift")))
11033 (set_attr "mode" "DI")])
11035 ;; Convert lea to the lea pattern to avoid flags dependency.
11037 [(set (match_operand:DI 0 "register_operand" "")
11038 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11039 (match_operand:QI 2 "immediate_operand" "")))
11040 (clobber (reg:CC FLAGS_REG))]
11041 "TARGET_64BIT && reload_completed
11042 && true_regnum (operands[0]) != true_regnum (operands[1])"
11043 [(set (match_dup 0)
11044 (mult:DI (match_dup 1)
11046 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11048 ;; This pattern can't accept a variable shift count, since shifts by
11049 ;; zero don't affect the flags. We assume that shifts by constant
11050 ;; zero are optimized away.
11051 (define_insn "*ashldi3_cmp_rex64"
11052 [(set (reg FLAGS_REG)
11054 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11055 (match_operand:QI 2 "immediate_operand" "e"))
11057 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11058 (ashift:DI (match_dup 1) (match_dup 2)))]
11061 || !TARGET_PARTIAL_FLAG_REG_STALL
11062 || (operands[2] == const1_rtx
11064 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11065 && ix86_match_ccmode (insn, CCGOCmode)
11066 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11068 switch (get_attr_type (insn))
11071 gcc_assert (operands[2] == const1_rtx);
11072 return "add{q}\t%0, %0";
11075 if (REG_P (operands[2]))
11076 return "sal{q}\t{%b2, %0|%0, %b2}";
11077 else if (operands[2] == const1_rtx
11078 && (TARGET_SHIFT1 || optimize_size))
11079 return "sal{q}\t%0";
11081 return "sal{q}\t{%2, %0|%0, %2}";
11084 [(set (attr "type")
11085 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11087 (match_operand 0 "register_operand" ""))
11088 (match_operand 2 "const1_operand" ""))
11089 (const_string "alu")
11091 (const_string "ishift")))
11092 (set_attr "mode" "DI")])
11094 (define_insn "*ashldi3_cconly_rex64"
11095 [(set (reg FLAGS_REG)
11097 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11098 (match_operand:QI 2 "immediate_operand" "e"))
11100 (clobber (match_scratch:DI 0 "=r"))]
11103 || !TARGET_PARTIAL_FLAG_REG_STALL
11104 || (operands[2] == const1_rtx
11106 || TARGET_DOUBLE_WITH_ADD)))
11107 && ix86_match_ccmode (insn, CCGOCmode)
11108 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11110 switch (get_attr_type (insn))
11113 gcc_assert (operands[2] == const1_rtx);
11114 return "add{q}\t%0, %0";
11117 if (REG_P (operands[2]))
11118 return "sal{q}\t{%b2, %0|%0, %b2}";
11119 else if (operands[2] == const1_rtx
11120 && (TARGET_SHIFT1 || optimize_size))
11121 return "sal{q}\t%0";
11123 return "sal{q}\t{%2, %0|%0, %2}";
11126 [(set (attr "type")
11127 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11129 (match_operand 0 "register_operand" ""))
11130 (match_operand 2 "const1_operand" ""))
11131 (const_string "alu")
11133 (const_string "ishift")))
11134 (set_attr "mode" "DI")])
11136 (define_insn "*ashldi3_1"
11137 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11138 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11139 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11140 (clobber (reg:CC FLAGS_REG))]
11143 [(set_attr "type" "multi")])
11145 ;; By default we don't ask for a scratch register, because when DImode
11146 ;; values are manipulated, registers are already at a premium. But if
11147 ;; we have one handy, we won't turn it away.
11149 [(match_scratch:SI 3 "r")
11150 (parallel [(set (match_operand:DI 0 "register_operand" "")
11151 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11152 (match_operand:QI 2 "nonmemory_operand" "")))
11153 (clobber (reg:CC FLAGS_REG))])
11155 "!TARGET_64BIT && TARGET_CMOVE"
11157 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11160 [(set (match_operand:DI 0 "register_operand" "")
11161 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11162 (match_operand:QI 2 "nonmemory_operand" "")))
11163 (clobber (reg:CC FLAGS_REG))]
11164 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11165 ? epilogue_completed : reload_completed)"
11167 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11169 (define_insn "x86_shld_1"
11170 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11171 (ior:SI (ashift:SI (match_dup 0)
11172 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11173 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11174 (minus:QI (const_int 32) (match_dup 2)))))
11175 (clobber (reg:CC FLAGS_REG))]
11178 shld{l}\t{%2, %1, %0|%0, %1, %2}
11179 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11180 [(set_attr "type" "ishift")
11181 (set_attr "prefix_0f" "1")
11182 (set_attr "mode" "SI")
11183 (set_attr "pent_pair" "np")
11184 (set_attr "athlon_decode" "vector")
11185 (set_attr "amdfam10_decode" "vector")])
11187 (define_expand "x86_shift_adj_1"
11188 [(set (reg:CCZ FLAGS_REG)
11189 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11192 (set (match_operand:SI 0 "register_operand" "")
11193 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11194 (match_operand:SI 1 "register_operand" "")
11197 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11198 (match_operand:SI 3 "register_operand" "r")
11203 (define_expand "x86_shift_adj_2"
11204 [(use (match_operand:SI 0 "register_operand" ""))
11205 (use (match_operand:SI 1 "register_operand" ""))
11206 (use (match_operand:QI 2 "register_operand" ""))]
11209 rtx label = gen_label_rtx ();
11212 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11214 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11215 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11216 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11217 gen_rtx_LABEL_REF (VOIDmode, label),
11219 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11220 JUMP_LABEL (tmp) = label;
11222 emit_move_insn (operands[0], operands[1]);
11223 ix86_expand_clear (operands[1]);
11225 emit_label (label);
11226 LABEL_NUSES (label) = 1;
11231 (define_expand "ashlsi3"
11232 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11233 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11234 (match_operand:QI 2 "nonmemory_operand" "")))
11235 (clobber (reg:CC FLAGS_REG))]
11237 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11239 (define_insn "*ashlsi3_1"
11240 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11241 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11242 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11243 (clobber (reg:CC FLAGS_REG))]
11244 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11246 switch (get_attr_type (insn))
11249 gcc_assert (operands[2] == const1_rtx);
11250 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11251 return "add{l}\t%0, %0";
11257 if (REG_P (operands[2]))
11258 return "sal{l}\t{%b2, %0|%0, %b2}";
11259 else if (operands[2] == const1_rtx
11260 && (TARGET_SHIFT1 || optimize_size))
11261 return "sal{l}\t%0";
11263 return "sal{l}\t{%2, %0|%0, %2}";
11266 [(set (attr "type")
11267 (cond [(eq_attr "alternative" "1")
11268 (const_string "lea")
11269 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11271 (match_operand 0 "register_operand" ""))
11272 (match_operand 2 "const1_operand" ""))
11273 (const_string "alu")
11275 (const_string "ishift")))
11276 (set_attr "mode" "SI")])
11278 ;; Convert lea to the lea pattern to avoid flags dependency.
11280 [(set (match_operand 0 "register_operand" "")
11281 (ashift (match_operand 1 "index_register_operand" "")
11282 (match_operand:QI 2 "const_int_operand" "")))
11283 (clobber (reg:CC FLAGS_REG))]
11285 && true_regnum (operands[0]) != true_regnum (operands[1])
11286 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11290 enum machine_mode mode = GET_MODE (operands[0]);
11292 if (GET_MODE_SIZE (mode) < 4)
11293 operands[0] = gen_lowpart (SImode, operands[0]);
11295 operands[1] = gen_lowpart (Pmode, operands[1]);
11296 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11298 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11299 if (Pmode != SImode)
11300 pat = gen_rtx_SUBREG (SImode, pat, 0);
11301 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11305 ;; Rare case of shifting RSP is handled by generating move and shift
11307 [(set (match_operand 0 "register_operand" "")
11308 (ashift (match_operand 1 "register_operand" "")
11309 (match_operand:QI 2 "const_int_operand" "")))
11310 (clobber (reg:CC FLAGS_REG))]
11312 && true_regnum (operands[0]) != true_regnum (operands[1])"
11316 emit_move_insn (operands[0], operands[1]);
11317 pat = gen_rtx_SET (VOIDmode, operands[0],
11318 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11319 operands[0], operands[2]));
11320 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11321 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11325 (define_insn "*ashlsi3_1_zext"
11326 [(set (match_operand:DI 0 "register_operand" "=r,r")
11327 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11328 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11329 (clobber (reg:CC FLAGS_REG))]
11330 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11332 switch (get_attr_type (insn))
11335 gcc_assert (operands[2] == const1_rtx);
11336 return "add{l}\t%k0, %k0";
11342 if (REG_P (operands[2]))
11343 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11344 else if (operands[2] == const1_rtx
11345 && (TARGET_SHIFT1 || optimize_size))
11346 return "sal{l}\t%k0";
11348 return "sal{l}\t{%2, %k0|%k0, %2}";
11351 [(set (attr "type")
11352 (cond [(eq_attr "alternative" "1")
11353 (const_string "lea")
11354 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11356 (match_operand 2 "const1_operand" ""))
11357 (const_string "alu")
11359 (const_string "ishift")))
11360 (set_attr "mode" "SI")])
11362 ;; Convert lea to the lea pattern to avoid flags dependency.
11364 [(set (match_operand:DI 0 "register_operand" "")
11365 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11366 (match_operand:QI 2 "const_int_operand" ""))))
11367 (clobber (reg:CC FLAGS_REG))]
11368 "TARGET_64BIT && reload_completed
11369 && true_regnum (operands[0]) != true_regnum (operands[1])"
11370 [(set (match_dup 0) (zero_extend:DI
11371 (subreg:SI (mult:SI (match_dup 1)
11372 (match_dup 2)) 0)))]
11374 operands[1] = gen_lowpart (Pmode, operands[1]);
11375 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11378 ;; This pattern can't accept a variable shift count, since shifts by
11379 ;; zero don't affect the flags. We assume that shifts by constant
11380 ;; zero are optimized away.
11381 (define_insn "*ashlsi3_cmp"
11382 [(set (reg FLAGS_REG)
11384 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11385 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11387 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11388 (ashift:SI (match_dup 1) (match_dup 2)))]
11390 || !TARGET_PARTIAL_FLAG_REG_STALL
11391 || (operands[2] == const1_rtx
11393 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11394 && ix86_match_ccmode (insn, CCGOCmode)
11395 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11397 switch (get_attr_type (insn))
11400 gcc_assert (operands[2] == const1_rtx);
11401 return "add{l}\t%0, %0";
11404 if (REG_P (operands[2]))
11405 return "sal{l}\t{%b2, %0|%0, %b2}";
11406 else if (operands[2] == const1_rtx
11407 && (TARGET_SHIFT1 || optimize_size))
11408 return "sal{l}\t%0";
11410 return "sal{l}\t{%2, %0|%0, %2}";
11413 [(set (attr "type")
11414 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11416 (match_operand 0 "register_operand" ""))
11417 (match_operand 2 "const1_operand" ""))
11418 (const_string "alu")
11420 (const_string "ishift")))
11421 (set_attr "mode" "SI")])
11423 (define_insn "*ashlsi3_cconly"
11424 [(set (reg FLAGS_REG)
11426 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11427 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11429 (clobber (match_scratch:SI 0 "=r"))]
11431 || !TARGET_PARTIAL_FLAG_REG_STALL
11432 || (operands[2] == const1_rtx
11434 || TARGET_DOUBLE_WITH_ADD)))
11435 && ix86_match_ccmode (insn, CCGOCmode)
11436 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11438 switch (get_attr_type (insn))
11441 gcc_assert (operands[2] == const1_rtx);
11442 return "add{l}\t%0, %0";
11445 if (REG_P (operands[2]))
11446 return "sal{l}\t{%b2, %0|%0, %b2}";
11447 else if (operands[2] == const1_rtx
11448 && (TARGET_SHIFT1 || optimize_size))
11449 return "sal{l}\t%0";
11451 return "sal{l}\t{%2, %0|%0, %2}";
11454 [(set (attr "type")
11455 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11457 (match_operand 0 "register_operand" ""))
11458 (match_operand 2 "const1_operand" ""))
11459 (const_string "alu")
11461 (const_string "ishift")))
11462 (set_attr "mode" "SI")])
11464 (define_insn "*ashlsi3_cmp_zext"
11465 [(set (reg FLAGS_REG)
11467 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11468 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11470 (set (match_operand:DI 0 "register_operand" "=r")
11471 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11474 || !TARGET_PARTIAL_FLAG_REG_STALL
11475 || (operands[2] == const1_rtx
11477 || TARGET_DOUBLE_WITH_ADD)))
11478 && ix86_match_ccmode (insn, CCGOCmode)
11479 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11481 switch (get_attr_type (insn))
11484 gcc_assert (operands[2] == const1_rtx);
11485 return "add{l}\t%k0, %k0";
11488 if (REG_P (operands[2]))
11489 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11490 else if (operands[2] == const1_rtx
11491 && (TARGET_SHIFT1 || optimize_size))
11492 return "sal{l}\t%k0";
11494 return "sal{l}\t{%2, %k0|%k0, %2}";
11497 [(set (attr "type")
11498 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11500 (match_operand 2 "const1_operand" ""))
11501 (const_string "alu")
11503 (const_string "ishift")))
11504 (set_attr "mode" "SI")])
11506 (define_expand "ashlhi3"
11507 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11508 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11509 (match_operand:QI 2 "nonmemory_operand" "")))
11510 (clobber (reg:CC FLAGS_REG))]
11511 "TARGET_HIMODE_MATH"
11512 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11514 (define_insn "*ashlhi3_1_lea"
11515 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11516 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11517 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11518 (clobber (reg:CC FLAGS_REG))]
11519 "!TARGET_PARTIAL_REG_STALL
11520 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11522 switch (get_attr_type (insn))
11527 gcc_assert (operands[2] == const1_rtx);
11528 return "add{w}\t%0, %0";
11531 if (REG_P (operands[2]))
11532 return "sal{w}\t{%b2, %0|%0, %b2}";
11533 else if (operands[2] == const1_rtx
11534 && (TARGET_SHIFT1 || optimize_size))
11535 return "sal{w}\t%0";
11537 return "sal{w}\t{%2, %0|%0, %2}";
11540 [(set (attr "type")
11541 (cond [(eq_attr "alternative" "1")
11542 (const_string "lea")
11543 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11545 (match_operand 0 "register_operand" ""))
11546 (match_operand 2 "const1_operand" ""))
11547 (const_string "alu")
11549 (const_string "ishift")))
11550 (set_attr "mode" "HI,SI")])
11552 (define_insn "*ashlhi3_1"
11553 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11554 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11555 (match_operand:QI 2 "nonmemory_operand" "cI")))
11556 (clobber (reg:CC FLAGS_REG))]
11557 "TARGET_PARTIAL_REG_STALL
11558 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11560 switch (get_attr_type (insn))
11563 gcc_assert (operands[2] == const1_rtx);
11564 return "add{w}\t%0, %0";
11567 if (REG_P (operands[2]))
11568 return "sal{w}\t{%b2, %0|%0, %b2}";
11569 else if (operands[2] == const1_rtx
11570 && (TARGET_SHIFT1 || optimize_size))
11571 return "sal{w}\t%0";
11573 return "sal{w}\t{%2, %0|%0, %2}";
11576 [(set (attr "type")
11577 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11579 (match_operand 0 "register_operand" ""))
11580 (match_operand 2 "const1_operand" ""))
11581 (const_string "alu")
11583 (const_string "ishift")))
11584 (set_attr "mode" "HI")])
11586 ;; This pattern can't accept a variable shift count, since shifts by
11587 ;; zero don't affect the flags. We assume that shifts by constant
11588 ;; zero are optimized away.
11589 (define_insn "*ashlhi3_cmp"
11590 [(set (reg FLAGS_REG)
11592 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11593 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11595 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11596 (ashift:HI (match_dup 1) (match_dup 2)))]
11598 || !TARGET_PARTIAL_FLAG_REG_STALL
11599 || (operands[2] == const1_rtx
11601 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11602 && ix86_match_ccmode (insn, CCGOCmode)
11603 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11605 switch (get_attr_type (insn))
11608 gcc_assert (operands[2] == const1_rtx);
11609 return "add{w}\t%0, %0";
11612 if (REG_P (operands[2]))
11613 return "sal{w}\t{%b2, %0|%0, %b2}";
11614 else if (operands[2] == const1_rtx
11615 && (TARGET_SHIFT1 || optimize_size))
11616 return "sal{w}\t%0";
11618 return "sal{w}\t{%2, %0|%0, %2}";
11621 [(set (attr "type")
11622 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11624 (match_operand 0 "register_operand" ""))
11625 (match_operand 2 "const1_operand" ""))
11626 (const_string "alu")
11628 (const_string "ishift")))
11629 (set_attr "mode" "HI")])
11631 (define_insn "*ashlhi3_cconly"
11632 [(set (reg FLAGS_REG)
11634 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11635 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11637 (clobber (match_scratch:HI 0 "=r"))]
11639 || !TARGET_PARTIAL_FLAG_REG_STALL
11640 || (operands[2] == const1_rtx
11642 || TARGET_DOUBLE_WITH_ADD)))
11643 && ix86_match_ccmode (insn, CCGOCmode)
11644 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11646 switch (get_attr_type (insn))
11649 gcc_assert (operands[2] == const1_rtx);
11650 return "add{w}\t%0, %0";
11653 if (REG_P (operands[2]))
11654 return "sal{w}\t{%b2, %0|%0, %b2}";
11655 else if (operands[2] == const1_rtx
11656 && (TARGET_SHIFT1 || optimize_size))
11657 return "sal{w}\t%0";
11659 return "sal{w}\t{%2, %0|%0, %2}";
11662 [(set (attr "type")
11663 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11665 (match_operand 0 "register_operand" ""))
11666 (match_operand 2 "const1_operand" ""))
11667 (const_string "alu")
11669 (const_string "ishift")))
11670 (set_attr "mode" "HI")])
11672 (define_expand "ashlqi3"
11673 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11674 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11675 (match_operand:QI 2 "nonmemory_operand" "")))
11676 (clobber (reg:CC FLAGS_REG))]
11677 "TARGET_QIMODE_MATH"
11678 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11680 ;; %%% Potential partial reg stall on alternative 2. What to do?
11682 (define_insn "*ashlqi3_1_lea"
11683 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11684 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11685 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11686 (clobber (reg:CC FLAGS_REG))]
11687 "!TARGET_PARTIAL_REG_STALL
11688 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11690 switch (get_attr_type (insn))
11695 gcc_assert (operands[2] == const1_rtx);
11696 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11697 return "add{l}\t%k0, %k0";
11699 return "add{b}\t%0, %0";
11702 if (REG_P (operands[2]))
11704 if (get_attr_mode (insn) == MODE_SI)
11705 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11707 return "sal{b}\t{%b2, %0|%0, %b2}";
11709 else if (operands[2] == const1_rtx
11710 && (TARGET_SHIFT1 || optimize_size))
11712 if (get_attr_mode (insn) == MODE_SI)
11713 return "sal{l}\t%0";
11715 return "sal{b}\t%0";
11719 if (get_attr_mode (insn) == MODE_SI)
11720 return "sal{l}\t{%2, %k0|%k0, %2}";
11722 return "sal{b}\t{%2, %0|%0, %2}";
11726 [(set (attr "type")
11727 (cond [(eq_attr "alternative" "2")
11728 (const_string "lea")
11729 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11731 (match_operand 0 "register_operand" ""))
11732 (match_operand 2 "const1_operand" ""))
11733 (const_string "alu")
11735 (const_string "ishift")))
11736 (set_attr "mode" "QI,SI,SI")])
11738 (define_insn "*ashlqi3_1"
11739 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11740 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11741 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11742 (clobber (reg:CC FLAGS_REG))]
11743 "TARGET_PARTIAL_REG_STALL
11744 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11746 switch (get_attr_type (insn))
11749 gcc_assert (operands[2] == const1_rtx);
11750 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11751 return "add{l}\t%k0, %k0";
11753 return "add{b}\t%0, %0";
11756 if (REG_P (operands[2]))
11758 if (get_attr_mode (insn) == MODE_SI)
11759 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11761 return "sal{b}\t{%b2, %0|%0, %b2}";
11763 else if (operands[2] == const1_rtx
11764 && (TARGET_SHIFT1 || optimize_size))
11766 if (get_attr_mode (insn) == MODE_SI)
11767 return "sal{l}\t%0";
11769 return "sal{b}\t%0";
11773 if (get_attr_mode (insn) == MODE_SI)
11774 return "sal{l}\t{%2, %k0|%k0, %2}";
11776 return "sal{b}\t{%2, %0|%0, %2}";
11780 [(set (attr "type")
11781 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11783 (match_operand 0 "register_operand" ""))
11784 (match_operand 2 "const1_operand" ""))
11785 (const_string "alu")
11787 (const_string "ishift")))
11788 (set_attr "mode" "QI,SI")])
11790 ;; This pattern can't accept a variable shift count, since shifts by
11791 ;; zero don't affect the flags. We assume that shifts by constant
11792 ;; zero are optimized away.
11793 (define_insn "*ashlqi3_cmp"
11794 [(set (reg FLAGS_REG)
11796 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11797 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11799 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11800 (ashift:QI (match_dup 1) (match_dup 2)))]
11802 || !TARGET_PARTIAL_FLAG_REG_STALL
11803 || (operands[2] == const1_rtx
11805 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11806 && ix86_match_ccmode (insn, CCGOCmode)
11807 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11809 switch (get_attr_type (insn))
11812 gcc_assert (operands[2] == const1_rtx);
11813 return "add{b}\t%0, %0";
11816 if (REG_P (operands[2]))
11817 return "sal{b}\t{%b2, %0|%0, %b2}";
11818 else if (operands[2] == const1_rtx
11819 && (TARGET_SHIFT1 || optimize_size))
11820 return "sal{b}\t%0";
11822 return "sal{b}\t{%2, %0|%0, %2}";
11825 [(set (attr "type")
11826 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11828 (match_operand 0 "register_operand" ""))
11829 (match_operand 2 "const1_operand" ""))
11830 (const_string "alu")
11832 (const_string "ishift")))
11833 (set_attr "mode" "QI")])
11835 (define_insn "*ashlqi3_cconly"
11836 [(set (reg FLAGS_REG)
11838 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11839 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11841 (clobber (match_scratch:QI 0 "=q"))]
11843 || !TARGET_PARTIAL_FLAG_REG_STALL
11844 || (operands[2] == const1_rtx
11846 || TARGET_DOUBLE_WITH_ADD)))
11847 && ix86_match_ccmode (insn, CCGOCmode)
11848 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11850 switch (get_attr_type (insn))
11853 gcc_assert (operands[2] == const1_rtx);
11854 return "add{b}\t%0, %0";
11857 if (REG_P (operands[2]))
11858 return "sal{b}\t{%b2, %0|%0, %b2}";
11859 else if (operands[2] == const1_rtx
11860 && (TARGET_SHIFT1 || optimize_size))
11861 return "sal{b}\t%0";
11863 return "sal{b}\t{%2, %0|%0, %2}";
11866 [(set (attr "type")
11867 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11869 (match_operand 0 "register_operand" ""))
11870 (match_operand 2 "const1_operand" ""))
11871 (const_string "alu")
11873 (const_string "ishift")))
11874 (set_attr "mode" "QI")])
11876 ;; See comment above `ashldi3' about how this works.
11878 (define_expand "ashrti3"
11879 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11880 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11881 (match_operand:QI 2 "nonmemory_operand" "")))
11882 (clobber (reg:CC FLAGS_REG))])]
11885 if (! immediate_operand (operands[2], QImode))
11887 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11890 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11894 (define_insn "ashrti3_1"
11895 [(set (match_operand:TI 0 "register_operand" "=r")
11896 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11897 (match_operand:QI 2 "register_operand" "c")))
11898 (clobber (match_scratch:DI 3 "=&r"))
11899 (clobber (reg:CC FLAGS_REG))]
11902 [(set_attr "type" "multi")])
11904 (define_insn "*ashrti3_2"
11905 [(set (match_operand:TI 0 "register_operand" "=r")
11906 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11907 (match_operand:QI 2 "immediate_operand" "O")))
11908 (clobber (reg:CC FLAGS_REG))]
11911 [(set_attr "type" "multi")])
11914 [(set (match_operand:TI 0 "register_operand" "")
11915 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11916 (match_operand:QI 2 "register_operand" "")))
11917 (clobber (match_scratch:DI 3 ""))
11918 (clobber (reg:CC FLAGS_REG))]
11919 "TARGET_64BIT && reload_completed"
11921 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11924 [(set (match_operand:TI 0 "register_operand" "")
11925 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11926 (match_operand:QI 2 "immediate_operand" "")))
11927 (clobber (reg:CC FLAGS_REG))]
11928 "TARGET_64BIT && reload_completed"
11930 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11932 (define_insn "x86_64_shrd"
11933 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11934 (ior:DI (ashiftrt:DI (match_dup 0)
11935 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11936 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11937 (minus:QI (const_int 64) (match_dup 2)))))
11938 (clobber (reg:CC FLAGS_REG))]
11941 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11942 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11943 [(set_attr "type" "ishift")
11944 (set_attr "prefix_0f" "1")
11945 (set_attr "mode" "DI")
11946 (set_attr "athlon_decode" "vector")
11947 (set_attr "amdfam10_decode" "vector")])
11949 (define_expand "ashrdi3"
11950 [(set (match_operand:DI 0 "shiftdi_operand" "")
11951 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11952 (match_operand:QI 2 "nonmemory_operand" "")))]
11954 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11956 (define_insn "*ashrdi3_63_rex64"
11957 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11958 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11959 (match_operand:DI 2 "const_int_operand" "i,i")))
11960 (clobber (reg:CC FLAGS_REG))]
11961 "TARGET_64BIT && INTVAL (operands[2]) == 63
11962 && (TARGET_USE_CLTD || optimize_size)
11963 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11966 sar{q}\t{%2, %0|%0, %2}"
11967 [(set_attr "type" "imovx,ishift")
11968 (set_attr "prefix_0f" "0,*")
11969 (set_attr "length_immediate" "0,*")
11970 (set_attr "modrm" "0,1")
11971 (set_attr "mode" "DI")])
11973 (define_insn "*ashrdi3_1_one_bit_rex64"
11974 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11975 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11976 (match_operand:QI 2 "const1_operand" "")))
11977 (clobber (reg:CC FLAGS_REG))]
11979 && (TARGET_SHIFT1 || optimize_size)
11980 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11982 [(set_attr "type" "ishift")
11983 (set (attr "length")
11984 (if_then_else (match_operand:DI 0 "register_operand" "")
11986 (const_string "*")))])
11988 (define_insn "*ashrdi3_1_rex64"
11989 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11990 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11991 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11992 (clobber (reg:CC FLAGS_REG))]
11993 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11995 sar{q}\t{%2, %0|%0, %2}
11996 sar{q}\t{%b2, %0|%0, %b2}"
11997 [(set_attr "type" "ishift")
11998 (set_attr "mode" "DI")])
12000 ;; This pattern can't accept a variable shift count, since shifts by
12001 ;; zero don't affect the flags. We assume that shifts by constant
12002 ;; zero are optimized away.
12003 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12004 [(set (reg FLAGS_REG)
12006 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12007 (match_operand:QI 2 "const1_operand" ""))
12009 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12010 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12012 && (TARGET_SHIFT1 || optimize_size)
12013 && ix86_match_ccmode (insn, CCGOCmode)
12014 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12016 [(set_attr "type" "ishift")
12017 (set (attr "length")
12018 (if_then_else (match_operand:DI 0 "register_operand" "")
12020 (const_string "*")))])
12022 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12023 [(set (reg FLAGS_REG)
12025 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12026 (match_operand:QI 2 "const1_operand" ""))
12028 (clobber (match_scratch:DI 0 "=r"))]
12030 && (TARGET_SHIFT1 || optimize_size)
12031 && ix86_match_ccmode (insn, CCGOCmode)
12032 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12034 [(set_attr "type" "ishift")
12035 (set_attr "length" "2")])
12037 ;; This pattern can't accept a variable shift count, since shifts by
12038 ;; zero don't affect the flags. We assume that shifts by constant
12039 ;; zero are optimized away.
12040 (define_insn "*ashrdi3_cmp_rex64"
12041 [(set (reg FLAGS_REG)
12043 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12044 (match_operand:QI 2 "const_int_operand" "n"))
12046 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12047 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12049 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12050 && ix86_match_ccmode (insn, CCGOCmode)
12051 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12052 "sar{q}\t{%2, %0|%0, %2}"
12053 [(set_attr "type" "ishift")
12054 (set_attr "mode" "DI")])
12056 (define_insn "*ashrdi3_cconly_rex64"
12057 [(set (reg FLAGS_REG)
12059 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12060 (match_operand:QI 2 "const_int_operand" "n"))
12062 (clobber (match_scratch:DI 0 "=r"))]
12064 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12065 && ix86_match_ccmode (insn, CCGOCmode)
12066 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12067 "sar{q}\t{%2, %0|%0, %2}"
12068 [(set_attr "type" "ishift")
12069 (set_attr "mode" "DI")])
12071 (define_insn "*ashrdi3_1"
12072 [(set (match_operand:DI 0 "register_operand" "=r")
12073 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12074 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12075 (clobber (reg:CC FLAGS_REG))]
12078 [(set_attr "type" "multi")])
12080 ;; By default we don't ask for a scratch register, because when DImode
12081 ;; values are manipulated, registers are already at a premium. But if
12082 ;; we have one handy, we won't turn it away.
12084 [(match_scratch:SI 3 "r")
12085 (parallel [(set (match_operand:DI 0 "register_operand" "")
12086 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12087 (match_operand:QI 2 "nonmemory_operand" "")))
12088 (clobber (reg:CC FLAGS_REG))])
12090 "!TARGET_64BIT && TARGET_CMOVE"
12092 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12095 [(set (match_operand:DI 0 "register_operand" "")
12096 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12097 (match_operand:QI 2 "nonmemory_operand" "")))
12098 (clobber (reg:CC FLAGS_REG))]
12099 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12100 ? epilogue_completed : reload_completed)"
12102 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12104 (define_insn "x86_shrd_1"
12105 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12106 (ior:SI (ashiftrt:SI (match_dup 0)
12107 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12108 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12109 (minus:QI (const_int 32) (match_dup 2)))))
12110 (clobber (reg:CC FLAGS_REG))]
12113 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12114 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12115 [(set_attr "type" "ishift")
12116 (set_attr "prefix_0f" "1")
12117 (set_attr "pent_pair" "np")
12118 (set_attr "mode" "SI")])
12120 (define_expand "x86_shift_adj_3"
12121 [(use (match_operand:SI 0 "register_operand" ""))
12122 (use (match_operand:SI 1 "register_operand" ""))
12123 (use (match_operand:QI 2 "register_operand" ""))]
12126 rtx label = gen_label_rtx ();
12129 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12131 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12132 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12133 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12134 gen_rtx_LABEL_REF (VOIDmode, label),
12136 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12137 JUMP_LABEL (tmp) = label;
12139 emit_move_insn (operands[0], operands[1]);
12140 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12142 emit_label (label);
12143 LABEL_NUSES (label) = 1;
12148 (define_insn "ashrsi3_31"
12149 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12150 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12151 (match_operand:SI 2 "const_int_operand" "i,i")))
12152 (clobber (reg:CC FLAGS_REG))]
12153 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12154 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12157 sar{l}\t{%2, %0|%0, %2}"
12158 [(set_attr "type" "imovx,ishift")
12159 (set_attr "prefix_0f" "0,*")
12160 (set_attr "length_immediate" "0,*")
12161 (set_attr "modrm" "0,1")
12162 (set_attr "mode" "SI")])
12164 (define_insn "*ashrsi3_31_zext"
12165 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12166 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12167 (match_operand:SI 2 "const_int_operand" "i,i"))))
12168 (clobber (reg:CC FLAGS_REG))]
12169 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12170 && INTVAL (operands[2]) == 31
12171 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12174 sar{l}\t{%2, %k0|%k0, %2}"
12175 [(set_attr "type" "imovx,ishift")
12176 (set_attr "prefix_0f" "0,*")
12177 (set_attr "length_immediate" "0,*")
12178 (set_attr "modrm" "0,1")
12179 (set_attr "mode" "SI")])
12181 (define_expand "ashrsi3"
12182 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12183 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12184 (match_operand:QI 2 "nonmemory_operand" "")))
12185 (clobber (reg:CC FLAGS_REG))]
12187 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12189 (define_insn "*ashrsi3_1_one_bit"
12190 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12191 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12192 (match_operand:QI 2 "const1_operand" "")))
12193 (clobber (reg:CC FLAGS_REG))]
12194 "(TARGET_SHIFT1 || optimize_size)
12195 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12197 [(set_attr "type" "ishift")
12198 (set (attr "length")
12199 (if_then_else (match_operand:SI 0 "register_operand" "")
12201 (const_string "*")))])
12203 (define_insn "*ashrsi3_1_one_bit_zext"
12204 [(set (match_operand:DI 0 "register_operand" "=r")
12205 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12206 (match_operand:QI 2 "const1_operand" ""))))
12207 (clobber (reg:CC FLAGS_REG))]
12209 && (TARGET_SHIFT1 || optimize_size)
12210 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12212 [(set_attr "type" "ishift")
12213 (set_attr "length" "2")])
12215 (define_insn "*ashrsi3_1"
12216 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12217 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12218 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12219 (clobber (reg:CC FLAGS_REG))]
12220 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12222 sar{l}\t{%2, %0|%0, %2}
12223 sar{l}\t{%b2, %0|%0, %b2}"
12224 [(set_attr "type" "ishift")
12225 (set_attr "mode" "SI")])
12227 (define_insn "*ashrsi3_1_zext"
12228 [(set (match_operand:DI 0 "register_operand" "=r,r")
12229 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12230 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12231 (clobber (reg:CC FLAGS_REG))]
12232 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12234 sar{l}\t{%2, %k0|%k0, %2}
12235 sar{l}\t{%b2, %k0|%k0, %b2}"
12236 [(set_attr "type" "ishift")
12237 (set_attr "mode" "SI")])
12239 ;; This pattern can't accept a variable shift count, since shifts by
12240 ;; zero don't affect the flags. We assume that shifts by constant
12241 ;; zero are optimized away.
12242 (define_insn "*ashrsi3_one_bit_cmp"
12243 [(set (reg FLAGS_REG)
12245 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12246 (match_operand:QI 2 "const1_operand" ""))
12248 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12249 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12250 "(TARGET_SHIFT1 || optimize_size)
12251 && ix86_match_ccmode (insn, CCGOCmode)
12252 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12254 [(set_attr "type" "ishift")
12255 (set (attr "length")
12256 (if_then_else (match_operand:SI 0 "register_operand" "")
12258 (const_string "*")))])
12260 (define_insn "*ashrsi3_one_bit_cconly"
12261 [(set (reg FLAGS_REG)
12263 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12264 (match_operand:QI 2 "const1_operand" ""))
12266 (clobber (match_scratch:SI 0 "=r"))]
12267 "(TARGET_SHIFT1 || optimize_size)
12268 && ix86_match_ccmode (insn, CCGOCmode)
12269 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12271 [(set_attr "type" "ishift")
12272 (set_attr "length" "2")])
12274 (define_insn "*ashrsi3_one_bit_cmp_zext"
12275 [(set (reg FLAGS_REG)
12277 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12278 (match_operand:QI 2 "const1_operand" ""))
12280 (set (match_operand:DI 0 "register_operand" "=r")
12281 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12283 && (TARGET_SHIFT1 || optimize_size)
12284 && ix86_match_ccmode (insn, CCmode)
12285 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12287 [(set_attr "type" "ishift")
12288 (set_attr "length" "2")])
12290 ;; This pattern can't accept a variable shift count, since shifts by
12291 ;; zero don't affect the flags. We assume that shifts by constant
12292 ;; zero are optimized away.
12293 (define_insn "*ashrsi3_cmp"
12294 [(set (reg FLAGS_REG)
12296 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12297 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12299 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12300 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12301 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12302 && ix86_match_ccmode (insn, CCGOCmode)
12303 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12304 "sar{l}\t{%2, %0|%0, %2}"
12305 [(set_attr "type" "ishift")
12306 (set_attr "mode" "SI")])
12308 (define_insn "*ashrsi3_cconly"
12309 [(set (reg FLAGS_REG)
12311 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12312 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12314 (clobber (match_scratch:SI 0 "=r"))]
12315 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12316 && ix86_match_ccmode (insn, CCGOCmode)
12317 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12318 "sar{l}\t{%2, %0|%0, %2}"
12319 [(set_attr "type" "ishift")
12320 (set_attr "mode" "SI")])
12322 (define_insn "*ashrsi3_cmp_zext"
12323 [(set (reg FLAGS_REG)
12325 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12326 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12328 (set (match_operand:DI 0 "register_operand" "=r")
12329 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12331 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12332 && ix86_match_ccmode (insn, CCGOCmode)
12333 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12334 "sar{l}\t{%2, %k0|%k0, %2}"
12335 [(set_attr "type" "ishift")
12336 (set_attr "mode" "SI")])
12338 (define_expand "ashrhi3"
12339 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12340 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12341 (match_operand:QI 2 "nonmemory_operand" "")))
12342 (clobber (reg:CC FLAGS_REG))]
12343 "TARGET_HIMODE_MATH"
12344 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12346 (define_insn "*ashrhi3_1_one_bit"
12347 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12348 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12349 (match_operand:QI 2 "const1_operand" "")))
12350 (clobber (reg:CC FLAGS_REG))]
12351 "(TARGET_SHIFT1 || optimize_size)
12352 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12354 [(set_attr "type" "ishift")
12355 (set (attr "length")
12356 (if_then_else (match_operand 0 "register_operand" "")
12358 (const_string "*")))])
12360 (define_insn "*ashrhi3_1"
12361 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12362 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12363 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12364 (clobber (reg:CC FLAGS_REG))]
12365 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12367 sar{w}\t{%2, %0|%0, %2}
12368 sar{w}\t{%b2, %0|%0, %b2}"
12369 [(set_attr "type" "ishift")
12370 (set_attr "mode" "HI")])
12372 ;; This pattern can't accept a variable shift count, since shifts by
12373 ;; zero don't affect the flags. We assume that shifts by constant
12374 ;; zero are optimized away.
12375 (define_insn "*ashrhi3_one_bit_cmp"
12376 [(set (reg FLAGS_REG)
12378 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12379 (match_operand:QI 2 "const1_operand" ""))
12381 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12382 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12383 "(TARGET_SHIFT1 || optimize_size)
12384 && ix86_match_ccmode (insn, CCGOCmode)
12385 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12387 [(set_attr "type" "ishift")
12388 (set (attr "length")
12389 (if_then_else (match_operand 0 "register_operand" "")
12391 (const_string "*")))])
12393 (define_insn "*ashrhi3_one_bit_cconly"
12394 [(set (reg FLAGS_REG)
12396 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12397 (match_operand:QI 2 "const1_operand" ""))
12399 (clobber (match_scratch:HI 0 "=r"))]
12400 "(TARGET_SHIFT1 || optimize_size)
12401 && ix86_match_ccmode (insn, CCGOCmode)
12402 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12404 [(set_attr "type" "ishift")
12405 (set_attr "length" "2")])
12407 ;; This pattern can't accept a variable shift count, since shifts by
12408 ;; zero don't affect the flags. We assume that shifts by constant
12409 ;; zero are optimized away.
12410 (define_insn "*ashrhi3_cmp"
12411 [(set (reg FLAGS_REG)
12413 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12414 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12416 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12417 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12418 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12419 && ix86_match_ccmode (insn, CCGOCmode)
12420 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12421 "sar{w}\t{%2, %0|%0, %2}"
12422 [(set_attr "type" "ishift")
12423 (set_attr "mode" "HI")])
12425 (define_insn "*ashrhi3_cconly"
12426 [(set (reg FLAGS_REG)
12428 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12429 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12431 (clobber (match_scratch:HI 0 "=r"))]
12432 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12433 && ix86_match_ccmode (insn, CCGOCmode)
12434 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12435 "sar{w}\t{%2, %0|%0, %2}"
12436 [(set_attr "type" "ishift")
12437 (set_attr "mode" "HI")])
12439 (define_expand "ashrqi3"
12440 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12441 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12442 (match_operand:QI 2 "nonmemory_operand" "")))
12443 (clobber (reg:CC FLAGS_REG))]
12444 "TARGET_QIMODE_MATH"
12445 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12447 (define_insn "*ashrqi3_1_one_bit"
12448 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12449 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12450 (match_operand:QI 2 "const1_operand" "")))
12451 (clobber (reg:CC FLAGS_REG))]
12452 "(TARGET_SHIFT1 || optimize_size)
12453 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12455 [(set_attr "type" "ishift")
12456 (set (attr "length")
12457 (if_then_else (match_operand 0 "register_operand" "")
12459 (const_string "*")))])
12461 (define_insn "*ashrqi3_1_one_bit_slp"
12462 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12463 (ashiftrt:QI (match_dup 0)
12464 (match_operand:QI 1 "const1_operand" "")))
12465 (clobber (reg:CC FLAGS_REG))]
12466 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12467 && (TARGET_SHIFT1 || optimize_size)
12468 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12470 [(set_attr "type" "ishift1")
12471 (set (attr "length")
12472 (if_then_else (match_operand 0 "register_operand" "")
12474 (const_string "*")))])
12476 (define_insn "*ashrqi3_1"
12477 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12478 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12479 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12480 (clobber (reg:CC FLAGS_REG))]
12481 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12483 sar{b}\t{%2, %0|%0, %2}
12484 sar{b}\t{%b2, %0|%0, %b2}"
12485 [(set_attr "type" "ishift")
12486 (set_attr "mode" "QI")])
12488 (define_insn "*ashrqi3_1_slp"
12489 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12490 (ashiftrt:QI (match_dup 0)
12491 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12492 (clobber (reg:CC FLAGS_REG))]
12493 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12494 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12496 sar{b}\t{%1, %0|%0, %1}
12497 sar{b}\t{%b1, %0|%0, %b1}"
12498 [(set_attr "type" "ishift1")
12499 (set_attr "mode" "QI")])
12501 ;; This pattern can't accept a variable shift count, since shifts by
12502 ;; zero don't affect the flags. We assume that shifts by constant
12503 ;; zero are optimized away.
12504 (define_insn "*ashrqi3_one_bit_cmp"
12505 [(set (reg FLAGS_REG)
12507 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12508 (match_operand:QI 2 "const1_operand" "I"))
12510 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12511 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12512 "(TARGET_SHIFT1 || optimize_size)
12513 && ix86_match_ccmode (insn, CCGOCmode)
12514 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12516 [(set_attr "type" "ishift")
12517 (set (attr "length")
12518 (if_then_else (match_operand 0 "register_operand" "")
12520 (const_string "*")))])
12522 (define_insn "*ashrqi3_one_bit_cconly"
12523 [(set (reg FLAGS_REG)
12525 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12526 (match_operand:QI 2 "const1_operand" "I"))
12528 (clobber (match_scratch:QI 0 "=q"))]
12529 "(TARGET_SHIFT1 || optimize_size)
12530 && ix86_match_ccmode (insn, CCGOCmode)
12531 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12533 [(set_attr "type" "ishift")
12534 (set_attr "length" "2")])
12536 ;; This pattern can't accept a variable shift count, since shifts by
12537 ;; zero don't affect the flags. We assume that shifts by constant
12538 ;; zero are optimized away.
12539 (define_insn "*ashrqi3_cmp"
12540 [(set (reg FLAGS_REG)
12542 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12543 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12545 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12546 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12547 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12548 && ix86_match_ccmode (insn, CCGOCmode)
12549 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12550 "sar{b}\t{%2, %0|%0, %2}"
12551 [(set_attr "type" "ishift")
12552 (set_attr "mode" "QI")])
12554 (define_insn "*ashrqi3_cconly"
12555 [(set (reg FLAGS_REG)
12557 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12558 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12560 (clobber (match_scratch:QI 0 "=q"))]
12561 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12562 && ix86_match_ccmode (insn, CCGOCmode)
12563 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12564 "sar{b}\t{%2, %0|%0, %2}"
12565 [(set_attr "type" "ishift")
12566 (set_attr "mode" "QI")])
12569 ;; Logical shift instructions
12571 ;; See comment above `ashldi3' about how this works.
12573 (define_expand "lshrti3"
12574 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12575 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12576 (match_operand:QI 2 "nonmemory_operand" "")))
12577 (clobber (reg:CC FLAGS_REG))])]
12580 if (! immediate_operand (operands[2], QImode))
12582 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12585 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12589 (define_insn "lshrti3_1"
12590 [(set (match_operand:TI 0 "register_operand" "=r")
12591 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12592 (match_operand:QI 2 "register_operand" "c")))
12593 (clobber (match_scratch:DI 3 "=&r"))
12594 (clobber (reg:CC FLAGS_REG))]
12597 [(set_attr "type" "multi")])
12599 ;; This pattern must be defined before *lshrti3_2 to prevent
12600 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12602 (define_insn "sse2_lshrti3"
12603 [(set (match_operand:TI 0 "register_operand" "=x")
12604 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12605 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12608 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12609 return "psrldq\t{%2, %0|%0, %2}";
12611 [(set_attr "type" "sseishft")
12612 (set_attr "prefix_data16" "1")
12613 (set_attr "mode" "TI")])
12615 (define_insn "*lshrti3_2"
12616 [(set (match_operand:TI 0 "register_operand" "=r")
12617 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12618 (match_operand:QI 2 "immediate_operand" "O")))
12619 (clobber (reg:CC FLAGS_REG))]
12622 [(set_attr "type" "multi")])
12625 [(set (match_operand:TI 0 "register_operand" "")
12626 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12627 (match_operand:QI 2 "register_operand" "")))
12628 (clobber (match_scratch:DI 3 ""))
12629 (clobber (reg:CC FLAGS_REG))]
12630 "TARGET_64BIT && reload_completed"
12632 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12635 [(set (match_operand:TI 0 "register_operand" "")
12636 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12637 (match_operand:QI 2 "immediate_operand" "")))
12638 (clobber (reg:CC FLAGS_REG))]
12639 "TARGET_64BIT && reload_completed"
12641 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12643 (define_expand "lshrdi3"
12644 [(set (match_operand:DI 0 "shiftdi_operand" "")
12645 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12646 (match_operand:QI 2 "nonmemory_operand" "")))]
12648 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12650 (define_insn "*lshrdi3_1_one_bit_rex64"
12651 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12652 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12653 (match_operand:QI 2 "const1_operand" "")))
12654 (clobber (reg:CC FLAGS_REG))]
12656 && (TARGET_SHIFT1 || optimize_size)
12657 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12659 [(set_attr "type" "ishift")
12660 (set (attr "length")
12661 (if_then_else (match_operand:DI 0 "register_operand" "")
12663 (const_string "*")))])
12665 (define_insn "*lshrdi3_1_rex64"
12666 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12667 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12668 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12669 (clobber (reg:CC FLAGS_REG))]
12670 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12672 shr{q}\t{%2, %0|%0, %2}
12673 shr{q}\t{%b2, %0|%0, %b2}"
12674 [(set_attr "type" "ishift")
12675 (set_attr "mode" "DI")])
12677 ;; This pattern can't accept a variable shift count, since shifts by
12678 ;; zero don't affect the flags. We assume that shifts by constant
12679 ;; zero are optimized away.
12680 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12681 [(set (reg FLAGS_REG)
12683 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12684 (match_operand:QI 2 "const1_operand" ""))
12686 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12687 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12689 && (TARGET_SHIFT1 || optimize_size)
12690 && ix86_match_ccmode (insn, CCGOCmode)
12691 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12693 [(set_attr "type" "ishift")
12694 (set (attr "length")
12695 (if_then_else (match_operand:DI 0 "register_operand" "")
12697 (const_string "*")))])
12699 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12700 [(set (reg FLAGS_REG)
12702 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12703 (match_operand:QI 2 "const1_operand" ""))
12705 (clobber (match_scratch:DI 0 "=r"))]
12707 && (TARGET_SHIFT1 || optimize_size)
12708 && ix86_match_ccmode (insn, CCGOCmode)
12709 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12711 [(set_attr "type" "ishift")
12712 (set_attr "length" "2")])
12714 ;; This pattern can't accept a variable shift count, since shifts by
12715 ;; zero don't affect the flags. We assume that shifts by constant
12716 ;; zero are optimized away.
12717 (define_insn "*lshrdi3_cmp_rex64"
12718 [(set (reg FLAGS_REG)
12720 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12721 (match_operand:QI 2 "const_int_operand" "e"))
12723 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12724 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12726 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12727 && ix86_match_ccmode (insn, CCGOCmode)
12728 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12729 "shr{q}\t{%2, %0|%0, %2}"
12730 [(set_attr "type" "ishift")
12731 (set_attr "mode" "DI")])
12733 (define_insn "*lshrdi3_cconly_rex64"
12734 [(set (reg FLAGS_REG)
12736 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12737 (match_operand:QI 2 "const_int_operand" "e"))
12739 (clobber (match_scratch:DI 0 "=r"))]
12741 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12742 && ix86_match_ccmode (insn, CCGOCmode)
12743 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12744 "shr{q}\t{%2, %0|%0, %2}"
12745 [(set_attr "type" "ishift")
12746 (set_attr "mode" "DI")])
12748 (define_insn "*lshrdi3_1"
12749 [(set (match_operand:DI 0 "register_operand" "=r")
12750 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12751 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12752 (clobber (reg:CC FLAGS_REG))]
12755 [(set_attr "type" "multi")])
12757 ;; By default we don't ask for a scratch register, because when DImode
12758 ;; values are manipulated, registers are already at a premium. But if
12759 ;; we have one handy, we won't turn it away.
12761 [(match_scratch:SI 3 "r")
12762 (parallel [(set (match_operand:DI 0 "register_operand" "")
12763 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12764 (match_operand:QI 2 "nonmemory_operand" "")))
12765 (clobber (reg:CC FLAGS_REG))])
12767 "!TARGET_64BIT && TARGET_CMOVE"
12769 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12772 [(set (match_operand:DI 0 "register_operand" "")
12773 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12774 (match_operand:QI 2 "nonmemory_operand" "")))
12775 (clobber (reg:CC FLAGS_REG))]
12776 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12777 ? epilogue_completed : reload_completed)"
12779 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12781 (define_expand "lshrsi3"
12782 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12783 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12784 (match_operand:QI 2 "nonmemory_operand" "")))
12785 (clobber (reg:CC FLAGS_REG))]
12787 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12789 (define_insn "*lshrsi3_1_one_bit"
12790 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12791 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12792 (match_operand:QI 2 "const1_operand" "")))
12793 (clobber (reg:CC FLAGS_REG))]
12794 "(TARGET_SHIFT1 || optimize_size)
12795 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12797 [(set_attr "type" "ishift")
12798 (set (attr "length")
12799 (if_then_else (match_operand:SI 0 "register_operand" "")
12801 (const_string "*")))])
12803 (define_insn "*lshrsi3_1_one_bit_zext"
12804 [(set (match_operand:DI 0 "register_operand" "=r")
12805 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12806 (match_operand:QI 2 "const1_operand" "")))
12807 (clobber (reg:CC FLAGS_REG))]
12809 && (TARGET_SHIFT1 || optimize_size)
12810 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12812 [(set_attr "type" "ishift")
12813 (set_attr "length" "2")])
12815 (define_insn "*lshrsi3_1"
12816 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12817 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12818 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12819 (clobber (reg:CC FLAGS_REG))]
12820 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12822 shr{l}\t{%2, %0|%0, %2}
12823 shr{l}\t{%b2, %0|%0, %b2}"
12824 [(set_attr "type" "ishift")
12825 (set_attr "mode" "SI")])
12827 (define_insn "*lshrsi3_1_zext"
12828 [(set (match_operand:DI 0 "register_operand" "=r,r")
12830 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12831 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12832 (clobber (reg:CC FLAGS_REG))]
12833 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12835 shr{l}\t{%2, %k0|%k0, %2}
12836 shr{l}\t{%b2, %k0|%k0, %b2}"
12837 [(set_attr "type" "ishift")
12838 (set_attr "mode" "SI")])
12840 ;; This pattern can't accept a variable shift count, since shifts by
12841 ;; zero don't affect the flags. We assume that shifts by constant
12842 ;; zero are optimized away.
12843 (define_insn "*lshrsi3_one_bit_cmp"
12844 [(set (reg FLAGS_REG)
12846 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12847 (match_operand:QI 2 "const1_operand" ""))
12849 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12850 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12851 "(TARGET_SHIFT1 || optimize_size)
12852 && ix86_match_ccmode (insn, CCGOCmode)
12853 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12855 [(set_attr "type" "ishift")
12856 (set (attr "length")
12857 (if_then_else (match_operand:SI 0 "register_operand" "")
12859 (const_string "*")))])
12861 (define_insn "*lshrsi3_one_bit_cconly"
12862 [(set (reg FLAGS_REG)
12864 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12865 (match_operand:QI 2 "const1_operand" ""))
12867 (clobber (match_scratch:SI 0 "=r"))]
12868 "(TARGET_SHIFT1 || optimize_size)
12869 && ix86_match_ccmode (insn, CCGOCmode)
12870 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12872 [(set_attr "type" "ishift")
12873 (set_attr "length" "2")])
12875 (define_insn "*lshrsi3_cmp_one_bit_zext"
12876 [(set (reg FLAGS_REG)
12878 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12879 (match_operand:QI 2 "const1_operand" ""))
12881 (set (match_operand:DI 0 "register_operand" "=r")
12882 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12884 && (TARGET_SHIFT1 || optimize_size)
12885 && ix86_match_ccmode (insn, CCGOCmode)
12886 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12888 [(set_attr "type" "ishift")
12889 (set_attr "length" "2")])
12891 ;; This pattern can't accept a variable shift count, since shifts by
12892 ;; zero don't affect the flags. We assume that shifts by constant
12893 ;; zero are optimized away.
12894 (define_insn "*lshrsi3_cmp"
12895 [(set (reg FLAGS_REG)
12897 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12898 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12900 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12901 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12902 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12903 && ix86_match_ccmode (insn, CCGOCmode)
12904 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12905 "shr{l}\t{%2, %0|%0, %2}"
12906 [(set_attr "type" "ishift")
12907 (set_attr "mode" "SI")])
12909 (define_insn "*lshrsi3_cconly"
12910 [(set (reg FLAGS_REG)
12912 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12913 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12915 (clobber (match_scratch:SI 0 "=r"))]
12916 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12917 && ix86_match_ccmode (insn, CCGOCmode)
12918 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12919 "shr{l}\t{%2, %0|%0, %2}"
12920 [(set_attr "type" "ishift")
12921 (set_attr "mode" "SI")])
12923 (define_insn "*lshrsi3_cmp_zext"
12924 [(set (reg FLAGS_REG)
12926 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12927 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12929 (set (match_operand:DI 0 "register_operand" "=r")
12930 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12932 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12933 && ix86_match_ccmode (insn, CCGOCmode)
12934 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12935 "shr{l}\t{%2, %k0|%k0, %2}"
12936 [(set_attr "type" "ishift")
12937 (set_attr "mode" "SI")])
12939 (define_expand "lshrhi3"
12940 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12941 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12942 (match_operand:QI 2 "nonmemory_operand" "")))
12943 (clobber (reg:CC FLAGS_REG))]
12944 "TARGET_HIMODE_MATH"
12945 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12947 (define_insn "*lshrhi3_1_one_bit"
12948 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12949 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12950 (match_operand:QI 2 "const1_operand" "")))
12951 (clobber (reg:CC FLAGS_REG))]
12952 "(TARGET_SHIFT1 || optimize_size)
12953 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12955 [(set_attr "type" "ishift")
12956 (set (attr "length")
12957 (if_then_else (match_operand 0 "register_operand" "")
12959 (const_string "*")))])
12961 (define_insn "*lshrhi3_1"
12962 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12963 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12964 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12965 (clobber (reg:CC FLAGS_REG))]
12966 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12968 shr{w}\t{%2, %0|%0, %2}
12969 shr{w}\t{%b2, %0|%0, %b2}"
12970 [(set_attr "type" "ishift")
12971 (set_attr "mode" "HI")])
12973 ;; This pattern can't accept a variable shift count, since shifts by
12974 ;; zero don't affect the flags. We assume that shifts by constant
12975 ;; zero are optimized away.
12976 (define_insn "*lshrhi3_one_bit_cmp"
12977 [(set (reg FLAGS_REG)
12979 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12980 (match_operand:QI 2 "const1_operand" ""))
12982 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12983 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12984 "(TARGET_SHIFT1 || optimize_size)
12985 && ix86_match_ccmode (insn, CCGOCmode)
12986 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12988 [(set_attr "type" "ishift")
12989 (set (attr "length")
12990 (if_then_else (match_operand:SI 0 "register_operand" "")
12992 (const_string "*")))])
12994 (define_insn "*lshrhi3_one_bit_cconly"
12995 [(set (reg FLAGS_REG)
12997 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12998 (match_operand:QI 2 "const1_operand" ""))
13000 (clobber (match_scratch:HI 0 "=r"))]
13001 "(TARGET_SHIFT1 || optimize_size)
13002 && ix86_match_ccmode (insn, CCGOCmode)
13003 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13005 [(set_attr "type" "ishift")
13006 (set_attr "length" "2")])
13008 ;; This pattern can't accept a variable shift count, since shifts by
13009 ;; zero don't affect the flags. We assume that shifts by constant
13010 ;; zero are optimized away.
13011 (define_insn "*lshrhi3_cmp"
13012 [(set (reg FLAGS_REG)
13014 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13015 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13017 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13018 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13019 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13020 && ix86_match_ccmode (insn, CCGOCmode)
13021 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13022 "shr{w}\t{%2, %0|%0, %2}"
13023 [(set_attr "type" "ishift")
13024 (set_attr "mode" "HI")])
13026 (define_insn "*lshrhi3_cconly"
13027 [(set (reg FLAGS_REG)
13029 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13030 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13032 (clobber (match_scratch:HI 0 "=r"))]
13033 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13034 && ix86_match_ccmode (insn, CCGOCmode)
13035 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13036 "shr{w}\t{%2, %0|%0, %2}"
13037 [(set_attr "type" "ishift")
13038 (set_attr "mode" "HI")])
13040 (define_expand "lshrqi3"
13041 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13042 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13043 (match_operand:QI 2 "nonmemory_operand" "")))
13044 (clobber (reg:CC FLAGS_REG))]
13045 "TARGET_QIMODE_MATH"
13046 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13048 (define_insn "*lshrqi3_1_one_bit"
13049 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13050 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13051 (match_operand:QI 2 "const1_operand" "")))
13052 (clobber (reg:CC FLAGS_REG))]
13053 "(TARGET_SHIFT1 || optimize_size)
13054 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13056 [(set_attr "type" "ishift")
13057 (set (attr "length")
13058 (if_then_else (match_operand 0 "register_operand" "")
13060 (const_string "*")))])
13062 (define_insn "*lshrqi3_1_one_bit_slp"
13063 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13064 (lshiftrt:QI (match_dup 0)
13065 (match_operand:QI 1 "const1_operand" "")))
13066 (clobber (reg:CC FLAGS_REG))]
13067 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13068 && (TARGET_SHIFT1 || optimize_size)"
13070 [(set_attr "type" "ishift1")
13071 (set (attr "length")
13072 (if_then_else (match_operand 0 "register_operand" "")
13074 (const_string "*")))])
13076 (define_insn "*lshrqi3_1"
13077 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13078 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13079 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13080 (clobber (reg:CC FLAGS_REG))]
13081 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13083 shr{b}\t{%2, %0|%0, %2}
13084 shr{b}\t{%b2, %0|%0, %b2}"
13085 [(set_attr "type" "ishift")
13086 (set_attr "mode" "QI")])
13088 (define_insn "*lshrqi3_1_slp"
13089 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13090 (lshiftrt:QI (match_dup 0)
13091 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13092 (clobber (reg:CC FLAGS_REG))]
13093 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13094 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13096 shr{b}\t{%1, %0|%0, %1}
13097 shr{b}\t{%b1, %0|%0, %b1}"
13098 [(set_attr "type" "ishift1")
13099 (set_attr "mode" "QI")])
13101 ;; This pattern can't accept a variable shift count, since shifts by
13102 ;; zero don't affect the flags. We assume that shifts by constant
13103 ;; zero are optimized away.
13104 (define_insn "*lshrqi2_one_bit_cmp"
13105 [(set (reg FLAGS_REG)
13107 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13108 (match_operand:QI 2 "const1_operand" ""))
13110 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13111 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13112 "(TARGET_SHIFT1 || optimize_size)
13113 && ix86_match_ccmode (insn, CCGOCmode)
13114 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13116 [(set_attr "type" "ishift")
13117 (set (attr "length")
13118 (if_then_else (match_operand:SI 0 "register_operand" "")
13120 (const_string "*")))])
13122 (define_insn "*lshrqi2_one_bit_cconly"
13123 [(set (reg FLAGS_REG)
13125 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13126 (match_operand:QI 2 "const1_operand" ""))
13128 (clobber (match_scratch:QI 0 "=q"))]
13129 "(TARGET_SHIFT1 || optimize_size)
13130 && ix86_match_ccmode (insn, CCGOCmode)
13131 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13133 [(set_attr "type" "ishift")
13134 (set_attr "length" "2")])
13136 ;; This pattern can't accept a variable shift count, since shifts by
13137 ;; zero don't affect the flags. We assume that shifts by constant
13138 ;; zero are optimized away.
13139 (define_insn "*lshrqi2_cmp"
13140 [(set (reg FLAGS_REG)
13142 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13143 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13145 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13146 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13147 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13148 && ix86_match_ccmode (insn, CCGOCmode)
13149 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13150 "shr{b}\t{%2, %0|%0, %2}"
13151 [(set_attr "type" "ishift")
13152 (set_attr "mode" "QI")])
13154 (define_insn "*lshrqi2_cconly"
13155 [(set (reg FLAGS_REG)
13157 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13158 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13160 (clobber (match_scratch:QI 0 "=q"))]
13161 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13162 && ix86_match_ccmode (insn, CCGOCmode)
13163 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13164 "shr{b}\t{%2, %0|%0, %2}"
13165 [(set_attr "type" "ishift")
13166 (set_attr "mode" "QI")])
13168 ;; Rotate instructions
13170 (define_expand "rotldi3"
13171 [(set (match_operand:DI 0 "shiftdi_operand" "")
13172 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13173 (match_operand:QI 2 "nonmemory_operand" "")))
13174 (clobber (reg:CC FLAGS_REG))]
13179 ix86_expand_binary_operator (ROTATE, DImode, operands);
13182 if (!const_1_to_31_operand (operands[2], VOIDmode))
13184 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13188 ;; Implement rotation using two double-precision shift instructions
13189 ;; and a scratch register.
13190 (define_insn_and_split "ix86_rotldi3"
13191 [(set (match_operand:DI 0 "register_operand" "=r")
13192 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13193 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13194 (clobber (reg:CC FLAGS_REG))
13195 (clobber (match_scratch:SI 3 "=&r"))]
13198 "&& reload_completed"
13199 [(set (match_dup 3) (match_dup 4))
13201 [(set (match_dup 4)
13202 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13203 (lshiftrt:SI (match_dup 5)
13204 (minus:QI (const_int 32) (match_dup 2)))))
13205 (clobber (reg:CC FLAGS_REG))])
13207 [(set (match_dup 5)
13208 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13209 (lshiftrt:SI (match_dup 3)
13210 (minus:QI (const_int 32) (match_dup 2)))))
13211 (clobber (reg:CC FLAGS_REG))])]
13212 "split_di (operands, 1, operands + 4, operands + 5);")
13214 (define_insn "*rotlsi3_1_one_bit_rex64"
13215 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13216 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13217 (match_operand:QI 2 "const1_operand" "")))
13218 (clobber (reg:CC FLAGS_REG))]
13220 && (TARGET_SHIFT1 || optimize_size)
13221 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13223 [(set_attr "type" "rotate")
13224 (set (attr "length")
13225 (if_then_else (match_operand:DI 0 "register_operand" "")
13227 (const_string "*")))])
13229 (define_insn "*rotldi3_1_rex64"
13230 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13231 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13232 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13233 (clobber (reg:CC FLAGS_REG))]
13234 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13236 rol{q}\t{%2, %0|%0, %2}
13237 rol{q}\t{%b2, %0|%0, %b2}"
13238 [(set_attr "type" "rotate")
13239 (set_attr "mode" "DI")])
13241 (define_expand "rotlsi3"
13242 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13243 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13244 (match_operand:QI 2 "nonmemory_operand" "")))
13245 (clobber (reg:CC FLAGS_REG))]
13247 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13249 (define_insn "*rotlsi3_1_one_bit"
13250 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13251 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13252 (match_operand:QI 2 "const1_operand" "")))
13253 (clobber (reg:CC FLAGS_REG))]
13254 "(TARGET_SHIFT1 || optimize_size)
13255 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13257 [(set_attr "type" "rotate")
13258 (set (attr "length")
13259 (if_then_else (match_operand:SI 0 "register_operand" "")
13261 (const_string "*")))])
13263 (define_insn "*rotlsi3_1_one_bit_zext"
13264 [(set (match_operand:DI 0 "register_operand" "=r")
13266 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13267 (match_operand:QI 2 "const1_operand" ""))))
13268 (clobber (reg:CC FLAGS_REG))]
13270 && (TARGET_SHIFT1 || optimize_size)
13271 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13273 [(set_attr "type" "rotate")
13274 (set_attr "length" "2")])
13276 (define_insn "*rotlsi3_1"
13277 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13278 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13279 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13280 (clobber (reg:CC FLAGS_REG))]
13281 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13283 rol{l}\t{%2, %0|%0, %2}
13284 rol{l}\t{%b2, %0|%0, %b2}"
13285 [(set_attr "type" "rotate")
13286 (set_attr "mode" "SI")])
13288 (define_insn "*rotlsi3_1_zext"
13289 [(set (match_operand:DI 0 "register_operand" "=r,r")
13291 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13292 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13293 (clobber (reg:CC FLAGS_REG))]
13294 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13296 rol{l}\t{%2, %k0|%k0, %2}
13297 rol{l}\t{%b2, %k0|%k0, %b2}"
13298 [(set_attr "type" "rotate")
13299 (set_attr "mode" "SI")])
13301 (define_expand "rotlhi3"
13302 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13303 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13304 (match_operand:QI 2 "nonmemory_operand" "")))
13305 (clobber (reg:CC FLAGS_REG))]
13306 "TARGET_HIMODE_MATH"
13307 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13309 (define_insn "*rotlhi3_1_one_bit"
13310 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13311 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13312 (match_operand:QI 2 "const1_operand" "")))
13313 (clobber (reg:CC FLAGS_REG))]
13314 "(TARGET_SHIFT1 || optimize_size)
13315 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13317 [(set_attr "type" "rotate")
13318 (set (attr "length")
13319 (if_then_else (match_operand 0 "register_operand" "")
13321 (const_string "*")))])
13323 (define_insn "*rotlhi3_1"
13324 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13325 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13326 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13327 (clobber (reg:CC FLAGS_REG))]
13328 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13330 rol{w}\t{%2, %0|%0, %2}
13331 rol{w}\t{%b2, %0|%0, %b2}"
13332 [(set_attr "type" "rotate")
13333 (set_attr "mode" "HI")])
13336 [(set (match_operand:HI 0 "register_operand" "")
13337 (rotate:HI (match_dup 0) (const_int 8)))
13338 (clobber (reg:CC FLAGS_REG))]
13340 [(parallel [(set (strict_low_part (match_dup 0))
13341 (bswap:HI (match_dup 0)))
13342 (clobber (reg:CC FLAGS_REG))])]
13345 (define_expand "rotlqi3"
13346 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13347 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13348 (match_operand:QI 2 "nonmemory_operand" "")))
13349 (clobber (reg:CC FLAGS_REG))]
13350 "TARGET_QIMODE_MATH"
13351 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13353 (define_insn "*rotlqi3_1_one_bit_slp"
13354 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13355 (rotate:QI (match_dup 0)
13356 (match_operand:QI 1 "const1_operand" "")))
13357 (clobber (reg:CC FLAGS_REG))]
13358 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13359 && (TARGET_SHIFT1 || optimize_size)"
13361 [(set_attr "type" "rotate1")
13362 (set (attr "length")
13363 (if_then_else (match_operand 0 "register_operand" "")
13365 (const_string "*")))])
13367 (define_insn "*rotlqi3_1_one_bit"
13368 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13369 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13370 (match_operand:QI 2 "const1_operand" "")))
13371 (clobber (reg:CC FLAGS_REG))]
13372 "(TARGET_SHIFT1 || optimize_size)
13373 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13375 [(set_attr "type" "rotate")
13376 (set (attr "length")
13377 (if_then_else (match_operand 0 "register_operand" "")
13379 (const_string "*")))])
13381 (define_insn "*rotlqi3_1_slp"
13382 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13383 (rotate:QI (match_dup 0)
13384 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13385 (clobber (reg:CC FLAGS_REG))]
13386 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13387 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13389 rol{b}\t{%1, %0|%0, %1}
13390 rol{b}\t{%b1, %0|%0, %b1}"
13391 [(set_attr "type" "rotate1")
13392 (set_attr "mode" "QI")])
13394 (define_insn "*rotlqi3_1"
13395 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13396 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13397 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13398 (clobber (reg:CC FLAGS_REG))]
13399 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13401 rol{b}\t{%2, %0|%0, %2}
13402 rol{b}\t{%b2, %0|%0, %b2}"
13403 [(set_attr "type" "rotate")
13404 (set_attr "mode" "QI")])
13406 (define_expand "rotrdi3"
13407 [(set (match_operand:DI 0 "shiftdi_operand" "")
13408 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13409 (match_operand:QI 2 "nonmemory_operand" "")))
13410 (clobber (reg:CC FLAGS_REG))]
13415 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13418 if (!const_1_to_31_operand (operands[2], VOIDmode))
13420 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13424 ;; Implement rotation using two double-precision shift instructions
13425 ;; and a scratch register.
13426 (define_insn_and_split "ix86_rotrdi3"
13427 [(set (match_operand:DI 0 "register_operand" "=r")
13428 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13429 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13430 (clobber (reg:CC FLAGS_REG))
13431 (clobber (match_scratch:SI 3 "=&r"))]
13434 "&& reload_completed"
13435 [(set (match_dup 3) (match_dup 4))
13437 [(set (match_dup 4)
13438 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13439 (ashift:SI (match_dup 5)
13440 (minus:QI (const_int 32) (match_dup 2)))))
13441 (clobber (reg:CC FLAGS_REG))])
13443 [(set (match_dup 5)
13444 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13445 (ashift:SI (match_dup 3)
13446 (minus:QI (const_int 32) (match_dup 2)))))
13447 (clobber (reg:CC FLAGS_REG))])]
13448 "split_di (operands, 1, operands + 4, operands + 5);")
13450 (define_insn "*rotrdi3_1_one_bit_rex64"
13451 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13452 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13453 (match_operand:QI 2 "const1_operand" "")))
13454 (clobber (reg:CC FLAGS_REG))]
13456 && (TARGET_SHIFT1 || optimize_size)
13457 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13459 [(set_attr "type" "rotate")
13460 (set (attr "length")
13461 (if_then_else (match_operand:DI 0 "register_operand" "")
13463 (const_string "*")))])
13465 (define_insn "*rotrdi3_1_rex64"
13466 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13467 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13468 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13469 (clobber (reg:CC FLAGS_REG))]
13470 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13472 ror{q}\t{%2, %0|%0, %2}
13473 ror{q}\t{%b2, %0|%0, %b2}"
13474 [(set_attr "type" "rotate")
13475 (set_attr "mode" "DI")])
13477 (define_expand "rotrsi3"
13478 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13479 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13480 (match_operand:QI 2 "nonmemory_operand" "")))
13481 (clobber (reg:CC FLAGS_REG))]
13483 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13485 (define_insn "*rotrsi3_1_one_bit"
13486 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13487 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13488 (match_operand:QI 2 "const1_operand" "")))
13489 (clobber (reg:CC FLAGS_REG))]
13490 "(TARGET_SHIFT1 || optimize_size)
13491 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13493 [(set_attr "type" "rotate")
13494 (set (attr "length")
13495 (if_then_else (match_operand:SI 0 "register_operand" "")
13497 (const_string "*")))])
13499 (define_insn "*rotrsi3_1_one_bit_zext"
13500 [(set (match_operand:DI 0 "register_operand" "=r")
13502 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13503 (match_operand:QI 2 "const1_operand" ""))))
13504 (clobber (reg:CC FLAGS_REG))]
13506 && (TARGET_SHIFT1 || optimize_size)
13507 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13509 [(set_attr "type" "rotate")
13510 (set (attr "length")
13511 (if_then_else (match_operand:SI 0 "register_operand" "")
13513 (const_string "*")))])
13515 (define_insn "*rotrsi3_1"
13516 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13517 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13518 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13519 (clobber (reg:CC FLAGS_REG))]
13520 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13522 ror{l}\t{%2, %0|%0, %2}
13523 ror{l}\t{%b2, %0|%0, %b2}"
13524 [(set_attr "type" "rotate")
13525 (set_attr "mode" "SI")])
13527 (define_insn "*rotrsi3_1_zext"
13528 [(set (match_operand:DI 0 "register_operand" "=r,r")
13530 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13531 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13532 (clobber (reg:CC FLAGS_REG))]
13533 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13535 ror{l}\t{%2, %k0|%k0, %2}
13536 ror{l}\t{%b2, %k0|%k0, %b2}"
13537 [(set_attr "type" "rotate")
13538 (set_attr "mode" "SI")])
13540 (define_expand "rotrhi3"
13541 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13542 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13543 (match_operand:QI 2 "nonmemory_operand" "")))
13544 (clobber (reg:CC FLAGS_REG))]
13545 "TARGET_HIMODE_MATH"
13546 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13548 (define_insn "*rotrhi3_one_bit"
13549 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13550 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13551 (match_operand:QI 2 "const1_operand" "")))
13552 (clobber (reg:CC FLAGS_REG))]
13553 "(TARGET_SHIFT1 || optimize_size)
13554 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13556 [(set_attr "type" "rotate")
13557 (set (attr "length")
13558 (if_then_else (match_operand 0 "register_operand" "")
13560 (const_string "*")))])
13562 (define_insn "*rotrhi3_1"
13563 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13564 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13565 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13566 (clobber (reg:CC FLAGS_REG))]
13567 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13569 ror{w}\t{%2, %0|%0, %2}
13570 ror{w}\t{%b2, %0|%0, %b2}"
13571 [(set_attr "type" "rotate")
13572 (set_attr "mode" "HI")])
13575 [(set (match_operand:HI 0 "register_operand" "")
13576 (rotatert:HI (match_dup 0) (const_int 8)))
13577 (clobber (reg:CC FLAGS_REG))]
13579 [(parallel [(set (strict_low_part (match_dup 0))
13580 (bswap:HI (match_dup 0)))
13581 (clobber (reg:CC FLAGS_REG))])]
13584 (define_expand "rotrqi3"
13585 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13586 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13587 (match_operand:QI 2 "nonmemory_operand" "")))
13588 (clobber (reg:CC FLAGS_REG))]
13589 "TARGET_QIMODE_MATH"
13590 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13592 (define_insn "*rotrqi3_1_one_bit"
13593 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13594 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13595 (match_operand:QI 2 "const1_operand" "")))
13596 (clobber (reg:CC FLAGS_REG))]
13597 "(TARGET_SHIFT1 || optimize_size)
13598 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13600 [(set_attr "type" "rotate")
13601 (set (attr "length")
13602 (if_then_else (match_operand 0 "register_operand" "")
13604 (const_string "*")))])
13606 (define_insn "*rotrqi3_1_one_bit_slp"
13607 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13608 (rotatert:QI (match_dup 0)
13609 (match_operand:QI 1 "const1_operand" "")))
13610 (clobber (reg:CC FLAGS_REG))]
13611 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13612 && (TARGET_SHIFT1 || optimize_size)"
13614 [(set_attr "type" "rotate1")
13615 (set (attr "length")
13616 (if_then_else (match_operand 0 "register_operand" "")
13618 (const_string "*")))])
13620 (define_insn "*rotrqi3_1"
13621 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13622 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13623 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13624 (clobber (reg:CC FLAGS_REG))]
13625 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13627 ror{b}\t{%2, %0|%0, %2}
13628 ror{b}\t{%b2, %0|%0, %b2}"
13629 [(set_attr "type" "rotate")
13630 (set_attr "mode" "QI")])
13632 (define_insn "*rotrqi3_1_slp"
13633 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13634 (rotatert:QI (match_dup 0)
13635 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13636 (clobber (reg:CC FLAGS_REG))]
13637 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13638 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13640 ror{b}\t{%1, %0|%0, %1}
13641 ror{b}\t{%b1, %0|%0, %b1}"
13642 [(set_attr "type" "rotate1")
13643 (set_attr "mode" "QI")])
13645 ;; Bit set / bit test instructions
13647 (define_expand "extv"
13648 [(set (match_operand:SI 0 "register_operand" "")
13649 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13650 (match_operand:SI 2 "const8_operand" "")
13651 (match_operand:SI 3 "const8_operand" "")))]
13654 /* Handle extractions from %ah et al. */
13655 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13658 /* From mips.md: extract_bit_field doesn't verify that our source
13659 matches the predicate, so check it again here. */
13660 if (! ext_register_operand (operands[1], VOIDmode))
13664 (define_expand "extzv"
13665 [(set (match_operand:SI 0 "register_operand" "")
13666 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13667 (match_operand:SI 2 "const8_operand" "")
13668 (match_operand:SI 3 "const8_operand" "")))]
13671 /* Handle extractions from %ah et al. */
13672 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13675 /* From mips.md: extract_bit_field doesn't verify that our source
13676 matches the predicate, so check it again here. */
13677 if (! ext_register_operand (operands[1], VOIDmode))
13681 (define_expand "insv"
13682 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13683 (match_operand 1 "const8_operand" "")
13684 (match_operand 2 "const8_operand" ""))
13685 (match_operand 3 "register_operand" ""))]
13688 /* Handle insertions to %ah et al. */
13689 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13692 /* From mips.md: insert_bit_field doesn't verify that our source
13693 matches the predicate, so check it again here. */
13694 if (! ext_register_operand (operands[0], VOIDmode))
13698 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13700 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13705 ;; %%% bts, btr, btc, bt.
13706 ;; In general these instructions are *slow* when applied to memory,
13707 ;; since they enforce atomic operation. When applied to registers,
13708 ;; it depends on the cpu implementation. They're never faster than
13709 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13710 ;; no point. But in 64-bit, we can't hold the relevant immediates
13711 ;; within the instruction itself, so operating on bits in the high
13712 ;; 32-bits of a register becomes easier.
13714 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13715 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13716 ;; negdf respectively, so they can never be disabled entirely.
13718 (define_insn "*btsq"
13719 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13721 (match_operand:DI 1 "const_0_to_63_operand" ""))
13723 (clobber (reg:CC FLAGS_REG))]
13724 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13726 [(set_attr "type" "alu1")])
13728 (define_insn "*btrq"
13729 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13731 (match_operand:DI 1 "const_0_to_63_operand" ""))
13733 (clobber (reg:CC FLAGS_REG))]
13734 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13736 [(set_attr "type" "alu1")])
13738 (define_insn "*btcq"
13739 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13741 (match_operand:DI 1 "const_0_to_63_operand" ""))
13742 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13743 (clobber (reg:CC FLAGS_REG))]
13744 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13746 [(set_attr "type" "alu1")])
13748 ;; Allow Nocona to avoid these instructions if a register is available.
13751 [(match_scratch:DI 2 "r")
13752 (parallel [(set (zero_extract:DI
13753 (match_operand:DI 0 "register_operand" "")
13755 (match_operand:DI 1 "const_0_to_63_operand" ""))
13757 (clobber (reg:CC FLAGS_REG))])]
13758 "TARGET_64BIT && !TARGET_USE_BT"
13761 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13764 if (HOST_BITS_PER_WIDE_INT >= 64)
13765 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13766 else if (i < HOST_BITS_PER_WIDE_INT)
13767 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13769 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13771 op1 = immed_double_const (lo, hi, DImode);
13774 emit_move_insn (operands[2], op1);
13778 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13783 [(match_scratch:DI 2 "r")
13784 (parallel [(set (zero_extract:DI
13785 (match_operand:DI 0 "register_operand" "")
13787 (match_operand:DI 1 "const_0_to_63_operand" ""))
13789 (clobber (reg:CC FLAGS_REG))])]
13790 "TARGET_64BIT && !TARGET_USE_BT"
13793 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13796 if (HOST_BITS_PER_WIDE_INT >= 64)
13797 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13798 else if (i < HOST_BITS_PER_WIDE_INT)
13799 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13801 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13803 op1 = immed_double_const (~lo, ~hi, DImode);
13806 emit_move_insn (operands[2], op1);
13810 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13815 [(match_scratch:DI 2 "r")
13816 (parallel [(set (zero_extract:DI
13817 (match_operand:DI 0 "register_operand" "")
13819 (match_operand:DI 1 "const_0_to_63_operand" ""))
13820 (not:DI (zero_extract:DI
13821 (match_dup 0) (const_int 1) (match_dup 1))))
13822 (clobber (reg:CC FLAGS_REG))])]
13823 "TARGET_64BIT && !TARGET_USE_BT"
13826 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13829 if (HOST_BITS_PER_WIDE_INT >= 64)
13830 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13831 else if (i < HOST_BITS_PER_WIDE_INT)
13832 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13834 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13836 op1 = immed_double_const (lo, hi, DImode);
13839 emit_move_insn (operands[2], op1);
13843 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13847 ;; Store-flag instructions.
13849 ;; For all sCOND expanders, also expand the compare or test insn that
13850 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13852 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13853 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13854 ;; way, which can later delete the movzx if only QImode is needed.
13856 (define_expand "seq"
13857 [(set (match_operand:QI 0 "register_operand" "")
13858 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13860 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13862 (define_expand "sne"
13863 [(set (match_operand:QI 0 "register_operand" "")
13864 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13866 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13868 (define_expand "sgt"
13869 [(set (match_operand:QI 0 "register_operand" "")
13870 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13872 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13874 (define_expand "sgtu"
13875 [(set (match_operand:QI 0 "register_operand" "")
13876 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13878 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13880 (define_expand "slt"
13881 [(set (match_operand:QI 0 "register_operand" "")
13882 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13884 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13886 (define_expand "sltu"
13887 [(set (match_operand:QI 0 "register_operand" "")
13888 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13890 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13892 (define_expand "sge"
13893 [(set (match_operand:QI 0 "register_operand" "")
13894 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13896 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13898 (define_expand "sgeu"
13899 [(set (match_operand:QI 0 "register_operand" "")
13900 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13902 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13904 (define_expand "sle"
13905 [(set (match_operand:QI 0 "register_operand" "")
13906 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13908 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13910 (define_expand "sleu"
13911 [(set (match_operand:QI 0 "register_operand" "")
13912 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13914 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13916 (define_expand "sunordered"
13917 [(set (match_operand:QI 0 "register_operand" "")
13918 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13919 "TARGET_80387 || TARGET_SSE"
13920 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13922 (define_expand "sordered"
13923 [(set (match_operand:QI 0 "register_operand" "")
13924 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13926 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13928 (define_expand "suneq"
13929 [(set (match_operand:QI 0 "register_operand" "")
13930 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13931 "TARGET_80387 || TARGET_SSE"
13932 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13934 (define_expand "sunge"
13935 [(set (match_operand:QI 0 "register_operand" "")
13936 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13937 "TARGET_80387 || TARGET_SSE"
13938 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13940 (define_expand "sungt"
13941 [(set (match_operand:QI 0 "register_operand" "")
13942 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13943 "TARGET_80387 || TARGET_SSE"
13944 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13946 (define_expand "sunle"
13947 [(set (match_operand:QI 0 "register_operand" "")
13948 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13949 "TARGET_80387 || TARGET_SSE"
13950 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13952 (define_expand "sunlt"
13953 [(set (match_operand:QI 0 "register_operand" "")
13954 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13955 "TARGET_80387 || TARGET_SSE"
13956 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13958 (define_expand "sltgt"
13959 [(set (match_operand:QI 0 "register_operand" "")
13960 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13961 "TARGET_80387 || TARGET_SSE"
13962 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13964 (define_insn "*setcc_1"
13965 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13966 (match_operator:QI 1 "ix86_comparison_operator"
13967 [(reg FLAGS_REG) (const_int 0)]))]
13970 [(set_attr "type" "setcc")
13971 (set_attr "mode" "QI")])
13973 (define_insn "*setcc_2"
13974 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13975 (match_operator:QI 1 "ix86_comparison_operator"
13976 [(reg FLAGS_REG) (const_int 0)]))]
13979 [(set_attr "type" "setcc")
13980 (set_attr "mode" "QI")])
13982 ;; In general it is not safe to assume too much about CCmode registers,
13983 ;; so simplify-rtx stops when it sees a second one. Under certain
13984 ;; conditions this is safe on x86, so help combine not create
13991 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13992 (ne:QI (match_operator 1 "ix86_comparison_operator"
13993 [(reg FLAGS_REG) (const_int 0)])
13996 [(set (match_dup 0) (match_dup 1))]
13998 PUT_MODE (operands[1], QImode);
14002 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14003 (ne:QI (match_operator 1 "ix86_comparison_operator"
14004 [(reg FLAGS_REG) (const_int 0)])
14007 [(set (match_dup 0) (match_dup 1))]
14009 PUT_MODE (operands[1], QImode);
14013 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14014 (eq:QI (match_operator 1 "ix86_comparison_operator"
14015 [(reg FLAGS_REG) (const_int 0)])
14018 [(set (match_dup 0) (match_dup 1))]
14020 rtx new_op1 = copy_rtx (operands[1]);
14021 operands[1] = new_op1;
14022 PUT_MODE (new_op1, QImode);
14023 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14024 GET_MODE (XEXP (new_op1, 0))));
14026 /* Make sure that (a) the CCmode we have for the flags is strong
14027 enough for the reversed compare or (b) we have a valid FP compare. */
14028 if (! ix86_comparison_operator (new_op1, VOIDmode))
14033 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14034 (eq:QI (match_operator 1 "ix86_comparison_operator"
14035 [(reg FLAGS_REG) (const_int 0)])
14038 [(set (match_dup 0) (match_dup 1))]
14040 rtx new_op1 = copy_rtx (operands[1]);
14041 operands[1] = new_op1;
14042 PUT_MODE (new_op1, QImode);
14043 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14044 GET_MODE (XEXP (new_op1, 0))));
14046 /* Make sure that (a) the CCmode we have for the flags is strong
14047 enough for the reversed compare or (b) we have a valid FP compare. */
14048 if (! ix86_comparison_operator (new_op1, VOIDmode))
14052 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14053 ;; subsequent logical operations are used to imitate conditional moves.
14054 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14057 (define_insn "*sse_setccsf"
14058 [(set (match_operand:SF 0 "register_operand" "=x")
14059 (match_operator:SF 1 "sse_comparison_operator"
14060 [(match_operand:SF 2 "register_operand" "0")
14061 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
14063 "cmp%D1ss\t{%3, %0|%0, %3}"
14064 [(set_attr "type" "ssecmp")
14065 (set_attr "mode" "SF")])
14067 (define_insn "*sse_setccdf"
14068 [(set (match_operand:DF 0 "register_operand" "=x")
14069 (match_operator:DF 1 "sse_comparison_operator"
14070 [(match_operand:DF 2 "register_operand" "0")
14071 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
14073 "cmp%D1sd\t{%3, %0|%0, %3}"
14074 [(set_attr "type" "ssecmp")
14075 (set_attr "mode" "DF")])
14077 ;; Basic conditional jump instructions.
14078 ;; We ignore the overflow flag for signed branch instructions.
14080 ;; For all bCOND expanders, also expand the compare or test insn that
14081 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
14083 (define_expand "beq"
14085 (if_then_else (match_dup 1)
14086 (label_ref (match_operand 0 "" ""))
14089 "ix86_expand_branch (EQ, operands[0]); DONE;")
14091 (define_expand "bne"
14093 (if_then_else (match_dup 1)
14094 (label_ref (match_operand 0 "" ""))
14097 "ix86_expand_branch (NE, operands[0]); DONE;")
14099 (define_expand "bgt"
14101 (if_then_else (match_dup 1)
14102 (label_ref (match_operand 0 "" ""))
14105 "ix86_expand_branch (GT, operands[0]); DONE;")
14107 (define_expand "bgtu"
14109 (if_then_else (match_dup 1)
14110 (label_ref (match_operand 0 "" ""))
14113 "ix86_expand_branch (GTU, operands[0]); DONE;")
14115 (define_expand "blt"
14117 (if_then_else (match_dup 1)
14118 (label_ref (match_operand 0 "" ""))
14121 "ix86_expand_branch (LT, operands[0]); DONE;")
14123 (define_expand "bltu"
14125 (if_then_else (match_dup 1)
14126 (label_ref (match_operand 0 "" ""))
14129 "ix86_expand_branch (LTU, operands[0]); DONE;")
14131 (define_expand "bge"
14133 (if_then_else (match_dup 1)
14134 (label_ref (match_operand 0 "" ""))
14137 "ix86_expand_branch (GE, operands[0]); DONE;")
14139 (define_expand "bgeu"
14141 (if_then_else (match_dup 1)
14142 (label_ref (match_operand 0 "" ""))
14145 "ix86_expand_branch (GEU, operands[0]); DONE;")
14147 (define_expand "ble"
14149 (if_then_else (match_dup 1)
14150 (label_ref (match_operand 0 "" ""))
14153 "ix86_expand_branch (LE, operands[0]); DONE;")
14155 (define_expand "bleu"
14157 (if_then_else (match_dup 1)
14158 (label_ref (match_operand 0 "" ""))
14161 "ix86_expand_branch (LEU, operands[0]); DONE;")
14163 (define_expand "bunordered"
14165 (if_then_else (match_dup 1)
14166 (label_ref (match_operand 0 "" ""))
14168 "TARGET_80387 || TARGET_SSE_MATH"
14169 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
14171 (define_expand "bordered"
14173 (if_then_else (match_dup 1)
14174 (label_ref (match_operand 0 "" ""))
14176 "TARGET_80387 || TARGET_SSE_MATH"
14177 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
14179 (define_expand "buneq"
14181 (if_then_else (match_dup 1)
14182 (label_ref (match_operand 0 "" ""))
14184 "TARGET_80387 || TARGET_SSE_MATH"
14185 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
14187 (define_expand "bunge"
14189 (if_then_else (match_dup 1)
14190 (label_ref (match_operand 0 "" ""))
14192 "TARGET_80387 || TARGET_SSE_MATH"
14193 "ix86_expand_branch (UNGE, operands[0]); DONE;")
14195 (define_expand "bungt"
14197 (if_then_else (match_dup 1)
14198 (label_ref (match_operand 0 "" ""))
14200 "TARGET_80387 || TARGET_SSE_MATH"
14201 "ix86_expand_branch (UNGT, operands[0]); DONE;")
14203 (define_expand "bunle"
14205 (if_then_else (match_dup 1)
14206 (label_ref (match_operand 0 "" ""))
14208 "TARGET_80387 || TARGET_SSE_MATH"
14209 "ix86_expand_branch (UNLE, operands[0]); DONE;")
14211 (define_expand "bunlt"
14213 (if_then_else (match_dup 1)
14214 (label_ref (match_operand 0 "" ""))
14216 "TARGET_80387 || TARGET_SSE_MATH"
14217 "ix86_expand_branch (UNLT, operands[0]); DONE;")
14219 (define_expand "bltgt"
14221 (if_then_else (match_dup 1)
14222 (label_ref (match_operand 0 "" ""))
14224 "TARGET_80387 || TARGET_SSE_MATH"
14225 "ix86_expand_branch (LTGT, operands[0]); DONE;")
14227 (define_insn "*jcc_1"
14229 (if_then_else (match_operator 1 "ix86_comparison_operator"
14230 [(reg FLAGS_REG) (const_int 0)])
14231 (label_ref (match_operand 0 "" ""))
14235 [(set_attr "type" "ibr")
14236 (set_attr "modrm" "0")
14237 (set (attr "length")
14238 (if_then_else (and (ge (minus (match_dup 0) (pc))
14240 (lt (minus (match_dup 0) (pc))
14245 (define_insn "*jcc_2"
14247 (if_then_else (match_operator 1 "ix86_comparison_operator"
14248 [(reg FLAGS_REG) (const_int 0)])
14250 (label_ref (match_operand 0 "" ""))))]
14253 [(set_attr "type" "ibr")
14254 (set_attr "modrm" "0")
14255 (set (attr "length")
14256 (if_then_else (and (ge (minus (match_dup 0) (pc))
14258 (lt (minus (match_dup 0) (pc))
14263 ;; In general it is not safe to assume too much about CCmode registers,
14264 ;; so simplify-rtx stops when it sees a second one. Under certain
14265 ;; conditions this is safe on x86, so help combine not create
14273 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14274 [(reg FLAGS_REG) (const_int 0)])
14276 (label_ref (match_operand 1 "" ""))
14280 (if_then_else (match_dup 0)
14281 (label_ref (match_dup 1))
14284 PUT_MODE (operands[0], VOIDmode);
14289 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14290 [(reg FLAGS_REG) (const_int 0)])
14292 (label_ref (match_operand 1 "" ""))
14296 (if_then_else (match_dup 0)
14297 (label_ref (match_dup 1))
14300 rtx new_op0 = copy_rtx (operands[0]);
14301 operands[0] = new_op0;
14302 PUT_MODE (new_op0, VOIDmode);
14303 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14304 GET_MODE (XEXP (new_op0, 0))));
14306 /* Make sure that (a) the CCmode we have for the flags is strong
14307 enough for the reversed compare or (b) we have a valid FP compare. */
14308 if (! ix86_comparison_operator (new_op0, VOIDmode))
14312 ;; Define combination compare-and-branch fp compare instructions to use
14313 ;; during early optimization. Splitting the operation apart early makes
14314 ;; for bad code when we want to reverse the operation.
14316 (define_insn "*fp_jcc_1_mixed"
14318 (if_then_else (match_operator 0 "comparison_operator"
14319 [(match_operand 1 "register_operand" "f,x")
14320 (match_operand 2 "nonimmediate_operand" "f,xm")])
14321 (label_ref (match_operand 3 "" ""))
14323 (clobber (reg:CCFP FPSR_REG))
14324 (clobber (reg:CCFP FLAGS_REG))]
14325 "TARGET_MIX_SSE_I387
14326 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14327 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14328 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14331 (define_insn "*fp_jcc_1_sse"
14333 (if_then_else (match_operator 0 "comparison_operator"
14334 [(match_operand 1 "register_operand" "x")
14335 (match_operand 2 "nonimmediate_operand" "xm")])
14336 (label_ref (match_operand 3 "" ""))
14338 (clobber (reg:CCFP FPSR_REG))
14339 (clobber (reg:CCFP FLAGS_REG))]
14341 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14342 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14343 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14346 (define_insn "*fp_jcc_1_387"
14348 (if_then_else (match_operator 0 "comparison_operator"
14349 [(match_operand 1 "register_operand" "f")
14350 (match_operand 2 "register_operand" "f")])
14351 (label_ref (match_operand 3 "" ""))
14353 (clobber (reg:CCFP FPSR_REG))
14354 (clobber (reg:CCFP FLAGS_REG))]
14355 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14357 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14358 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14361 (define_insn "*fp_jcc_2_mixed"
14363 (if_then_else (match_operator 0 "comparison_operator"
14364 [(match_operand 1 "register_operand" "f,x")
14365 (match_operand 2 "nonimmediate_operand" "f,xm")])
14367 (label_ref (match_operand 3 "" ""))))
14368 (clobber (reg:CCFP FPSR_REG))
14369 (clobber (reg:CCFP FLAGS_REG))]
14370 "TARGET_MIX_SSE_I387
14371 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14372 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14373 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14376 (define_insn "*fp_jcc_2_sse"
14378 (if_then_else (match_operator 0 "comparison_operator"
14379 [(match_operand 1 "register_operand" "x")
14380 (match_operand 2 "nonimmediate_operand" "xm")])
14382 (label_ref (match_operand 3 "" ""))))
14383 (clobber (reg:CCFP FPSR_REG))
14384 (clobber (reg:CCFP FLAGS_REG))]
14386 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14387 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14388 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14391 (define_insn "*fp_jcc_2_387"
14393 (if_then_else (match_operator 0 "comparison_operator"
14394 [(match_operand 1 "register_operand" "f")
14395 (match_operand 2 "register_operand" "f")])
14397 (label_ref (match_operand 3 "" ""))))
14398 (clobber (reg:CCFP FPSR_REG))
14399 (clobber (reg:CCFP FLAGS_REG))]
14400 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14402 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14403 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14406 (define_insn "*fp_jcc_3_387"
14408 (if_then_else (match_operator 0 "comparison_operator"
14409 [(match_operand 1 "register_operand" "f")
14410 (match_operand 2 "nonimmediate_operand" "fm")])
14411 (label_ref (match_operand 3 "" ""))
14413 (clobber (reg:CCFP FPSR_REG))
14414 (clobber (reg:CCFP FLAGS_REG))
14415 (clobber (match_scratch:HI 4 "=a"))]
14417 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14418 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14419 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14420 && SELECT_CC_MODE (GET_CODE (operands[0]),
14421 operands[1], operands[2]) == CCFPmode
14422 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14425 (define_insn "*fp_jcc_4_387"
14427 (if_then_else (match_operator 0 "comparison_operator"
14428 [(match_operand 1 "register_operand" "f")
14429 (match_operand 2 "nonimmediate_operand" "fm")])
14431 (label_ref (match_operand 3 "" ""))))
14432 (clobber (reg:CCFP FPSR_REG))
14433 (clobber (reg:CCFP FLAGS_REG))
14434 (clobber (match_scratch:HI 4 "=a"))]
14436 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14437 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14438 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14439 && SELECT_CC_MODE (GET_CODE (operands[0]),
14440 operands[1], operands[2]) == CCFPmode
14441 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14444 (define_insn "*fp_jcc_5_387"
14446 (if_then_else (match_operator 0 "comparison_operator"
14447 [(match_operand 1 "register_operand" "f")
14448 (match_operand 2 "register_operand" "f")])
14449 (label_ref (match_operand 3 "" ""))
14451 (clobber (reg:CCFP FPSR_REG))
14452 (clobber (reg:CCFP FLAGS_REG))
14453 (clobber (match_scratch:HI 4 "=a"))]
14454 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14455 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14456 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14459 (define_insn "*fp_jcc_6_387"
14461 (if_then_else (match_operator 0 "comparison_operator"
14462 [(match_operand 1 "register_operand" "f")
14463 (match_operand 2 "register_operand" "f")])
14465 (label_ref (match_operand 3 "" ""))))
14466 (clobber (reg:CCFP FPSR_REG))
14467 (clobber (reg:CCFP FLAGS_REG))
14468 (clobber (match_scratch:HI 4 "=a"))]
14469 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14470 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14471 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14474 (define_insn "*fp_jcc_7_387"
14476 (if_then_else (match_operator 0 "comparison_operator"
14477 [(match_operand 1 "register_operand" "f")
14478 (match_operand 2 "const0_operand" "X")])
14479 (label_ref (match_operand 3 "" ""))
14481 (clobber (reg:CCFP FPSR_REG))
14482 (clobber (reg:CCFP FLAGS_REG))
14483 (clobber (match_scratch:HI 4 "=a"))]
14484 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14485 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14486 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14487 && SELECT_CC_MODE (GET_CODE (operands[0]),
14488 operands[1], operands[2]) == CCFPmode
14489 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14492 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14493 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14494 ;; with a precedence over other operators and is always put in the first
14495 ;; place. Swap condition and operands to match ficom instruction.
14497 (define_insn "*fp_jcc_8<mode>_387"
14499 (if_then_else (match_operator 0 "comparison_operator"
14500 [(match_operator 1 "float_operator"
14501 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14502 (match_operand 3 "register_operand" "f,f")])
14503 (label_ref (match_operand 4 "" ""))
14505 (clobber (reg:CCFP FPSR_REG))
14506 (clobber (reg:CCFP FLAGS_REG))
14507 (clobber (match_scratch:HI 5 "=a,a"))]
14508 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14509 && TARGET_USE_<MODE>MODE_FIOP
14510 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14511 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14512 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14513 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14518 (if_then_else (match_operator 0 "comparison_operator"
14519 [(match_operand 1 "register_operand" "")
14520 (match_operand 2 "nonimmediate_operand" "")])
14521 (match_operand 3 "" "")
14522 (match_operand 4 "" "")))
14523 (clobber (reg:CCFP FPSR_REG))
14524 (clobber (reg:CCFP FLAGS_REG))]
14528 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14529 operands[3], operands[4], NULL_RTX, NULL_RTX);
14535 (if_then_else (match_operator 0 "comparison_operator"
14536 [(match_operand 1 "register_operand" "")
14537 (match_operand 2 "general_operand" "")])
14538 (match_operand 3 "" "")
14539 (match_operand 4 "" "")))
14540 (clobber (reg:CCFP FPSR_REG))
14541 (clobber (reg:CCFP FLAGS_REG))
14542 (clobber (match_scratch:HI 5 "=a"))]
14546 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14547 operands[3], operands[4], operands[5], NULL_RTX);
14553 (if_then_else (match_operator 0 "comparison_operator"
14554 [(match_operator 1 "float_operator"
14555 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14556 (match_operand 3 "register_operand" "")])
14557 (match_operand 4 "" "")
14558 (match_operand 5 "" "")))
14559 (clobber (reg:CCFP FPSR_REG))
14560 (clobber (reg:CCFP FLAGS_REG))
14561 (clobber (match_scratch:HI 6 "=a"))]
14565 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14566 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14567 operands[3], operands[7],
14568 operands[4], operands[5], operands[6], NULL_RTX);
14572 ;; %%% Kill this when reload knows how to do it.
14575 (if_then_else (match_operator 0 "comparison_operator"
14576 [(match_operator 1 "float_operator"
14577 [(match_operand:X87MODEI12 2 "register_operand" "")])
14578 (match_operand 3 "register_operand" "")])
14579 (match_operand 4 "" "")
14580 (match_operand 5 "" "")))
14581 (clobber (reg:CCFP FPSR_REG))
14582 (clobber (reg:CCFP FLAGS_REG))
14583 (clobber (match_scratch:HI 6 "=a"))]
14587 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14588 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14589 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14590 operands[3], operands[7],
14591 operands[4], operands[5], operands[6], operands[2]);
14595 ;; Unconditional and other jump instructions
14597 (define_insn "jump"
14599 (label_ref (match_operand 0 "" "")))]
14602 [(set_attr "type" "ibr")
14603 (set (attr "length")
14604 (if_then_else (and (ge (minus (match_dup 0) (pc))
14606 (lt (minus (match_dup 0) (pc))
14610 (set_attr "modrm" "0")])
14612 (define_expand "indirect_jump"
14613 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14617 (define_insn "*indirect_jump"
14618 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14621 [(set_attr "type" "ibr")
14622 (set_attr "length_immediate" "0")])
14624 (define_insn "*indirect_jump_rtx64"
14625 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14628 [(set_attr "type" "ibr")
14629 (set_attr "length_immediate" "0")])
14631 (define_expand "tablejump"
14632 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14633 (use (label_ref (match_operand 1 "" "")))])]
14636 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14637 relative. Convert the relative address to an absolute address. */
14641 enum rtx_code code;
14643 /* We can't use @GOTOFF for text labels on VxWorks;
14644 see gotoff_operand. */
14645 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14649 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14651 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14655 op1 = pic_offset_table_rtx;
14660 op0 = pic_offset_table_rtx;
14664 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14669 (define_insn "*tablejump_1"
14670 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14671 (use (label_ref (match_operand 1 "" "")))]
14674 [(set_attr "type" "ibr")
14675 (set_attr "length_immediate" "0")])
14677 (define_insn "*tablejump_1_rtx64"
14678 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14679 (use (label_ref (match_operand 1 "" "")))]
14682 [(set_attr "type" "ibr")
14683 (set_attr "length_immediate" "0")])
14685 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14688 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14689 (set (match_operand:QI 1 "register_operand" "")
14690 (match_operator:QI 2 "ix86_comparison_operator"
14691 [(reg FLAGS_REG) (const_int 0)]))
14692 (set (match_operand 3 "q_regs_operand" "")
14693 (zero_extend (match_dup 1)))]
14694 "(peep2_reg_dead_p (3, operands[1])
14695 || operands_match_p (operands[1], operands[3]))
14696 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14697 [(set (match_dup 4) (match_dup 0))
14698 (set (strict_low_part (match_dup 5))
14701 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14702 operands[5] = gen_lowpart (QImode, operands[3]);
14703 ix86_expand_clear (operands[3]);
14706 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14709 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14710 (set (match_operand:QI 1 "register_operand" "")
14711 (match_operator:QI 2 "ix86_comparison_operator"
14712 [(reg FLAGS_REG) (const_int 0)]))
14713 (parallel [(set (match_operand 3 "q_regs_operand" "")
14714 (zero_extend (match_dup 1)))
14715 (clobber (reg:CC FLAGS_REG))])]
14716 "(peep2_reg_dead_p (3, operands[1])
14717 || operands_match_p (operands[1], operands[3]))
14718 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14719 [(set (match_dup 4) (match_dup 0))
14720 (set (strict_low_part (match_dup 5))
14723 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14724 operands[5] = gen_lowpart (QImode, operands[3]);
14725 ix86_expand_clear (operands[3]);
14728 ;; Call instructions.
14730 ;; The predicates normally associated with named expanders are not properly
14731 ;; checked for calls. This is a bug in the generic code, but it isn't that
14732 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14734 ;; Call subroutine returning no value.
14736 (define_expand "call_pop"
14737 [(parallel [(call (match_operand:QI 0 "" "")
14738 (match_operand:SI 1 "" ""))
14739 (set (reg:SI SP_REG)
14740 (plus:SI (reg:SI SP_REG)
14741 (match_operand:SI 3 "" "")))])]
14744 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14748 (define_insn "*call_pop_0"
14749 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14750 (match_operand:SI 1 "" ""))
14751 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14752 (match_operand:SI 2 "immediate_operand" "")))]
14755 if (SIBLING_CALL_P (insn))
14758 return "call\t%P0";
14760 [(set_attr "type" "call")])
14762 (define_insn "*call_pop_1"
14763 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14764 (match_operand:SI 1 "" ""))
14765 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14766 (match_operand:SI 2 "immediate_operand" "i")))]
14769 if (constant_call_address_operand (operands[0], Pmode))
14771 if (SIBLING_CALL_P (insn))
14774 return "call\t%P0";
14776 if (SIBLING_CALL_P (insn))
14779 return "call\t%A0";
14781 [(set_attr "type" "call")])
14783 (define_expand "call"
14784 [(call (match_operand:QI 0 "" "")
14785 (match_operand 1 "" ""))
14786 (use (match_operand 2 "" ""))]
14789 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14793 (define_expand "sibcall"
14794 [(call (match_operand:QI 0 "" "")
14795 (match_operand 1 "" ""))
14796 (use (match_operand 2 "" ""))]
14799 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14803 (define_insn "*call_0"
14804 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14805 (match_operand 1 "" ""))]
14808 if (SIBLING_CALL_P (insn))
14811 return "call\t%P0";
14813 [(set_attr "type" "call")])
14815 (define_insn "*call_1"
14816 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14817 (match_operand 1 "" ""))]
14818 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14820 if (constant_call_address_operand (operands[0], Pmode))
14821 return "call\t%P0";
14822 return "call\t%A0";
14824 [(set_attr "type" "call")])
14826 (define_insn "*sibcall_1"
14827 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14828 (match_operand 1 "" ""))]
14829 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14831 if (constant_call_address_operand (operands[0], Pmode))
14835 [(set_attr "type" "call")])
14837 (define_insn "*call_1_rex64"
14838 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14839 (match_operand 1 "" ""))]
14840 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14841 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14843 if (constant_call_address_operand (operands[0], Pmode))
14844 return "call\t%P0";
14845 return "call\t%A0";
14847 [(set_attr "type" "call")])
14849 (define_insn "*call_1_rex64_large"
14850 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14851 (match_operand 1 "" ""))]
14852 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14854 [(set_attr "type" "call")])
14856 (define_insn "*sibcall_1_rex64"
14857 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14858 (match_operand 1 "" ""))]
14859 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14861 [(set_attr "type" "call")])
14863 (define_insn "*sibcall_1_rex64_v"
14864 [(call (mem:QI (reg:DI R11_REG))
14865 (match_operand 0 "" ""))]
14866 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14868 [(set_attr "type" "call")])
14871 ;; Call subroutine, returning value in operand 0
14873 (define_expand "call_value_pop"
14874 [(parallel [(set (match_operand 0 "" "")
14875 (call (match_operand:QI 1 "" "")
14876 (match_operand:SI 2 "" "")))
14877 (set (reg:SI SP_REG)
14878 (plus:SI (reg:SI SP_REG)
14879 (match_operand:SI 4 "" "")))])]
14882 ix86_expand_call (operands[0], operands[1], operands[2],
14883 operands[3], operands[4], 0);
14887 (define_expand "call_value"
14888 [(set (match_operand 0 "" "")
14889 (call (match_operand:QI 1 "" "")
14890 (match_operand:SI 2 "" "")))
14891 (use (match_operand:SI 3 "" ""))]
14892 ;; Operand 2 not used on the i386.
14895 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14899 (define_expand "sibcall_value"
14900 [(set (match_operand 0 "" "")
14901 (call (match_operand:QI 1 "" "")
14902 (match_operand:SI 2 "" "")))
14903 (use (match_operand:SI 3 "" ""))]
14904 ;; Operand 2 not used on the i386.
14907 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14911 ;; Call subroutine returning any type.
14913 (define_expand "untyped_call"
14914 [(parallel [(call (match_operand 0 "" "")
14916 (match_operand 1 "" "")
14917 (match_operand 2 "" "")])]
14922 /* In order to give reg-stack an easier job in validating two
14923 coprocessor registers as containing a possible return value,
14924 simply pretend the untyped call returns a complex long double
14927 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14928 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14929 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14932 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14934 rtx set = XVECEXP (operands[2], 0, i);
14935 emit_move_insn (SET_DEST (set), SET_SRC (set));
14938 /* The optimizer does not know that the call sets the function value
14939 registers we stored in the result block. We avoid problems by
14940 claiming that all hard registers are used and clobbered at this
14942 emit_insn (gen_blockage ());
14947 ;; Prologue and epilogue instructions
14949 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14950 ;; all of memory. This blocks insns from being moved across this point.
14952 (define_insn "blockage"
14953 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14956 [(set_attr "length" "0")])
14958 ;; As USE insns aren't meaningful after reload, this is used instead
14959 ;; to prevent deleting instructions setting registers for PIC code
14960 (define_insn "prologue_use"
14961 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14964 [(set_attr "length" "0")])
14966 ;; Insn emitted into the body of a function to return from a function.
14967 ;; This is only done if the function's epilogue is known to be simple.
14968 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14970 (define_expand "return"
14972 "ix86_can_use_return_insn_p ()"
14974 if (current_function_pops_args)
14976 rtx popc = GEN_INT (current_function_pops_args);
14977 emit_jump_insn (gen_return_pop_internal (popc));
14982 (define_insn "return_internal"
14986 [(set_attr "length" "1")
14987 (set_attr "length_immediate" "0")
14988 (set_attr "modrm" "0")])
14990 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14991 ;; instruction Athlon and K8 have.
14993 (define_insn "return_internal_long"
14995 (unspec [(const_int 0)] UNSPEC_REP)]
14998 [(set_attr "length" "1")
14999 (set_attr "length_immediate" "0")
15000 (set_attr "prefix_rep" "1")
15001 (set_attr "modrm" "0")])
15003 (define_insn "return_pop_internal"
15005 (use (match_operand:SI 0 "const_int_operand" ""))]
15008 [(set_attr "length" "3")
15009 (set_attr "length_immediate" "2")
15010 (set_attr "modrm" "0")])
15012 (define_insn "return_indirect_internal"
15014 (use (match_operand:SI 0 "register_operand" "r"))]
15017 [(set_attr "type" "ibr")
15018 (set_attr "length_immediate" "0")])
15024 [(set_attr "length" "1")
15025 (set_attr "length_immediate" "0")
15026 (set_attr "modrm" "0")])
15028 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
15029 ;; branch prediction penalty for the third jump in a 16-byte
15032 (define_insn "align"
15033 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15036 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15037 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15039 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15040 The align insn is used to avoid 3 jump instructions in the row to improve
15041 branch prediction and the benefits hardly outweigh the cost of extra 8
15042 nops on the average inserted by full alignment pseudo operation. */
15046 [(set_attr "length" "16")])
15048 (define_expand "prologue"
15051 "ix86_expand_prologue (); DONE;")
15053 (define_insn "set_got"
15054 [(set (match_operand:SI 0 "register_operand" "=r")
15055 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15056 (clobber (reg:CC FLAGS_REG))]
15058 { return output_set_got (operands[0], NULL_RTX); }
15059 [(set_attr "type" "multi")
15060 (set_attr "length" "12")])
15062 (define_insn "set_got_labelled"
15063 [(set (match_operand:SI 0 "register_operand" "=r")
15064 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15066 (clobber (reg:CC FLAGS_REG))]
15068 { return output_set_got (operands[0], operands[1]); }
15069 [(set_attr "type" "multi")
15070 (set_attr "length" "12")])
15072 (define_insn "set_got_rex64"
15073 [(set (match_operand:DI 0 "register_operand" "=r")
15074 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15076 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
15077 [(set_attr "type" "lea")
15078 (set_attr "length" "6")])
15080 (define_insn "set_rip_rex64"
15081 [(set (match_operand:DI 0 "register_operand" "=r")
15082 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15084 "lea{q}\t%l1(%%rip), %0"
15085 [(set_attr "type" "lea")
15086 (set_attr "length" "6")])
15088 (define_insn "set_got_offset_rex64"
15089 [(set (match_operand:DI 0 "register_operand" "=r")
15090 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15092 "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
15093 [(set_attr "type" "imov")
15094 (set_attr "length" "11")])
15096 (define_expand "epilogue"
15099 "ix86_expand_epilogue (1); DONE;")
15101 (define_expand "sibcall_epilogue"
15104 "ix86_expand_epilogue (0); DONE;")
15106 (define_expand "eh_return"
15107 [(use (match_operand 0 "register_operand" ""))]
15110 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15112 /* Tricky bit: we write the address of the handler to which we will
15113 be returning into someone else's stack frame, one word below the
15114 stack address we wish to restore. */
15115 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15116 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15117 tmp = gen_rtx_MEM (Pmode, tmp);
15118 emit_move_insn (tmp, ra);
15120 if (Pmode == SImode)
15121 emit_jump_insn (gen_eh_return_si (sa));
15123 emit_jump_insn (gen_eh_return_di (sa));
15128 (define_insn_and_split "eh_return_si"
15130 (unspec [(match_operand:SI 0 "register_operand" "c")]
15131 UNSPEC_EH_RETURN))]
15136 "ix86_expand_epilogue (2); DONE;")
15138 (define_insn_and_split "eh_return_di"
15140 (unspec [(match_operand:DI 0 "register_operand" "c")]
15141 UNSPEC_EH_RETURN))]
15146 "ix86_expand_epilogue (2); DONE;")
15148 (define_insn "leave"
15149 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15150 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15151 (clobber (mem:BLK (scratch)))]
15154 [(set_attr "type" "leave")])
15156 (define_insn "leave_rex64"
15157 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15158 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15159 (clobber (mem:BLK (scratch)))]
15162 [(set_attr "type" "leave")])
15164 (define_expand "ffssi2"
15166 [(set (match_operand:SI 0 "register_operand" "")
15167 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15168 (clobber (match_scratch:SI 2 ""))
15169 (clobber (reg:CC FLAGS_REG))])]
15174 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15179 (define_expand "ffs_cmove"
15180 [(set (match_dup 2) (const_int -1))
15181 (parallel [(set (reg:CCZ FLAGS_REG)
15182 (compare:CCZ (match_operand:SI 1 "register_operand" "")
15184 (set (match_operand:SI 0 "nonimmediate_operand" "")
15185 (ctz:SI (match_dup 1)))])
15186 (set (match_dup 0) (if_then_else:SI
15187 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15190 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15191 (clobber (reg:CC FLAGS_REG))])]
15193 "operands[2] = gen_reg_rtx (SImode);")
15195 (define_insn_and_split "*ffs_no_cmove"
15196 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15197 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15198 (clobber (match_scratch:SI 2 "=&q"))
15199 (clobber (reg:CC FLAGS_REG))]
15202 "&& reload_completed"
15203 [(parallel [(set (reg:CCZ FLAGS_REG)
15204 (compare:CCZ (match_dup 1) (const_int 0)))
15205 (set (match_dup 0) (ctz:SI (match_dup 1)))])
15206 (set (strict_low_part (match_dup 3))
15207 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15208 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15209 (clobber (reg:CC FLAGS_REG))])
15210 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15211 (clobber (reg:CC FLAGS_REG))])
15212 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15213 (clobber (reg:CC FLAGS_REG))])]
15215 operands[3] = gen_lowpart (QImode, operands[2]);
15216 ix86_expand_clear (operands[2]);
15219 (define_insn "*ffssi_1"
15220 [(set (reg:CCZ FLAGS_REG)
15221 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15223 (set (match_operand:SI 0 "register_operand" "=r")
15224 (ctz:SI (match_dup 1)))]
15226 "bsf{l}\t{%1, %0|%0, %1}"
15227 [(set_attr "prefix_0f" "1")])
15229 (define_expand "ffsdi2"
15230 [(set (match_dup 2) (const_int -1))
15231 (parallel [(set (reg:CCZ FLAGS_REG)
15232 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15234 (set (match_operand:DI 0 "nonimmediate_operand" "")
15235 (ctz:DI (match_dup 1)))])
15236 (set (match_dup 0) (if_then_else:DI
15237 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15240 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15241 (clobber (reg:CC FLAGS_REG))])]
15243 "operands[2] = gen_reg_rtx (DImode);")
15245 (define_insn "*ffsdi_1"
15246 [(set (reg:CCZ FLAGS_REG)
15247 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15249 (set (match_operand:DI 0 "register_operand" "=r")
15250 (ctz:DI (match_dup 1)))]
15252 "bsf{q}\t{%1, %0|%0, %1}"
15253 [(set_attr "prefix_0f" "1")])
15255 (define_insn "ctzsi2"
15256 [(set (match_operand:SI 0 "register_operand" "=r")
15257 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15258 (clobber (reg:CC FLAGS_REG))]
15260 "bsf{l}\t{%1, %0|%0, %1}"
15261 [(set_attr "prefix_0f" "1")])
15263 (define_insn "ctzdi2"
15264 [(set (match_operand:DI 0 "register_operand" "=r")
15265 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15266 (clobber (reg:CC FLAGS_REG))]
15268 "bsf{q}\t{%1, %0|%0, %1}"
15269 [(set_attr "prefix_0f" "1")])
15271 (define_expand "clzsi2"
15273 [(set (match_operand:SI 0 "register_operand" "")
15274 (minus:SI (const_int 31)
15275 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15276 (clobber (reg:CC FLAGS_REG))])
15278 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15279 (clobber (reg:CC FLAGS_REG))])]
15284 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15289 (define_insn "clzsi2_abm"
15290 [(set (match_operand:SI 0 "register_operand" "=r")
15291 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15292 (clobber (reg:CC FLAGS_REG))]
15294 "lzcnt{l}\t{%1, %0|%0, %1}"
15295 [(set_attr "prefix_rep" "1")
15296 (set_attr "type" "bitmanip")
15297 (set_attr "mode" "SI")])
15299 (define_insn "*bsr"
15300 [(set (match_operand:SI 0 "register_operand" "=r")
15301 (minus:SI (const_int 31)
15302 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15303 (clobber (reg:CC FLAGS_REG))]
15305 "bsr{l}\t{%1, %0|%0, %1}"
15306 [(set_attr "prefix_0f" "1")
15307 (set_attr "mode" "SI")])
15309 (define_insn "popcountsi2"
15310 [(set (match_operand:SI 0 "register_operand" "=r")
15311 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15312 (clobber (reg:CC FLAGS_REG))]
15314 "popcnt{l}\t{%1, %0|%0, %1}"
15315 [(set_attr "prefix_rep" "1")
15316 (set_attr "type" "bitmanip")
15317 (set_attr "mode" "SI")])
15319 (define_insn "*popcountsi2_cmp"
15320 [(set (reg FLAGS_REG)
15322 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15324 (set (match_operand:SI 0 "register_operand" "=r")
15325 (popcount:SI (match_dup 1)))]
15326 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15327 "popcnt{l}\t{%1, %0|%0, %1}"
15328 [(set_attr "prefix_rep" "1")
15329 (set_attr "type" "bitmanip")
15330 (set_attr "mode" "SI")])
15332 (define_insn "*popcountsi2_cmp_zext"
15333 [(set (reg FLAGS_REG)
15335 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15337 (set (match_operand:DI 0 "register_operand" "=r")
15338 (zero_extend:DI(popcount:SI (match_dup 1))))]
15339 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15340 "popcnt{l}\t{%1, %0|%0, %1}"
15341 [(set_attr "prefix_rep" "1")
15342 (set_attr "type" "bitmanip")
15343 (set_attr "mode" "SI")])
15345 (define_expand "bswapsi2"
15346 [(set (match_operand:SI 0 "register_operand" "")
15347 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15352 rtx x = operands[0];
15354 emit_move_insn (x, operands[1]);
15355 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15356 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15357 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15362 (define_insn "*bswapsi_1"
15363 [(set (match_operand:SI 0 "register_operand" "=r")
15364 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15367 [(set_attr "prefix_0f" "1")
15368 (set_attr "length" "2")])
15370 (define_insn "*bswaphi_lowpart_1"
15371 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15372 (bswap:HI (match_dup 0)))
15373 (clobber (reg:CC FLAGS_REG))]
15374 "TARGET_USE_XCHGB || optimize_size"
15376 xchg{b}\t{%h0, %b0|%b0, %h0}
15377 rol{w}\t{$8, %0|%0, 8}"
15378 [(set_attr "length" "2,4")
15379 (set_attr "mode" "QI,HI")])
15381 (define_insn "bswaphi_lowpart"
15382 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15383 (bswap:HI (match_dup 0)))
15384 (clobber (reg:CC FLAGS_REG))]
15386 "rol{w}\t{$8, %0|%0, 8}"
15387 [(set_attr "length" "4")
15388 (set_attr "mode" "HI")])
15390 (define_insn "bswapdi2"
15391 [(set (match_operand:DI 0 "register_operand" "=r")
15392 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15395 [(set_attr "prefix_0f" "1")
15396 (set_attr "length" "3")])
15398 (define_expand "clzdi2"
15400 [(set (match_operand:DI 0 "register_operand" "")
15401 (minus:DI (const_int 63)
15402 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15403 (clobber (reg:CC FLAGS_REG))])
15405 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15406 (clobber (reg:CC FLAGS_REG))])]
15411 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15416 (define_insn "clzdi2_abm"
15417 [(set (match_operand:DI 0 "register_operand" "=r")
15418 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15419 (clobber (reg:CC FLAGS_REG))]
15420 "TARGET_64BIT && TARGET_ABM"
15421 "lzcnt{q}\t{%1, %0|%0, %1}"
15422 [(set_attr "prefix_rep" "1")
15423 (set_attr "type" "bitmanip")
15424 (set_attr "mode" "DI")])
15426 (define_insn "*bsr_rex64"
15427 [(set (match_operand:DI 0 "register_operand" "=r")
15428 (minus:DI (const_int 63)
15429 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15430 (clobber (reg:CC FLAGS_REG))]
15432 "bsr{q}\t{%1, %0|%0, %1}"
15433 [(set_attr "prefix_0f" "1")
15434 (set_attr "mode" "DI")])
15436 (define_insn "popcountdi2"
15437 [(set (match_operand:DI 0 "register_operand" "=r")
15438 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15439 (clobber (reg:CC FLAGS_REG))]
15440 "TARGET_64BIT && TARGET_POPCNT"
15441 "popcnt{q}\t{%1, %0|%0, %1}"
15442 [(set_attr "prefix_rep" "1")
15443 (set_attr "type" "bitmanip")
15444 (set_attr "mode" "DI")])
15446 (define_insn "*popcountdi2_cmp"
15447 [(set (reg FLAGS_REG)
15449 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15451 (set (match_operand:DI 0 "register_operand" "=r")
15452 (popcount:DI (match_dup 1)))]
15453 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15454 "popcnt{q}\t{%1, %0|%0, %1}"
15455 [(set_attr "prefix_rep" "1")
15456 (set_attr "type" "bitmanip")
15457 (set_attr "mode" "DI")])
15459 (define_expand "clzhi2"
15461 [(set (match_operand:HI 0 "register_operand" "")
15462 (minus:HI (const_int 15)
15463 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15464 (clobber (reg:CC FLAGS_REG))])
15466 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15467 (clobber (reg:CC FLAGS_REG))])]
15472 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15477 (define_insn "clzhi2_abm"
15478 [(set (match_operand:HI 0 "register_operand" "=r")
15479 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15480 (clobber (reg:CC FLAGS_REG))]
15482 "lzcnt{w}\t{%1, %0|%0, %1}"
15483 [(set_attr "prefix_rep" "1")
15484 (set_attr "type" "bitmanip")
15485 (set_attr "mode" "HI")])
15487 (define_insn "*bsrhi"
15488 [(set (match_operand:HI 0 "register_operand" "=r")
15489 (minus:HI (const_int 15)
15490 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15491 (clobber (reg:CC FLAGS_REG))]
15493 "bsr{w}\t{%1, %0|%0, %1}"
15494 [(set_attr "prefix_0f" "1")
15495 (set_attr "mode" "HI")])
15497 (define_insn "popcounthi2"
15498 [(set (match_operand:HI 0 "register_operand" "=r")
15499 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15500 (clobber (reg:CC FLAGS_REG))]
15502 "popcnt{w}\t{%1, %0|%0, %1}"
15503 [(set_attr "prefix_rep" "1")
15504 (set_attr "type" "bitmanip")
15505 (set_attr "mode" "HI")])
15507 (define_insn "*popcounthi2_cmp"
15508 [(set (reg FLAGS_REG)
15510 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15512 (set (match_operand:HI 0 "register_operand" "=r")
15513 (popcount:HI (match_dup 1)))]
15514 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15515 "popcnt{w}\t{%1, %0|%0, %1}"
15516 [(set_attr "prefix_rep" "1")
15517 (set_attr "type" "bitmanip")
15518 (set_attr "mode" "HI")])
15520 (define_expand "paritydi2"
15521 [(set (match_operand:DI 0 "register_operand" "")
15522 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15525 rtx scratch = gen_reg_rtx (QImode);
15528 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15529 NULL_RTX, operands[1]));
15531 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15532 gen_rtx_REG (CCmode, FLAGS_REG),
15534 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15537 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15540 rtx tmp = gen_reg_rtx (SImode);
15542 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15543 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15548 (define_insn_and_split "paritydi2_cmp"
15549 [(set (reg:CC FLAGS_REG)
15550 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15551 (clobber (match_scratch:DI 0 "=r,X"))
15552 (clobber (match_scratch:SI 1 "=r,r"))
15553 (clobber (match_scratch:HI 2 "=Q,Q"))]
15556 "&& reload_completed"
15558 [(set (match_dup 1)
15559 (xor:SI (match_dup 1) (match_dup 4)))
15560 (clobber (reg:CC FLAGS_REG))])
15562 [(set (reg:CC FLAGS_REG)
15563 (parity:CC (match_dup 1)))
15564 (clobber (match_dup 1))
15565 (clobber (match_dup 2))])]
15567 operands[4] = gen_lowpart (SImode, operands[3]);
15569 if (MEM_P (operands[3]))
15570 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15571 else if (! TARGET_64BIT)
15572 operands[1] = gen_highpart (SImode, operands[3]);
15575 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15576 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15580 (define_expand "paritysi2"
15581 [(set (match_operand:SI 0 "register_operand" "")
15582 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15585 rtx scratch = gen_reg_rtx (QImode);
15588 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15590 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15591 gen_rtx_REG (CCmode, FLAGS_REG),
15593 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15595 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15599 (define_insn_and_split "paritysi2_cmp"
15600 [(set (reg:CC FLAGS_REG)
15601 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15602 (clobber (match_scratch:SI 0 "=r,X"))
15603 (clobber (match_scratch:HI 1 "=Q,Q"))]
15606 "&& reload_completed"
15608 [(set (match_dup 1)
15609 (xor:HI (match_dup 1) (match_dup 3)))
15610 (clobber (reg:CC FLAGS_REG))])
15612 [(set (reg:CC FLAGS_REG)
15613 (parity:CC (match_dup 1)))
15614 (clobber (match_dup 1))])]
15616 operands[3] = gen_lowpart (HImode, operands[2]);
15618 if (MEM_P (operands[2]))
15619 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15622 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15623 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15627 (define_insn "*parityhi2_cmp"
15628 [(set (reg:CC FLAGS_REG)
15629 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15630 (clobber (match_scratch:HI 0 "=Q"))]
15632 "xor{b}\t{%h0, %b0|%b0, %h0}"
15633 [(set_attr "length" "2")
15634 (set_attr "mode" "HI")])
15636 (define_insn "*parityqi2_cmp"
15637 [(set (reg:CC FLAGS_REG)
15638 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15641 [(set_attr "length" "2")
15642 (set_attr "mode" "QI")])
15644 ;; Thread-local storage patterns for ELF.
15646 ;; Note that these code sequences must appear exactly as shown
15647 ;; in order to allow linker relaxation.
15649 (define_insn "*tls_global_dynamic_32_gnu"
15650 [(set (match_operand:SI 0 "register_operand" "=a")
15651 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15652 (match_operand:SI 2 "tls_symbolic_operand" "")
15653 (match_operand:SI 3 "call_insn_operand" "")]
15655 (clobber (match_scratch:SI 4 "=d"))
15656 (clobber (match_scratch:SI 5 "=c"))
15657 (clobber (reg:CC FLAGS_REG))]
15658 "!TARGET_64BIT && TARGET_GNU_TLS"
15659 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15660 [(set_attr "type" "multi")
15661 (set_attr "length" "12")])
15663 (define_insn "*tls_global_dynamic_32_sun"
15664 [(set (match_operand:SI 0 "register_operand" "=a")
15665 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15666 (match_operand:SI 2 "tls_symbolic_operand" "")
15667 (match_operand:SI 3 "call_insn_operand" "")]
15669 (clobber (match_scratch:SI 4 "=d"))
15670 (clobber (match_scratch:SI 5 "=c"))
15671 (clobber (reg:CC FLAGS_REG))]
15672 "!TARGET_64BIT && TARGET_SUN_TLS"
15673 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15674 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15675 [(set_attr "type" "multi")
15676 (set_attr "length" "14")])
15678 (define_expand "tls_global_dynamic_32"
15679 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15682 (match_operand:SI 1 "tls_symbolic_operand" "")
15685 (clobber (match_scratch:SI 4 ""))
15686 (clobber (match_scratch:SI 5 ""))
15687 (clobber (reg:CC FLAGS_REG))])]
15691 operands[2] = pic_offset_table_rtx;
15694 operands[2] = gen_reg_rtx (Pmode);
15695 emit_insn (gen_set_got (operands[2]));
15697 if (TARGET_GNU2_TLS)
15699 emit_insn (gen_tls_dynamic_gnu2_32
15700 (operands[0], operands[1], operands[2]));
15703 operands[3] = ix86_tls_get_addr ();
15706 (define_insn "*tls_global_dynamic_64"
15707 [(set (match_operand:DI 0 "register_operand" "=a")
15708 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15709 (match_operand:DI 3 "" "")))
15710 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15713 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15714 [(set_attr "type" "multi")
15715 (set_attr "length" "16")])
15717 (define_expand "tls_global_dynamic_64"
15718 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15719 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15720 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15724 if (TARGET_GNU2_TLS)
15726 emit_insn (gen_tls_dynamic_gnu2_64
15727 (operands[0], operands[1]));
15730 operands[2] = ix86_tls_get_addr ();
15733 (define_insn "*tls_local_dynamic_base_32_gnu"
15734 [(set (match_operand:SI 0 "register_operand" "=a")
15735 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15736 (match_operand:SI 2 "call_insn_operand" "")]
15737 UNSPEC_TLS_LD_BASE))
15738 (clobber (match_scratch:SI 3 "=d"))
15739 (clobber (match_scratch:SI 4 "=c"))
15740 (clobber (reg:CC FLAGS_REG))]
15741 "!TARGET_64BIT && TARGET_GNU_TLS"
15742 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15743 [(set_attr "type" "multi")
15744 (set_attr "length" "11")])
15746 (define_insn "*tls_local_dynamic_base_32_sun"
15747 [(set (match_operand:SI 0 "register_operand" "=a")
15748 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15749 (match_operand:SI 2 "call_insn_operand" "")]
15750 UNSPEC_TLS_LD_BASE))
15751 (clobber (match_scratch:SI 3 "=d"))
15752 (clobber (match_scratch:SI 4 "=c"))
15753 (clobber (reg:CC FLAGS_REG))]
15754 "!TARGET_64BIT && TARGET_SUN_TLS"
15755 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15756 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15757 [(set_attr "type" "multi")
15758 (set_attr "length" "13")])
15760 (define_expand "tls_local_dynamic_base_32"
15761 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15762 (unspec:SI [(match_dup 1) (match_dup 2)]
15763 UNSPEC_TLS_LD_BASE))
15764 (clobber (match_scratch:SI 3 ""))
15765 (clobber (match_scratch:SI 4 ""))
15766 (clobber (reg:CC FLAGS_REG))])]
15770 operands[1] = pic_offset_table_rtx;
15773 operands[1] = gen_reg_rtx (Pmode);
15774 emit_insn (gen_set_got (operands[1]));
15776 if (TARGET_GNU2_TLS)
15778 emit_insn (gen_tls_dynamic_gnu2_32
15779 (operands[0], ix86_tls_module_base (), operands[1]));
15782 operands[2] = ix86_tls_get_addr ();
15785 (define_insn "*tls_local_dynamic_base_64"
15786 [(set (match_operand:DI 0 "register_operand" "=a")
15787 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15788 (match_operand:DI 2 "" "")))
15789 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15791 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15792 [(set_attr "type" "multi")
15793 (set_attr "length" "12")])
15795 (define_expand "tls_local_dynamic_base_64"
15796 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15797 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15798 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15801 if (TARGET_GNU2_TLS)
15803 emit_insn (gen_tls_dynamic_gnu2_64
15804 (operands[0], ix86_tls_module_base ()));
15807 operands[1] = ix86_tls_get_addr ();
15810 ;; Local dynamic of a single variable is a lose. Show combine how
15811 ;; to convert that back to global dynamic.
15813 (define_insn_and_split "*tls_local_dynamic_32_once"
15814 [(set (match_operand:SI 0 "register_operand" "=a")
15815 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15816 (match_operand:SI 2 "call_insn_operand" "")]
15817 UNSPEC_TLS_LD_BASE)
15818 (const:SI (unspec:SI
15819 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15821 (clobber (match_scratch:SI 4 "=d"))
15822 (clobber (match_scratch:SI 5 "=c"))
15823 (clobber (reg:CC FLAGS_REG))]
15827 [(parallel [(set (match_dup 0)
15828 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15830 (clobber (match_dup 4))
15831 (clobber (match_dup 5))
15832 (clobber (reg:CC FLAGS_REG))])]
15835 ;; Load and add the thread base pointer from %gs:0.
15837 (define_insn "*load_tp_si"
15838 [(set (match_operand:SI 0 "register_operand" "=r")
15839 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15841 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15842 [(set_attr "type" "imov")
15843 (set_attr "modrm" "0")
15844 (set_attr "length" "7")
15845 (set_attr "memory" "load")
15846 (set_attr "imm_disp" "false")])
15848 (define_insn "*add_tp_si"
15849 [(set (match_operand:SI 0 "register_operand" "=r")
15850 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15851 (match_operand:SI 1 "register_operand" "0")))
15852 (clobber (reg:CC FLAGS_REG))]
15854 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15855 [(set_attr "type" "alu")
15856 (set_attr "modrm" "0")
15857 (set_attr "length" "7")
15858 (set_attr "memory" "load")
15859 (set_attr "imm_disp" "false")])
15861 (define_insn "*load_tp_di"
15862 [(set (match_operand:DI 0 "register_operand" "=r")
15863 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15865 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15866 [(set_attr "type" "imov")
15867 (set_attr "modrm" "0")
15868 (set_attr "length" "7")
15869 (set_attr "memory" "load")
15870 (set_attr "imm_disp" "false")])
15872 (define_insn "*add_tp_di"
15873 [(set (match_operand:DI 0 "register_operand" "=r")
15874 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15875 (match_operand:DI 1 "register_operand" "0")))
15876 (clobber (reg:CC FLAGS_REG))]
15878 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15879 [(set_attr "type" "alu")
15880 (set_attr "modrm" "0")
15881 (set_attr "length" "7")
15882 (set_attr "memory" "load")
15883 (set_attr "imm_disp" "false")])
15885 ;; GNU2 TLS patterns can be split.
15887 (define_expand "tls_dynamic_gnu2_32"
15888 [(set (match_dup 3)
15889 (plus:SI (match_operand:SI 2 "register_operand" "")
15891 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15894 [(set (match_operand:SI 0 "register_operand" "")
15895 (unspec:SI [(match_dup 1) (match_dup 3)
15896 (match_dup 2) (reg:SI SP_REG)]
15898 (clobber (reg:CC FLAGS_REG))])]
15899 "!TARGET_64BIT && TARGET_GNU2_TLS"
15901 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15902 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15905 (define_insn "*tls_dynamic_lea_32"
15906 [(set (match_operand:SI 0 "register_operand" "=r")
15907 (plus:SI (match_operand:SI 1 "register_operand" "b")
15909 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15910 UNSPEC_TLSDESC))))]
15911 "!TARGET_64BIT && TARGET_GNU2_TLS"
15912 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15913 [(set_attr "type" "lea")
15914 (set_attr "mode" "SI")
15915 (set_attr "length" "6")
15916 (set_attr "length_address" "4")])
15918 (define_insn "*tls_dynamic_call_32"
15919 [(set (match_operand:SI 0 "register_operand" "=a")
15920 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15921 (match_operand:SI 2 "register_operand" "0")
15922 ;; we have to make sure %ebx still points to the GOT
15923 (match_operand:SI 3 "register_operand" "b")
15926 (clobber (reg:CC FLAGS_REG))]
15927 "!TARGET_64BIT && TARGET_GNU2_TLS"
15928 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15929 [(set_attr "type" "call")
15930 (set_attr "length" "2")
15931 (set_attr "length_address" "0")])
15933 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15934 [(set (match_operand:SI 0 "register_operand" "=&a")
15936 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15937 (match_operand:SI 4 "" "")
15938 (match_operand:SI 2 "register_operand" "b")
15941 (const:SI (unspec:SI
15942 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15944 (clobber (reg:CC FLAGS_REG))]
15945 "!TARGET_64BIT && TARGET_GNU2_TLS"
15948 [(set (match_dup 0) (match_dup 5))]
15950 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15951 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15954 (define_expand "tls_dynamic_gnu2_64"
15955 [(set (match_dup 2)
15956 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15959 [(set (match_operand:DI 0 "register_operand" "")
15960 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15962 (clobber (reg:CC FLAGS_REG))])]
15963 "TARGET_64BIT && TARGET_GNU2_TLS"
15965 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15966 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15969 (define_insn "*tls_dynamic_lea_64"
15970 [(set (match_operand:DI 0 "register_operand" "=r")
15971 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15973 "TARGET_64BIT && TARGET_GNU2_TLS"
15974 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15975 [(set_attr "type" "lea")
15976 (set_attr "mode" "DI")
15977 (set_attr "length" "7")
15978 (set_attr "length_address" "4")])
15980 (define_insn "*tls_dynamic_call_64"
15981 [(set (match_operand:DI 0 "register_operand" "=a")
15982 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15983 (match_operand:DI 2 "register_operand" "0")
15986 (clobber (reg:CC FLAGS_REG))]
15987 "TARGET_64BIT && TARGET_GNU2_TLS"
15988 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15989 [(set_attr "type" "call")
15990 (set_attr "length" "2")
15991 (set_attr "length_address" "0")])
15993 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15994 [(set (match_operand:DI 0 "register_operand" "=&a")
15996 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15997 (match_operand:DI 3 "" "")
16000 (const:DI (unspec:DI
16001 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16003 (clobber (reg:CC FLAGS_REG))]
16004 "TARGET_64BIT && TARGET_GNU2_TLS"
16007 [(set (match_dup 0) (match_dup 4))]
16009 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16010 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16015 ;; These patterns match the binary 387 instructions for addM3, subM3,
16016 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16017 ;; SFmode. The first is the normal insn, the second the same insn but
16018 ;; with one operand a conversion, and the third the same insn but with
16019 ;; the other operand a conversion. The conversion may be SFmode or
16020 ;; SImode if the target mode DFmode, but only SImode if the target mode
16023 ;; Gcc is slightly more smart about handling normal two address instructions
16024 ;; so use special patterns for add and mull.
16026 (define_insn "*fop_sf_comm_mixed"
16027 [(set (match_operand:SF 0 "register_operand" "=f,x")
16028 (match_operator:SF 3 "binary_fp_operator"
16029 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
16030 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
16031 "TARGET_MIX_SSE_I387
16032 && COMMUTATIVE_ARITH_P (operands[3])
16033 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16034 "* return output_387_binary_op (insn, operands);"
16035 [(set (attr "type")
16036 (if_then_else (eq_attr "alternative" "1")
16037 (if_then_else (match_operand:SF 3 "mult_operator" "")
16038 (const_string "ssemul")
16039 (const_string "sseadd"))
16040 (if_then_else (match_operand:SF 3 "mult_operator" "")
16041 (const_string "fmul")
16042 (const_string "fop"))))
16043 (set_attr "mode" "SF")])
16045 (define_insn "*fop_sf_comm_sse"
16046 [(set (match_operand:SF 0 "register_operand" "=x")
16047 (match_operator:SF 3 "binary_fp_operator"
16048 [(match_operand:SF 1 "nonimmediate_operand" "%0")
16049 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16051 && COMMUTATIVE_ARITH_P (operands[3])
16052 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16053 "* return output_387_binary_op (insn, operands);"
16054 [(set (attr "type")
16055 (if_then_else (match_operand:SF 3 "mult_operator" "")
16056 (const_string "ssemul")
16057 (const_string "sseadd")))
16058 (set_attr "mode" "SF")])
16060 (define_insn "*fop_sf_comm_i387"
16061 [(set (match_operand:SF 0 "register_operand" "=f")
16062 (match_operator:SF 3 "binary_fp_operator"
16063 [(match_operand:SF 1 "nonimmediate_operand" "%0")
16064 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
16066 && COMMUTATIVE_ARITH_P (operands[3])
16067 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16068 "* return output_387_binary_op (insn, operands);"
16069 [(set (attr "type")
16070 (if_then_else (match_operand:SF 3 "mult_operator" "")
16071 (const_string "fmul")
16072 (const_string "fop")))
16073 (set_attr "mode" "SF")])
16075 (define_insn "*fop_sf_1_mixed"
16076 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
16077 (match_operator:SF 3 "binary_fp_operator"
16078 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
16079 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
16080 "TARGET_MIX_SSE_I387
16081 && !COMMUTATIVE_ARITH_P (operands[3])
16082 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16083 "* return output_387_binary_op (insn, operands);"
16084 [(set (attr "type")
16085 (cond [(and (eq_attr "alternative" "2")
16086 (match_operand:SF 3 "mult_operator" ""))
16087 (const_string "ssemul")
16088 (and (eq_attr "alternative" "2")
16089 (match_operand:SF 3 "div_operator" ""))
16090 (const_string "ssediv")
16091 (eq_attr "alternative" "2")
16092 (const_string "sseadd")
16093 (match_operand:SF 3 "mult_operator" "")
16094 (const_string "fmul")
16095 (match_operand:SF 3 "div_operator" "")
16096 (const_string "fdiv")
16098 (const_string "fop")))
16099 (set_attr "mode" "SF")])
16101 (define_insn "*rcpsf2_sse"
16102 [(set (match_operand:SF 0 "register_operand" "=x")
16103 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16106 "rcpss\t{%1, %0|%0, %1}"
16107 [(set_attr "type" "sse")
16108 (set_attr "mode" "SF")])
16110 (define_insn "*fop_sf_1_sse"
16111 [(set (match_operand:SF 0 "register_operand" "=x")
16112 (match_operator:SF 3 "binary_fp_operator"
16113 [(match_operand:SF 1 "register_operand" "0")
16114 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
16116 && !COMMUTATIVE_ARITH_P (operands[3])"
16117 "* return output_387_binary_op (insn, operands);"
16118 [(set (attr "type")
16119 (cond [(match_operand:SF 3 "mult_operator" "")
16120 (const_string "ssemul")
16121 (match_operand:SF 3 "div_operator" "")
16122 (const_string "ssediv")
16124 (const_string "sseadd")))
16125 (set_attr "mode" "SF")])
16127 ;; This pattern is not fully shadowed by the pattern above.
16128 (define_insn "*fop_sf_1_i387"
16129 [(set (match_operand:SF 0 "register_operand" "=f,f")
16130 (match_operator:SF 3 "binary_fp_operator"
16131 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
16132 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
16133 "TARGET_80387 && !TARGET_SSE_MATH
16134 && !COMMUTATIVE_ARITH_P (operands[3])
16135 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16136 "* return output_387_binary_op (insn, operands);"
16137 [(set (attr "type")
16138 (cond [(match_operand:SF 3 "mult_operator" "")
16139 (const_string "fmul")
16140 (match_operand:SF 3 "div_operator" "")
16141 (const_string "fdiv")
16143 (const_string "fop")))
16144 (set_attr "mode" "SF")])
16146 ;; ??? Add SSE splitters for these!
16147 (define_insn "*fop_sf_2<mode>_i387"
16148 [(set (match_operand:SF 0 "register_operand" "=f,f")
16149 (match_operator:SF 3 "binary_fp_operator"
16150 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16151 (match_operand:SF 2 "register_operand" "0,0")]))]
16152 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16153 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16154 [(set (attr "type")
16155 (cond [(match_operand:SF 3 "mult_operator" "")
16156 (const_string "fmul")
16157 (match_operand:SF 3 "div_operator" "")
16158 (const_string "fdiv")
16160 (const_string "fop")))
16161 (set_attr "fp_int_src" "true")
16162 (set_attr "mode" "<MODE>")])
16164 (define_insn "*fop_sf_3<mode>_i387"
16165 [(set (match_operand:SF 0 "register_operand" "=f,f")
16166 (match_operator:SF 3 "binary_fp_operator"
16167 [(match_operand:SF 1 "register_operand" "0,0")
16168 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16169 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
16170 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16171 [(set (attr "type")
16172 (cond [(match_operand:SF 3 "mult_operator" "")
16173 (const_string "fmul")
16174 (match_operand:SF 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_comm_mixed"
16182 [(set (match_operand:DF 0 "register_operand" "=f,x")
16183 (match_operator:DF 3 "binary_fp_operator"
16184 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
16185 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
16186 "TARGET_SSE2 && TARGET_MIX_SSE_I387
16187 && COMMUTATIVE_ARITH_P (operands[3])
16188 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16189 "* return output_387_binary_op (insn, operands);"
16190 [(set (attr "type")
16191 (if_then_else (eq_attr "alternative" "1")
16192 (if_then_else (match_operand:DF 3 "mult_operator" "")
16193 (const_string "ssemul")
16194 (const_string "sseadd"))
16195 (if_then_else (match_operand:DF 3 "mult_operator" "")
16196 (const_string "fmul")
16197 (const_string "fop"))))
16198 (set_attr "mode" "DF")])
16200 (define_insn "*fop_df_comm_sse"
16201 [(set (match_operand:DF 0 "register_operand" "=x")
16202 (match_operator:DF 3 "binary_fp_operator"
16203 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16204 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16205 "TARGET_SSE2 && TARGET_SSE_MATH
16206 && COMMUTATIVE_ARITH_P (operands[3])
16207 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16208 "* return output_387_binary_op (insn, operands);"
16209 [(set (attr "type")
16210 (if_then_else (match_operand:DF 3 "mult_operator" "")
16211 (const_string "ssemul")
16212 (const_string "sseadd")))
16213 (set_attr "mode" "DF")])
16215 (define_insn "*fop_df_comm_i387"
16216 [(set (match_operand:DF 0 "register_operand" "=f")
16217 (match_operator:DF 3 "binary_fp_operator"
16218 [(match_operand:DF 1 "nonimmediate_operand" "%0")
16219 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
16221 && COMMUTATIVE_ARITH_P (operands[3])
16222 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16223 "* return output_387_binary_op (insn, operands);"
16224 [(set (attr "type")
16225 (if_then_else (match_operand:DF 3 "mult_operator" "")
16226 (const_string "fmul")
16227 (const_string "fop")))
16228 (set_attr "mode" "DF")])
16230 (define_insn "*fop_df_1_mixed"
16231 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16232 (match_operator:DF 3 "binary_fp_operator"
16233 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16234 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16235 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16236 && !COMMUTATIVE_ARITH_P (operands[3])
16237 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16238 "* return output_387_binary_op (insn, operands);"
16239 [(set (attr "type")
16240 (cond [(and (eq_attr "alternative" "2")
16241 (match_operand:DF 3 "mult_operator" ""))
16242 (const_string "ssemul")
16243 (and (eq_attr "alternative" "2")
16244 (match_operand:DF 3 "div_operator" ""))
16245 (const_string "ssediv")
16246 (eq_attr "alternative" "2")
16247 (const_string "sseadd")
16248 (match_operand:DF 3 "mult_operator" "")
16249 (const_string "fmul")
16250 (match_operand:DF 3 "div_operator" "")
16251 (const_string "fdiv")
16253 (const_string "fop")))
16254 (set_attr "mode" "DF")])
16256 (define_insn "*fop_df_1_sse"
16257 [(set (match_operand:DF 0 "register_operand" "=x")
16258 (match_operator:DF 3 "binary_fp_operator"
16259 [(match_operand:DF 1 "register_operand" "0")
16260 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16261 "TARGET_SSE2 && TARGET_SSE_MATH
16262 && !COMMUTATIVE_ARITH_P (operands[3])"
16263 "* return output_387_binary_op (insn, operands);"
16264 [(set_attr "mode" "DF")
16266 (cond [(match_operand:DF 3 "mult_operator" "")
16267 (const_string "ssemul")
16268 (match_operand:DF 3 "div_operator" "")
16269 (const_string "ssediv")
16271 (const_string "sseadd")))])
16273 ;; This pattern is not fully shadowed by the pattern above.
16274 (define_insn "*fop_df_1_i387"
16275 [(set (match_operand:DF 0 "register_operand" "=f,f")
16276 (match_operator:DF 3 "binary_fp_operator"
16277 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16278 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16279 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16280 && !COMMUTATIVE_ARITH_P (operands[3])
16281 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16282 "* return output_387_binary_op (insn, operands);"
16283 [(set (attr "type")
16284 (cond [(match_operand:DF 3 "mult_operator" "")
16285 (const_string "fmul")
16286 (match_operand:DF 3 "div_operator" "")
16287 (const_string "fdiv")
16289 (const_string "fop")))
16290 (set_attr "mode" "DF")])
16292 ;; ??? Add SSE splitters for these!
16293 (define_insn "*fop_df_2<mode>_i387"
16294 [(set (match_operand:DF 0 "register_operand" "=f,f")
16295 (match_operator:DF 3 "binary_fp_operator"
16296 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16297 (match_operand:DF 2 "register_operand" "0,0")]))]
16298 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16299 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16300 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16301 [(set (attr "type")
16302 (cond [(match_operand:DF 3 "mult_operator" "")
16303 (const_string "fmul")
16304 (match_operand:DF 3 "div_operator" "")
16305 (const_string "fdiv")
16307 (const_string "fop")))
16308 (set_attr "fp_int_src" "true")
16309 (set_attr "mode" "<MODE>")])
16311 (define_insn "*fop_df_3<mode>_i387"
16312 [(set (match_operand:DF 0 "register_operand" "=f,f")
16313 (match_operator:DF 3 "binary_fp_operator"
16314 [(match_operand:DF 1 "register_operand" "0,0")
16315 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16316 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16317 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16318 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16319 [(set (attr "type")
16320 (cond [(match_operand:DF 3 "mult_operator" "")
16321 (const_string "fmul")
16322 (match_operand:DF 3 "div_operator" "")
16323 (const_string "fdiv")
16325 (const_string "fop")))
16326 (set_attr "fp_int_src" "true")
16327 (set_attr "mode" "<MODE>")])
16329 (define_insn "*fop_df_4_i387"
16330 [(set (match_operand:DF 0 "register_operand" "=f,f")
16331 (match_operator:DF 3 "binary_fp_operator"
16332 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16333 (match_operand:DF 2 "register_operand" "0,f")]))]
16334 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16335 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16336 "* return output_387_binary_op (insn, operands);"
16337 [(set (attr "type")
16338 (cond [(match_operand:DF 3 "mult_operator" "")
16339 (const_string "fmul")
16340 (match_operand:DF 3 "div_operator" "")
16341 (const_string "fdiv")
16343 (const_string "fop")))
16344 (set_attr "mode" "SF")])
16346 (define_insn "*fop_df_5_i387"
16347 [(set (match_operand:DF 0 "register_operand" "=f,f")
16348 (match_operator:DF 3 "binary_fp_operator"
16349 [(match_operand:DF 1 "register_operand" "0,f")
16351 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16352 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16353 "* return output_387_binary_op (insn, operands);"
16354 [(set (attr "type")
16355 (cond [(match_operand:DF 3 "mult_operator" "")
16356 (const_string "fmul")
16357 (match_operand:DF 3 "div_operator" "")
16358 (const_string "fdiv")
16360 (const_string "fop")))
16361 (set_attr "mode" "SF")])
16363 (define_insn "*fop_df_6_i387"
16364 [(set (match_operand:DF 0 "register_operand" "=f,f")
16365 (match_operator:DF 3 "binary_fp_operator"
16367 (match_operand:SF 1 "register_operand" "0,f"))
16369 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16370 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16371 "* return output_387_binary_op (insn, operands);"
16372 [(set (attr "type")
16373 (cond [(match_operand:DF 3 "mult_operator" "")
16374 (const_string "fmul")
16375 (match_operand:DF 3 "div_operator" "")
16376 (const_string "fdiv")
16378 (const_string "fop")))
16379 (set_attr "mode" "SF")])
16381 (define_insn "*fop_xf_comm_i387"
16382 [(set (match_operand:XF 0 "register_operand" "=f")
16383 (match_operator:XF 3 "binary_fp_operator"
16384 [(match_operand:XF 1 "register_operand" "%0")
16385 (match_operand:XF 2 "register_operand" "f")]))]
16387 && COMMUTATIVE_ARITH_P (operands[3])"
16388 "* return output_387_binary_op (insn, operands);"
16389 [(set (attr "type")
16390 (if_then_else (match_operand:XF 3 "mult_operator" "")
16391 (const_string "fmul")
16392 (const_string "fop")))
16393 (set_attr "mode" "XF")])
16395 (define_insn "*fop_xf_1_i387"
16396 [(set (match_operand:XF 0 "register_operand" "=f,f")
16397 (match_operator:XF 3 "binary_fp_operator"
16398 [(match_operand:XF 1 "register_operand" "0,f")
16399 (match_operand:XF 2 "register_operand" "f,0")]))]
16401 && !COMMUTATIVE_ARITH_P (operands[3])"
16402 "* return output_387_binary_op (insn, operands);"
16403 [(set (attr "type")
16404 (cond [(match_operand:XF 3 "mult_operator" "")
16405 (const_string "fmul")
16406 (match_operand:XF 3 "div_operator" "")
16407 (const_string "fdiv")
16409 (const_string "fop")))
16410 (set_attr "mode" "XF")])
16412 (define_insn "*fop_xf_2<mode>_i387"
16413 [(set (match_operand:XF 0 "register_operand" "=f,f")
16414 (match_operator:XF 3 "binary_fp_operator"
16415 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16416 (match_operand:XF 2 "register_operand" "0,0")]))]
16417 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16418 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16419 [(set (attr "type")
16420 (cond [(match_operand:XF 3 "mult_operator" "")
16421 (const_string "fmul")
16422 (match_operand:XF 3 "div_operator" "")
16423 (const_string "fdiv")
16425 (const_string "fop")))
16426 (set_attr "fp_int_src" "true")
16427 (set_attr "mode" "<MODE>")])
16429 (define_insn "*fop_xf_3<mode>_i387"
16430 [(set (match_operand:XF 0 "register_operand" "=f,f")
16431 (match_operator:XF 3 "binary_fp_operator"
16432 [(match_operand:XF 1 "register_operand" "0,0")
16433 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16434 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16435 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16436 [(set (attr "type")
16437 (cond [(match_operand:XF 3 "mult_operator" "")
16438 (const_string "fmul")
16439 (match_operand:XF 3 "div_operator" "")
16440 (const_string "fdiv")
16442 (const_string "fop")))
16443 (set_attr "fp_int_src" "true")
16444 (set_attr "mode" "<MODE>")])
16446 (define_insn "*fop_xf_4_i387"
16447 [(set (match_operand:XF 0 "register_operand" "=f,f")
16448 (match_operator:XF 3 "binary_fp_operator"
16450 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16451 (match_operand:XF 2 "register_operand" "0,f")]))]
16453 "* return output_387_binary_op (insn, operands);"
16454 [(set (attr "type")
16455 (cond [(match_operand:XF 3 "mult_operator" "")
16456 (const_string "fmul")
16457 (match_operand:XF 3 "div_operator" "")
16458 (const_string "fdiv")
16460 (const_string "fop")))
16461 (set_attr "mode" "SF")])
16463 (define_insn "*fop_xf_5_i387"
16464 [(set (match_operand:XF 0 "register_operand" "=f,f")
16465 (match_operator:XF 3 "binary_fp_operator"
16466 [(match_operand:XF 1 "register_operand" "0,f")
16468 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16470 "* return output_387_binary_op (insn, operands);"
16471 [(set (attr "type")
16472 (cond [(match_operand:XF 3 "mult_operator" "")
16473 (const_string "fmul")
16474 (match_operand:XF 3 "div_operator" "")
16475 (const_string "fdiv")
16477 (const_string "fop")))
16478 (set_attr "mode" "SF")])
16480 (define_insn "*fop_xf_6_i387"
16481 [(set (match_operand:XF 0 "register_operand" "=f,f")
16482 (match_operator:XF 3 "binary_fp_operator"
16484 (match_operand:MODEF 1 "register_operand" "0,f"))
16486 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16488 "* return output_387_binary_op (insn, operands);"
16489 [(set (attr "type")
16490 (cond [(match_operand:XF 3 "mult_operator" "")
16491 (const_string "fmul")
16492 (match_operand:XF 3 "div_operator" "")
16493 (const_string "fdiv")
16495 (const_string "fop")))
16496 (set_attr "mode" "SF")])
16499 [(set (match_operand 0 "register_operand" "")
16500 (match_operator 3 "binary_fp_operator"
16501 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16502 (match_operand 2 "register_operand" "")]))]
16504 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16507 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16508 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16509 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16510 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16511 GET_MODE (operands[3]),
16514 ix86_free_from_memory (GET_MODE (operands[1]));
16519 [(set (match_operand 0 "register_operand" "")
16520 (match_operator 3 "binary_fp_operator"
16521 [(match_operand 1 "register_operand" "")
16522 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16524 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16527 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16528 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16529 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16530 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16531 GET_MODE (operands[3]),
16534 ix86_free_from_memory (GET_MODE (operands[2]));
16538 ;; FPU special functions.
16540 ;; This pattern implements a no-op XFmode truncation for
16541 ;; all fancy i386 XFmode math functions.
16543 (define_insn "truncxf<mode>2_i387_noop_unspec"
16544 [(set (match_operand:MODEF 0 "register_operand" "=f")
16545 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16546 UNSPEC_TRUNC_NOOP))]
16547 "TARGET_USE_FANCY_MATH_387"
16548 "* return output_387_reg_move (insn, operands);"
16549 [(set_attr "type" "fmov")
16550 (set_attr "mode" "<MODE>")])
16552 (define_insn "sqrtxf2"
16553 [(set (match_operand:XF 0 "register_operand" "=f")
16554 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16555 "TARGET_USE_FANCY_MATH_387"
16557 [(set_attr "type" "fpspc")
16558 (set_attr "mode" "XF")
16559 (set_attr "athlon_decode" "direct")
16560 (set_attr "amdfam10_decode" "direct")])
16562 (define_insn "sqrt_extend<mode>xf2_i387"
16563 [(set (match_operand:XF 0 "register_operand" "=f")
16566 (match_operand:MODEF 1 "register_operand" "0"))))]
16567 "TARGET_USE_FANCY_MATH_387"
16569 [(set_attr "type" "fpspc")
16570 (set_attr "mode" "XF")
16571 (set_attr "athlon_decode" "direct")
16572 (set_attr "amdfam10_decode" "direct")])
16574 (define_insn "*rsqrtsf2_sse"
16575 [(set (match_operand:SF 0 "register_operand" "=x")
16576 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16579 "rsqrtss\t{%1, %0|%0, %1}"
16580 [(set_attr "type" "sse")
16581 (set_attr "mode" "SF")])
16583 (define_expand "rsqrtsf2"
16584 [(set (match_operand:SF 0 "register_operand" "")
16585 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16587 "TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16588 && flag_finite_math_only && !flag_trapping_math
16589 && flag_unsafe_math_optimizations"
16591 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16595 (define_insn "*sqrt<mode>2_sse"
16596 [(set (match_operand:MODEF 0 "register_operand" "=x")
16598 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16599 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16600 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16601 [(set_attr "type" "sse")
16602 (set_attr "mode" "<MODE>")
16603 (set_attr "athlon_decode" "*")
16604 (set_attr "amdfam10_decode" "*")])
16606 (define_expand "sqrt<mode>2"
16607 [(set (match_operand:MODEF 0 "register_operand" "")
16609 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16610 "TARGET_USE_FANCY_MATH_387
16611 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16613 if (<MODE>mode == SFmode
16614 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16615 && flag_finite_math_only && !flag_trapping_math
16616 && flag_unsafe_math_optimizations)
16618 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16622 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16624 rtx op0 = gen_reg_rtx (XFmode);
16625 rtx op1 = force_reg (<MODE>mode, operands[1]);
16627 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16628 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16633 (define_insn "fpremxf4_i387"
16634 [(set (match_operand:XF 0 "register_operand" "=f")
16635 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16636 (match_operand:XF 3 "register_operand" "1")]
16638 (set (match_operand:XF 1 "register_operand" "=u")
16639 (unspec:XF [(match_dup 2) (match_dup 3)]
16641 (set (reg:CCFP FPSR_REG)
16642 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16644 "TARGET_USE_FANCY_MATH_387"
16646 [(set_attr "type" "fpspc")
16647 (set_attr "mode" "XF")])
16649 (define_expand "fmodxf3"
16650 [(use (match_operand:XF 0 "register_operand" ""))
16651 (use (match_operand:XF 1 "register_operand" ""))
16652 (use (match_operand:XF 2 "register_operand" ""))]
16653 "TARGET_USE_FANCY_MATH_387"
16655 rtx label = gen_label_rtx ();
16657 emit_label (label);
16659 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16660 operands[1], operands[2]));
16661 ix86_emit_fp_unordered_jump (label);
16662 LABEL_NUSES (label) = 1;
16664 emit_move_insn (operands[0], operands[1]);
16668 (define_expand "fmod<mode>3"
16669 [(use (match_operand:MODEF 0 "register_operand" ""))
16670 (use (match_operand:MODEF 1 "general_operand" ""))
16671 (use (match_operand:MODEF 2 "general_operand" ""))]
16672 "TARGET_USE_FANCY_MATH_387"
16674 rtx label = gen_label_rtx ();
16676 rtx op1 = gen_reg_rtx (XFmode);
16677 rtx op2 = gen_reg_rtx (XFmode);
16679 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16680 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16682 emit_label (label);
16683 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16684 ix86_emit_fp_unordered_jump (label);
16685 LABEL_NUSES (label) = 1;
16687 /* Truncate the result properly for strict SSE math. */
16688 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16689 && !TARGET_MIX_SSE_I387)
16690 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16692 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16697 (define_insn "fprem1xf4_i387"
16698 [(set (match_operand:XF 0 "register_operand" "=f")
16699 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16700 (match_operand:XF 3 "register_operand" "1")]
16702 (set (match_operand:XF 1 "register_operand" "=u")
16703 (unspec:XF [(match_dup 2) (match_dup 3)]
16705 (set (reg:CCFP FPSR_REG)
16706 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16708 "TARGET_USE_FANCY_MATH_387"
16710 [(set_attr "type" "fpspc")
16711 (set_attr "mode" "XF")])
16713 (define_expand "remainderxf3"
16714 [(use (match_operand:XF 0 "register_operand" ""))
16715 (use (match_operand:XF 1 "register_operand" ""))
16716 (use (match_operand:XF 2 "register_operand" ""))]
16717 "TARGET_USE_FANCY_MATH_387"
16719 rtx label = gen_label_rtx ();
16721 emit_label (label);
16723 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16724 operands[1], operands[2]));
16725 ix86_emit_fp_unordered_jump (label);
16726 LABEL_NUSES (label) = 1;
16728 emit_move_insn (operands[0], operands[1]);
16732 (define_expand "remainder<mode>3"
16733 [(use (match_operand:MODEF 0 "register_operand" ""))
16734 (use (match_operand:MODEF 1 "general_operand" ""))
16735 (use (match_operand:MODEF 2 "general_operand" ""))]
16736 "TARGET_USE_FANCY_MATH_387"
16738 rtx label = gen_label_rtx ();
16740 rtx op1 = gen_reg_rtx (XFmode);
16741 rtx op2 = gen_reg_rtx (XFmode);
16743 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16744 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16746 emit_label (label);
16748 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16749 ix86_emit_fp_unordered_jump (label);
16750 LABEL_NUSES (label) = 1;
16752 /* Truncate the result properly for strict SSE math. */
16753 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16754 && !TARGET_MIX_SSE_I387)
16755 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16757 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16762 (define_insn "*sinxf2_i387"
16763 [(set (match_operand:XF 0 "register_operand" "=f")
16764 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16765 "TARGET_USE_FANCY_MATH_387
16766 && flag_unsafe_math_optimizations"
16768 [(set_attr "type" "fpspc")
16769 (set_attr "mode" "XF")])
16771 (define_insn "*sin_extend<mode>xf2_i387"
16772 [(set (match_operand:XF 0 "register_operand" "=f")
16773 (unspec:XF [(float_extend:XF
16774 (match_operand:MODEF 1 "register_operand" "0"))]
16776 "TARGET_USE_FANCY_MATH_387
16777 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16778 || TARGET_MIX_SSE_I387)
16779 && flag_unsafe_math_optimizations"
16781 [(set_attr "type" "fpspc")
16782 (set_attr "mode" "XF")])
16784 (define_insn "*cosxf2_i387"
16785 [(set (match_operand:XF 0 "register_operand" "=f")
16786 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16787 "TARGET_USE_FANCY_MATH_387
16788 && flag_unsafe_math_optimizations"
16790 [(set_attr "type" "fpspc")
16791 (set_attr "mode" "XF")])
16793 (define_insn "*cos_extend<mode>xf2_i387"
16794 [(set (match_operand:XF 0 "register_operand" "=f")
16795 (unspec:XF [(float_extend:XF
16796 (match_operand:MODEF 1 "register_operand" "0"))]
16798 "TARGET_USE_FANCY_MATH_387
16799 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16800 || TARGET_MIX_SSE_I387)
16801 && flag_unsafe_math_optimizations"
16803 [(set_attr "type" "fpspc")
16804 (set_attr "mode" "XF")])
16806 ;; When sincos pattern is defined, sin and cos builtin functions will be
16807 ;; expanded to sincos pattern with one of its outputs left unused.
16808 ;; CSE pass will figure out if two sincos patterns can be combined,
16809 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16810 ;; depending on the unused output.
16812 (define_insn "sincosxf3"
16813 [(set (match_operand:XF 0 "register_operand" "=f")
16814 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16815 UNSPEC_SINCOS_COS))
16816 (set (match_operand:XF 1 "register_operand" "=u")
16817 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16818 "TARGET_USE_FANCY_MATH_387
16819 && flag_unsafe_math_optimizations"
16821 [(set_attr "type" "fpspc")
16822 (set_attr "mode" "XF")])
16825 [(set (match_operand:XF 0 "register_operand" "")
16826 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16827 UNSPEC_SINCOS_COS))
16828 (set (match_operand:XF 1 "register_operand" "")
16829 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16830 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16831 && !(reload_completed || reload_in_progress)"
16832 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16836 [(set (match_operand:XF 0 "register_operand" "")
16837 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16838 UNSPEC_SINCOS_COS))
16839 (set (match_operand:XF 1 "register_operand" "")
16840 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16841 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16842 && !(reload_completed || reload_in_progress)"
16843 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16846 (define_insn "sincos_extend<mode>xf3_i387"
16847 [(set (match_operand:XF 0 "register_operand" "=f")
16848 (unspec:XF [(float_extend:XF
16849 (match_operand:MODEF 2 "register_operand" "0"))]
16850 UNSPEC_SINCOS_COS))
16851 (set (match_operand:XF 1 "register_operand" "=u")
16852 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16853 "TARGET_USE_FANCY_MATH_387
16854 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16855 || TARGET_MIX_SSE_I387)
16856 && flag_unsafe_math_optimizations"
16858 [(set_attr "type" "fpspc")
16859 (set_attr "mode" "XF")])
16862 [(set (match_operand:XF 0 "register_operand" "")
16863 (unspec:XF [(float_extend:XF
16864 (match_operand:MODEF 2 "register_operand" ""))]
16865 UNSPEC_SINCOS_COS))
16866 (set (match_operand:XF 1 "register_operand" "")
16867 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16868 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16869 && !(reload_completed || reload_in_progress)"
16870 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16874 [(set (match_operand:XF 0 "register_operand" "")
16875 (unspec:XF [(float_extend:XF
16876 (match_operand:MODEF 2 "register_operand" ""))]
16877 UNSPEC_SINCOS_COS))
16878 (set (match_operand:XF 1 "register_operand" "")
16879 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16880 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16881 && !(reload_completed || reload_in_progress)"
16882 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16885 (define_expand "sincos<mode>3"
16886 [(use (match_operand:MODEF 0 "register_operand" ""))
16887 (use (match_operand:MODEF 1 "register_operand" ""))
16888 (use (match_operand:MODEF 2 "register_operand" ""))]
16889 "TARGET_USE_FANCY_MATH_387
16890 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16891 || TARGET_MIX_SSE_I387)
16892 && flag_unsafe_math_optimizations"
16894 rtx op0 = gen_reg_rtx (XFmode);
16895 rtx op1 = gen_reg_rtx (XFmode);
16897 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16898 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16899 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16903 (define_insn "fptanxf4_i387"
16904 [(set (match_operand:XF 0 "register_operand" "=f")
16905 (match_operand:XF 3 "const_double_operand" "F"))
16906 (set (match_operand:XF 1 "register_operand" "=u")
16907 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16909 "TARGET_USE_FANCY_MATH_387
16910 && flag_unsafe_math_optimizations
16911 && standard_80387_constant_p (operands[3]) == 2"
16913 [(set_attr "type" "fpspc")
16914 (set_attr "mode" "XF")])
16916 (define_insn "fptan_extend<mode>xf4_i387"
16917 [(set (match_operand:MODEF 0 "register_operand" "=f")
16918 (match_operand:MODEF 3 "const_double_operand" "F"))
16919 (set (match_operand:XF 1 "register_operand" "=u")
16920 (unspec:XF [(float_extend:XF
16921 (match_operand:MODEF 2 "register_operand" "0"))]
16923 "TARGET_USE_FANCY_MATH_387
16924 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16925 || TARGET_MIX_SSE_I387)
16926 && flag_unsafe_math_optimizations
16927 && standard_80387_constant_p (operands[3]) == 2"
16929 [(set_attr "type" "fpspc")
16930 (set_attr "mode" "XF")])
16932 (define_expand "tanxf2"
16933 [(use (match_operand:XF 0 "register_operand" ""))
16934 (use (match_operand:XF 1 "register_operand" ""))]
16935 "TARGET_USE_FANCY_MATH_387
16936 && flag_unsafe_math_optimizations"
16938 rtx one = gen_reg_rtx (XFmode);
16939 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16941 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16945 (define_expand "tan<mode>2"
16946 [(use (match_operand:MODEF 0 "register_operand" ""))
16947 (use (match_operand:MODEF 1 "register_operand" ""))]
16948 "TARGET_USE_FANCY_MATH_387
16949 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16950 || TARGET_MIX_SSE_I387)
16951 && flag_unsafe_math_optimizations"
16953 rtx op0 = gen_reg_rtx (XFmode);
16955 rtx one = gen_reg_rtx (<MODE>mode);
16956 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16958 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16959 operands[1], op2));
16960 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16964 (define_insn "*fpatanxf3_i387"
16965 [(set (match_operand:XF 0 "register_operand" "=f")
16966 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16967 (match_operand:XF 2 "register_operand" "u")]
16969 (clobber (match_scratch:XF 3 "=2"))]
16970 "TARGET_USE_FANCY_MATH_387
16971 && flag_unsafe_math_optimizations"
16973 [(set_attr "type" "fpspc")
16974 (set_attr "mode" "XF")])
16976 (define_insn "fpatan_extend<mode>xf3_i387"
16977 [(set (match_operand:XF 0 "register_operand" "=f")
16978 (unspec:XF [(float_extend:XF
16979 (match_operand:MODEF 1 "register_operand" "0"))
16981 (match_operand:MODEF 2 "register_operand" "u"))]
16983 (clobber (match_scratch:XF 3 "=2"))]
16984 "TARGET_USE_FANCY_MATH_387
16985 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16986 || TARGET_MIX_SSE_I387)
16987 && flag_unsafe_math_optimizations"
16989 [(set_attr "type" "fpspc")
16990 (set_attr "mode" "XF")])
16992 (define_expand "atan2xf3"
16993 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16994 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16995 (match_operand:XF 1 "register_operand" "")]
16997 (clobber (match_scratch:XF 3 ""))])]
16998 "TARGET_USE_FANCY_MATH_387
16999 && flag_unsafe_math_optimizations"
17002 (define_expand "atan2<mode>3"
17003 [(use (match_operand:MODEF 0 "register_operand" ""))
17004 (use (match_operand:MODEF 1 "register_operand" ""))
17005 (use (match_operand:MODEF 2 "register_operand" ""))]
17006 "TARGET_USE_FANCY_MATH_387
17007 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17008 || TARGET_MIX_SSE_I387)
17009 && flag_unsafe_math_optimizations"
17011 rtx op0 = gen_reg_rtx (XFmode);
17013 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17014 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17018 (define_expand "atanxf2"
17019 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17020 (unspec:XF [(match_dup 2)
17021 (match_operand:XF 1 "register_operand" "")]
17023 (clobber (match_scratch:XF 3 ""))])]
17024 "TARGET_USE_FANCY_MATH_387
17025 && flag_unsafe_math_optimizations"
17027 operands[2] = gen_reg_rtx (XFmode);
17028 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17031 (define_expand "atan<mode>2"
17032 [(use (match_operand:MODEF 0 "register_operand" ""))
17033 (use (match_operand:MODEF 1 "register_operand" ""))]
17034 "TARGET_USE_FANCY_MATH_387
17035 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17036 || TARGET_MIX_SSE_I387)
17037 && flag_unsafe_math_optimizations"
17039 rtx op0 = gen_reg_rtx (XFmode);
17041 rtx op2 = gen_reg_rtx (<MODE>mode);
17042 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17044 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17045 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17049 (define_expand "asinxf2"
17050 [(set (match_dup 2)
17051 (mult:XF (match_operand:XF 1 "register_operand" "")
17053 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17054 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17055 (parallel [(set (match_operand:XF 0 "register_operand" "")
17056 (unspec:XF [(match_dup 5) (match_dup 1)]
17058 (clobber (match_scratch:XF 6 ""))])]
17059 "TARGET_USE_FANCY_MATH_387
17060 && flag_unsafe_math_optimizations && !optimize_size"
17064 for (i = 2; i < 6; i++)
17065 operands[i] = gen_reg_rtx (XFmode);
17067 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17070 (define_expand "asin<mode>2"
17071 [(use (match_operand:MODEF 0 "register_operand" ""))
17072 (use (match_operand:MODEF 1 "general_operand" ""))]
17073 "TARGET_USE_FANCY_MATH_387
17074 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17075 || TARGET_MIX_SSE_I387)
17076 && flag_unsafe_math_optimizations && !optimize_size"
17078 rtx op0 = gen_reg_rtx (XFmode);
17079 rtx op1 = gen_reg_rtx (XFmode);
17081 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17082 emit_insn (gen_asinxf2 (op0, op1));
17083 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17087 (define_expand "acosxf2"
17088 [(set (match_dup 2)
17089 (mult:XF (match_operand:XF 1 "register_operand" "")
17091 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17092 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17093 (parallel [(set (match_operand:XF 0 "register_operand" "")
17094 (unspec:XF [(match_dup 1) (match_dup 5)]
17096 (clobber (match_scratch:XF 6 ""))])]
17097 "TARGET_USE_FANCY_MATH_387
17098 && flag_unsafe_math_optimizations && !optimize_size"
17102 for (i = 2; i < 6; i++)
17103 operands[i] = gen_reg_rtx (XFmode);
17105 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17108 (define_expand "acos<mode>2"
17109 [(use (match_operand:MODEF 0 "register_operand" ""))
17110 (use (match_operand:MODEF 1 "general_operand" ""))]
17111 "TARGET_USE_FANCY_MATH_387
17112 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17113 || TARGET_MIX_SSE_I387)
17114 && flag_unsafe_math_optimizations && !optimize_size"
17116 rtx op0 = gen_reg_rtx (XFmode);
17117 rtx op1 = gen_reg_rtx (XFmode);
17119 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17120 emit_insn (gen_acosxf2 (op0, op1));
17121 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17125 (define_insn "fyl2xxf3_i387"
17126 [(set (match_operand:XF 0 "register_operand" "=f")
17127 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17128 (match_operand:XF 2 "register_operand" "u")]
17130 (clobber (match_scratch:XF 3 "=2"))]
17131 "TARGET_USE_FANCY_MATH_387
17132 && flag_unsafe_math_optimizations"
17134 [(set_attr "type" "fpspc")
17135 (set_attr "mode" "XF")])
17137 (define_insn "fyl2x_extend<mode>xf3_i387"
17138 [(set (match_operand:XF 0 "register_operand" "=f")
17139 (unspec:XF [(float_extend:XF
17140 (match_operand:MODEF 1 "register_operand" "0"))
17141 (match_operand:XF 2 "register_operand" "u")]
17143 (clobber (match_scratch:XF 3 "=2"))]
17144 "TARGET_USE_FANCY_MATH_387
17145 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17146 || TARGET_MIX_SSE_I387)
17147 && flag_unsafe_math_optimizations"
17149 [(set_attr "type" "fpspc")
17150 (set_attr "mode" "XF")])
17152 (define_expand "logxf2"
17153 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17154 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17155 (match_dup 2)] UNSPEC_FYL2X))
17156 (clobber (match_scratch:XF 3 ""))])]
17157 "TARGET_USE_FANCY_MATH_387
17158 && flag_unsafe_math_optimizations"
17160 operands[2] = gen_reg_rtx (XFmode);
17161 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17164 (define_expand "log<mode>2"
17165 [(use (match_operand:MODEF 0 "register_operand" ""))
17166 (use (match_operand:MODEF 1 "register_operand" ""))]
17167 "TARGET_USE_FANCY_MATH_387
17168 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17169 || TARGET_MIX_SSE_I387)
17170 && flag_unsafe_math_optimizations"
17172 rtx op0 = gen_reg_rtx (XFmode);
17174 rtx op2 = gen_reg_rtx (XFmode);
17175 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17177 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17178 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17182 (define_expand "log10xf2"
17183 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17184 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17185 (match_dup 2)] UNSPEC_FYL2X))
17186 (clobber (match_scratch:XF 3 ""))])]
17187 "TARGET_USE_FANCY_MATH_387
17188 && flag_unsafe_math_optimizations"
17190 operands[2] = gen_reg_rtx (XFmode);
17191 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17194 (define_expand "log10<mode>2"
17195 [(use (match_operand:MODEF 0 "register_operand" ""))
17196 (use (match_operand:MODEF 1 "register_operand" ""))]
17197 "TARGET_USE_FANCY_MATH_387
17198 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17199 || TARGET_MIX_SSE_I387)
17200 && flag_unsafe_math_optimizations"
17202 rtx op0 = gen_reg_rtx (XFmode);
17204 rtx op2 = gen_reg_rtx (XFmode);
17205 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17207 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17208 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17212 (define_expand "log2xf2"
17213 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17214 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17215 (match_dup 2)] UNSPEC_FYL2X))
17216 (clobber (match_scratch:XF 3 ""))])]
17217 "TARGET_USE_FANCY_MATH_387
17218 && flag_unsafe_math_optimizations"
17220 operands[2] = gen_reg_rtx (XFmode);
17221 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17224 (define_expand "log2<mode>2"
17225 [(use (match_operand:MODEF 0 "register_operand" ""))
17226 (use (match_operand:MODEF 1 "register_operand" ""))]
17227 "TARGET_USE_FANCY_MATH_387
17228 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17229 || TARGET_MIX_SSE_I387)
17230 && flag_unsafe_math_optimizations"
17232 rtx op0 = gen_reg_rtx (XFmode);
17234 rtx op2 = gen_reg_rtx (XFmode);
17235 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17237 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17238 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17242 (define_insn "fyl2xp1xf3_i387"
17243 [(set (match_operand:XF 0 "register_operand" "=f")
17244 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17245 (match_operand:XF 2 "register_operand" "u")]
17247 (clobber (match_scratch:XF 3 "=2"))]
17248 "TARGET_USE_FANCY_MATH_387
17249 && flag_unsafe_math_optimizations"
17251 [(set_attr "type" "fpspc")
17252 (set_attr "mode" "XF")])
17254 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17255 [(set (match_operand:XF 0 "register_operand" "=f")
17256 (unspec:XF [(float_extend:XF
17257 (match_operand:MODEF 1 "register_operand" "0"))
17258 (match_operand:XF 2 "register_operand" "u")]
17260 (clobber (match_scratch:XF 3 "=2"))]
17261 "TARGET_USE_FANCY_MATH_387
17262 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17263 || TARGET_MIX_SSE_I387)
17264 && flag_unsafe_math_optimizations"
17266 [(set_attr "type" "fpspc")
17267 (set_attr "mode" "XF")])
17269 (define_expand "log1pxf2"
17270 [(use (match_operand:XF 0 "register_operand" ""))
17271 (use (match_operand:XF 1 "register_operand" ""))]
17272 "TARGET_USE_FANCY_MATH_387
17273 && flag_unsafe_math_optimizations && !optimize_size"
17275 ix86_emit_i387_log1p (operands[0], operands[1]);
17279 (define_expand "log1p<mode>2"
17280 [(use (match_operand:MODEF 0 "register_operand" ""))
17281 (use (match_operand:MODEF 1 "register_operand" ""))]
17282 "TARGET_USE_FANCY_MATH_387
17283 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17284 || TARGET_MIX_SSE_I387)
17285 && flag_unsafe_math_optimizations && !optimize_size"
17287 rtx op0 = gen_reg_rtx (XFmode);
17289 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17291 ix86_emit_i387_log1p (op0, operands[1]);
17292 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17296 (define_insn "fxtractxf3_i387"
17297 [(set (match_operand:XF 0 "register_operand" "=f")
17298 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17299 UNSPEC_XTRACT_FRACT))
17300 (set (match_operand:XF 1 "register_operand" "=u")
17301 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17302 "TARGET_USE_FANCY_MATH_387
17303 && flag_unsafe_math_optimizations"
17305 [(set_attr "type" "fpspc")
17306 (set_attr "mode" "XF")])
17308 (define_insn "fxtract_extend<mode>xf3_i387"
17309 [(set (match_operand:XF 0 "register_operand" "=f")
17310 (unspec:XF [(float_extend:XF
17311 (match_operand:MODEF 2 "register_operand" "0"))]
17312 UNSPEC_XTRACT_FRACT))
17313 (set (match_operand:XF 1 "register_operand" "=u")
17314 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17315 "TARGET_USE_FANCY_MATH_387
17316 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17317 || TARGET_MIX_SSE_I387)
17318 && flag_unsafe_math_optimizations"
17320 [(set_attr "type" "fpspc")
17321 (set_attr "mode" "XF")])
17323 (define_expand "logbxf2"
17324 [(parallel [(set (match_dup 2)
17325 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17326 UNSPEC_XTRACT_FRACT))
17327 (set (match_operand:XF 0 "register_operand" "")
17328 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17329 "TARGET_USE_FANCY_MATH_387
17330 && flag_unsafe_math_optimizations"
17332 operands[2] = gen_reg_rtx (XFmode);
17335 (define_expand "logb<mode>2"
17336 [(use (match_operand:MODEF 0 "register_operand" ""))
17337 (use (match_operand:MODEF 1 "register_operand" ""))]
17338 "TARGET_USE_FANCY_MATH_387
17339 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17340 || TARGET_MIX_SSE_I387)
17341 && flag_unsafe_math_optimizations"
17343 rtx op0 = gen_reg_rtx (XFmode);
17344 rtx op1 = gen_reg_rtx (XFmode);
17346 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17347 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17351 (define_expand "ilogbxf2"
17352 [(use (match_operand:SI 0 "register_operand" ""))
17353 (use (match_operand:XF 1 "register_operand" ""))]
17354 "TARGET_USE_FANCY_MATH_387
17355 && flag_unsafe_math_optimizations && !optimize_size"
17357 rtx op0 = gen_reg_rtx (XFmode);
17358 rtx op1 = gen_reg_rtx (XFmode);
17360 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17361 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17365 (define_expand "ilogb<mode>2"
17366 [(use (match_operand:SI 0 "register_operand" ""))
17367 (use (match_operand:MODEF 1 "register_operand" ""))]
17368 "TARGET_USE_FANCY_MATH_387
17369 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17370 || TARGET_MIX_SSE_I387)
17371 && flag_unsafe_math_optimizations && !optimize_size"
17373 rtx op0 = gen_reg_rtx (XFmode);
17374 rtx op1 = gen_reg_rtx (XFmode);
17376 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17377 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17381 (define_insn "*f2xm1xf2_i387"
17382 [(set (match_operand:XF 0 "register_operand" "=f")
17383 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17385 "TARGET_USE_FANCY_MATH_387
17386 && flag_unsafe_math_optimizations"
17388 [(set_attr "type" "fpspc")
17389 (set_attr "mode" "XF")])
17391 (define_insn "*fscalexf4_i387"
17392 [(set (match_operand:XF 0 "register_operand" "=f")
17393 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17394 (match_operand:XF 3 "register_operand" "1")]
17395 UNSPEC_FSCALE_FRACT))
17396 (set (match_operand:XF 1 "register_operand" "=u")
17397 (unspec:XF [(match_dup 2) (match_dup 3)]
17398 UNSPEC_FSCALE_EXP))]
17399 "TARGET_USE_FANCY_MATH_387
17400 && flag_unsafe_math_optimizations"
17402 [(set_attr "type" "fpspc")
17403 (set_attr "mode" "XF")])
17405 (define_expand "expNcorexf3"
17406 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17407 (match_operand:XF 2 "register_operand" "")))
17408 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17409 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17410 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17411 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17412 (parallel [(set (match_operand:XF 0 "register_operand" "")
17413 (unspec:XF [(match_dup 8) (match_dup 4)]
17414 UNSPEC_FSCALE_FRACT))
17416 (unspec:XF [(match_dup 8) (match_dup 4)]
17417 UNSPEC_FSCALE_EXP))])]
17418 "TARGET_USE_FANCY_MATH_387
17419 && flag_unsafe_math_optimizations && !optimize_size"
17423 for (i = 3; i < 10; i++)
17424 operands[i] = gen_reg_rtx (XFmode);
17426 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17429 (define_expand "expxf2"
17430 [(use (match_operand:XF 0 "register_operand" ""))
17431 (use (match_operand:XF 1 "register_operand" ""))]
17432 "TARGET_USE_FANCY_MATH_387
17433 && flag_unsafe_math_optimizations && !optimize_size"
17435 rtx op2 = gen_reg_rtx (XFmode);
17436 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17438 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17442 (define_expand "exp<mode>2"
17443 [(use (match_operand:MODEF 0 "register_operand" ""))
17444 (use (match_operand:MODEF 1 "general_operand" ""))]
17445 "TARGET_USE_FANCY_MATH_387
17446 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17447 || TARGET_MIX_SSE_I387)
17448 && flag_unsafe_math_optimizations && !optimize_size"
17450 rtx op0 = gen_reg_rtx (XFmode);
17451 rtx op1 = gen_reg_rtx (XFmode);
17453 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17454 emit_insn (gen_expxf2 (op0, op1));
17455 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17459 (define_expand "exp10xf2"
17460 [(use (match_operand:XF 0 "register_operand" ""))
17461 (use (match_operand:XF 1 "register_operand" ""))]
17462 "TARGET_USE_FANCY_MATH_387
17463 && flag_unsafe_math_optimizations && !optimize_size"
17465 rtx op2 = gen_reg_rtx (XFmode);
17466 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17468 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17472 (define_expand "exp10<mode>2"
17473 [(use (match_operand:MODEF 0 "register_operand" ""))
17474 (use (match_operand:MODEF 1 "general_operand" ""))]
17475 "TARGET_USE_FANCY_MATH_387
17476 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17477 || TARGET_MIX_SSE_I387)
17478 && flag_unsafe_math_optimizations && !optimize_size"
17480 rtx op0 = gen_reg_rtx (XFmode);
17481 rtx op1 = gen_reg_rtx (XFmode);
17483 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17484 emit_insn (gen_exp10xf2 (op0, op1));
17485 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17489 (define_expand "exp2xf2"
17490 [(use (match_operand:XF 0 "register_operand" ""))
17491 (use (match_operand:XF 1 "register_operand" ""))]
17492 "TARGET_USE_FANCY_MATH_387
17493 && flag_unsafe_math_optimizations && !optimize_size"
17495 rtx op2 = gen_reg_rtx (XFmode);
17496 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17498 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17502 (define_expand "exp2<mode>2"
17503 [(use (match_operand:MODEF 0 "register_operand" ""))
17504 (use (match_operand:MODEF 1 "general_operand" ""))]
17505 "TARGET_USE_FANCY_MATH_387
17506 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17507 || TARGET_MIX_SSE_I387)
17508 && flag_unsafe_math_optimizations && !optimize_size"
17510 rtx op0 = gen_reg_rtx (XFmode);
17511 rtx op1 = gen_reg_rtx (XFmode);
17513 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17514 emit_insn (gen_exp2xf2 (op0, op1));
17515 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17519 (define_expand "expm1xf2"
17520 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17522 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17523 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17524 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17525 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17526 (parallel [(set (match_dup 7)
17527 (unspec:XF [(match_dup 6) (match_dup 4)]
17528 UNSPEC_FSCALE_FRACT))
17530 (unspec:XF [(match_dup 6) (match_dup 4)]
17531 UNSPEC_FSCALE_EXP))])
17532 (parallel [(set (match_dup 10)
17533 (unspec:XF [(match_dup 9) (match_dup 8)]
17534 UNSPEC_FSCALE_FRACT))
17535 (set (match_dup 11)
17536 (unspec:XF [(match_dup 9) (match_dup 8)]
17537 UNSPEC_FSCALE_EXP))])
17538 (set (match_dup 12) (minus:XF (match_dup 10)
17539 (float_extend:XF (match_dup 13))))
17540 (set (match_operand:XF 0 "register_operand" "")
17541 (plus:XF (match_dup 12) (match_dup 7)))]
17542 "TARGET_USE_FANCY_MATH_387
17543 && flag_unsafe_math_optimizations && !optimize_size"
17547 for (i = 2; i < 13; i++)
17548 operands[i] = gen_reg_rtx (XFmode);
17551 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17553 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17556 (define_expand "expm1<mode>2"
17557 [(use (match_operand:MODEF 0 "register_operand" ""))
17558 (use (match_operand:MODEF 1 "general_operand" ""))]
17559 "TARGET_USE_FANCY_MATH_387
17560 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17561 || TARGET_MIX_SSE_I387)
17562 && flag_unsafe_math_optimizations && !optimize_size"
17564 rtx op0 = gen_reg_rtx (XFmode);
17565 rtx op1 = gen_reg_rtx (XFmode);
17567 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17568 emit_insn (gen_expm1xf2 (op0, op1));
17569 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17573 (define_expand "ldexpxf3"
17574 [(set (match_dup 3)
17575 (float:XF (match_operand:SI 2 "register_operand" "")))
17576 (parallel [(set (match_operand:XF 0 " register_operand" "")
17577 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17579 UNSPEC_FSCALE_FRACT))
17581 (unspec:XF [(match_dup 1) (match_dup 3)]
17582 UNSPEC_FSCALE_EXP))])]
17583 "TARGET_USE_FANCY_MATH_387
17584 && flag_unsafe_math_optimizations && !optimize_size"
17586 operands[3] = gen_reg_rtx (XFmode);
17587 operands[4] = gen_reg_rtx (XFmode);
17590 (define_expand "ldexp<mode>3"
17591 [(use (match_operand:MODEF 0 "register_operand" ""))
17592 (use (match_operand:MODEF 1 "general_operand" ""))
17593 (use (match_operand:SI 2 "register_operand" ""))]
17594 "TARGET_USE_FANCY_MATH_387
17595 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17596 || TARGET_MIX_SSE_I387)
17597 && flag_unsafe_math_optimizations && !optimize_size"
17599 rtx op0 = gen_reg_rtx (XFmode);
17600 rtx op1 = gen_reg_rtx (XFmode);
17602 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17603 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17604 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17608 (define_expand "scalbxf3"
17609 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17610 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17611 (match_operand:XF 2 "register_operand" "")]
17612 UNSPEC_FSCALE_FRACT))
17614 (unspec:XF [(match_dup 1) (match_dup 2)]
17615 UNSPEC_FSCALE_EXP))])]
17616 "TARGET_USE_FANCY_MATH_387
17617 && flag_unsafe_math_optimizations && !optimize_size"
17619 operands[3] = gen_reg_rtx (XFmode);
17622 (define_expand "scalb<mode>3"
17623 [(use (match_operand:MODEF 0 "register_operand" ""))
17624 (use (match_operand:MODEF 1 "general_operand" ""))
17625 (use (match_operand:MODEF 2 "register_operand" ""))]
17626 "TARGET_USE_FANCY_MATH_387
17627 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17628 || TARGET_MIX_SSE_I387)
17629 && flag_unsafe_math_optimizations && !optimize_size"
17631 rtx op0 = gen_reg_rtx (XFmode);
17632 rtx op1 = gen_reg_rtx (XFmode);
17633 rtx op2 = gen_reg_rtx (XFmode);
17635 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17636 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17637 emit_insn (gen_scalbxf3 (op0, op1, op2));
17638 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17643 (define_insn "sse4_1_round<mode>2"
17644 [(set (match_operand:MODEF 0 "register_operand" "=x")
17645 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17646 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17649 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17650 [(set_attr "type" "ssecvt")
17651 (set_attr "prefix_extra" "1")
17652 (set_attr "mode" "<MODE>")])
17654 (define_insn "rintxf2"
17655 [(set (match_operand:XF 0 "register_operand" "=f")
17656 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17658 "TARGET_USE_FANCY_MATH_387
17659 && flag_unsafe_math_optimizations"
17661 [(set_attr "type" "fpspc")
17662 (set_attr "mode" "XF")])
17664 (define_expand "rint<mode>2"
17665 [(use (match_operand:MODEF 0 "register_operand" ""))
17666 (use (match_operand:MODEF 1 "register_operand" ""))]
17667 "(TARGET_USE_FANCY_MATH_387
17668 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17669 || TARGET_MIX_SSE_I387)
17670 && flag_unsafe_math_optimizations)
17671 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17672 && !flag_trapping_math
17673 && (TARGET_SSE4_1 || !optimize_size))"
17675 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17676 && !flag_trapping_math
17677 && (TARGET_SSE4_1 || !optimize_size))
17680 emit_insn (gen_sse4_1_round<mode>2
17681 (operands[0], operands[1], GEN_INT (0x04)));
17683 ix86_expand_rint (operand0, operand1);
17687 rtx op0 = gen_reg_rtx (XFmode);
17688 rtx op1 = gen_reg_rtx (XFmode);
17690 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17691 emit_insn (gen_rintxf2 (op0, op1));
17693 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17698 (define_expand "round<mode>2"
17699 [(match_operand:MODEF 0 "register_operand" "")
17700 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17701 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17702 && !flag_trapping_math && !flag_rounding_math
17705 if (TARGET_64BIT || (<MODE>mode != DFmode))
17706 ix86_expand_round (operand0, operand1);
17708 ix86_expand_rounddf_32 (operand0, operand1);
17712 (define_insn_and_split "*fistdi2_1"
17713 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17714 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17716 "TARGET_USE_FANCY_MATH_387
17717 && !(reload_completed || reload_in_progress)"
17722 if (memory_operand (operands[0], VOIDmode))
17723 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17726 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17727 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17732 [(set_attr "type" "fpspc")
17733 (set_attr "mode" "DI")])
17735 (define_insn "fistdi2"
17736 [(set (match_operand:DI 0 "memory_operand" "=m")
17737 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17739 (clobber (match_scratch:XF 2 "=&1f"))]
17740 "TARGET_USE_FANCY_MATH_387"
17741 "* return output_fix_trunc (insn, operands, 0);"
17742 [(set_attr "type" "fpspc")
17743 (set_attr "mode" "DI")])
17745 (define_insn "fistdi2_with_temp"
17746 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17747 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17749 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17750 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17751 "TARGET_USE_FANCY_MATH_387"
17753 [(set_attr "type" "fpspc")
17754 (set_attr "mode" "DI")])
17757 [(set (match_operand:DI 0 "register_operand" "")
17758 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17760 (clobber (match_operand:DI 2 "memory_operand" ""))
17761 (clobber (match_scratch 3 ""))]
17763 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17764 (clobber (match_dup 3))])
17765 (set (match_dup 0) (match_dup 2))]
17769 [(set (match_operand:DI 0 "memory_operand" "")
17770 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17772 (clobber (match_operand:DI 2 "memory_operand" ""))
17773 (clobber (match_scratch 3 ""))]
17775 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17776 (clobber (match_dup 3))])]
17779 (define_insn_and_split "*fist<mode>2_1"
17780 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17781 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17783 "TARGET_USE_FANCY_MATH_387
17784 && !(reload_completed || reload_in_progress)"
17789 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17790 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17794 [(set_attr "type" "fpspc")
17795 (set_attr "mode" "<MODE>")])
17797 (define_insn "fist<mode>2"
17798 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17799 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17801 "TARGET_USE_FANCY_MATH_387"
17802 "* return output_fix_trunc (insn, operands, 0);"
17803 [(set_attr "type" "fpspc")
17804 (set_attr "mode" "<MODE>")])
17806 (define_insn "fist<mode>2_with_temp"
17807 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17808 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17810 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17811 "TARGET_USE_FANCY_MATH_387"
17813 [(set_attr "type" "fpspc")
17814 (set_attr "mode" "<MODE>")])
17817 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17818 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17820 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17822 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17823 (set (match_dup 0) (match_dup 2))]
17827 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17828 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17830 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17832 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17835 (define_expand "lrintxf<mode>2"
17836 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17837 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17839 "TARGET_USE_FANCY_MATH_387"
17842 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17843 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17844 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17845 UNSPEC_FIX_NOTRUNC))]
17846 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17847 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17850 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17851 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17852 (match_operand:MODEF 1 "register_operand" "")]
17853 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17854 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17855 && !flag_trapping_math && !flag_rounding_math
17858 ix86_expand_lround (operand0, operand1);
17862 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17863 (define_insn_and_split "frndintxf2_floor"
17864 [(set (match_operand:XF 0 "register_operand" "")
17865 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17866 UNSPEC_FRNDINT_FLOOR))
17867 (clobber (reg:CC FLAGS_REG))]
17868 "TARGET_USE_FANCY_MATH_387
17869 && flag_unsafe_math_optimizations
17870 && !(reload_completed || reload_in_progress)"
17875 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17877 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17878 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17880 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17881 operands[2], operands[3]));
17884 [(set_attr "type" "frndint")
17885 (set_attr "i387_cw" "floor")
17886 (set_attr "mode" "XF")])
17888 (define_insn "frndintxf2_floor_i387"
17889 [(set (match_operand:XF 0 "register_operand" "=f")
17890 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17891 UNSPEC_FRNDINT_FLOOR))
17892 (use (match_operand:HI 2 "memory_operand" "m"))
17893 (use (match_operand:HI 3 "memory_operand" "m"))]
17894 "TARGET_USE_FANCY_MATH_387
17895 && flag_unsafe_math_optimizations"
17896 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17897 [(set_attr "type" "frndint")
17898 (set_attr "i387_cw" "floor")
17899 (set_attr "mode" "XF")])
17901 (define_expand "floorxf2"
17902 [(use (match_operand:XF 0 "register_operand" ""))
17903 (use (match_operand:XF 1 "register_operand" ""))]
17904 "TARGET_USE_FANCY_MATH_387
17905 && flag_unsafe_math_optimizations && !optimize_size"
17907 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17911 (define_expand "floor<mode>2"
17912 [(use (match_operand:MODEF 0 "register_operand" ""))
17913 (use (match_operand:MODEF 1 "register_operand" ""))]
17914 "(TARGET_USE_FANCY_MATH_387
17915 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17916 || TARGET_MIX_SSE_I387)
17917 && flag_unsafe_math_optimizations && !optimize_size)
17918 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17919 && !flag_trapping_math
17920 && (TARGET_SSE4_1 || !optimize_size))"
17922 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17923 && !flag_trapping_math
17924 && (TARGET_SSE4_1 || !optimize_size))
17927 emit_insn (gen_sse4_1_round<mode>2
17928 (operands[0], operands[1], GEN_INT (0x01)));
17929 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17930 ix86_expand_floorceil (operand0, operand1, true);
17932 ix86_expand_floorceildf_32 (operand0, operand1, true);
17936 rtx op0 = gen_reg_rtx (XFmode);
17937 rtx op1 = gen_reg_rtx (XFmode);
17939 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17940 emit_insn (gen_frndintxf2_floor (op0, op1));
17942 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17947 (define_insn_and_split "*fist<mode>2_floor_1"
17948 [(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 && flag_unsafe_math_optimizations
17954 && !(reload_completed || reload_in_progress)"
17959 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17961 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17962 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17963 if (memory_operand (operands[0], VOIDmode))
17964 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17965 operands[2], operands[3]));
17968 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17969 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17970 operands[2], operands[3],
17975 [(set_attr "type" "fistp")
17976 (set_attr "i387_cw" "floor")
17977 (set_attr "mode" "<MODE>")])
17979 (define_insn "fistdi2_floor"
17980 [(set (match_operand:DI 0 "memory_operand" "=m")
17981 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17982 UNSPEC_FIST_FLOOR))
17983 (use (match_operand:HI 2 "memory_operand" "m"))
17984 (use (match_operand:HI 3 "memory_operand" "m"))
17985 (clobber (match_scratch:XF 4 "=&1f"))]
17986 "TARGET_USE_FANCY_MATH_387
17987 && flag_unsafe_math_optimizations"
17988 "* return output_fix_trunc (insn, operands, 0);"
17989 [(set_attr "type" "fistp")
17990 (set_attr "i387_cw" "floor")
17991 (set_attr "mode" "DI")])
17993 (define_insn "fistdi2_floor_with_temp"
17994 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17995 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17996 UNSPEC_FIST_FLOOR))
17997 (use (match_operand:HI 2 "memory_operand" "m,m"))
17998 (use (match_operand:HI 3 "memory_operand" "m,m"))
17999 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18000 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18001 "TARGET_USE_FANCY_MATH_387
18002 && flag_unsafe_math_optimizations"
18004 [(set_attr "type" "fistp")
18005 (set_attr "i387_cw" "floor")
18006 (set_attr "mode" "DI")])
18009 [(set (match_operand:DI 0 "register_operand" "")
18010 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18011 UNSPEC_FIST_FLOOR))
18012 (use (match_operand:HI 2 "memory_operand" ""))
18013 (use (match_operand:HI 3 "memory_operand" ""))
18014 (clobber (match_operand:DI 4 "memory_operand" ""))
18015 (clobber (match_scratch 5 ""))]
18017 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18018 (use (match_dup 2))
18019 (use (match_dup 3))
18020 (clobber (match_dup 5))])
18021 (set (match_dup 0) (match_dup 4))]
18025 [(set (match_operand:DI 0 "memory_operand" "")
18026 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18027 UNSPEC_FIST_FLOOR))
18028 (use (match_operand:HI 2 "memory_operand" ""))
18029 (use (match_operand:HI 3 "memory_operand" ""))
18030 (clobber (match_operand:DI 4 "memory_operand" ""))
18031 (clobber (match_scratch 5 ""))]
18033 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18034 (use (match_dup 2))
18035 (use (match_dup 3))
18036 (clobber (match_dup 5))])]
18039 (define_insn "fist<mode>2_floor"
18040 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18041 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18042 UNSPEC_FIST_FLOOR))
18043 (use (match_operand:HI 2 "memory_operand" "m"))
18044 (use (match_operand:HI 3 "memory_operand" "m"))]
18045 "TARGET_USE_FANCY_MATH_387
18046 && flag_unsafe_math_optimizations"
18047 "* return output_fix_trunc (insn, operands, 0);"
18048 [(set_attr "type" "fistp")
18049 (set_attr "i387_cw" "floor")
18050 (set_attr "mode" "<MODE>")])
18052 (define_insn "fist<mode>2_floor_with_temp"
18053 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18054 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18055 UNSPEC_FIST_FLOOR))
18056 (use (match_operand:HI 2 "memory_operand" "m,m"))
18057 (use (match_operand:HI 3 "memory_operand" "m,m"))
18058 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18059 "TARGET_USE_FANCY_MATH_387
18060 && flag_unsafe_math_optimizations"
18062 [(set_attr "type" "fistp")
18063 (set_attr "i387_cw" "floor")
18064 (set_attr "mode" "<MODE>")])
18067 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18068 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18069 UNSPEC_FIST_FLOOR))
18070 (use (match_operand:HI 2 "memory_operand" ""))
18071 (use (match_operand:HI 3 "memory_operand" ""))
18072 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18074 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18075 UNSPEC_FIST_FLOOR))
18076 (use (match_dup 2))
18077 (use (match_dup 3))])
18078 (set (match_dup 0) (match_dup 4))]
18082 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18083 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18084 UNSPEC_FIST_FLOOR))
18085 (use (match_operand:HI 2 "memory_operand" ""))
18086 (use (match_operand:HI 3 "memory_operand" ""))
18087 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18089 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18090 UNSPEC_FIST_FLOOR))
18091 (use (match_dup 2))
18092 (use (match_dup 3))])]
18095 (define_expand "lfloorxf<mode>2"
18096 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18097 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18098 UNSPEC_FIST_FLOOR))
18099 (clobber (reg:CC FLAGS_REG))])]
18100 "TARGET_USE_FANCY_MATH_387
18101 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18102 && flag_unsafe_math_optimizations"
18105 (define_expand "lfloor<mode>di2"
18106 [(match_operand:DI 0 "nonimmediate_operand" "")
18107 (match_operand:MODEF 1 "register_operand" "")]
18108 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18109 && !flag_trapping_math
18112 ix86_expand_lfloorceil (operand0, operand1, true);
18116 (define_expand "lfloor<mode>si2"
18117 [(match_operand:SI 0 "nonimmediate_operand" "")
18118 (match_operand:MODEF 1 "register_operand" "")]
18119 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18120 && !flag_trapping_math
18121 && (!optimize_size || !TARGET_64BIT)"
18123 ix86_expand_lfloorceil (operand0, operand1, true);
18127 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18128 (define_insn_and_split "frndintxf2_ceil"
18129 [(set (match_operand:XF 0 "register_operand" "")
18130 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18131 UNSPEC_FRNDINT_CEIL))
18132 (clobber (reg:CC FLAGS_REG))]
18133 "TARGET_USE_FANCY_MATH_387
18134 && flag_unsafe_math_optimizations
18135 && !(reload_completed || reload_in_progress)"
18140 ix86_optimize_mode_switching[I387_CEIL] = 1;
18142 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18143 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18145 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18146 operands[2], operands[3]));
18149 [(set_attr "type" "frndint")
18150 (set_attr "i387_cw" "ceil")
18151 (set_attr "mode" "XF")])
18153 (define_insn "frndintxf2_ceil_i387"
18154 [(set (match_operand:XF 0 "register_operand" "=f")
18155 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18156 UNSPEC_FRNDINT_CEIL))
18157 (use (match_operand:HI 2 "memory_operand" "m"))
18158 (use (match_operand:HI 3 "memory_operand" "m"))]
18159 "TARGET_USE_FANCY_MATH_387
18160 && flag_unsafe_math_optimizations"
18161 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18162 [(set_attr "type" "frndint")
18163 (set_attr "i387_cw" "ceil")
18164 (set_attr "mode" "XF")])
18166 (define_expand "ceilxf2"
18167 [(use (match_operand:XF 0 "register_operand" ""))
18168 (use (match_operand:XF 1 "register_operand" ""))]
18169 "TARGET_USE_FANCY_MATH_387
18170 && flag_unsafe_math_optimizations && !optimize_size"
18172 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18176 (define_expand "ceil<mode>2"
18177 [(use (match_operand:MODEF 0 "register_operand" ""))
18178 (use (match_operand:MODEF 1 "register_operand" ""))]
18179 "(TARGET_USE_FANCY_MATH_387
18180 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18181 || TARGET_MIX_SSE_I387)
18182 && flag_unsafe_math_optimizations && !optimize_size)
18183 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18184 && !flag_trapping_math
18185 && (TARGET_SSE4_1 || !optimize_size))"
18187 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18188 && !flag_trapping_math
18189 && (TARGET_SSE4_1 || !optimize_size))
18192 emit_insn (gen_sse4_1_round<mode>2
18193 (operands[0], operands[1], GEN_INT (0x02)));
18194 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18195 ix86_expand_floorceil (operand0, operand1, false);
18197 ix86_expand_floorceildf_32 (operand0, operand1, false);
18201 rtx op0 = gen_reg_rtx (XFmode);
18202 rtx op1 = gen_reg_rtx (XFmode);
18204 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18205 emit_insn (gen_frndintxf2_ceil (op0, op1));
18207 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18212 (define_insn_and_split "*fist<mode>2_ceil_1"
18213 [(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 && flag_unsafe_math_optimizations
18219 && !(reload_completed || reload_in_progress)"
18224 ix86_optimize_mode_switching[I387_CEIL] = 1;
18226 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18227 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18228 if (memory_operand (operands[0], VOIDmode))
18229 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18230 operands[2], operands[3]));
18233 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18234 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18235 operands[2], operands[3],
18240 [(set_attr "type" "fistp")
18241 (set_attr "i387_cw" "ceil")
18242 (set_attr "mode" "<MODE>")])
18244 (define_insn "fistdi2_ceil"
18245 [(set (match_operand:DI 0 "memory_operand" "=m")
18246 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18248 (use (match_operand:HI 2 "memory_operand" "m"))
18249 (use (match_operand:HI 3 "memory_operand" "m"))
18250 (clobber (match_scratch:XF 4 "=&1f"))]
18251 "TARGET_USE_FANCY_MATH_387
18252 && flag_unsafe_math_optimizations"
18253 "* return output_fix_trunc (insn, operands, 0);"
18254 [(set_attr "type" "fistp")
18255 (set_attr "i387_cw" "ceil")
18256 (set_attr "mode" "DI")])
18258 (define_insn "fistdi2_ceil_with_temp"
18259 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18260 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18262 (use (match_operand:HI 2 "memory_operand" "m,m"))
18263 (use (match_operand:HI 3 "memory_operand" "m,m"))
18264 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
18265 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18266 "TARGET_USE_FANCY_MATH_387
18267 && flag_unsafe_math_optimizations"
18269 [(set_attr "type" "fistp")
18270 (set_attr "i387_cw" "ceil")
18271 (set_attr "mode" "DI")])
18274 [(set (match_operand:DI 0 "register_operand" "")
18275 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18277 (use (match_operand:HI 2 "memory_operand" ""))
18278 (use (match_operand:HI 3 "memory_operand" ""))
18279 (clobber (match_operand:DI 4 "memory_operand" ""))
18280 (clobber (match_scratch 5 ""))]
18282 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18283 (use (match_dup 2))
18284 (use (match_dup 3))
18285 (clobber (match_dup 5))])
18286 (set (match_dup 0) (match_dup 4))]
18290 [(set (match_operand:DI 0 "memory_operand" "")
18291 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18293 (use (match_operand:HI 2 "memory_operand" ""))
18294 (use (match_operand:HI 3 "memory_operand" ""))
18295 (clobber (match_operand:DI 4 "memory_operand" ""))
18296 (clobber (match_scratch 5 ""))]
18298 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18299 (use (match_dup 2))
18300 (use (match_dup 3))
18301 (clobber (match_dup 5))])]
18304 (define_insn "fist<mode>2_ceil"
18305 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18306 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18308 (use (match_operand:HI 2 "memory_operand" "m"))
18309 (use (match_operand:HI 3 "memory_operand" "m"))]
18310 "TARGET_USE_FANCY_MATH_387
18311 && flag_unsafe_math_optimizations"
18312 "* return output_fix_trunc (insn, operands, 0);"
18313 [(set_attr "type" "fistp")
18314 (set_attr "i387_cw" "ceil")
18315 (set_attr "mode" "<MODE>")])
18317 (define_insn "fist<mode>2_ceil_with_temp"
18318 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18319 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18321 (use (match_operand:HI 2 "memory_operand" "m,m"))
18322 (use (match_operand:HI 3 "memory_operand" "m,m"))
18323 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18324 "TARGET_USE_FANCY_MATH_387
18325 && flag_unsafe_math_optimizations"
18327 [(set_attr "type" "fistp")
18328 (set_attr "i387_cw" "ceil")
18329 (set_attr "mode" "<MODE>")])
18332 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18333 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18335 (use (match_operand:HI 2 "memory_operand" ""))
18336 (use (match_operand:HI 3 "memory_operand" ""))
18337 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18339 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18341 (use (match_dup 2))
18342 (use (match_dup 3))])
18343 (set (match_dup 0) (match_dup 4))]
18347 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18348 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18350 (use (match_operand:HI 2 "memory_operand" ""))
18351 (use (match_operand:HI 3 "memory_operand" ""))
18352 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18354 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18356 (use (match_dup 2))
18357 (use (match_dup 3))])]
18360 (define_expand "lceilxf<mode>2"
18361 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18362 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18364 (clobber (reg:CC FLAGS_REG))])]
18365 "TARGET_USE_FANCY_MATH_387
18366 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18367 && flag_unsafe_math_optimizations"
18370 (define_expand "lceil<mode>di2"
18371 [(match_operand:DI 0 "nonimmediate_operand" "")
18372 (match_operand:MODEF 1 "register_operand" "")]
18373 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18374 && !flag_trapping_math"
18376 ix86_expand_lfloorceil (operand0, operand1, false);
18380 (define_expand "lceil<mode>si2"
18381 [(match_operand:SI 0 "nonimmediate_operand" "")
18382 (match_operand:MODEF 1 "register_operand" "")]
18383 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18384 && !flag_trapping_math"
18386 ix86_expand_lfloorceil (operand0, operand1, false);
18390 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18391 (define_insn_and_split "frndintxf2_trunc"
18392 [(set (match_operand:XF 0 "register_operand" "")
18393 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18394 UNSPEC_FRNDINT_TRUNC))
18395 (clobber (reg:CC FLAGS_REG))]
18396 "TARGET_USE_FANCY_MATH_387
18397 && flag_unsafe_math_optimizations
18398 && !(reload_completed || reload_in_progress)"
18403 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18405 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18406 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18408 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18409 operands[2], operands[3]));
18412 [(set_attr "type" "frndint")
18413 (set_attr "i387_cw" "trunc")
18414 (set_attr "mode" "XF")])
18416 (define_insn "frndintxf2_trunc_i387"
18417 [(set (match_operand:XF 0 "register_operand" "=f")
18418 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18419 UNSPEC_FRNDINT_TRUNC))
18420 (use (match_operand:HI 2 "memory_operand" "m"))
18421 (use (match_operand:HI 3 "memory_operand" "m"))]
18422 "TARGET_USE_FANCY_MATH_387
18423 && flag_unsafe_math_optimizations"
18424 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18425 [(set_attr "type" "frndint")
18426 (set_attr "i387_cw" "trunc")
18427 (set_attr "mode" "XF")])
18429 (define_expand "btruncxf2"
18430 [(use (match_operand:XF 0 "register_operand" ""))
18431 (use (match_operand:XF 1 "register_operand" ""))]
18432 "TARGET_USE_FANCY_MATH_387
18433 && flag_unsafe_math_optimizations && !optimize_size"
18435 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18439 (define_expand "btrunc<mode>2"
18440 [(use (match_operand:MODEF 0 "register_operand" ""))
18441 (use (match_operand:MODEF 1 "register_operand" ""))]
18442 "(TARGET_USE_FANCY_MATH_387
18443 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18444 || TARGET_MIX_SSE_I387)
18445 && flag_unsafe_math_optimizations && !optimize_size)
18446 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18447 && !flag_trapping_math
18448 && (TARGET_SSE4_1 || !optimize_size))"
18450 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18451 && !flag_trapping_math
18452 && (TARGET_SSE4_1 || !optimize_size))
18455 emit_insn (gen_sse4_1_round<mode>2
18456 (operands[0], operands[1], GEN_INT (0x03)));
18457 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18458 ix86_expand_trunc (operand0, operand1);
18460 ix86_expand_truncdf_32 (operand0, operand1);
18464 rtx op0 = gen_reg_rtx (XFmode);
18465 rtx op1 = gen_reg_rtx (XFmode);
18467 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18468 emit_insn (gen_frndintxf2_trunc (op0, op1));
18470 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18475 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18476 (define_insn_and_split "frndintxf2_mask_pm"
18477 [(set (match_operand:XF 0 "register_operand" "")
18478 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18479 UNSPEC_FRNDINT_MASK_PM))
18480 (clobber (reg:CC FLAGS_REG))]
18481 "TARGET_USE_FANCY_MATH_387
18482 && flag_unsafe_math_optimizations
18483 && !(reload_completed || reload_in_progress)"
18488 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18490 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18491 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18493 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18494 operands[2], operands[3]));
18497 [(set_attr "type" "frndint")
18498 (set_attr "i387_cw" "mask_pm")
18499 (set_attr "mode" "XF")])
18501 (define_insn "frndintxf2_mask_pm_i387"
18502 [(set (match_operand:XF 0 "register_operand" "=f")
18503 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18504 UNSPEC_FRNDINT_MASK_PM))
18505 (use (match_operand:HI 2 "memory_operand" "m"))
18506 (use (match_operand:HI 3 "memory_operand" "m"))]
18507 "TARGET_USE_FANCY_MATH_387
18508 && flag_unsafe_math_optimizations"
18509 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18510 [(set_attr "type" "frndint")
18511 (set_attr "i387_cw" "mask_pm")
18512 (set_attr "mode" "XF")])
18514 (define_expand "nearbyintxf2"
18515 [(use (match_operand:XF 0 "register_operand" ""))
18516 (use (match_operand:XF 1 "register_operand" ""))]
18517 "TARGET_USE_FANCY_MATH_387
18518 && flag_unsafe_math_optimizations"
18520 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18525 (define_expand "nearbyint<mode>2"
18526 [(use (match_operand:MODEF 0 "register_operand" ""))
18527 (use (match_operand:MODEF 1 "register_operand" ""))]
18528 "TARGET_USE_FANCY_MATH_387
18529 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18530 || TARGET_MIX_SSE_I387)
18531 && flag_unsafe_math_optimizations"
18533 rtx op0 = gen_reg_rtx (XFmode);
18534 rtx op1 = gen_reg_rtx (XFmode);
18536 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18537 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18539 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18543 (define_insn "fxam<mode>2_i387"
18544 [(set (match_operand:HI 0 "register_operand" "=a")
18546 [(match_operand:X87MODEF 1 "register_operand" "f")]
18548 "TARGET_USE_FANCY_MATH_387"
18549 "fxam\n\tfnstsw\t%0"
18550 [(set_attr "type" "multi")
18551 (set_attr "unit" "i387")
18552 (set_attr "mode" "<MODE>")])
18554 (define_expand "isinf<mode>2"
18555 [(use (match_operand:SI 0 "register_operand" ""))
18556 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18557 "TARGET_USE_FANCY_MATH_387
18558 && TARGET_C99_FUNCTIONS
18559 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18561 rtx mask = GEN_INT (0x45);
18562 rtx val = GEN_INT (0x05);
18566 rtx scratch = gen_reg_rtx (HImode);
18567 rtx res = gen_reg_rtx (QImode);
18569 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18570 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18571 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18572 cond = gen_rtx_fmt_ee (EQ, QImode,
18573 gen_rtx_REG (CCmode, FLAGS_REG),
18575 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18576 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18580 (define_expand "signbit<mode>2"
18581 [(use (match_operand:SI 0 "register_operand" ""))
18582 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18583 "TARGET_USE_FANCY_MATH_387
18584 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18586 rtx mask = GEN_INT (0x0200);
18588 rtx scratch = gen_reg_rtx (HImode);
18590 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18591 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18595 ;; Block operation instructions
18597 (define_expand "movmemsi"
18598 [(use (match_operand:BLK 0 "memory_operand" ""))
18599 (use (match_operand:BLK 1 "memory_operand" ""))
18600 (use (match_operand:SI 2 "nonmemory_operand" ""))
18601 (use (match_operand:SI 3 "const_int_operand" ""))
18602 (use (match_operand:SI 4 "const_int_operand" ""))
18603 (use (match_operand:SI 5 "const_int_operand" ""))]
18606 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18607 operands[4], operands[5]))
18613 (define_expand "movmemdi"
18614 [(use (match_operand:BLK 0 "memory_operand" ""))
18615 (use (match_operand:BLK 1 "memory_operand" ""))
18616 (use (match_operand:DI 2 "nonmemory_operand" ""))
18617 (use (match_operand:DI 3 "const_int_operand" ""))
18618 (use (match_operand:SI 4 "const_int_operand" ""))
18619 (use (match_operand:SI 5 "const_int_operand" ""))]
18622 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18623 operands[4], operands[5]))
18629 ;; Most CPUs don't like single string operations
18630 ;; Handle this case here to simplify previous expander.
18632 (define_expand "strmov"
18633 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18634 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18635 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18636 (clobber (reg:CC FLAGS_REG))])
18637 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18638 (clobber (reg:CC FLAGS_REG))])]
18641 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18643 /* If .md ever supports :P for Pmode, these can be directly
18644 in the pattern above. */
18645 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18646 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18648 if (TARGET_SINGLE_STRINGOP || optimize_size)
18650 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18651 operands[2], operands[3],
18652 operands[5], operands[6]));
18656 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18659 (define_expand "strmov_singleop"
18660 [(parallel [(set (match_operand 1 "memory_operand" "")
18661 (match_operand 3 "memory_operand" ""))
18662 (set (match_operand 0 "register_operand" "")
18663 (match_operand 4 "" ""))
18664 (set (match_operand 2 "register_operand" "")
18665 (match_operand 5 "" ""))])]
18666 "TARGET_SINGLE_STRINGOP || optimize_size"
18669 (define_insn "*strmovdi_rex_1"
18670 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18671 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18672 (set (match_operand:DI 0 "register_operand" "=D")
18673 (plus:DI (match_dup 2)
18675 (set (match_operand:DI 1 "register_operand" "=S")
18676 (plus:DI (match_dup 3)
18678 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18680 [(set_attr "type" "str")
18681 (set_attr "mode" "DI")
18682 (set_attr "memory" "both")])
18684 (define_insn "*strmovsi_1"
18685 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18686 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18687 (set (match_operand:SI 0 "register_operand" "=D")
18688 (plus:SI (match_dup 2)
18690 (set (match_operand:SI 1 "register_operand" "=S")
18691 (plus:SI (match_dup 3)
18693 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18695 [(set_attr "type" "str")
18696 (set_attr "mode" "SI")
18697 (set_attr "memory" "both")])
18699 (define_insn "*strmovsi_rex_1"
18700 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18701 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18702 (set (match_operand:DI 0 "register_operand" "=D")
18703 (plus:DI (match_dup 2)
18705 (set (match_operand:DI 1 "register_operand" "=S")
18706 (plus:DI (match_dup 3)
18708 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18710 [(set_attr "type" "str")
18711 (set_attr "mode" "SI")
18712 (set_attr "memory" "both")])
18714 (define_insn "*strmovhi_1"
18715 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18716 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18717 (set (match_operand:SI 0 "register_operand" "=D")
18718 (plus:SI (match_dup 2)
18720 (set (match_operand:SI 1 "register_operand" "=S")
18721 (plus:SI (match_dup 3)
18723 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18725 [(set_attr "type" "str")
18726 (set_attr "memory" "both")
18727 (set_attr "mode" "HI")])
18729 (define_insn "*strmovhi_rex_1"
18730 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18731 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18732 (set (match_operand:DI 0 "register_operand" "=D")
18733 (plus:DI (match_dup 2)
18735 (set (match_operand:DI 1 "register_operand" "=S")
18736 (plus:DI (match_dup 3)
18738 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18740 [(set_attr "type" "str")
18741 (set_attr "memory" "both")
18742 (set_attr "mode" "HI")])
18744 (define_insn "*strmovqi_1"
18745 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18746 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18747 (set (match_operand:SI 0 "register_operand" "=D")
18748 (plus:SI (match_dup 2)
18750 (set (match_operand:SI 1 "register_operand" "=S")
18751 (plus:SI (match_dup 3)
18753 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18755 [(set_attr "type" "str")
18756 (set_attr "memory" "both")
18757 (set_attr "mode" "QI")])
18759 (define_insn "*strmovqi_rex_1"
18760 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18761 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18762 (set (match_operand:DI 0 "register_operand" "=D")
18763 (plus:DI (match_dup 2)
18765 (set (match_operand:DI 1 "register_operand" "=S")
18766 (plus:DI (match_dup 3)
18768 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18770 [(set_attr "type" "str")
18771 (set_attr "memory" "both")
18772 (set_attr "mode" "QI")])
18774 (define_expand "rep_mov"
18775 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18776 (set (match_operand 0 "register_operand" "")
18777 (match_operand 5 "" ""))
18778 (set (match_operand 2 "register_operand" "")
18779 (match_operand 6 "" ""))
18780 (set (match_operand 1 "memory_operand" "")
18781 (match_operand 3 "memory_operand" ""))
18782 (use (match_dup 4))])]
18786 (define_insn "*rep_movdi_rex64"
18787 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18788 (set (match_operand:DI 0 "register_operand" "=D")
18789 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18791 (match_operand:DI 3 "register_operand" "0")))
18792 (set (match_operand:DI 1 "register_operand" "=S")
18793 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18794 (match_operand:DI 4 "register_operand" "1")))
18795 (set (mem:BLK (match_dup 3))
18796 (mem:BLK (match_dup 4)))
18797 (use (match_dup 5))]
18800 [(set_attr "type" "str")
18801 (set_attr "prefix_rep" "1")
18802 (set_attr "memory" "both")
18803 (set_attr "mode" "DI")])
18805 (define_insn "*rep_movsi"
18806 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18807 (set (match_operand:SI 0 "register_operand" "=D")
18808 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18810 (match_operand:SI 3 "register_operand" "0")))
18811 (set (match_operand:SI 1 "register_operand" "=S")
18812 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18813 (match_operand:SI 4 "register_operand" "1")))
18814 (set (mem:BLK (match_dup 3))
18815 (mem:BLK (match_dup 4)))
18816 (use (match_dup 5))]
18819 [(set_attr "type" "str")
18820 (set_attr "prefix_rep" "1")
18821 (set_attr "memory" "both")
18822 (set_attr "mode" "SI")])
18824 (define_insn "*rep_movsi_rex64"
18825 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18826 (set (match_operand:DI 0 "register_operand" "=D")
18827 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18829 (match_operand:DI 3 "register_operand" "0")))
18830 (set (match_operand:DI 1 "register_operand" "=S")
18831 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18832 (match_operand:DI 4 "register_operand" "1")))
18833 (set (mem:BLK (match_dup 3))
18834 (mem:BLK (match_dup 4)))
18835 (use (match_dup 5))]
18838 [(set_attr "type" "str")
18839 (set_attr "prefix_rep" "1")
18840 (set_attr "memory" "both")
18841 (set_attr "mode" "SI")])
18843 (define_insn "*rep_movqi"
18844 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18845 (set (match_operand:SI 0 "register_operand" "=D")
18846 (plus:SI (match_operand:SI 3 "register_operand" "0")
18847 (match_operand:SI 5 "register_operand" "2")))
18848 (set (match_operand:SI 1 "register_operand" "=S")
18849 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18850 (set (mem:BLK (match_dup 3))
18851 (mem:BLK (match_dup 4)))
18852 (use (match_dup 5))]
18855 [(set_attr "type" "str")
18856 (set_attr "prefix_rep" "1")
18857 (set_attr "memory" "both")
18858 (set_attr "mode" "SI")])
18860 (define_insn "*rep_movqi_rex64"
18861 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18862 (set (match_operand:DI 0 "register_operand" "=D")
18863 (plus:DI (match_operand:DI 3 "register_operand" "0")
18864 (match_operand:DI 5 "register_operand" "2")))
18865 (set (match_operand:DI 1 "register_operand" "=S")
18866 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18867 (set (mem:BLK (match_dup 3))
18868 (mem:BLK (match_dup 4)))
18869 (use (match_dup 5))]
18872 [(set_attr "type" "str")
18873 (set_attr "prefix_rep" "1")
18874 (set_attr "memory" "both")
18875 (set_attr "mode" "SI")])
18877 (define_expand "setmemsi"
18878 [(use (match_operand:BLK 0 "memory_operand" ""))
18879 (use (match_operand:SI 1 "nonmemory_operand" ""))
18880 (use (match_operand 2 "const_int_operand" ""))
18881 (use (match_operand 3 "const_int_operand" ""))
18882 (use (match_operand:SI 4 "const_int_operand" ""))
18883 (use (match_operand:SI 5 "const_int_operand" ""))]
18886 if (ix86_expand_setmem (operands[0], operands[1],
18887 operands[2], operands[3],
18888 operands[4], operands[5]))
18894 (define_expand "setmemdi"
18895 [(use (match_operand:BLK 0 "memory_operand" ""))
18896 (use (match_operand:DI 1 "nonmemory_operand" ""))
18897 (use (match_operand 2 "const_int_operand" ""))
18898 (use (match_operand 3 "const_int_operand" ""))
18899 (use (match_operand 4 "const_int_operand" ""))
18900 (use (match_operand 5 "const_int_operand" ""))]
18903 if (ix86_expand_setmem (operands[0], operands[1],
18904 operands[2], operands[3],
18905 operands[4], operands[5]))
18911 ;; Most CPUs don't like single string operations
18912 ;; Handle this case here to simplify previous expander.
18914 (define_expand "strset"
18915 [(set (match_operand 1 "memory_operand" "")
18916 (match_operand 2 "register_operand" ""))
18917 (parallel [(set (match_operand 0 "register_operand" "")
18919 (clobber (reg:CC FLAGS_REG))])]
18922 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18923 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18925 /* If .md ever supports :P for Pmode, this can be directly
18926 in the pattern above. */
18927 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18928 GEN_INT (GET_MODE_SIZE (GET_MODE
18930 if (TARGET_SINGLE_STRINGOP || optimize_size)
18932 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18938 (define_expand "strset_singleop"
18939 [(parallel [(set (match_operand 1 "memory_operand" "")
18940 (match_operand 2 "register_operand" ""))
18941 (set (match_operand 0 "register_operand" "")
18942 (match_operand 3 "" ""))])]
18943 "TARGET_SINGLE_STRINGOP || optimize_size"
18946 (define_insn "*strsetdi_rex_1"
18947 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18948 (match_operand:DI 2 "register_operand" "a"))
18949 (set (match_operand:DI 0 "register_operand" "=D")
18950 (plus:DI (match_dup 1)
18952 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18954 [(set_attr "type" "str")
18955 (set_attr "memory" "store")
18956 (set_attr "mode" "DI")])
18958 (define_insn "*strsetsi_1"
18959 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18960 (match_operand:SI 2 "register_operand" "a"))
18961 (set (match_operand:SI 0 "register_operand" "=D")
18962 (plus:SI (match_dup 1)
18964 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18966 [(set_attr "type" "str")
18967 (set_attr "memory" "store")
18968 (set_attr "mode" "SI")])
18970 (define_insn "*strsetsi_rex_1"
18971 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18972 (match_operand:SI 2 "register_operand" "a"))
18973 (set (match_operand:DI 0 "register_operand" "=D")
18974 (plus:DI (match_dup 1)
18976 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18978 [(set_attr "type" "str")
18979 (set_attr "memory" "store")
18980 (set_attr "mode" "SI")])
18982 (define_insn "*strsethi_1"
18983 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18984 (match_operand:HI 2 "register_operand" "a"))
18985 (set (match_operand:SI 0 "register_operand" "=D")
18986 (plus:SI (match_dup 1)
18988 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18990 [(set_attr "type" "str")
18991 (set_attr "memory" "store")
18992 (set_attr "mode" "HI")])
18994 (define_insn "*strsethi_rex_1"
18995 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18996 (match_operand:HI 2 "register_operand" "a"))
18997 (set (match_operand:DI 0 "register_operand" "=D")
18998 (plus:DI (match_dup 1)
19000 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19002 [(set_attr "type" "str")
19003 (set_attr "memory" "store")
19004 (set_attr "mode" "HI")])
19006 (define_insn "*strsetqi_1"
19007 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19008 (match_operand:QI 2 "register_operand" "a"))
19009 (set (match_operand:SI 0 "register_operand" "=D")
19010 (plus:SI (match_dup 1)
19012 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19014 [(set_attr "type" "str")
19015 (set_attr "memory" "store")
19016 (set_attr "mode" "QI")])
19018 (define_insn "*strsetqi_rex_1"
19019 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19020 (match_operand:QI 2 "register_operand" "a"))
19021 (set (match_operand:DI 0 "register_operand" "=D")
19022 (plus:DI (match_dup 1)
19024 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
19026 [(set_attr "type" "str")
19027 (set_attr "memory" "store")
19028 (set_attr "mode" "QI")])
19030 (define_expand "rep_stos"
19031 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19032 (set (match_operand 0 "register_operand" "")
19033 (match_operand 4 "" ""))
19034 (set (match_operand 2 "memory_operand" "") (const_int 0))
19035 (use (match_operand 3 "register_operand" ""))
19036 (use (match_dup 1))])]
19040 (define_insn "*rep_stosdi_rex64"
19041 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19042 (set (match_operand:DI 0 "register_operand" "=D")
19043 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19045 (match_operand:DI 3 "register_operand" "0")))
19046 (set (mem:BLK (match_dup 3))
19048 (use (match_operand:DI 2 "register_operand" "a"))
19049 (use (match_dup 4))]
19052 [(set_attr "type" "str")
19053 (set_attr "prefix_rep" "1")
19054 (set_attr "memory" "store")
19055 (set_attr "mode" "DI")])
19057 (define_insn "*rep_stossi"
19058 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19059 (set (match_operand:SI 0 "register_operand" "=D")
19060 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19062 (match_operand:SI 3 "register_operand" "0")))
19063 (set (mem:BLK (match_dup 3))
19065 (use (match_operand:SI 2 "register_operand" "a"))
19066 (use (match_dup 4))]
19069 [(set_attr "type" "str")
19070 (set_attr "prefix_rep" "1")
19071 (set_attr "memory" "store")
19072 (set_attr "mode" "SI")])
19074 (define_insn "*rep_stossi_rex64"
19075 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19076 (set (match_operand:DI 0 "register_operand" "=D")
19077 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19079 (match_operand:DI 3 "register_operand" "0")))
19080 (set (mem:BLK (match_dup 3))
19082 (use (match_operand:SI 2 "register_operand" "a"))
19083 (use (match_dup 4))]
19086 [(set_attr "type" "str")
19087 (set_attr "prefix_rep" "1")
19088 (set_attr "memory" "store")
19089 (set_attr "mode" "SI")])
19091 (define_insn "*rep_stosqi"
19092 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19093 (set (match_operand:SI 0 "register_operand" "=D")
19094 (plus:SI (match_operand:SI 3 "register_operand" "0")
19095 (match_operand:SI 4 "register_operand" "1")))
19096 (set (mem:BLK (match_dup 3))
19098 (use (match_operand:QI 2 "register_operand" "a"))
19099 (use (match_dup 4))]
19102 [(set_attr "type" "str")
19103 (set_attr "prefix_rep" "1")
19104 (set_attr "memory" "store")
19105 (set_attr "mode" "QI")])
19107 (define_insn "*rep_stosqi_rex64"
19108 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19109 (set (match_operand:DI 0 "register_operand" "=D")
19110 (plus:DI (match_operand:DI 3 "register_operand" "0")
19111 (match_operand:DI 4 "register_operand" "1")))
19112 (set (mem:BLK (match_dup 3))
19114 (use (match_operand:QI 2 "register_operand" "a"))
19115 (use (match_dup 4))]
19118 [(set_attr "type" "str")
19119 (set_attr "prefix_rep" "1")
19120 (set_attr "memory" "store")
19121 (set_attr "mode" "QI")])
19123 (define_expand "cmpstrnsi"
19124 [(set (match_operand:SI 0 "register_operand" "")
19125 (compare:SI (match_operand:BLK 1 "general_operand" "")
19126 (match_operand:BLK 2 "general_operand" "")))
19127 (use (match_operand 3 "general_operand" ""))
19128 (use (match_operand 4 "immediate_operand" ""))]
19129 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
19131 rtx addr1, addr2, out, outlow, count, countreg, align;
19133 /* Can't use this if the user has appropriated esi or edi. */
19134 if (global_regs[4] || global_regs[5])
19139 out = gen_reg_rtx (SImode);
19141 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19142 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19143 if (addr1 != XEXP (operands[1], 0))
19144 operands[1] = replace_equiv_address_nv (operands[1], addr1);
19145 if (addr2 != XEXP (operands[2], 0))
19146 operands[2] = replace_equiv_address_nv (operands[2], addr2);
19148 count = operands[3];
19149 countreg = ix86_zero_extend_to_Pmode (count);
19151 /* %%% Iff we are testing strict equality, we can use known alignment
19152 to good advantage. This may be possible with combine, particularly
19153 once cc0 is dead. */
19154 align = operands[4];
19156 if (CONST_INT_P (count))
19158 if (INTVAL (count) == 0)
19160 emit_move_insn (operands[0], const0_rtx);
19163 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19164 operands[1], operands[2]));
19169 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19171 emit_insn (gen_cmpsi_1 (countreg, countreg));
19172 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19173 operands[1], operands[2]));
19176 outlow = gen_lowpart (QImode, out);
19177 emit_insn (gen_cmpintqi (outlow));
19178 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19180 if (operands[0] != out)
19181 emit_move_insn (operands[0], out);
19186 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19188 (define_expand "cmpintqi"
19189 [(set (match_dup 1)
19190 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19192 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19193 (parallel [(set (match_operand:QI 0 "register_operand" "")
19194 (minus:QI (match_dup 1)
19196 (clobber (reg:CC FLAGS_REG))])]
19198 "operands[1] = gen_reg_rtx (QImode);
19199 operands[2] = gen_reg_rtx (QImode);")
19201 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19202 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19204 (define_expand "cmpstrnqi_nz_1"
19205 [(parallel [(set (reg:CC FLAGS_REG)
19206 (compare:CC (match_operand 4 "memory_operand" "")
19207 (match_operand 5 "memory_operand" "")))
19208 (use (match_operand 2 "register_operand" ""))
19209 (use (match_operand:SI 3 "immediate_operand" ""))
19210 (clobber (match_operand 0 "register_operand" ""))
19211 (clobber (match_operand 1 "register_operand" ""))
19212 (clobber (match_dup 2))])]
19216 (define_insn "*cmpstrnqi_nz_1"
19217 [(set (reg:CC FLAGS_REG)
19218 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19219 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19220 (use (match_operand:SI 6 "register_operand" "2"))
19221 (use (match_operand:SI 3 "immediate_operand" "i"))
19222 (clobber (match_operand:SI 0 "register_operand" "=S"))
19223 (clobber (match_operand:SI 1 "register_operand" "=D"))
19224 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19227 [(set_attr "type" "str")
19228 (set_attr "mode" "QI")
19229 (set_attr "prefix_rep" "1")])
19231 (define_insn "*cmpstrnqi_nz_rex_1"
19232 [(set (reg:CC FLAGS_REG)
19233 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19234 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19235 (use (match_operand:DI 6 "register_operand" "2"))
19236 (use (match_operand:SI 3 "immediate_operand" "i"))
19237 (clobber (match_operand:DI 0 "register_operand" "=S"))
19238 (clobber (match_operand:DI 1 "register_operand" "=D"))
19239 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19242 [(set_attr "type" "str")
19243 (set_attr "mode" "QI")
19244 (set_attr "prefix_rep" "1")])
19246 ;; The same, but the count is not known to not be zero.
19248 (define_expand "cmpstrnqi_1"
19249 [(parallel [(set (reg:CC FLAGS_REG)
19250 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19252 (compare:CC (match_operand 4 "memory_operand" "")
19253 (match_operand 5 "memory_operand" ""))
19255 (use (match_operand:SI 3 "immediate_operand" ""))
19256 (use (reg:CC FLAGS_REG))
19257 (clobber (match_operand 0 "register_operand" ""))
19258 (clobber (match_operand 1 "register_operand" ""))
19259 (clobber (match_dup 2))])]
19263 (define_insn "*cmpstrnqi_1"
19264 [(set (reg:CC FLAGS_REG)
19265 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19267 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19268 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19270 (use (match_operand:SI 3 "immediate_operand" "i"))
19271 (use (reg:CC FLAGS_REG))
19272 (clobber (match_operand:SI 0 "register_operand" "=S"))
19273 (clobber (match_operand:SI 1 "register_operand" "=D"))
19274 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19277 [(set_attr "type" "str")
19278 (set_attr "mode" "QI")
19279 (set_attr "prefix_rep" "1")])
19281 (define_insn "*cmpstrnqi_rex_1"
19282 [(set (reg:CC FLAGS_REG)
19283 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19285 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19286 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19288 (use (match_operand:SI 3 "immediate_operand" "i"))
19289 (use (reg:CC FLAGS_REG))
19290 (clobber (match_operand:DI 0 "register_operand" "=S"))
19291 (clobber (match_operand:DI 1 "register_operand" "=D"))
19292 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19295 [(set_attr "type" "str")
19296 (set_attr "mode" "QI")
19297 (set_attr "prefix_rep" "1")])
19299 (define_expand "strlensi"
19300 [(set (match_operand:SI 0 "register_operand" "")
19301 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19302 (match_operand:QI 2 "immediate_operand" "")
19303 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19306 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19312 (define_expand "strlendi"
19313 [(set (match_operand:DI 0 "register_operand" "")
19314 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19315 (match_operand:QI 2 "immediate_operand" "")
19316 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19319 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19325 (define_expand "strlenqi_1"
19326 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19327 (clobber (match_operand 1 "register_operand" ""))
19328 (clobber (reg:CC FLAGS_REG))])]
19332 (define_insn "*strlenqi_1"
19333 [(set (match_operand:SI 0 "register_operand" "=&c")
19334 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19335 (match_operand:QI 2 "register_operand" "a")
19336 (match_operand:SI 3 "immediate_operand" "i")
19337 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19338 (clobber (match_operand:SI 1 "register_operand" "=D"))
19339 (clobber (reg:CC FLAGS_REG))]
19342 [(set_attr "type" "str")
19343 (set_attr "mode" "QI")
19344 (set_attr "prefix_rep" "1")])
19346 (define_insn "*strlenqi_rex_1"
19347 [(set (match_operand:DI 0 "register_operand" "=&c")
19348 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19349 (match_operand:QI 2 "register_operand" "a")
19350 (match_operand:DI 3 "immediate_operand" "i")
19351 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19352 (clobber (match_operand:DI 1 "register_operand" "=D"))
19353 (clobber (reg:CC FLAGS_REG))]
19356 [(set_attr "type" "str")
19357 (set_attr "mode" "QI")
19358 (set_attr "prefix_rep" "1")])
19360 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19361 ;; handled in combine, but it is not currently up to the task.
19362 ;; When used for their truth value, the cmpstrn* expanders generate
19371 ;; The intermediate three instructions are unnecessary.
19373 ;; This one handles cmpstrn*_nz_1...
19376 (set (reg:CC FLAGS_REG)
19377 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19378 (mem:BLK (match_operand 5 "register_operand" ""))))
19379 (use (match_operand 6 "register_operand" ""))
19380 (use (match_operand:SI 3 "immediate_operand" ""))
19381 (clobber (match_operand 0 "register_operand" ""))
19382 (clobber (match_operand 1 "register_operand" ""))
19383 (clobber (match_operand 2 "register_operand" ""))])
19384 (set (match_operand:QI 7 "register_operand" "")
19385 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19386 (set (match_operand:QI 8 "register_operand" "")
19387 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19388 (set (reg FLAGS_REG)
19389 (compare (match_dup 7) (match_dup 8)))
19391 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19393 (set (reg:CC FLAGS_REG)
19394 (compare:CC (mem:BLK (match_dup 4))
19395 (mem:BLK (match_dup 5))))
19396 (use (match_dup 6))
19397 (use (match_dup 3))
19398 (clobber (match_dup 0))
19399 (clobber (match_dup 1))
19400 (clobber (match_dup 2))])]
19403 ;; ...and this one handles cmpstrn*_1.
19406 (set (reg:CC FLAGS_REG)
19407 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19409 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19410 (mem:BLK (match_operand 5 "register_operand" "")))
19412 (use (match_operand:SI 3 "immediate_operand" ""))
19413 (use (reg:CC FLAGS_REG))
19414 (clobber (match_operand 0 "register_operand" ""))
19415 (clobber (match_operand 1 "register_operand" ""))
19416 (clobber (match_operand 2 "register_operand" ""))])
19417 (set (match_operand:QI 7 "register_operand" "")
19418 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19419 (set (match_operand:QI 8 "register_operand" "")
19420 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19421 (set (reg FLAGS_REG)
19422 (compare (match_dup 7) (match_dup 8)))
19424 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19426 (set (reg:CC FLAGS_REG)
19427 (if_then_else:CC (ne (match_dup 6)
19429 (compare:CC (mem:BLK (match_dup 4))
19430 (mem:BLK (match_dup 5)))
19432 (use (match_dup 3))
19433 (use (reg:CC FLAGS_REG))
19434 (clobber (match_dup 0))
19435 (clobber (match_dup 1))
19436 (clobber (match_dup 2))])]
19441 ;; Conditional move instructions.
19443 (define_expand "movdicc"
19444 [(set (match_operand:DI 0 "register_operand" "")
19445 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19446 (match_operand:DI 2 "general_operand" "")
19447 (match_operand:DI 3 "general_operand" "")))]
19449 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19451 (define_insn "x86_movdicc_0_m1_rex64"
19452 [(set (match_operand:DI 0 "register_operand" "=r")
19453 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19456 (clobber (reg:CC FLAGS_REG))]
19459 ; Since we don't have the proper number of operands for an alu insn,
19460 ; fill in all the blanks.
19461 [(set_attr "type" "alu")
19462 (set_attr "pent_pair" "pu")
19463 (set_attr "memory" "none")
19464 (set_attr "imm_disp" "false")
19465 (set_attr "mode" "DI")
19466 (set_attr "length_immediate" "0")])
19468 (define_insn "*movdicc_c_rex64"
19469 [(set (match_operand:DI 0 "register_operand" "=r,r")
19470 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19471 [(reg FLAGS_REG) (const_int 0)])
19472 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19473 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19474 "TARGET_64BIT && TARGET_CMOVE
19475 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19477 cmov%O2%C1\t{%2, %0|%0, %2}
19478 cmov%O2%c1\t{%3, %0|%0, %3}"
19479 [(set_attr "type" "icmov")
19480 (set_attr "mode" "DI")])
19482 (define_expand "movsicc"
19483 [(set (match_operand:SI 0 "register_operand" "")
19484 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19485 (match_operand:SI 2 "general_operand" "")
19486 (match_operand:SI 3 "general_operand" "")))]
19488 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19490 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19491 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19492 ;; So just document what we're doing explicitly.
19494 (define_insn "x86_movsicc_0_m1"
19495 [(set (match_operand:SI 0 "register_operand" "=r")
19496 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19499 (clobber (reg:CC FLAGS_REG))]
19502 ; Since we don't have the proper number of operands for an alu insn,
19503 ; fill in all the blanks.
19504 [(set_attr "type" "alu")
19505 (set_attr "pent_pair" "pu")
19506 (set_attr "memory" "none")
19507 (set_attr "imm_disp" "false")
19508 (set_attr "mode" "SI")
19509 (set_attr "length_immediate" "0")])
19511 (define_insn "*movsicc_noc"
19512 [(set (match_operand:SI 0 "register_operand" "=r,r")
19513 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19514 [(reg FLAGS_REG) (const_int 0)])
19515 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19516 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19518 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19520 cmov%O2%C1\t{%2, %0|%0, %2}
19521 cmov%O2%c1\t{%3, %0|%0, %3}"
19522 [(set_attr "type" "icmov")
19523 (set_attr "mode" "SI")])
19525 (define_expand "movhicc"
19526 [(set (match_operand:HI 0 "register_operand" "")
19527 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19528 (match_operand:HI 2 "general_operand" "")
19529 (match_operand:HI 3 "general_operand" "")))]
19530 "TARGET_HIMODE_MATH"
19531 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19533 (define_insn "*movhicc_noc"
19534 [(set (match_operand:HI 0 "register_operand" "=r,r")
19535 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19536 [(reg FLAGS_REG) (const_int 0)])
19537 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19538 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19540 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19542 cmov%O2%C1\t{%2, %0|%0, %2}
19543 cmov%O2%c1\t{%3, %0|%0, %3}"
19544 [(set_attr "type" "icmov")
19545 (set_attr "mode" "HI")])
19547 (define_expand "movqicc"
19548 [(set (match_operand:QI 0 "register_operand" "")
19549 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19550 (match_operand:QI 2 "general_operand" "")
19551 (match_operand:QI 3 "general_operand" "")))]
19552 "TARGET_QIMODE_MATH"
19553 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19555 (define_insn_and_split "*movqicc_noc"
19556 [(set (match_operand:QI 0 "register_operand" "=r,r")
19557 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19558 [(match_operand 4 "flags_reg_operand" "")
19560 (match_operand:QI 2 "register_operand" "r,0")
19561 (match_operand:QI 3 "register_operand" "0,r")))]
19562 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19564 "&& reload_completed"
19565 [(set (match_dup 0)
19566 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19569 "operands[0] = gen_lowpart (SImode, operands[0]);
19570 operands[2] = gen_lowpart (SImode, operands[2]);
19571 operands[3] = gen_lowpart (SImode, operands[3]);"
19572 [(set_attr "type" "icmov")
19573 (set_attr "mode" "SI")])
19575 (define_expand "movsfcc"
19576 [(set (match_operand:SF 0 "register_operand" "")
19577 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19578 (match_operand:SF 2 "register_operand" "")
19579 (match_operand:SF 3 "register_operand" "")))]
19580 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19581 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19583 (define_insn "*movsfcc_1_387"
19584 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19585 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19586 [(reg FLAGS_REG) (const_int 0)])
19587 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19588 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19589 "TARGET_80387 && TARGET_CMOVE
19590 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19592 fcmov%F1\t{%2, %0|%0, %2}
19593 fcmov%f1\t{%3, %0|%0, %3}
19594 cmov%O2%C1\t{%2, %0|%0, %2}
19595 cmov%O2%c1\t{%3, %0|%0, %3}"
19596 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19597 (set_attr "mode" "SF,SF,SI,SI")])
19599 (define_expand "movdfcc"
19600 [(set (match_operand:DF 0 "register_operand" "")
19601 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19602 (match_operand:DF 2 "register_operand" "")
19603 (match_operand:DF 3 "register_operand" "")))]
19604 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19605 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19607 (define_insn "*movdfcc_1"
19608 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19609 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19610 [(reg FLAGS_REG) (const_int 0)])
19611 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19612 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19613 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19614 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19616 fcmov%F1\t{%2, %0|%0, %2}
19617 fcmov%f1\t{%3, %0|%0, %3}
19620 [(set_attr "type" "fcmov,fcmov,multi,multi")
19621 (set_attr "mode" "DF")])
19623 (define_insn "*movdfcc_1_rex64"
19624 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19625 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19626 [(reg FLAGS_REG) (const_int 0)])
19627 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19628 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19629 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19630 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19632 fcmov%F1\t{%2, %0|%0, %2}
19633 fcmov%f1\t{%3, %0|%0, %3}
19634 cmov%O2%C1\t{%2, %0|%0, %2}
19635 cmov%O2%c1\t{%3, %0|%0, %3}"
19636 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19637 (set_attr "mode" "DF")])
19640 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19641 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19642 [(match_operand 4 "flags_reg_operand" "")
19644 (match_operand:DF 2 "nonimmediate_operand" "")
19645 (match_operand:DF 3 "nonimmediate_operand" "")))]
19646 "!TARGET_64BIT && reload_completed"
19647 [(set (match_dup 2)
19648 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19652 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19655 "split_di (operands+2, 1, operands+5, operands+6);
19656 split_di (operands+3, 1, operands+7, operands+8);
19657 split_di (operands, 1, operands+2, operands+3);")
19659 (define_expand "movxfcc"
19660 [(set (match_operand:XF 0 "register_operand" "")
19661 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19662 (match_operand:XF 2 "register_operand" "")
19663 (match_operand:XF 3 "register_operand" "")))]
19664 "TARGET_80387 && TARGET_CMOVE"
19665 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19667 (define_insn "*movxfcc_1"
19668 [(set (match_operand:XF 0 "register_operand" "=f,f")
19669 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19670 [(reg FLAGS_REG) (const_int 0)])
19671 (match_operand:XF 2 "register_operand" "f,0")
19672 (match_operand:XF 3 "register_operand" "0,f")))]
19673 "TARGET_80387 && TARGET_CMOVE"
19675 fcmov%F1\t{%2, %0|%0, %2}
19676 fcmov%f1\t{%3, %0|%0, %3}"
19677 [(set_attr "type" "fcmov")
19678 (set_attr "mode" "XF")])
19680 ;; These versions of the min/max patterns are intentionally ignorant of
19681 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19682 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19683 ;; are undefined in this condition, we're certain this is correct.
19685 (define_insn "sminsf3"
19686 [(set (match_operand:SF 0 "register_operand" "=x")
19687 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19688 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19690 "minss\t{%2, %0|%0, %2}"
19691 [(set_attr "type" "sseadd")
19692 (set_attr "mode" "SF")])
19694 (define_insn "smaxsf3"
19695 [(set (match_operand:SF 0 "register_operand" "=x")
19696 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19697 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19699 "maxss\t{%2, %0|%0, %2}"
19700 [(set_attr "type" "sseadd")
19701 (set_attr "mode" "SF")])
19703 (define_insn "smindf3"
19704 [(set (match_operand:DF 0 "register_operand" "=x")
19705 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19706 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19707 "TARGET_SSE2 && TARGET_SSE_MATH"
19708 "minsd\t{%2, %0|%0, %2}"
19709 [(set_attr "type" "sseadd")
19710 (set_attr "mode" "DF")])
19712 (define_insn "smaxdf3"
19713 [(set (match_operand:DF 0 "register_operand" "=x")
19714 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19715 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19716 "TARGET_SSE2 && TARGET_SSE_MATH"
19717 "maxsd\t{%2, %0|%0, %2}"
19718 [(set_attr "type" "sseadd")
19719 (set_attr "mode" "DF")])
19721 ;; These versions of the min/max patterns implement exactly the operations
19722 ;; min = (op1 < op2 ? op1 : op2)
19723 ;; max = (!(op1 < op2) ? op1 : op2)
19724 ;; Their operands are not commutative, and thus they may be used in the
19725 ;; presence of -0.0 and NaN.
19727 (define_insn "*ieee_sminsf3"
19728 [(set (match_operand:SF 0 "register_operand" "=x")
19729 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19730 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19733 "minss\t{%2, %0|%0, %2}"
19734 [(set_attr "type" "sseadd")
19735 (set_attr "mode" "SF")])
19737 (define_insn "*ieee_smaxsf3"
19738 [(set (match_operand:SF 0 "register_operand" "=x")
19739 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19740 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19743 "maxss\t{%2, %0|%0, %2}"
19744 [(set_attr "type" "sseadd")
19745 (set_attr "mode" "SF")])
19747 (define_insn "*ieee_smindf3"
19748 [(set (match_operand:DF 0 "register_operand" "=x")
19749 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19750 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19752 "TARGET_SSE2 && TARGET_SSE_MATH"
19753 "minsd\t{%2, %0|%0, %2}"
19754 [(set_attr "type" "sseadd")
19755 (set_attr "mode" "DF")])
19757 (define_insn "*ieee_smaxdf3"
19758 [(set (match_operand:DF 0 "register_operand" "=x")
19759 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19760 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19762 "TARGET_SSE2 && TARGET_SSE_MATH"
19763 "maxsd\t{%2, %0|%0, %2}"
19764 [(set_attr "type" "sseadd")
19765 (set_attr "mode" "DF")])
19767 ;; Make two stack loads independent:
19769 ;; fld %st(0) -> fld bb
19770 ;; fmul bb fmul %st(1), %st
19772 ;; Actually we only match the last two instructions for simplicity.
19774 [(set (match_operand 0 "fp_register_operand" "")
19775 (match_operand 1 "fp_register_operand" ""))
19777 (match_operator 2 "binary_fp_operator"
19779 (match_operand 3 "memory_operand" "")]))]
19780 "REGNO (operands[0]) != REGNO (operands[1])"
19781 [(set (match_dup 0) (match_dup 3))
19782 (set (match_dup 0) (match_dup 4))]
19784 ;; The % modifier is not operational anymore in peephole2's, so we have to
19785 ;; swap the operands manually in the case of addition and multiplication.
19786 "if (COMMUTATIVE_ARITH_P (operands[2]))
19787 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19788 operands[0], operands[1]);
19790 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19791 operands[1], operands[0]);")
19793 ;; Conditional addition patterns
19794 (define_expand "addqicc"
19795 [(match_operand:QI 0 "register_operand" "")
19796 (match_operand 1 "comparison_operator" "")
19797 (match_operand:QI 2 "register_operand" "")
19798 (match_operand:QI 3 "const_int_operand" "")]
19800 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19802 (define_expand "addhicc"
19803 [(match_operand:HI 0 "register_operand" "")
19804 (match_operand 1 "comparison_operator" "")
19805 (match_operand:HI 2 "register_operand" "")
19806 (match_operand:HI 3 "const_int_operand" "")]
19808 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19810 (define_expand "addsicc"
19811 [(match_operand:SI 0 "register_operand" "")
19812 (match_operand 1 "comparison_operator" "")
19813 (match_operand:SI 2 "register_operand" "")
19814 (match_operand:SI 3 "const_int_operand" "")]
19816 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19818 (define_expand "adddicc"
19819 [(match_operand:DI 0 "register_operand" "")
19820 (match_operand 1 "comparison_operator" "")
19821 (match_operand:DI 2 "register_operand" "")
19822 (match_operand:DI 3 "const_int_operand" "")]
19824 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19827 ;; Misc patterns (?)
19829 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19830 ;; Otherwise there will be nothing to keep
19832 ;; [(set (reg ebp) (reg esp))]
19833 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19834 ;; (clobber (eflags)]
19835 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19837 ;; in proper program order.
19838 (define_insn "pro_epilogue_adjust_stack_1"
19839 [(set (match_operand:SI 0 "register_operand" "=r,r")
19840 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19841 (match_operand:SI 2 "immediate_operand" "i,i")))
19842 (clobber (reg:CC FLAGS_REG))
19843 (clobber (mem:BLK (scratch)))]
19846 switch (get_attr_type (insn))
19849 return "mov{l}\t{%1, %0|%0, %1}";
19852 if (CONST_INT_P (operands[2])
19853 && (INTVAL (operands[2]) == 128
19854 || (INTVAL (operands[2]) < 0
19855 && INTVAL (operands[2]) != -128)))
19857 operands[2] = GEN_INT (-INTVAL (operands[2]));
19858 return "sub{l}\t{%2, %0|%0, %2}";
19860 return "add{l}\t{%2, %0|%0, %2}";
19863 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19864 return "lea{l}\t{%a2, %0|%0, %a2}";
19867 gcc_unreachable ();
19870 [(set (attr "type")
19871 (cond [(eq_attr "alternative" "0")
19872 (const_string "alu")
19873 (match_operand:SI 2 "const0_operand" "")
19874 (const_string "imov")
19876 (const_string "lea")))
19877 (set_attr "mode" "SI")])
19879 (define_insn "pro_epilogue_adjust_stack_rex64"
19880 [(set (match_operand:DI 0 "register_operand" "=r,r")
19881 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19882 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19883 (clobber (reg:CC FLAGS_REG))
19884 (clobber (mem:BLK (scratch)))]
19887 switch (get_attr_type (insn))
19890 return "mov{q}\t{%1, %0|%0, %1}";
19893 if (CONST_INT_P (operands[2])
19894 /* Avoid overflows. */
19895 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19896 && (INTVAL (operands[2]) == 128
19897 || (INTVAL (operands[2]) < 0
19898 && INTVAL (operands[2]) != -128)))
19900 operands[2] = GEN_INT (-INTVAL (operands[2]));
19901 return "sub{q}\t{%2, %0|%0, %2}";
19903 return "add{q}\t{%2, %0|%0, %2}";
19906 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19907 return "lea{q}\t{%a2, %0|%0, %a2}";
19910 gcc_unreachable ();
19913 [(set (attr "type")
19914 (cond [(eq_attr "alternative" "0")
19915 (const_string "alu")
19916 (match_operand:DI 2 "const0_operand" "")
19917 (const_string "imov")
19919 (const_string "lea")))
19920 (set_attr "mode" "DI")])
19922 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19923 [(set (match_operand:DI 0 "register_operand" "=r,r")
19924 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19925 (match_operand:DI 3 "immediate_operand" "i,i")))
19926 (use (match_operand:DI 2 "register_operand" "r,r"))
19927 (clobber (reg:CC FLAGS_REG))
19928 (clobber (mem:BLK (scratch)))]
19931 switch (get_attr_type (insn))
19934 return "add{q}\t{%2, %0|%0, %2}";
19937 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19938 return "lea{q}\t{%a2, %0|%0, %a2}";
19941 gcc_unreachable ();
19944 [(set_attr "type" "alu,lea")
19945 (set_attr "mode" "DI")])
19947 (define_insn "allocate_stack_worker_32"
19948 [(set (match_operand:SI 0 "register_operand" "+a")
19949 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19950 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19951 (clobber (reg:CC FLAGS_REG))]
19952 "!TARGET_64BIT && TARGET_STACK_PROBE"
19954 [(set_attr "type" "multi")
19955 (set_attr "length" "5")])
19957 (define_insn "allocate_stack_worker_64"
19958 [(set (match_operand:DI 0 "register_operand" "=a")
19959 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19960 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19961 (clobber (reg:DI R10_REG))
19962 (clobber (reg:DI R11_REG))
19963 (clobber (reg:CC FLAGS_REG))]
19964 "TARGET_64BIT && TARGET_STACK_PROBE"
19966 [(set_attr "type" "multi")
19967 (set_attr "length" "5")])
19969 (define_expand "allocate_stack"
19970 [(match_operand 0 "register_operand" "")
19971 (match_operand 1 "general_operand" "")]
19972 "TARGET_STACK_PROBE"
19976 #ifndef CHECK_STACK_LIMIT
19977 #define CHECK_STACK_LIMIT 0
19980 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19981 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19983 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19984 stack_pointer_rtx, 0, OPTAB_DIRECT);
19985 if (x != stack_pointer_rtx)
19986 emit_move_insn (stack_pointer_rtx, x);
19990 x = copy_to_mode_reg (Pmode, operands[1]);
19992 x = gen_allocate_stack_worker_64 (x);
19994 x = gen_allocate_stack_worker_32 (x);
19998 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20002 (define_expand "builtin_setjmp_receiver"
20003 [(label_ref (match_operand 0 "" ""))]
20004 "!TARGET_64BIT && flag_pic"
20009 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20010 rtx label_rtx = gen_label_rtx ();
20011 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20012 xops[0] = xops[1] = picreg;
20013 xops[2] = gen_rtx_CONST (SImode,
20014 gen_rtx_MINUS (SImode,
20015 gen_rtx_LABEL_REF (SImode, label_rtx),
20016 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
20017 ix86_expand_binary_operator (MINUS, SImode, xops);
20020 emit_insn (gen_set_got (pic_offset_table_rtx));
20024 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20027 [(set (match_operand 0 "register_operand" "")
20028 (match_operator 3 "promotable_binary_operator"
20029 [(match_operand 1 "register_operand" "")
20030 (match_operand 2 "aligned_operand" "")]))
20031 (clobber (reg:CC FLAGS_REG))]
20032 "! TARGET_PARTIAL_REG_STALL && reload_completed
20033 && ((GET_MODE (operands[0]) == HImode
20034 && ((!optimize_size && !TARGET_FAST_PREFIX)
20035 /* ??? next two lines just !satisfies_constraint_K (...) */
20036 || !CONST_INT_P (operands[2])
20037 || satisfies_constraint_K (operands[2])))
20038 || (GET_MODE (operands[0]) == QImode
20039 && (TARGET_PROMOTE_QImode || optimize_size)))"
20040 [(parallel [(set (match_dup 0)
20041 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20042 (clobber (reg:CC FLAGS_REG))])]
20043 "operands[0] = gen_lowpart (SImode, operands[0]);
20044 operands[1] = gen_lowpart (SImode, operands[1]);
20045 if (GET_CODE (operands[3]) != ASHIFT)
20046 operands[2] = gen_lowpart (SImode, operands[2]);
20047 PUT_MODE (operands[3], SImode);")
20049 ; Promote the QImode tests, as i386 has encoding of the AND
20050 ; instruction with 32-bit sign-extended immediate and thus the
20051 ; instruction size is unchanged, except in the %eax case for
20052 ; which it is increased by one byte, hence the ! optimize_size.
20054 [(set (match_operand 0 "flags_reg_operand" "")
20055 (match_operator 2 "compare_operator"
20056 [(and (match_operand 3 "aligned_operand" "")
20057 (match_operand 4 "const_int_operand" ""))
20059 (set (match_operand 1 "register_operand" "")
20060 (and (match_dup 3) (match_dup 4)))]
20061 "! TARGET_PARTIAL_REG_STALL && reload_completed
20063 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20064 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20065 /* Ensure that the operand will remain sign-extended immediate. */
20066 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20067 [(parallel [(set (match_dup 0)
20068 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20071 (and:SI (match_dup 3) (match_dup 4)))])]
20074 = gen_int_mode (INTVAL (operands[4])
20075 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20076 operands[1] = gen_lowpart (SImode, operands[1]);
20077 operands[3] = gen_lowpart (SImode, operands[3]);
20080 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20081 ; the TEST instruction with 32-bit sign-extended immediate and thus
20082 ; the instruction size would at least double, which is not what we
20083 ; want even with ! optimize_size.
20085 [(set (match_operand 0 "flags_reg_operand" "")
20086 (match_operator 1 "compare_operator"
20087 [(and (match_operand:HI 2 "aligned_operand" "")
20088 (match_operand:HI 3 "const_int_operand" ""))
20090 "! TARGET_PARTIAL_REG_STALL && reload_completed
20091 && ! TARGET_FAST_PREFIX
20093 /* Ensure that the operand will remain sign-extended immediate. */
20094 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20095 [(set (match_dup 0)
20096 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20100 = gen_int_mode (INTVAL (operands[3])
20101 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20102 operands[2] = gen_lowpart (SImode, operands[2]);
20106 [(set (match_operand 0 "register_operand" "")
20107 (neg (match_operand 1 "register_operand" "")))
20108 (clobber (reg:CC FLAGS_REG))]
20109 "! TARGET_PARTIAL_REG_STALL && reload_completed
20110 && (GET_MODE (operands[0]) == HImode
20111 || (GET_MODE (operands[0]) == QImode
20112 && (TARGET_PROMOTE_QImode || optimize_size)))"
20113 [(parallel [(set (match_dup 0)
20114 (neg:SI (match_dup 1)))
20115 (clobber (reg:CC FLAGS_REG))])]
20116 "operands[0] = gen_lowpart (SImode, operands[0]);
20117 operands[1] = gen_lowpart (SImode, operands[1]);")
20120 [(set (match_operand 0 "register_operand" "")
20121 (not (match_operand 1 "register_operand" "")))]
20122 "! TARGET_PARTIAL_REG_STALL && reload_completed
20123 && (GET_MODE (operands[0]) == HImode
20124 || (GET_MODE (operands[0]) == QImode
20125 && (TARGET_PROMOTE_QImode || optimize_size)))"
20126 [(set (match_dup 0)
20127 (not:SI (match_dup 1)))]
20128 "operands[0] = gen_lowpart (SImode, operands[0]);
20129 operands[1] = gen_lowpart (SImode, operands[1]);")
20132 [(set (match_operand 0 "register_operand" "")
20133 (if_then_else (match_operator 1 "comparison_operator"
20134 [(reg FLAGS_REG) (const_int 0)])
20135 (match_operand 2 "register_operand" "")
20136 (match_operand 3 "register_operand" "")))]
20137 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20138 && (GET_MODE (operands[0]) == HImode
20139 || (GET_MODE (operands[0]) == QImode
20140 && (TARGET_PROMOTE_QImode || optimize_size)))"
20141 [(set (match_dup 0)
20142 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20143 "operands[0] = gen_lowpart (SImode, operands[0]);
20144 operands[2] = gen_lowpart (SImode, operands[2]);
20145 operands[3] = gen_lowpart (SImode, operands[3]);")
20148 ;; RTL Peephole optimizations, run before sched2. These primarily look to
20149 ;; transform a complex memory operation into two memory to register operations.
20151 ;; Don't push memory operands
20153 [(set (match_operand:SI 0 "push_operand" "")
20154 (match_operand:SI 1 "memory_operand" ""))
20155 (match_scratch:SI 2 "r")]
20156 "!optimize_size && !TARGET_PUSH_MEMORY
20157 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20158 [(set (match_dup 2) (match_dup 1))
20159 (set (match_dup 0) (match_dup 2))]
20163 [(set (match_operand:DI 0 "push_operand" "")
20164 (match_operand:DI 1 "memory_operand" ""))
20165 (match_scratch:DI 2 "r")]
20166 "!optimize_size && !TARGET_PUSH_MEMORY
20167 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20168 [(set (match_dup 2) (match_dup 1))
20169 (set (match_dup 0) (match_dup 2))]
20172 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20175 [(set (match_operand:SF 0 "push_operand" "")
20176 (match_operand:SF 1 "memory_operand" ""))
20177 (match_scratch:SF 2 "r")]
20178 "!optimize_size && !TARGET_PUSH_MEMORY
20179 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20180 [(set (match_dup 2) (match_dup 1))
20181 (set (match_dup 0) (match_dup 2))]
20185 [(set (match_operand:HI 0 "push_operand" "")
20186 (match_operand:HI 1 "memory_operand" ""))
20187 (match_scratch:HI 2 "r")]
20188 "!optimize_size && !TARGET_PUSH_MEMORY
20189 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20190 [(set (match_dup 2) (match_dup 1))
20191 (set (match_dup 0) (match_dup 2))]
20195 [(set (match_operand:QI 0 "push_operand" "")
20196 (match_operand:QI 1 "memory_operand" ""))
20197 (match_scratch:QI 2 "q")]
20198 "!optimize_size && !TARGET_PUSH_MEMORY
20199 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20200 [(set (match_dup 2) (match_dup 1))
20201 (set (match_dup 0) (match_dup 2))]
20204 ;; Don't move an immediate directly to memory when the instruction
20207 [(match_scratch:SI 1 "r")
20208 (set (match_operand:SI 0 "memory_operand" "")
20211 && ! TARGET_USE_MOV0
20212 && TARGET_SPLIT_LONG_MOVES
20213 && get_attr_length (insn) >= ix86_cost->large_insn
20214 && peep2_regno_dead_p (0, FLAGS_REG)"
20215 [(parallel [(set (match_dup 1) (const_int 0))
20216 (clobber (reg:CC FLAGS_REG))])
20217 (set (match_dup 0) (match_dup 1))]
20221 [(match_scratch:HI 1 "r")
20222 (set (match_operand:HI 0 "memory_operand" "")
20225 && ! TARGET_USE_MOV0
20226 && TARGET_SPLIT_LONG_MOVES
20227 && get_attr_length (insn) >= ix86_cost->large_insn
20228 && peep2_regno_dead_p (0, FLAGS_REG)"
20229 [(parallel [(set (match_dup 2) (const_int 0))
20230 (clobber (reg:CC FLAGS_REG))])
20231 (set (match_dup 0) (match_dup 1))]
20232 "operands[2] = gen_lowpart (SImode, operands[1]);")
20235 [(match_scratch:QI 1 "q")
20236 (set (match_operand:QI 0 "memory_operand" "")
20239 && ! TARGET_USE_MOV0
20240 && TARGET_SPLIT_LONG_MOVES
20241 && get_attr_length (insn) >= ix86_cost->large_insn
20242 && peep2_regno_dead_p (0, FLAGS_REG)"
20243 [(parallel [(set (match_dup 2) (const_int 0))
20244 (clobber (reg:CC FLAGS_REG))])
20245 (set (match_dup 0) (match_dup 1))]
20246 "operands[2] = gen_lowpart (SImode, operands[1]);")
20249 [(match_scratch:SI 2 "r")
20250 (set (match_operand:SI 0 "memory_operand" "")
20251 (match_operand:SI 1 "immediate_operand" ""))]
20253 && TARGET_SPLIT_LONG_MOVES
20254 && get_attr_length (insn) >= ix86_cost->large_insn"
20255 [(set (match_dup 2) (match_dup 1))
20256 (set (match_dup 0) (match_dup 2))]
20260 [(match_scratch:HI 2 "r")
20261 (set (match_operand:HI 0 "memory_operand" "")
20262 (match_operand:HI 1 "immediate_operand" ""))]
20264 && TARGET_SPLIT_LONG_MOVES
20265 && get_attr_length (insn) >= ix86_cost->large_insn"
20266 [(set (match_dup 2) (match_dup 1))
20267 (set (match_dup 0) (match_dup 2))]
20271 [(match_scratch:QI 2 "q")
20272 (set (match_operand:QI 0 "memory_operand" "")
20273 (match_operand:QI 1 "immediate_operand" ""))]
20275 && TARGET_SPLIT_LONG_MOVES
20276 && get_attr_length (insn) >= ix86_cost->large_insn"
20277 [(set (match_dup 2) (match_dup 1))
20278 (set (match_dup 0) (match_dup 2))]
20281 ;; Don't compare memory with zero, load and use a test instead.
20283 [(set (match_operand 0 "flags_reg_operand" "")
20284 (match_operator 1 "compare_operator"
20285 [(match_operand:SI 2 "memory_operand" "")
20287 (match_scratch:SI 3 "r")]
20288 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20289 [(set (match_dup 3) (match_dup 2))
20290 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20293 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20294 ;; Don't split NOTs with a displacement operand, because resulting XOR
20295 ;; will not be pairable anyway.
20297 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20298 ;; represented using a modRM byte. The XOR replacement is long decoded,
20299 ;; so this split helps here as well.
20301 ;; Note: Can't do this as a regular split because we can't get proper
20302 ;; lifetime information then.
20305 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20306 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20308 && ((TARGET_NOT_UNPAIRABLE
20309 && (!MEM_P (operands[0])
20310 || !memory_displacement_operand (operands[0], SImode)))
20311 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20312 && peep2_regno_dead_p (0, FLAGS_REG)"
20313 [(parallel [(set (match_dup 0)
20314 (xor:SI (match_dup 1) (const_int -1)))
20315 (clobber (reg:CC FLAGS_REG))])]
20319 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20320 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20322 && ((TARGET_NOT_UNPAIRABLE
20323 && (!MEM_P (operands[0])
20324 || !memory_displacement_operand (operands[0], HImode)))
20325 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20326 && peep2_regno_dead_p (0, FLAGS_REG)"
20327 [(parallel [(set (match_dup 0)
20328 (xor:HI (match_dup 1) (const_int -1)))
20329 (clobber (reg:CC FLAGS_REG))])]
20333 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20334 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20336 && ((TARGET_NOT_UNPAIRABLE
20337 && (!MEM_P (operands[0])
20338 || !memory_displacement_operand (operands[0], QImode)))
20339 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20340 && peep2_regno_dead_p (0, FLAGS_REG)"
20341 [(parallel [(set (match_dup 0)
20342 (xor:QI (match_dup 1) (const_int -1)))
20343 (clobber (reg:CC FLAGS_REG))])]
20346 ;; Non pairable "test imm, reg" instructions can be translated to
20347 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20348 ;; byte opcode instead of two, have a short form for byte operands),
20349 ;; so do it for other CPUs as well. Given that the value was dead,
20350 ;; this should not create any new dependencies. Pass on the sub-word
20351 ;; versions if we're concerned about partial register stalls.
20354 [(set (match_operand 0 "flags_reg_operand" "")
20355 (match_operator 1 "compare_operator"
20356 [(and:SI (match_operand:SI 2 "register_operand" "")
20357 (match_operand:SI 3 "immediate_operand" ""))
20359 "ix86_match_ccmode (insn, CCNOmode)
20360 && (true_regnum (operands[2]) != 0
20361 || satisfies_constraint_K (operands[3]))
20362 && peep2_reg_dead_p (1, operands[2])"
20364 [(set (match_dup 0)
20365 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20368 (and:SI (match_dup 2) (match_dup 3)))])]
20371 ;; We don't need to handle HImode case, because it will be promoted to SImode
20372 ;; on ! TARGET_PARTIAL_REG_STALL
20375 [(set (match_operand 0 "flags_reg_operand" "")
20376 (match_operator 1 "compare_operator"
20377 [(and:QI (match_operand:QI 2 "register_operand" "")
20378 (match_operand:QI 3 "immediate_operand" ""))
20380 "! TARGET_PARTIAL_REG_STALL
20381 && ix86_match_ccmode (insn, CCNOmode)
20382 && true_regnum (operands[2]) != 0
20383 && peep2_reg_dead_p (1, operands[2])"
20385 [(set (match_dup 0)
20386 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20389 (and:QI (match_dup 2) (match_dup 3)))])]
20393 [(set (match_operand 0 "flags_reg_operand" "")
20394 (match_operator 1 "compare_operator"
20397 (match_operand 2 "ext_register_operand" "")
20400 (match_operand 3 "const_int_operand" ""))
20402 "! TARGET_PARTIAL_REG_STALL
20403 && ix86_match_ccmode (insn, CCNOmode)
20404 && true_regnum (operands[2]) != 0
20405 && peep2_reg_dead_p (1, operands[2])"
20406 [(parallel [(set (match_dup 0)
20415 (set (zero_extract:SI (match_dup 2)
20426 ;; Don't do logical operations with memory inputs.
20428 [(match_scratch:SI 2 "r")
20429 (parallel [(set (match_operand:SI 0 "register_operand" "")
20430 (match_operator:SI 3 "arith_or_logical_operator"
20432 (match_operand:SI 1 "memory_operand" "")]))
20433 (clobber (reg:CC FLAGS_REG))])]
20434 "! optimize_size && ! TARGET_READ_MODIFY"
20435 [(set (match_dup 2) (match_dup 1))
20436 (parallel [(set (match_dup 0)
20437 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20438 (clobber (reg:CC FLAGS_REG))])]
20442 [(match_scratch:SI 2 "r")
20443 (parallel [(set (match_operand:SI 0 "register_operand" "")
20444 (match_operator:SI 3 "arith_or_logical_operator"
20445 [(match_operand:SI 1 "memory_operand" "")
20447 (clobber (reg:CC FLAGS_REG))])]
20448 "! optimize_size && ! TARGET_READ_MODIFY"
20449 [(set (match_dup 2) (match_dup 1))
20450 (parallel [(set (match_dup 0)
20451 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20452 (clobber (reg:CC FLAGS_REG))])]
20455 ; Don't do logical operations with memory outputs
20457 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20458 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20459 ; the same decoder scheduling characteristics as the original.
20462 [(match_scratch:SI 2 "r")
20463 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20464 (match_operator:SI 3 "arith_or_logical_operator"
20466 (match_operand:SI 1 "nonmemory_operand" "")]))
20467 (clobber (reg:CC FLAGS_REG))])]
20468 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20469 [(set (match_dup 2) (match_dup 0))
20470 (parallel [(set (match_dup 2)
20471 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20472 (clobber (reg:CC FLAGS_REG))])
20473 (set (match_dup 0) (match_dup 2))]
20477 [(match_scratch:SI 2 "r")
20478 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20479 (match_operator:SI 3 "arith_or_logical_operator"
20480 [(match_operand:SI 1 "nonmemory_operand" "")
20482 (clobber (reg:CC FLAGS_REG))])]
20483 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20484 [(set (match_dup 2) (match_dup 0))
20485 (parallel [(set (match_dup 2)
20486 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20487 (clobber (reg:CC FLAGS_REG))])
20488 (set (match_dup 0) (match_dup 2))]
20491 ;; Attempt to always use XOR for zeroing registers.
20493 [(set (match_operand 0 "register_operand" "")
20494 (match_operand 1 "const0_operand" ""))]
20495 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20496 && (! TARGET_USE_MOV0 || optimize_size)
20497 && GENERAL_REG_P (operands[0])
20498 && peep2_regno_dead_p (0, FLAGS_REG)"
20499 [(parallel [(set (match_dup 0) (const_int 0))
20500 (clobber (reg:CC FLAGS_REG))])]
20502 operands[0] = gen_lowpart (word_mode, operands[0]);
20506 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20508 "(GET_MODE (operands[0]) == QImode
20509 || GET_MODE (operands[0]) == HImode)
20510 && (! TARGET_USE_MOV0 || optimize_size)
20511 && peep2_regno_dead_p (0, FLAGS_REG)"
20512 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20513 (clobber (reg:CC FLAGS_REG))])])
20515 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20517 [(set (match_operand 0 "register_operand" "")
20519 "(GET_MODE (operands[0]) == HImode
20520 || GET_MODE (operands[0]) == SImode
20521 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20522 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20523 && peep2_regno_dead_p (0, FLAGS_REG)"
20524 [(parallel [(set (match_dup 0) (const_int -1))
20525 (clobber (reg:CC FLAGS_REG))])]
20526 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20529 ;; Attempt to convert simple leas to adds. These can be created by
20532 [(set (match_operand:SI 0 "register_operand" "")
20533 (plus:SI (match_dup 0)
20534 (match_operand:SI 1 "nonmemory_operand" "")))]
20535 "peep2_regno_dead_p (0, FLAGS_REG)"
20536 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20537 (clobber (reg:CC FLAGS_REG))])]
20541 [(set (match_operand:SI 0 "register_operand" "")
20542 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20543 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20544 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20545 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20546 (clobber (reg:CC FLAGS_REG))])]
20547 "operands[2] = gen_lowpart (SImode, operands[2]);")
20550 [(set (match_operand:DI 0 "register_operand" "")
20551 (plus:DI (match_dup 0)
20552 (match_operand:DI 1 "x86_64_general_operand" "")))]
20553 "peep2_regno_dead_p (0, FLAGS_REG)"
20554 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20555 (clobber (reg:CC FLAGS_REG))])]
20559 [(set (match_operand:SI 0 "register_operand" "")
20560 (mult:SI (match_dup 0)
20561 (match_operand:SI 1 "const_int_operand" "")))]
20562 "exact_log2 (INTVAL (operands[1])) >= 0
20563 && peep2_regno_dead_p (0, FLAGS_REG)"
20564 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20565 (clobber (reg:CC FLAGS_REG))])]
20566 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20569 [(set (match_operand:DI 0 "register_operand" "")
20570 (mult:DI (match_dup 0)
20571 (match_operand:DI 1 "const_int_operand" "")))]
20572 "exact_log2 (INTVAL (operands[1])) >= 0
20573 && peep2_regno_dead_p (0, FLAGS_REG)"
20574 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20575 (clobber (reg:CC FLAGS_REG))])]
20576 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20579 [(set (match_operand:SI 0 "register_operand" "")
20580 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20581 (match_operand:DI 2 "const_int_operand" "")) 0))]
20582 "exact_log2 (INTVAL (operands[2])) >= 0
20583 && REGNO (operands[0]) == REGNO (operands[1])
20584 && peep2_regno_dead_p (0, FLAGS_REG)"
20585 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20586 (clobber (reg:CC FLAGS_REG))])]
20587 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20589 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20590 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20591 ;; many CPUs it is also faster, since special hardware to avoid esp
20592 ;; dependencies is present.
20594 ;; While some of these conversions may be done using splitters, we use peepholes
20595 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20597 ;; Convert prologue esp subtractions to push.
20598 ;; We need register to push. In order to keep verify_flow_info happy we have
20600 ;; - use scratch and clobber it in order to avoid dependencies
20601 ;; - use already live register
20602 ;; We can't use the second way right now, since there is no reliable way how to
20603 ;; verify that given register is live. First choice will also most likely in
20604 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20605 ;; call clobbered registers are dead. We may want to use base pointer as an
20606 ;; alternative when no register is available later.
20609 [(match_scratch:SI 0 "r")
20610 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20611 (clobber (reg:CC FLAGS_REG))
20612 (clobber (mem:BLK (scratch)))])]
20613 "optimize_size || !TARGET_SUB_ESP_4"
20614 [(clobber (match_dup 0))
20615 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20616 (clobber (mem:BLK (scratch)))])])
20619 [(match_scratch:SI 0 "r")
20620 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20621 (clobber (reg:CC FLAGS_REG))
20622 (clobber (mem:BLK (scratch)))])]
20623 "optimize_size || !TARGET_SUB_ESP_8"
20624 [(clobber (match_dup 0))
20625 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20626 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20627 (clobber (mem:BLK (scratch)))])])
20629 ;; Convert esp subtractions to push.
20631 [(match_scratch:SI 0 "r")
20632 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20633 (clobber (reg:CC FLAGS_REG))])]
20634 "optimize_size || !TARGET_SUB_ESP_4"
20635 [(clobber (match_dup 0))
20636 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20639 [(match_scratch:SI 0 "r")
20640 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20641 (clobber (reg:CC FLAGS_REG))])]
20642 "optimize_size || !TARGET_SUB_ESP_8"
20643 [(clobber (match_dup 0))
20644 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20645 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20647 ;; Convert epilogue deallocator to pop.
20649 [(match_scratch:SI 0 "r")
20650 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20651 (clobber (reg:CC FLAGS_REG))
20652 (clobber (mem:BLK (scratch)))])]
20653 "optimize_size || !TARGET_ADD_ESP_4"
20654 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20655 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20656 (clobber (mem:BLK (scratch)))])]
20659 ;; Two pops case is tricky, since pop causes dependency on destination register.
20660 ;; We use two registers if available.
20662 [(match_scratch:SI 0 "r")
20663 (match_scratch:SI 1 "r")
20664 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20665 (clobber (reg:CC FLAGS_REG))
20666 (clobber (mem:BLK (scratch)))])]
20667 "optimize_size || !TARGET_ADD_ESP_8"
20668 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20669 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20670 (clobber (mem:BLK (scratch)))])
20671 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20672 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20676 [(match_scratch:SI 0 "r")
20677 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20678 (clobber (reg:CC FLAGS_REG))
20679 (clobber (mem:BLK (scratch)))])]
20681 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20682 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20683 (clobber (mem:BLK (scratch)))])
20684 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20685 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20688 ;; Convert esp additions to pop.
20690 [(match_scratch:SI 0 "r")
20691 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20692 (clobber (reg:CC FLAGS_REG))])]
20694 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20695 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20698 ;; Two pops case is tricky, since pop causes dependency on destination register.
20699 ;; We use two registers if available.
20701 [(match_scratch:SI 0 "r")
20702 (match_scratch:SI 1 "r")
20703 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20704 (clobber (reg:CC FLAGS_REG))])]
20706 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20707 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20708 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20709 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20713 [(match_scratch:SI 0 "r")
20714 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20715 (clobber (reg:CC FLAGS_REG))])]
20717 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20718 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20719 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20720 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20723 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20724 ;; required and register dies. Similarly for 128 to plus -128.
20726 [(set (match_operand 0 "flags_reg_operand" "")
20727 (match_operator 1 "compare_operator"
20728 [(match_operand 2 "register_operand" "")
20729 (match_operand 3 "const_int_operand" "")]))]
20730 "(INTVAL (operands[3]) == -1
20731 || INTVAL (operands[3]) == 1
20732 || INTVAL (operands[3]) == 128)
20733 && ix86_match_ccmode (insn, CCGCmode)
20734 && peep2_reg_dead_p (1, operands[2])"
20735 [(parallel [(set (match_dup 0)
20736 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20737 (clobber (match_dup 2))])]
20741 [(match_scratch:DI 0 "r")
20742 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20743 (clobber (reg:CC FLAGS_REG))
20744 (clobber (mem:BLK (scratch)))])]
20745 "optimize_size || !TARGET_SUB_ESP_4"
20746 [(clobber (match_dup 0))
20747 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20748 (clobber (mem:BLK (scratch)))])])
20751 [(match_scratch:DI 0 "r")
20752 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20753 (clobber (reg:CC FLAGS_REG))
20754 (clobber (mem:BLK (scratch)))])]
20755 "optimize_size || !TARGET_SUB_ESP_8"
20756 [(clobber (match_dup 0))
20757 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20758 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20759 (clobber (mem:BLK (scratch)))])])
20761 ;; Convert esp subtractions to push.
20763 [(match_scratch:DI 0 "r")
20764 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20765 (clobber (reg:CC FLAGS_REG))])]
20766 "optimize_size || !TARGET_SUB_ESP_4"
20767 [(clobber (match_dup 0))
20768 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20771 [(match_scratch:DI 0 "r")
20772 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20773 (clobber (reg:CC FLAGS_REG))])]
20774 "optimize_size || !TARGET_SUB_ESP_8"
20775 [(clobber (match_dup 0))
20776 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20777 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20779 ;; Convert epilogue deallocator to pop.
20781 [(match_scratch:DI 0 "r")
20782 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20783 (clobber (reg:CC FLAGS_REG))
20784 (clobber (mem:BLK (scratch)))])]
20785 "optimize_size || !TARGET_ADD_ESP_4"
20786 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20787 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20788 (clobber (mem:BLK (scratch)))])]
20791 ;; Two pops case is tricky, since pop causes dependency on destination register.
20792 ;; We use two registers if available.
20794 [(match_scratch:DI 0 "r")
20795 (match_scratch:DI 1 "r")
20796 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20797 (clobber (reg:CC FLAGS_REG))
20798 (clobber (mem:BLK (scratch)))])]
20799 "optimize_size || !TARGET_ADD_ESP_8"
20800 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20801 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20802 (clobber (mem:BLK (scratch)))])
20803 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20804 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20808 [(match_scratch:DI 0 "r")
20809 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20810 (clobber (reg:CC FLAGS_REG))
20811 (clobber (mem:BLK (scratch)))])]
20813 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20814 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20815 (clobber (mem:BLK (scratch)))])
20816 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20817 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20820 ;; Convert esp additions to pop.
20822 [(match_scratch:DI 0 "r")
20823 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20824 (clobber (reg:CC FLAGS_REG))])]
20826 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20827 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20830 ;; Two pops case is tricky, since pop causes dependency on destination register.
20831 ;; We use two registers if available.
20833 [(match_scratch:DI 0 "r")
20834 (match_scratch:DI 1 "r")
20835 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20836 (clobber (reg:CC FLAGS_REG))])]
20838 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20839 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20840 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20841 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20845 [(match_scratch:DI 0 "r")
20846 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20847 (clobber (reg:CC FLAGS_REG))])]
20849 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20850 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20851 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20852 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20855 ;; Convert imul by three, five and nine into lea
20858 [(set (match_operand:SI 0 "register_operand" "")
20859 (mult:SI (match_operand:SI 1 "register_operand" "")
20860 (match_operand:SI 2 "const_int_operand" "")))
20861 (clobber (reg:CC FLAGS_REG))])]
20862 "INTVAL (operands[2]) == 3
20863 || INTVAL (operands[2]) == 5
20864 || INTVAL (operands[2]) == 9"
20865 [(set (match_dup 0)
20866 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20868 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20872 [(set (match_operand:SI 0 "register_operand" "")
20873 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20874 (match_operand:SI 2 "const_int_operand" "")))
20875 (clobber (reg:CC FLAGS_REG))])]
20877 && (INTVAL (operands[2]) == 3
20878 || INTVAL (operands[2]) == 5
20879 || INTVAL (operands[2]) == 9)"
20880 [(set (match_dup 0) (match_dup 1))
20882 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20884 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20888 [(set (match_operand:DI 0 "register_operand" "")
20889 (mult:DI (match_operand:DI 1 "register_operand" "")
20890 (match_operand:DI 2 "const_int_operand" "")))
20891 (clobber (reg:CC FLAGS_REG))])]
20893 && (INTVAL (operands[2]) == 3
20894 || INTVAL (operands[2]) == 5
20895 || INTVAL (operands[2]) == 9)"
20896 [(set (match_dup 0)
20897 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20899 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20903 [(set (match_operand:DI 0 "register_operand" "")
20904 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20905 (match_operand:DI 2 "const_int_operand" "")))
20906 (clobber (reg:CC FLAGS_REG))])]
20909 && (INTVAL (operands[2]) == 3
20910 || INTVAL (operands[2]) == 5
20911 || INTVAL (operands[2]) == 9)"
20912 [(set (match_dup 0) (match_dup 1))
20914 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20916 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20918 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20919 ;; imul $32bit_imm, reg, reg is direct decoded.
20921 [(match_scratch:DI 3 "r")
20922 (parallel [(set (match_operand:DI 0 "register_operand" "")
20923 (mult:DI (match_operand:DI 1 "memory_operand" "")
20924 (match_operand:DI 2 "immediate_operand" "")))
20925 (clobber (reg:CC FLAGS_REG))])]
20926 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20927 && !satisfies_constraint_K (operands[2])"
20928 [(set (match_dup 3) (match_dup 1))
20929 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20930 (clobber (reg:CC FLAGS_REG))])]
20934 [(match_scratch:SI 3 "r")
20935 (parallel [(set (match_operand:SI 0 "register_operand" "")
20936 (mult:SI (match_operand:SI 1 "memory_operand" "")
20937 (match_operand:SI 2 "immediate_operand" "")))
20938 (clobber (reg:CC FLAGS_REG))])]
20939 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20940 && !satisfies_constraint_K (operands[2])"
20941 [(set (match_dup 3) (match_dup 1))
20942 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20943 (clobber (reg:CC FLAGS_REG))])]
20947 [(match_scratch:SI 3 "r")
20948 (parallel [(set (match_operand:DI 0 "register_operand" "")
20950 (mult:SI (match_operand:SI 1 "memory_operand" "")
20951 (match_operand:SI 2 "immediate_operand" ""))))
20952 (clobber (reg:CC FLAGS_REG))])]
20953 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20954 && !satisfies_constraint_K (operands[2])"
20955 [(set (match_dup 3) (match_dup 1))
20956 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20957 (clobber (reg:CC FLAGS_REG))])]
20960 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20961 ;; Convert it into imul reg, reg
20962 ;; It would be better to force assembler to encode instruction using long
20963 ;; immediate, but there is apparently no way to do so.
20965 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20966 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20967 (match_operand:DI 2 "const_int_operand" "")))
20968 (clobber (reg:CC FLAGS_REG))])
20969 (match_scratch:DI 3 "r")]
20970 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20971 && satisfies_constraint_K (operands[2])"
20972 [(set (match_dup 3) (match_dup 2))
20973 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20974 (clobber (reg:CC FLAGS_REG))])]
20976 if (!rtx_equal_p (operands[0], operands[1]))
20977 emit_move_insn (operands[0], operands[1]);
20981 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20982 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20983 (match_operand:SI 2 "const_int_operand" "")))
20984 (clobber (reg:CC FLAGS_REG))])
20985 (match_scratch:SI 3 "r")]
20986 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20987 && satisfies_constraint_K (operands[2])"
20988 [(set (match_dup 3) (match_dup 2))
20989 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20990 (clobber (reg:CC FLAGS_REG))])]
20992 if (!rtx_equal_p (operands[0], operands[1]))
20993 emit_move_insn (operands[0], operands[1]);
20997 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20998 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20999 (match_operand:HI 2 "immediate_operand" "")))
21000 (clobber (reg:CC FLAGS_REG))])
21001 (match_scratch:HI 3 "r")]
21002 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
21003 [(set (match_dup 3) (match_dup 2))
21004 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21005 (clobber (reg:CC FLAGS_REG))])]
21007 if (!rtx_equal_p (operands[0], operands[1]))
21008 emit_move_insn (operands[0], operands[1]);
21011 ;; After splitting up read-modify operations, array accesses with memory
21012 ;; operands might end up in form:
21014 ;; movl 4(%esp), %edx
21016 ;; instead of pre-splitting:
21018 ;; addl 4(%esp), %eax
21020 ;; movl 4(%esp), %edx
21021 ;; leal (%edx,%eax,4), %eax
21024 [(parallel [(set (match_operand 0 "register_operand" "")
21025 (ashift (match_operand 1 "register_operand" "")
21026 (match_operand 2 "const_int_operand" "")))
21027 (clobber (reg:CC FLAGS_REG))])
21028 (set (match_operand 3 "register_operand")
21029 (match_operand 4 "x86_64_general_operand" ""))
21030 (parallel [(set (match_operand 5 "register_operand" "")
21031 (plus (match_operand 6 "register_operand" "")
21032 (match_operand 7 "register_operand" "")))
21033 (clobber (reg:CC FLAGS_REG))])]
21034 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21035 /* Validate MODE for lea. */
21036 && ((!TARGET_PARTIAL_REG_STALL
21037 && (GET_MODE (operands[0]) == QImode
21038 || GET_MODE (operands[0]) == HImode))
21039 || GET_MODE (operands[0]) == SImode
21040 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21041 /* We reorder load and the shift. */
21042 && !rtx_equal_p (operands[1], operands[3])
21043 && !reg_overlap_mentioned_p (operands[0], operands[4])
21044 /* Last PLUS must consist of operand 0 and 3. */
21045 && !rtx_equal_p (operands[0], operands[3])
21046 && (rtx_equal_p (operands[3], operands[6])
21047 || rtx_equal_p (operands[3], operands[7]))
21048 && (rtx_equal_p (operands[0], operands[6])
21049 || rtx_equal_p (operands[0], operands[7]))
21050 /* The intermediate operand 0 must die or be same as output. */
21051 && (rtx_equal_p (operands[0], operands[5])
21052 || peep2_reg_dead_p (3, operands[0]))"
21053 [(set (match_dup 3) (match_dup 4))
21054 (set (match_dup 0) (match_dup 1))]
21056 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21057 int scale = 1 << INTVAL (operands[2]);
21058 rtx index = gen_lowpart (Pmode, operands[1]);
21059 rtx base = gen_lowpart (Pmode, operands[3]);
21060 rtx dest = gen_lowpart (mode, operands[5]);
21062 operands[1] = gen_rtx_PLUS (Pmode, base,
21063 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21065 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21066 operands[0] = dest;
21069 ;; Call-value patterns last so that the wildcard operand does not
21070 ;; disrupt insn-recog's switch tables.
21072 (define_insn "*call_value_pop_0"
21073 [(set (match_operand 0 "" "")
21074 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21075 (match_operand:SI 2 "" "")))
21076 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21077 (match_operand:SI 3 "immediate_operand" "")))]
21080 if (SIBLING_CALL_P (insn))
21083 return "call\t%P1";
21085 [(set_attr "type" "callv")])
21087 (define_insn "*call_value_pop_1"
21088 [(set (match_operand 0 "" "")
21089 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21090 (match_operand:SI 2 "" "")))
21091 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21092 (match_operand:SI 3 "immediate_operand" "i")))]
21095 if (constant_call_address_operand (operands[1], Pmode))
21097 if (SIBLING_CALL_P (insn))
21100 return "call\t%P1";
21102 if (SIBLING_CALL_P (insn))
21105 return "call\t%A1";
21107 [(set_attr "type" "callv")])
21109 (define_insn "*call_value_0"
21110 [(set (match_operand 0 "" "")
21111 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21112 (match_operand:SI 2 "" "")))]
21115 if (SIBLING_CALL_P (insn))
21118 return "call\t%P1";
21120 [(set_attr "type" "callv")])
21122 (define_insn "*call_value_0_rex64"
21123 [(set (match_operand 0 "" "")
21124 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21125 (match_operand:DI 2 "const_int_operand" "")))]
21128 if (SIBLING_CALL_P (insn))
21131 return "call\t%P1";
21133 [(set_attr "type" "callv")])
21135 (define_insn "*call_value_1"
21136 [(set (match_operand 0 "" "")
21137 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21138 (match_operand:SI 2 "" "")))]
21139 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21141 if (constant_call_address_operand (operands[1], Pmode))
21142 return "call\t%P1";
21143 return "call\t%A1";
21145 [(set_attr "type" "callv")])
21147 (define_insn "*sibcall_value_1"
21148 [(set (match_operand 0 "" "")
21149 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21150 (match_operand:SI 2 "" "")))]
21151 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21153 if (constant_call_address_operand (operands[1], Pmode))
21157 [(set_attr "type" "callv")])
21159 (define_insn "*call_value_1_rex64"
21160 [(set (match_operand 0 "" "")
21161 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21162 (match_operand:DI 2 "" "")))]
21163 "!SIBLING_CALL_P (insn) && TARGET_64BIT
21164 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21166 if (constant_call_address_operand (operands[1], Pmode))
21167 return "call\t%P1";
21168 return "call\t%A1";
21170 [(set_attr "type" "callv")])
21172 (define_insn "*call_value_1_rex64_large"
21173 [(set (match_operand 0 "" "")
21174 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21175 (match_operand:DI 2 "" "")))]
21176 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21178 [(set_attr "type" "callv")])
21180 (define_insn "*sibcall_value_1_rex64"
21181 [(set (match_operand 0 "" "")
21182 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21183 (match_operand:DI 2 "" "")))]
21184 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21186 [(set_attr "type" "callv")])
21188 (define_insn "*sibcall_value_1_rex64_v"
21189 [(set (match_operand 0 "" "")
21190 (call (mem:QI (reg:DI R11_REG))
21191 (match_operand:DI 1 "" "")))]
21192 "SIBLING_CALL_P (insn) && TARGET_64BIT"
21194 [(set_attr "type" "callv")])
21196 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21197 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21198 ;; caught for use by garbage collectors and the like. Using an insn that
21199 ;; maps to SIGILL makes it more likely the program will rightfully die.
21200 ;; Keeping with tradition, "6" is in honor of #UD.
21201 (define_insn "trap"
21202 [(trap_if (const_int 1) (const_int 6))]
21204 { return ASM_SHORT "0x0b0f"; }
21205 [(set_attr "length" "2")])
21207 (define_expand "sse_prologue_save"
21208 [(parallel [(set (match_operand:BLK 0 "" "")
21209 (unspec:BLK [(reg:DI 21)
21216 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21217 (use (match_operand:DI 1 "register_operand" ""))
21218 (use (match_operand:DI 2 "immediate_operand" ""))
21219 (use (label_ref:DI (match_operand 3 "" "")))])]
21223 (define_insn "*sse_prologue_save_insn"
21224 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21225 (match_operand:DI 4 "const_int_operand" "n")))
21226 (unspec:BLK [(reg:DI 21)
21233 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21234 (use (match_operand:DI 1 "register_operand" "r"))
21235 (use (match_operand:DI 2 "const_int_operand" "i"))
21236 (use (label_ref:DI (match_operand 3 "" "X")))]
21238 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21239 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21243 operands[0] = gen_rtx_MEM (Pmode,
21244 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21245 output_asm_insn (\"jmp\\t%A1\", operands);
21246 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21248 operands[4] = adjust_address (operands[0], DImode, i*16);
21249 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21250 PUT_MODE (operands[4], TImode);
21251 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21252 output_asm_insn (\"rex\", operands);
21253 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21255 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21256 CODE_LABEL_NUMBER (operands[3]));
21260 [(set_attr "type" "other")
21261 (set_attr "length_immediate" "0")
21262 (set_attr "length_address" "0")
21263 (set_attr "length" "135")
21264 (set_attr "memory" "store")
21265 (set_attr "modrm" "0")
21266 (set_attr "mode" "DI")])
21268 (define_expand "prefetch"
21269 [(prefetch (match_operand 0 "address_operand" "")
21270 (match_operand:SI 1 "const_int_operand" "")
21271 (match_operand:SI 2 "const_int_operand" ""))]
21272 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21274 int rw = INTVAL (operands[1]);
21275 int locality = INTVAL (operands[2]);
21277 gcc_assert (rw == 0 || rw == 1);
21278 gcc_assert (locality >= 0 && locality <= 3);
21279 gcc_assert (GET_MODE (operands[0]) == Pmode
21280 || GET_MODE (operands[0]) == VOIDmode);
21282 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21283 supported by SSE counterpart or the SSE prefetch is not available
21284 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21286 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21287 operands[2] = GEN_INT (3);
21289 operands[1] = const0_rtx;
21292 (define_insn "*prefetch_sse"
21293 [(prefetch (match_operand:SI 0 "address_operand" "p")
21295 (match_operand:SI 1 "const_int_operand" ""))]
21296 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21298 static const char * const patterns[4] = {
21299 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21302 int locality = INTVAL (operands[1]);
21303 gcc_assert (locality >= 0 && locality <= 3);
21305 return patterns[locality];
21307 [(set_attr "type" "sse")
21308 (set_attr "memory" "none")])
21310 (define_insn "*prefetch_sse_rex"
21311 [(prefetch (match_operand:DI 0 "address_operand" "p")
21313 (match_operand:SI 1 "const_int_operand" ""))]
21314 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21316 static const char * const patterns[4] = {
21317 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21320 int locality = INTVAL (operands[1]);
21321 gcc_assert (locality >= 0 && locality <= 3);
21323 return patterns[locality];
21325 [(set_attr "type" "sse")
21326 (set_attr "memory" "none")])
21328 (define_insn "*prefetch_3dnow"
21329 [(prefetch (match_operand:SI 0 "address_operand" "p")
21330 (match_operand:SI 1 "const_int_operand" "n")
21332 "TARGET_3DNOW && !TARGET_64BIT"
21334 if (INTVAL (operands[1]) == 0)
21335 return "prefetch\t%a0";
21337 return "prefetchw\t%a0";
21339 [(set_attr "type" "mmx")
21340 (set_attr "memory" "none")])
21342 (define_insn "*prefetch_3dnow_rex"
21343 [(prefetch (match_operand:DI 0 "address_operand" "p")
21344 (match_operand:SI 1 "const_int_operand" "n")
21346 "TARGET_3DNOW && TARGET_64BIT"
21348 if (INTVAL (operands[1]) == 0)
21349 return "prefetch\t%a0";
21351 return "prefetchw\t%a0";
21353 [(set_attr "type" "mmx")
21354 (set_attr "memory" "none")])
21356 (define_expand "stack_protect_set"
21357 [(match_operand 0 "memory_operand" "")
21358 (match_operand 1 "memory_operand" "")]
21361 #ifdef TARGET_THREAD_SSP_OFFSET
21363 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21364 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21366 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21367 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21370 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21372 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21377 (define_insn "stack_protect_set_si"
21378 [(set (match_operand:SI 0 "memory_operand" "=m")
21379 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21380 (set (match_scratch:SI 2 "=&r") (const_int 0))
21381 (clobber (reg:CC FLAGS_REG))]
21383 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21384 [(set_attr "type" "multi")])
21386 (define_insn "stack_protect_set_di"
21387 [(set (match_operand:DI 0 "memory_operand" "=m")
21388 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21389 (set (match_scratch:DI 2 "=&r") (const_int 0))
21390 (clobber (reg:CC FLAGS_REG))]
21392 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21393 [(set_attr "type" "multi")])
21395 (define_insn "stack_tls_protect_set_si"
21396 [(set (match_operand:SI 0 "memory_operand" "=m")
21397 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21398 (set (match_scratch:SI 2 "=&r") (const_int 0))
21399 (clobber (reg:CC FLAGS_REG))]
21401 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21402 [(set_attr "type" "multi")])
21404 (define_insn "stack_tls_protect_set_di"
21405 [(set (match_operand:DI 0 "memory_operand" "=m")
21406 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21407 (set (match_scratch:DI 2 "=&r") (const_int 0))
21408 (clobber (reg:CC FLAGS_REG))]
21411 /* The kernel uses a different segment register for performance reasons; a
21412 system call would not have to trash the userspace segment register,
21413 which would be expensive */
21414 if (ix86_cmodel != CM_KERNEL)
21415 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21417 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21419 [(set_attr "type" "multi")])
21421 (define_expand "stack_protect_test"
21422 [(match_operand 0 "memory_operand" "")
21423 (match_operand 1 "memory_operand" "")
21424 (match_operand 2 "" "")]
21427 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21428 ix86_compare_op0 = operands[0];
21429 ix86_compare_op1 = operands[1];
21430 ix86_compare_emitted = flags;
21432 #ifdef TARGET_THREAD_SSP_OFFSET
21434 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21435 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21437 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21438 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21441 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21443 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21445 emit_jump_insn (gen_beq (operands[2]));
21449 (define_insn "stack_protect_test_si"
21450 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21451 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21452 (match_operand:SI 2 "memory_operand" "m")]
21454 (clobber (match_scratch:SI 3 "=&r"))]
21456 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21457 [(set_attr "type" "multi")])
21459 (define_insn "stack_protect_test_di"
21460 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21461 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21462 (match_operand:DI 2 "memory_operand" "m")]
21464 (clobber (match_scratch:DI 3 "=&r"))]
21466 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21467 [(set_attr "type" "multi")])
21469 (define_insn "stack_tls_protect_test_si"
21470 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21471 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21472 (match_operand:SI 2 "const_int_operand" "i")]
21473 UNSPEC_SP_TLS_TEST))
21474 (clobber (match_scratch:SI 3 "=r"))]
21476 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21477 [(set_attr "type" "multi")])
21479 (define_insn "stack_tls_protect_test_di"
21480 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21481 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21482 (match_operand:DI 2 "const_int_operand" "i")]
21483 UNSPEC_SP_TLS_TEST))
21484 (clobber (match_scratch:DI 3 "=r"))]
21487 /* The kernel uses a different segment register for performance reasons; a
21488 system call would not have to trash the userspace segment register,
21489 which would be expensive */
21490 if (ix86_cmodel != CM_KERNEL)
21491 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21493 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21495 [(set_attr "type" "multi")])
21497 (define_mode_iterator CRC32MODE [QI HI SI])
21498 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21499 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21501 (define_insn "sse4_2_crc32<mode>"
21502 [(set (match_operand:SI 0 "register_operand" "=r")
21504 [(match_operand:SI 1 "register_operand" "0")
21505 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21508 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21509 [(set_attr "type" "sselog1")
21510 (set_attr "prefix_rep" "1")
21511 (set_attr "prefix_extra" "1")
21512 (set_attr "mode" "SI")])
21514 (define_insn "sse4_2_crc32di"
21515 [(set (match_operand:DI 0 "register_operand" "=r")
21517 [(match_operand:DI 1 "register_operand" "0")
21518 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21520 "TARGET_SSE4_2 && TARGET_64BIT"
21521 "crc32q\t{%2, %0|%0, %2}"
21522 [(set_attr "type" "sselog1")
21523 (set_attr "prefix_rep" "1")
21524 (set_attr "prefix_extra" "1")
21525 (set_attr "mode" "DI")])
21529 (include "sync.md")