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 ;; All x87 floating point modes
519 (define_mode_iterator X87MODEF [SF DF XF])
521 ;; x87 SFmode and DFMode floating point modes
522 (define_mode_iterator X87MODEF12 [SF DF])
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 SSE floating point modes
531 (define_mode_iterator SSEMODEF [SF DF])
533 ;; All integer modes handled by SSE cvtts?2si* operators.
534 (define_mode_iterator SSEMODEI24 [SI DI])
536 ;; SSE asm suffix for floating point modes
537 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
539 ;; SSE vector mode corresponding to a scalar mode
540 (define_mode_attr ssevecmode
541 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
543 ;; Scheduling descriptions
545 (include "pentium.md")
548 (include "athlon.md")
552 ;; Operand and operator predicates and constraints
554 (include "predicates.md")
555 (include "constraints.md")
558 ;; Compare instructions.
560 ;; All compare insns have expanders that save the operands away without
561 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
562 ;; after the cmp) will actually emit the cmpM.
564 (define_expand "cmpti"
565 [(set (reg:CC FLAGS_REG)
566 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
567 (match_operand:TI 1 "x86_64_general_operand" "")))]
570 if (MEM_P (operands[0]) && MEM_P (operands[1]))
571 operands[0] = force_reg (TImode, operands[0]);
572 ix86_compare_op0 = operands[0];
573 ix86_compare_op1 = operands[1];
577 (define_expand "cmpdi"
578 [(set (reg:CC FLAGS_REG)
579 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
580 (match_operand:DI 1 "x86_64_general_operand" "")))]
583 if (MEM_P (operands[0]) && MEM_P (operands[1]))
584 operands[0] = force_reg (DImode, operands[0]);
585 ix86_compare_op0 = operands[0];
586 ix86_compare_op1 = operands[1];
590 (define_expand "cmpsi"
591 [(set (reg:CC FLAGS_REG)
592 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
593 (match_operand:SI 1 "general_operand" "")))]
596 if (MEM_P (operands[0]) && MEM_P (operands[1]))
597 operands[0] = force_reg (SImode, operands[0]);
598 ix86_compare_op0 = operands[0];
599 ix86_compare_op1 = operands[1];
603 (define_expand "cmphi"
604 [(set (reg:CC FLAGS_REG)
605 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
606 (match_operand:HI 1 "general_operand" "")))]
609 if (MEM_P (operands[0]) && MEM_P (operands[1]))
610 operands[0] = force_reg (HImode, operands[0]);
611 ix86_compare_op0 = operands[0];
612 ix86_compare_op1 = operands[1];
616 (define_expand "cmpqi"
617 [(set (reg:CC FLAGS_REG)
618 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
619 (match_operand:QI 1 "general_operand" "")))]
622 if (MEM_P (operands[0]) && MEM_P (operands[1]))
623 operands[0] = force_reg (QImode, operands[0]);
624 ix86_compare_op0 = operands[0];
625 ix86_compare_op1 = operands[1];
629 (define_insn "cmpdi_ccno_1_rex64"
630 [(set (reg FLAGS_REG)
631 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
632 (match_operand:DI 1 "const0_operand" "n,n")))]
633 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
636 cmp{q}\t{%1, %0|%0, %1}"
637 [(set_attr "type" "test,icmp")
638 (set_attr "length_immediate" "0,1")
639 (set_attr "mode" "DI")])
641 (define_insn "*cmpdi_minus_1_rex64"
642 [(set (reg FLAGS_REG)
643 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
644 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
646 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
647 "cmp{q}\t{%1, %0|%0, %1}"
648 [(set_attr "type" "icmp")
649 (set_attr "mode" "DI")])
651 (define_expand "cmpdi_1_rex64"
652 [(set (reg:CC FLAGS_REG)
653 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
654 (match_operand:DI 1 "general_operand" "")))]
658 (define_insn "cmpdi_1_insn_rex64"
659 [(set (reg FLAGS_REG)
660 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
661 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
662 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
663 "cmp{q}\t{%1, %0|%0, %1}"
664 [(set_attr "type" "icmp")
665 (set_attr "mode" "DI")])
668 (define_insn "*cmpsi_ccno_1"
669 [(set (reg FLAGS_REG)
670 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
671 (match_operand:SI 1 "const0_operand" "n,n")))]
672 "ix86_match_ccmode (insn, CCNOmode)"
675 cmp{l}\t{%1, %0|%0, %1}"
676 [(set_attr "type" "test,icmp")
677 (set_attr "length_immediate" "0,1")
678 (set_attr "mode" "SI")])
680 (define_insn "*cmpsi_minus_1"
681 [(set (reg FLAGS_REG)
682 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
683 (match_operand:SI 1 "general_operand" "ri,mr"))
685 "ix86_match_ccmode (insn, CCGOCmode)"
686 "cmp{l}\t{%1, %0|%0, %1}"
687 [(set_attr "type" "icmp")
688 (set_attr "mode" "SI")])
690 (define_expand "cmpsi_1"
691 [(set (reg:CC FLAGS_REG)
692 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
693 (match_operand:SI 1 "general_operand" "ri,mr")))]
697 (define_insn "*cmpsi_1_insn"
698 [(set (reg FLAGS_REG)
699 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
700 (match_operand:SI 1 "general_operand" "ri,mr")))]
701 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
702 && ix86_match_ccmode (insn, CCmode)"
703 "cmp{l}\t{%1, %0|%0, %1}"
704 [(set_attr "type" "icmp")
705 (set_attr "mode" "SI")])
707 (define_insn "*cmphi_ccno_1"
708 [(set (reg FLAGS_REG)
709 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
710 (match_operand:HI 1 "const0_operand" "n,n")))]
711 "ix86_match_ccmode (insn, CCNOmode)"
714 cmp{w}\t{%1, %0|%0, %1}"
715 [(set_attr "type" "test,icmp")
716 (set_attr "length_immediate" "0,1")
717 (set_attr "mode" "HI")])
719 (define_insn "*cmphi_minus_1"
720 [(set (reg FLAGS_REG)
721 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
722 (match_operand:HI 1 "general_operand" "ri,mr"))
724 "ix86_match_ccmode (insn, CCGOCmode)"
725 "cmp{w}\t{%1, %0|%0, %1}"
726 [(set_attr "type" "icmp")
727 (set_attr "mode" "HI")])
729 (define_insn "*cmphi_1"
730 [(set (reg FLAGS_REG)
731 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
732 (match_operand:HI 1 "general_operand" "ri,mr")))]
733 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
734 && ix86_match_ccmode (insn, CCmode)"
735 "cmp{w}\t{%1, %0|%0, %1}"
736 [(set_attr "type" "icmp")
737 (set_attr "mode" "HI")])
739 (define_insn "*cmpqi_ccno_1"
740 [(set (reg FLAGS_REG)
741 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
742 (match_operand:QI 1 "const0_operand" "n,n")))]
743 "ix86_match_ccmode (insn, CCNOmode)"
746 cmp{b}\t{$0, %0|%0, 0}"
747 [(set_attr "type" "test,icmp")
748 (set_attr "length_immediate" "0,1")
749 (set_attr "mode" "QI")])
751 (define_insn "*cmpqi_1"
752 [(set (reg FLAGS_REG)
753 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
754 (match_operand:QI 1 "general_operand" "qi,mq")))]
755 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
756 && ix86_match_ccmode (insn, CCmode)"
757 "cmp{b}\t{%1, %0|%0, %1}"
758 [(set_attr "type" "icmp")
759 (set_attr "mode" "QI")])
761 (define_insn "*cmpqi_minus_1"
762 [(set (reg FLAGS_REG)
763 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
764 (match_operand:QI 1 "general_operand" "qi,mq"))
766 "ix86_match_ccmode (insn, CCGOCmode)"
767 "cmp{b}\t{%1, %0|%0, %1}"
768 [(set_attr "type" "icmp")
769 (set_attr "mode" "QI")])
771 (define_insn "*cmpqi_ext_1"
772 [(set (reg FLAGS_REG)
774 (match_operand:QI 0 "general_operand" "Qm")
777 (match_operand 1 "ext_register_operand" "Q")
780 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
781 "cmp{b}\t{%h1, %0|%0, %h1}"
782 [(set_attr "type" "icmp")
783 (set_attr "mode" "QI")])
785 (define_insn "*cmpqi_ext_1_rex64"
786 [(set (reg FLAGS_REG)
788 (match_operand:QI 0 "register_operand" "Q")
791 (match_operand 1 "ext_register_operand" "Q")
794 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
795 "cmp{b}\t{%h1, %0|%0, %h1}"
796 [(set_attr "type" "icmp")
797 (set_attr "mode" "QI")])
799 (define_insn "*cmpqi_ext_2"
800 [(set (reg FLAGS_REG)
804 (match_operand 0 "ext_register_operand" "Q")
807 (match_operand:QI 1 "const0_operand" "n")))]
808 "ix86_match_ccmode (insn, CCNOmode)"
810 [(set_attr "type" "test")
811 (set_attr "length_immediate" "0")
812 (set_attr "mode" "QI")])
814 (define_expand "cmpqi_ext_3"
815 [(set (reg:CC FLAGS_REG)
819 (match_operand 0 "ext_register_operand" "")
822 (match_operand:QI 1 "general_operand" "")))]
826 (define_insn "cmpqi_ext_3_insn"
827 [(set (reg FLAGS_REG)
831 (match_operand 0 "ext_register_operand" "Q")
834 (match_operand:QI 1 "general_operand" "Qmn")))]
835 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
836 "cmp{b}\t{%1, %h0|%h0, %1}"
837 [(set_attr "type" "icmp")
838 (set_attr "mode" "QI")])
840 (define_insn "cmpqi_ext_3_insn_rex64"
841 [(set (reg FLAGS_REG)
845 (match_operand 0 "ext_register_operand" "Q")
848 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
849 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
850 "cmp{b}\t{%1, %h0|%h0, %1}"
851 [(set_attr "type" "icmp")
852 (set_attr "mode" "QI")])
854 (define_insn "*cmpqi_ext_4"
855 [(set (reg FLAGS_REG)
859 (match_operand 0 "ext_register_operand" "Q")
864 (match_operand 1 "ext_register_operand" "Q")
867 "ix86_match_ccmode (insn, CCmode)"
868 "cmp{b}\t{%h1, %h0|%h0, %h1}"
869 [(set_attr "type" "icmp")
870 (set_attr "mode" "QI")])
872 ;; These implement float point compares.
873 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
874 ;; which would allow mix and match FP modes on the compares. Which is what
875 ;; the old patterns did, but with many more of them.
877 (define_expand "cmpxf"
878 [(set (reg:CC FLAGS_REG)
879 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
880 (match_operand:XF 1 "nonmemory_operand" "")))]
883 ix86_compare_op0 = operands[0];
884 ix86_compare_op1 = operands[1];
888 (define_expand "cmp<mode>"
889 [(set (reg:CC FLAGS_REG)
890 (compare:CC (match_operand:SSEMODEF 0 "cmp_fp_expander_operand" "")
891 (match_operand:SSEMODEF 1 "cmp_fp_expander_operand" "")))]
892 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
894 ix86_compare_op0 = operands[0];
895 ix86_compare_op1 = operands[1];
899 ;; FP compares, step 1:
900 ;; Set the FP condition codes.
902 ;; CCFPmode compare with exceptions
903 ;; CCFPUmode compare with no exceptions
905 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
906 ;; used to manage the reg stack popping would not be preserved.
908 (define_insn "*cmpfp_0"
909 [(set (match_operand:HI 0 "register_operand" "=a")
912 (match_operand 1 "register_operand" "f")
913 (match_operand 2 "const0_operand" "X"))]
915 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
916 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
917 "* return output_fp_compare (insn, operands, 0, 0);"
918 [(set_attr "type" "multi")
919 (set_attr "unit" "i387")
921 (cond [(match_operand:SF 1 "" "")
923 (match_operand:DF 1 "" "")
926 (const_string "XF")))])
928 (define_insn_and_split "*cmpfp_0_cc"
929 [(set (reg:CCFP FLAGS_REG)
931 (match_operand 1 "register_operand" "f")
932 (match_operand 2 "const0_operand" "X")))
933 (clobber (match_operand:HI 0 "register_operand" "=a"))]
934 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
935 && TARGET_SAHF && !TARGET_CMOVE
936 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
938 "&& reload_completed"
941 [(compare:CCFP (match_dup 1)(match_dup 2))]
943 (set (reg:CC FLAGS_REG)
944 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
946 [(set_attr "type" "multi")
947 (set_attr "unit" "i387")
949 (cond [(match_operand:SF 1 "" "")
951 (match_operand:DF 1 "" "")
954 (const_string "XF")))])
956 (define_insn "*cmpfp_xf"
957 [(set (match_operand:HI 0 "register_operand" "=a")
960 (match_operand:XF 1 "register_operand" "f")
961 (match_operand:XF 2 "register_operand" "f"))]
964 "* return output_fp_compare (insn, operands, 0, 0);"
965 [(set_attr "type" "multi")
966 (set_attr "unit" "i387")
967 (set_attr "mode" "XF")])
969 (define_insn_and_split "*cmpfp_xf_cc"
970 [(set (reg:CCFP FLAGS_REG)
972 (match_operand:XF 1 "register_operand" "f")
973 (match_operand:XF 2 "register_operand" "f")))
974 (clobber (match_operand:HI 0 "register_operand" "=a"))]
976 && TARGET_SAHF && !TARGET_CMOVE"
978 "&& reload_completed"
981 [(compare:CCFP (match_dup 1)(match_dup 2))]
983 (set (reg:CC FLAGS_REG)
984 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
986 [(set_attr "type" "multi")
987 (set_attr "unit" "i387")
988 (set_attr "mode" "XF")])
990 (define_insn "*cmpfp_<mode>"
991 [(set (match_operand:HI 0 "register_operand" "=a")
994 (match_operand:X87MODEF12 1 "register_operand" "f")
995 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm"))]
998 "* return output_fp_compare (insn, operands, 0, 0);"
999 [(set_attr "type" "multi")
1000 (set_attr "unit" "i387")
1001 (set_attr "mode" "<MODE>")])
1003 (define_insn_and_split "*cmpfp_<mode>_cc"
1004 [(set (reg:CCFP FLAGS_REG)
1006 (match_operand:X87MODEF12 1 "register_operand" "f")
1007 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm")))
1008 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1010 && TARGET_SAHF && !TARGET_CMOVE"
1012 "&& reload_completed"
1015 [(compare:CCFP (match_dup 1)(match_dup 2))]
1017 (set (reg:CC FLAGS_REG)
1018 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1020 [(set_attr "type" "multi")
1021 (set_attr "unit" "i387")
1022 (set_attr "mode" "<MODE>")])
1024 (define_insn "*cmpfp_u"
1025 [(set (match_operand:HI 0 "register_operand" "=a")
1028 (match_operand 1 "register_operand" "f")
1029 (match_operand 2 "register_operand" "f"))]
1031 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1032 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1033 "* return output_fp_compare (insn, operands, 0, 1);"
1034 [(set_attr "type" "multi")
1035 (set_attr "unit" "i387")
1037 (cond [(match_operand:SF 1 "" "")
1039 (match_operand:DF 1 "" "")
1042 (const_string "XF")))])
1044 (define_insn_and_split "*cmpfp_u_cc"
1045 [(set (reg:CCFPU FLAGS_REG)
1047 (match_operand 1 "register_operand" "f")
1048 (match_operand 2 "register_operand" "f")))
1049 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1050 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1051 && TARGET_SAHF && !TARGET_CMOVE
1052 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1054 "&& reload_completed"
1057 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1059 (set (reg:CC FLAGS_REG)
1060 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1062 [(set_attr "type" "multi")
1063 (set_attr "unit" "i387")
1065 (cond [(match_operand:SF 1 "" "")
1067 (match_operand:DF 1 "" "")
1070 (const_string "XF")))])
1072 (define_insn "*cmpfp_<mode>"
1073 [(set (match_operand:HI 0 "register_operand" "=a")
1076 (match_operand 1 "register_operand" "f")
1077 (match_operator 3 "float_operator"
1078 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1080 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1081 && TARGET_USE_<MODE>MODE_FIOP
1082 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1083 "* return output_fp_compare (insn, operands, 0, 0);"
1084 [(set_attr "type" "multi")
1085 (set_attr "unit" "i387")
1086 (set_attr "fp_int_src" "true")
1087 (set_attr "mode" "<MODE>")])
1089 (define_insn_and_split "*cmpfp_<mode>_cc"
1090 [(set (reg:CCFP FLAGS_REG)
1092 (match_operand 1 "register_operand" "f")
1093 (match_operator 3 "float_operator"
1094 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1095 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1096 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1097 && TARGET_SAHF && !TARGET_CMOVE
1098 && TARGET_USE_<MODE>MODE_FIOP
1099 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1101 "&& reload_completed"
1106 (match_op_dup 3 [(match_dup 2)]))]
1108 (set (reg:CC FLAGS_REG)
1109 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1111 [(set_attr "type" "multi")
1112 (set_attr "unit" "i387")
1113 (set_attr "fp_int_src" "true")
1114 (set_attr "mode" "<MODE>")])
1116 ;; FP compares, step 2
1117 ;; Move the fpsw to ax.
1119 (define_insn "x86_fnstsw_1"
1120 [(set (match_operand:HI 0 "register_operand" "=a")
1121 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1124 [(set_attr "length" "2")
1125 (set_attr "mode" "SI")
1126 (set_attr "unit" "i387")])
1128 ;; FP compares, step 3
1129 ;; Get ax into flags, general case.
1131 (define_insn "x86_sahf_1"
1132 [(set (reg:CC FLAGS_REG)
1133 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1137 #ifdef HAVE_AS_IX86_SAHF
1140 return ".byte\t0x9e";
1143 [(set_attr "length" "1")
1144 (set_attr "athlon_decode" "vector")
1145 (set_attr "amdfam10_decode" "direct")
1146 (set_attr "mode" "SI")])
1148 ;; Pentium Pro can do steps 1 through 3 in one go.
1149 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1150 (define_insn "*cmpfp_i_mixed"
1151 [(set (reg:CCFP FLAGS_REG)
1152 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1153 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1154 "TARGET_MIX_SSE_I387
1155 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1156 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1157 "* return output_fp_compare (insn, operands, 1, 0);"
1158 [(set_attr "type" "fcmp,ssecomi")
1160 (if_then_else (match_operand:SF 1 "" "")
1162 (const_string "DF")))
1163 (set_attr "athlon_decode" "vector")
1164 (set_attr "amdfam10_decode" "direct")])
1166 (define_insn "*cmpfp_i_sse"
1167 [(set (reg:CCFP FLAGS_REG)
1168 (compare:CCFP (match_operand 0 "register_operand" "x")
1169 (match_operand 1 "nonimmediate_operand" "xm")))]
1171 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1172 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1173 "* return output_fp_compare (insn, operands, 1, 0);"
1174 [(set_attr "type" "ssecomi")
1176 (if_then_else (match_operand:SF 1 "" "")
1178 (const_string "DF")))
1179 (set_attr "athlon_decode" "vector")
1180 (set_attr "amdfam10_decode" "direct")])
1182 (define_insn "*cmpfp_i_i387"
1183 [(set (reg:CCFP FLAGS_REG)
1184 (compare:CCFP (match_operand 0 "register_operand" "f")
1185 (match_operand 1 "register_operand" "f")))]
1186 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1188 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1189 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1190 "* return output_fp_compare (insn, operands, 1, 0);"
1191 [(set_attr "type" "fcmp")
1193 (cond [(match_operand:SF 1 "" "")
1195 (match_operand:DF 1 "" "")
1198 (const_string "XF")))
1199 (set_attr "athlon_decode" "vector")
1200 (set_attr "amdfam10_decode" "direct")])
1202 (define_insn "*cmpfp_iu_mixed"
1203 [(set (reg:CCFPU FLAGS_REG)
1204 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1205 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1206 "TARGET_MIX_SSE_I387
1207 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1208 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1209 "* return output_fp_compare (insn, operands, 1, 1);"
1210 [(set_attr "type" "fcmp,ssecomi")
1212 (if_then_else (match_operand:SF 1 "" "")
1214 (const_string "DF")))
1215 (set_attr "athlon_decode" "vector")
1216 (set_attr "amdfam10_decode" "direct")])
1218 (define_insn "*cmpfp_iu_sse"
1219 [(set (reg:CCFPU FLAGS_REG)
1220 (compare:CCFPU (match_operand 0 "register_operand" "x")
1221 (match_operand 1 "nonimmediate_operand" "xm")))]
1223 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1224 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1225 "* return output_fp_compare (insn, operands, 1, 1);"
1226 [(set_attr "type" "ssecomi")
1228 (if_then_else (match_operand:SF 1 "" "")
1230 (const_string "DF")))
1231 (set_attr "athlon_decode" "vector")
1232 (set_attr "amdfam10_decode" "direct")])
1234 (define_insn "*cmpfp_iu_387"
1235 [(set (reg:CCFPU FLAGS_REG)
1236 (compare:CCFPU (match_operand 0 "register_operand" "f")
1237 (match_operand 1 "register_operand" "f")))]
1238 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1240 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1241 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1242 "* return output_fp_compare (insn, operands, 1, 1);"
1243 [(set_attr "type" "fcmp")
1245 (cond [(match_operand:SF 1 "" "")
1247 (match_operand:DF 1 "" "")
1250 (const_string "XF")))
1251 (set_attr "athlon_decode" "vector")
1252 (set_attr "amdfam10_decode" "direct")])
1254 ;; Move instructions.
1256 ;; General case of fullword move.
1258 (define_expand "movsi"
1259 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1260 (match_operand:SI 1 "general_operand" ""))]
1262 "ix86_expand_move (SImode, operands); DONE;")
1264 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1267 ;; %%% We don't use a post-inc memory reference because x86 is not a
1268 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1269 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1270 ;; targets without our curiosities, and it is just as easy to represent
1271 ;; this differently.
1273 (define_insn "*pushsi2"
1274 [(set (match_operand:SI 0 "push_operand" "=<")
1275 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1278 [(set_attr "type" "push")
1279 (set_attr "mode" "SI")])
1281 ;; For 64BIT abi we always round up to 8 bytes.
1282 (define_insn "*pushsi2_rex64"
1283 [(set (match_operand:SI 0 "push_operand" "=X")
1284 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1287 [(set_attr "type" "push")
1288 (set_attr "mode" "SI")])
1290 (define_insn "*pushsi2_prologue"
1291 [(set (match_operand:SI 0 "push_operand" "=<")
1292 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1293 (clobber (mem:BLK (scratch)))]
1296 [(set_attr "type" "push")
1297 (set_attr "mode" "SI")])
1299 (define_insn "*popsi1_epilogue"
1300 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1301 (mem:SI (reg:SI SP_REG)))
1302 (set (reg:SI SP_REG)
1303 (plus:SI (reg:SI SP_REG) (const_int 4)))
1304 (clobber (mem:BLK (scratch)))]
1307 [(set_attr "type" "pop")
1308 (set_attr "mode" "SI")])
1310 (define_insn "popsi1"
1311 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1312 (mem:SI (reg:SI SP_REG)))
1313 (set (reg:SI SP_REG)
1314 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1317 [(set_attr "type" "pop")
1318 (set_attr "mode" "SI")])
1320 (define_insn "*movsi_xor"
1321 [(set (match_operand:SI 0 "register_operand" "=r")
1322 (match_operand:SI 1 "const0_operand" "i"))
1323 (clobber (reg:CC FLAGS_REG))]
1324 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1326 [(set_attr "type" "alu1")
1327 (set_attr "mode" "SI")
1328 (set_attr "length_immediate" "0")])
1330 (define_insn "*movsi_or"
1331 [(set (match_operand:SI 0 "register_operand" "=r")
1332 (match_operand:SI 1 "immediate_operand" "i"))
1333 (clobber (reg:CC FLAGS_REG))]
1335 && operands[1] == constm1_rtx
1336 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1338 operands[1] = constm1_rtx;
1339 return "or{l}\t{%1, %0|%0, %1}";
1341 [(set_attr "type" "alu1")
1342 (set_attr "mode" "SI")
1343 (set_attr "length_immediate" "1")])
1345 (define_insn "*movsi_1"
1346 [(set (match_operand:SI 0 "nonimmediate_operand"
1347 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1348 (match_operand:SI 1 "general_operand"
1349 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1350 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1352 switch (get_attr_type (insn))
1355 if (get_attr_mode (insn) == MODE_TI)
1356 return "pxor\t%0, %0";
1357 return "xorps\t%0, %0";
1360 switch (get_attr_mode (insn))
1363 return "movdqa\t{%1, %0|%0, %1}";
1365 return "movaps\t{%1, %0|%0, %1}";
1367 return "movd\t{%1, %0|%0, %1}";
1369 return "movss\t{%1, %0|%0, %1}";
1375 return "pxor\t%0, %0";
1378 if (get_attr_mode (insn) == MODE_DI)
1379 return "movq\t{%1, %0|%0, %1}";
1380 return "movd\t{%1, %0|%0, %1}";
1383 return "lea{l}\t{%1, %0|%0, %1}";
1386 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1387 return "mov{l}\t{%1, %0|%0, %1}";
1391 (cond [(eq_attr "alternative" "2")
1392 (const_string "mmxadd")
1393 (eq_attr "alternative" "3,4,5")
1394 (const_string "mmxmov")
1395 (eq_attr "alternative" "6")
1396 (const_string "sselog1")
1397 (eq_attr "alternative" "7,8,9,10,11")
1398 (const_string "ssemov")
1399 (match_operand:DI 1 "pic_32bit_operand" "")
1400 (const_string "lea")
1402 (const_string "imov")))
1404 (cond [(eq_attr "alternative" "2,3")
1406 (eq_attr "alternative" "6,7")
1408 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1409 (const_string "V4SF")
1410 (const_string "TI"))
1411 (and (eq_attr "alternative" "8,9,10,11")
1412 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1415 (const_string "SI")))])
1417 ;; Stores and loads of ax to arbitrary constant address.
1418 ;; We fake an second form of instruction to force reload to load address
1419 ;; into register when rax is not available
1420 (define_insn "*movabssi_1_rex64"
1421 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1422 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1423 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1425 movabs{l}\t{%1, %P0|%P0, %1}
1426 mov{l}\t{%1, %a0|%a0, %1}"
1427 [(set_attr "type" "imov")
1428 (set_attr "modrm" "0,*")
1429 (set_attr "length_address" "8,0")
1430 (set_attr "length_immediate" "0,*")
1431 (set_attr "memory" "store")
1432 (set_attr "mode" "SI")])
1434 (define_insn "*movabssi_2_rex64"
1435 [(set (match_operand:SI 0 "register_operand" "=a,r")
1436 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1437 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1439 movabs{l}\t{%P1, %0|%0, %P1}
1440 mov{l}\t{%a1, %0|%0, %a1}"
1441 [(set_attr "type" "imov")
1442 (set_attr "modrm" "0,*")
1443 (set_attr "length_address" "8,0")
1444 (set_attr "length_immediate" "0")
1445 (set_attr "memory" "load")
1446 (set_attr "mode" "SI")])
1448 (define_insn "*swapsi"
1449 [(set (match_operand:SI 0 "register_operand" "+r")
1450 (match_operand:SI 1 "register_operand" "+r"))
1455 [(set_attr "type" "imov")
1456 (set_attr "mode" "SI")
1457 (set_attr "pent_pair" "np")
1458 (set_attr "athlon_decode" "vector")
1459 (set_attr "amdfam10_decode" "double")])
1461 (define_expand "movhi"
1462 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1463 (match_operand:HI 1 "general_operand" ""))]
1465 "ix86_expand_move (HImode, operands); DONE;")
1467 (define_insn "*pushhi2"
1468 [(set (match_operand:HI 0 "push_operand" "=X")
1469 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1472 [(set_attr "type" "push")
1473 (set_attr "mode" "SI")])
1475 ;; For 64BIT abi we always round up to 8 bytes.
1476 (define_insn "*pushhi2_rex64"
1477 [(set (match_operand:HI 0 "push_operand" "=X")
1478 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1481 [(set_attr "type" "push")
1482 (set_attr "mode" "DI")])
1484 (define_insn "*movhi_1"
1485 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1486 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1487 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1489 switch (get_attr_type (insn))
1492 /* movzwl is faster than movw on p2 due to partial word stalls,
1493 though not as fast as an aligned movl. */
1494 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1496 if (get_attr_mode (insn) == MODE_SI)
1497 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1499 return "mov{w}\t{%1, %0|%0, %1}";
1503 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1504 (const_string "imov")
1505 (and (eq_attr "alternative" "0")
1506 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1508 (eq (symbol_ref "TARGET_HIMODE_MATH")
1510 (const_string "imov")
1511 (and (eq_attr "alternative" "1,2")
1512 (match_operand:HI 1 "aligned_operand" ""))
1513 (const_string "imov")
1514 (and (ne (symbol_ref "TARGET_MOVX")
1516 (eq_attr "alternative" "0,2"))
1517 (const_string "imovx")
1519 (const_string "imov")))
1521 (cond [(eq_attr "type" "imovx")
1523 (and (eq_attr "alternative" "1,2")
1524 (match_operand:HI 1 "aligned_operand" ""))
1526 (and (eq_attr "alternative" "0")
1527 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1529 (eq (symbol_ref "TARGET_HIMODE_MATH")
1533 (const_string "HI")))])
1535 ;; Stores and loads of ax to arbitrary constant address.
1536 ;; We fake an second form of instruction to force reload to load address
1537 ;; into register when rax is not available
1538 (define_insn "*movabshi_1_rex64"
1539 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1540 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1541 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1543 movabs{w}\t{%1, %P0|%P0, %1}
1544 mov{w}\t{%1, %a0|%a0, %1}"
1545 [(set_attr "type" "imov")
1546 (set_attr "modrm" "0,*")
1547 (set_attr "length_address" "8,0")
1548 (set_attr "length_immediate" "0,*")
1549 (set_attr "memory" "store")
1550 (set_attr "mode" "HI")])
1552 (define_insn "*movabshi_2_rex64"
1553 [(set (match_operand:HI 0 "register_operand" "=a,r")
1554 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1555 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1557 movabs{w}\t{%P1, %0|%0, %P1}
1558 mov{w}\t{%a1, %0|%0, %a1}"
1559 [(set_attr "type" "imov")
1560 (set_attr "modrm" "0,*")
1561 (set_attr "length_address" "8,0")
1562 (set_attr "length_immediate" "0")
1563 (set_attr "memory" "load")
1564 (set_attr "mode" "HI")])
1566 (define_insn "*swaphi_1"
1567 [(set (match_operand:HI 0 "register_operand" "+r")
1568 (match_operand:HI 1 "register_operand" "+r"))
1571 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1573 [(set_attr "type" "imov")
1574 (set_attr "mode" "SI")
1575 (set_attr "pent_pair" "np")
1576 (set_attr "athlon_decode" "vector")
1577 (set_attr "amdfam10_decode" "double")])
1579 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1580 (define_insn "*swaphi_2"
1581 [(set (match_operand:HI 0 "register_operand" "+r")
1582 (match_operand:HI 1 "register_operand" "+r"))
1585 "TARGET_PARTIAL_REG_STALL"
1587 [(set_attr "type" "imov")
1588 (set_attr "mode" "HI")
1589 (set_attr "pent_pair" "np")
1590 (set_attr "athlon_decode" "vector")])
1592 (define_expand "movstricthi"
1593 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1594 (match_operand:HI 1 "general_operand" ""))]
1595 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1597 /* Don't generate memory->memory moves, go through a register */
1598 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1599 operands[1] = force_reg (HImode, operands[1]);
1602 (define_insn "*movstricthi_1"
1603 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1604 (match_operand:HI 1 "general_operand" "rn,m"))]
1605 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1606 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1607 "mov{w}\t{%1, %0|%0, %1}"
1608 [(set_attr "type" "imov")
1609 (set_attr "mode" "HI")])
1611 (define_insn "*movstricthi_xor"
1612 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1613 (match_operand:HI 1 "const0_operand" "i"))
1614 (clobber (reg:CC FLAGS_REG))]
1616 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1618 [(set_attr "type" "alu1")
1619 (set_attr "mode" "HI")
1620 (set_attr "length_immediate" "0")])
1622 (define_expand "movqi"
1623 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1624 (match_operand:QI 1 "general_operand" ""))]
1626 "ix86_expand_move (QImode, operands); DONE;")
1628 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1629 ;; "push a byte". But actually we use pushl, which has the effect
1630 ;; of rounding the amount pushed up to a word.
1632 (define_insn "*pushqi2"
1633 [(set (match_operand:QI 0 "push_operand" "=X")
1634 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1637 [(set_attr "type" "push")
1638 (set_attr "mode" "SI")])
1640 ;; For 64BIT abi we always round up to 8 bytes.
1641 (define_insn "*pushqi2_rex64"
1642 [(set (match_operand:QI 0 "push_operand" "=X")
1643 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1646 [(set_attr "type" "push")
1647 (set_attr "mode" "DI")])
1649 ;; Situation is quite tricky about when to choose full sized (SImode) move
1650 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1651 ;; partial register dependency machines (such as AMD Athlon), where QImode
1652 ;; moves issue extra dependency and for partial register stalls machines
1653 ;; that don't use QImode patterns (and QImode move cause stall on the next
1656 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1657 ;; register stall machines with, where we use QImode instructions, since
1658 ;; partial register stall can be caused there. Then we use movzx.
1659 (define_insn "*movqi_1"
1660 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1661 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1662 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1664 switch (get_attr_type (insn))
1667 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1668 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1670 if (get_attr_mode (insn) == MODE_SI)
1671 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1673 return "mov{b}\t{%1, %0|%0, %1}";
1677 (cond [(and (eq_attr "alternative" "5")
1678 (not (match_operand:QI 1 "aligned_operand" "")))
1679 (const_string "imovx")
1680 (ne (symbol_ref "optimize_size") (const_int 0))
1681 (const_string "imov")
1682 (and (eq_attr "alternative" "3")
1683 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1685 (eq (symbol_ref "TARGET_QIMODE_MATH")
1687 (const_string "imov")
1688 (eq_attr "alternative" "3,5")
1689 (const_string "imovx")
1690 (and (ne (symbol_ref "TARGET_MOVX")
1692 (eq_attr "alternative" "2"))
1693 (const_string "imovx")
1695 (const_string "imov")))
1697 (cond [(eq_attr "alternative" "3,4,5")
1699 (eq_attr "alternative" "6")
1701 (eq_attr "type" "imovx")
1703 (and (eq_attr "type" "imov")
1704 (and (eq_attr "alternative" "0,1")
1705 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1707 (and (eq (symbol_ref "optimize_size")
1709 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1712 ;; Avoid partial register stalls when not using QImode arithmetic
1713 (and (eq_attr "type" "imov")
1714 (and (eq_attr "alternative" "0,1")
1715 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1717 (eq (symbol_ref "TARGET_QIMODE_MATH")
1721 (const_string "QI")))])
1723 (define_expand "reload_outqi"
1724 [(parallel [(match_operand:QI 0 "" "=m")
1725 (match_operand:QI 1 "register_operand" "r")
1726 (match_operand:QI 2 "register_operand" "=&q")])]
1730 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1732 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1733 if (! q_regs_operand (op1, QImode))
1735 emit_insn (gen_movqi (op2, op1));
1738 emit_insn (gen_movqi (op0, op1));
1742 (define_insn "*swapqi_1"
1743 [(set (match_operand:QI 0 "register_operand" "+r")
1744 (match_operand:QI 1 "register_operand" "+r"))
1747 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1749 [(set_attr "type" "imov")
1750 (set_attr "mode" "SI")
1751 (set_attr "pent_pair" "np")
1752 (set_attr "athlon_decode" "vector")
1753 (set_attr "amdfam10_decode" "vector")])
1755 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1756 (define_insn "*swapqi_2"
1757 [(set (match_operand:QI 0 "register_operand" "+q")
1758 (match_operand:QI 1 "register_operand" "+q"))
1761 "TARGET_PARTIAL_REG_STALL"
1763 [(set_attr "type" "imov")
1764 (set_attr "mode" "QI")
1765 (set_attr "pent_pair" "np")
1766 (set_attr "athlon_decode" "vector")])
1768 (define_expand "movstrictqi"
1769 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1770 (match_operand:QI 1 "general_operand" ""))]
1771 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1773 /* Don't generate memory->memory moves, go through a register. */
1774 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1775 operands[1] = force_reg (QImode, operands[1]);
1778 (define_insn "*movstrictqi_1"
1779 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1780 (match_operand:QI 1 "general_operand" "*qn,m"))]
1781 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1782 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1783 "mov{b}\t{%1, %0|%0, %1}"
1784 [(set_attr "type" "imov")
1785 (set_attr "mode" "QI")])
1787 (define_insn "*movstrictqi_xor"
1788 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1789 (match_operand:QI 1 "const0_operand" "i"))
1790 (clobber (reg:CC FLAGS_REG))]
1791 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1793 [(set_attr "type" "alu1")
1794 (set_attr "mode" "QI")
1795 (set_attr "length_immediate" "0")])
1797 (define_insn "*movsi_extv_1"
1798 [(set (match_operand:SI 0 "register_operand" "=R")
1799 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1803 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1804 [(set_attr "type" "imovx")
1805 (set_attr "mode" "SI")])
1807 (define_insn "*movhi_extv_1"
1808 [(set (match_operand:HI 0 "register_operand" "=R")
1809 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1813 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1814 [(set_attr "type" "imovx")
1815 (set_attr "mode" "SI")])
1817 (define_insn "*movqi_extv_1"
1818 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1819 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1824 switch (get_attr_type (insn))
1827 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1829 return "mov{b}\t{%h1, %0|%0, %h1}";
1833 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1834 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1835 (ne (symbol_ref "TARGET_MOVX")
1837 (const_string "imovx")
1838 (const_string "imov")))
1840 (if_then_else (eq_attr "type" "imovx")
1842 (const_string "QI")))])
1844 (define_insn "*movqi_extv_1_rex64"
1845 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1846 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1851 switch (get_attr_type (insn))
1854 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1856 return "mov{b}\t{%h1, %0|%0, %h1}";
1860 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1861 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1862 (ne (symbol_ref "TARGET_MOVX")
1864 (const_string "imovx")
1865 (const_string "imov")))
1867 (if_then_else (eq_attr "type" "imovx")
1869 (const_string "QI")))])
1871 ;; Stores and loads of ax to arbitrary constant address.
1872 ;; We fake an second form of instruction to force reload to load address
1873 ;; into register when rax is not available
1874 (define_insn "*movabsqi_1_rex64"
1875 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1876 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1877 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1879 movabs{b}\t{%1, %P0|%P0, %1}
1880 mov{b}\t{%1, %a0|%a0, %1}"
1881 [(set_attr "type" "imov")
1882 (set_attr "modrm" "0,*")
1883 (set_attr "length_address" "8,0")
1884 (set_attr "length_immediate" "0,*")
1885 (set_attr "memory" "store")
1886 (set_attr "mode" "QI")])
1888 (define_insn "*movabsqi_2_rex64"
1889 [(set (match_operand:QI 0 "register_operand" "=a,r")
1890 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1891 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1893 movabs{b}\t{%P1, %0|%0, %P1}
1894 mov{b}\t{%a1, %0|%0, %a1}"
1895 [(set_attr "type" "imov")
1896 (set_attr "modrm" "0,*")
1897 (set_attr "length_address" "8,0")
1898 (set_attr "length_immediate" "0")
1899 (set_attr "memory" "load")
1900 (set_attr "mode" "QI")])
1902 (define_insn "*movdi_extzv_1"
1903 [(set (match_operand:DI 0 "register_operand" "=R")
1904 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1908 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1909 [(set_attr "type" "imovx")
1910 (set_attr "mode" "DI")])
1912 (define_insn "*movsi_extzv_1"
1913 [(set (match_operand:SI 0 "register_operand" "=R")
1914 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1918 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1919 [(set_attr "type" "imovx")
1920 (set_attr "mode" "SI")])
1922 (define_insn "*movqi_extzv_2"
1923 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1924 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1929 switch (get_attr_type (insn))
1932 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1934 return "mov{b}\t{%h1, %0|%0, %h1}";
1938 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1939 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1940 (ne (symbol_ref "TARGET_MOVX")
1942 (const_string "imovx")
1943 (const_string "imov")))
1945 (if_then_else (eq_attr "type" "imovx")
1947 (const_string "QI")))])
1949 (define_insn "*movqi_extzv_2_rex64"
1950 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1951 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1956 switch (get_attr_type (insn))
1959 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1961 return "mov{b}\t{%h1, %0|%0, %h1}";
1965 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1966 (ne (symbol_ref "TARGET_MOVX")
1968 (const_string "imovx")
1969 (const_string "imov")))
1971 (if_then_else (eq_attr "type" "imovx")
1973 (const_string "QI")))])
1975 (define_insn "movsi_insv_1"
1976 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1979 (match_operand:SI 1 "general_operand" "Qmn"))]
1981 "mov{b}\t{%b1, %h0|%h0, %b1}"
1982 [(set_attr "type" "imov")
1983 (set_attr "mode" "QI")])
1985 (define_insn "*movsi_insv_1_rex64"
1986 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1989 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1991 "mov{b}\t{%b1, %h0|%h0, %b1}"
1992 [(set_attr "type" "imov")
1993 (set_attr "mode" "QI")])
1995 (define_insn "movdi_insv_1_rex64"
1996 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1999 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2001 "mov{b}\t{%b1, %h0|%h0, %b1}"
2002 [(set_attr "type" "imov")
2003 (set_attr "mode" "QI")])
2005 (define_insn "*movqi_insv_2"
2006 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2009 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2012 "mov{b}\t{%h1, %h0|%h0, %h1}"
2013 [(set_attr "type" "imov")
2014 (set_attr "mode" "QI")])
2016 (define_expand "movdi"
2017 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2018 (match_operand:DI 1 "general_operand" ""))]
2020 "ix86_expand_move (DImode, operands); DONE;")
2022 (define_insn "*pushdi"
2023 [(set (match_operand:DI 0 "push_operand" "=<")
2024 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2028 (define_insn "*pushdi2_rex64"
2029 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2030 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2035 [(set_attr "type" "push,multi")
2036 (set_attr "mode" "DI")])
2038 ;; Convert impossible pushes of immediate to existing instructions.
2039 ;; First try to get scratch register and go through it. In case this
2040 ;; fails, push sign extended lower part first and then overwrite
2041 ;; upper part by 32bit move.
2043 [(match_scratch:DI 2 "r")
2044 (set (match_operand:DI 0 "push_operand" "")
2045 (match_operand:DI 1 "immediate_operand" ""))]
2046 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2047 && !x86_64_immediate_operand (operands[1], DImode)"
2048 [(set (match_dup 2) (match_dup 1))
2049 (set (match_dup 0) (match_dup 2))]
2052 ;; We need to define this as both peepholer and splitter for case
2053 ;; peephole2 pass is not run.
2054 ;; "&& 1" is needed to keep it from matching the previous pattern.
2056 [(set (match_operand:DI 0 "push_operand" "")
2057 (match_operand:DI 1 "immediate_operand" ""))]
2058 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2059 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2060 [(set (match_dup 0) (match_dup 1))
2061 (set (match_dup 2) (match_dup 3))]
2062 "split_di (operands + 1, 1, operands + 2, operands + 3);
2063 operands[1] = gen_lowpart (DImode, operands[2]);
2064 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2069 [(set (match_operand:DI 0 "push_operand" "")
2070 (match_operand:DI 1 "immediate_operand" ""))]
2071 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2072 ? epilogue_completed : reload_completed)
2073 && !symbolic_operand (operands[1], DImode)
2074 && !x86_64_immediate_operand (operands[1], DImode)"
2075 [(set (match_dup 0) (match_dup 1))
2076 (set (match_dup 2) (match_dup 3))]
2077 "split_di (operands + 1, 1, operands + 2, operands + 3);
2078 operands[1] = gen_lowpart (DImode, operands[2]);
2079 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2083 (define_insn "*pushdi2_prologue_rex64"
2084 [(set (match_operand:DI 0 "push_operand" "=<")
2085 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2086 (clobber (mem:BLK (scratch)))]
2089 [(set_attr "type" "push")
2090 (set_attr "mode" "DI")])
2092 (define_insn "*popdi1_epilogue_rex64"
2093 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2094 (mem:DI (reg:DI SP_REG)))
2095 (set (reg:DI SP_REG)
2096 (plus:DI (reg:DI SP_REG) (const_int 8)))
2097 (clobber (mem:BLK (scratch)))]
2100 [(set_attr "type" "pop")
2101 (set_attr "mode" "DI")])
2103 (define_insn "popdi1"
2104 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2105 (mem:DI (reg:DI SP_REG)))
2106 (set (reg:DI SP_REG)
2107 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2110 [(set_attr "type" "pop")
2111 (set_attr "mode" "DI")])
2113 (define_insn "*movdi_xor_rex64"
2114 [(set (match_operand:DI 0 "register_operand" "=r")
2115 (match_operand:DI 1 "const0_operand" "i"))
2116 (clobber (reg:CC FLAGS_REG))]
2117 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2118 && reload_completed"
2120 [(set_attr "type" "alu1")
2121 (set_attr "mode" "SI")
2122 (set_attr "length_immediate" "0")])
2124 (define_insn "*movdi_or_rex64"
2125 [(set (match_operand:DI 0 "register_operand" "=r")
2126 (match_operand:DI 1 "const_int_operand" "i"))
2127 (clobber (reg:CC FLAGS_REG))]
2128 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2130 && operands[1] == constm1_rtx"
2132 operands[1] = constm1_rtx;
2133 return "or{q}\t{%1, %0|%0, %1}";
2135 [(set_attr "type" "alu1")
2136 (set_attr "mode" "DI")
2137 (set_attr "length_immediate" "1")])
2139 (define_insn "*movdi_2"
2140 [(set (match_operand:DI 0 "nonimmediate_operand"
2141 "=r ,o ,*y,m*y,*y,*Yt,m ,*Yt,*Yt,*x,m ,*x,*x")
2142 (match_operand:DI 1 "general_operand"
2143 "riFo,riF,C ,*y ,m ,C ,*Yt,*Yt,m ,C ,*x,*x,m "))]
2144 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2149 movq\t{%1, %0|%0, %1}
2150 movq\t{%1, %0|%0, %1}
2152 movq\t{%1, %0|%0, %1}
2153 movdqa\t{%1, %0|%0, %1}
2154 movq\t{%1, %0|%0, %1}
2156 movlps\t{%1, %0|%0, %1}
2157 movaps\t{%1, %0|%0, %1}
2158 movlps\t{%1, %0|%0, %1}"
2159 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2160 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2163 [(set (match_operand:DI 0 "push_operand" "")
2164 (match_operand:DI 1 "general_operand" ""))]
2165 "!TARGET_64BIT && reload_completed
2166 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2168 "ix86_split_long_move (operands); DONE;")
2170 ;; %%% This multiword shite has got to go.
2172 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2173 (match_operand:DI 1 "general_operand" ""))]
2174 "!TARGET_64BIT && reload_completed
2175 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2176 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2178 "ix86_split_long_move (operands); DONE;")
2180 (define_insn "*movdi_1_rex64"
2181 [(set (match_operand:DI 0 "nonimmediate_operand"
2182 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2183 (match_operand:DI 1 "general_operand"
2184 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2185 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2187 switch (get_attr_type (insn))
2190 if (SSE_REG_P (operands[0]))
2191 return "movq2dq\t{%1, %0|%0, %1}";
2193 return "movdq2q\t{%1, %0|%0, %1}";
2196 if (get_attr_mode (insn) == MODE_TI)
2197 return "movdqa\t{%1, %0|%0, %1}";
2201 /* Moves from and into integer register is done using movd
2202 opcode with REX prefix. */
2203 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2204 return "movd\t{%1, %0|%0, %1}";
2205 return "movq\t{%1, %0|%0, %1}";
2209 return "pxor\t%0, %0";
2215 return "lea{q}\t{%a1, %0|%0, %a1}";
2218 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2219 if (get_attr_mode (insn) == MODE_SI)
2220 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2221 else if (which_alternative == 2)
2222 return "movabs{q}\t{%1, %0|%0, %1}";
2224 return "mov{q}\t{%1, %0|%0, %1}";
2228 (cond [(eq_attr "alternative" "5")
2229 (const_string "mmxadd")
2230 (eq_attr "alternative" "6,7,8,9,10")
2231 (const_string "mmxmov")
2232 (eq_attr "alternative" "11")
2233 (const_string "sselog1")
2234 (eq_attr "alternative" "12,13,14,15,16")
2235 (const_string "ssemov")
2236 (eq_attr "alternative" "17,18")
2237 (const_string "ssecvt")
2238 (eq_attr "alternative" "4")
2239 (const_string "multi")
2240 (match_operand:DI 1 "pic_32bit_operand" "")
2241 (const_string "lea")
2243 (const_string "imov")))
2244 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2245 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2246 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2248 ;; Stores and loads of ax to arbitrary constant address.
2249 ;; We fake an second form of instruction to force reload to load address
2250 ;; into register when rax is not available
2251 (define_insn "*movabsdi_1_rex64"
2252 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2253 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2254 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2256 movabs{q}\t{%1, %P0|%P0, %1}
2257 mov{q}\t{%1, %a0|%a0, %1}"
2258 [(set_attr "type" "imov")
2259 (set_attr "modrm" "0,*")
2260 (set_attr "length_address" "8,0")
2261 (set_attr "length_immediate" "0,*")
2262 (set_attr "memory" "store")
2263 (set_attr "mode" "DI")])
2265 (define_insn "*movabsdi_2_rex64"
2266 [(set (match_operand:DI 0 "register_operand" "=a,r")
2267 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2268 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2270 movabs{q}\t{%P1, %0|%0, %P1}
2271 mov{q}\t{%a1, %0|%0, %a1}"
2272 [(set_attr "type" "imov")
2273 (set_attr "modrm" "0,*")
2274 (set_attr "length_address" "8,0")
2275 (set_attr "length_immediate" "0")
2276 (set_attr "memory" "load")
2277 (set_attr "mode" "DI")])
2279 ;; Convert impossible stores of immediate to existing instructions.
2280 ;; First try to get scratch register and go through it. In case this
2281 ;; fails, move by 32bit parts.
2283 [(match_scratch:DI 2 "r")
2284 (set (match_operand:DI 0 "memory_operand" "")
2285 (match_operand:DI 1 "immediate_operand" ""))]
2286 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2287 && !x86_64_immediate_operand (operands[1], DImode)"
2288 [(set (match_dup 2) (match_dup 1))
2289 (set (match_dup 0) (match_dup 2))]
2292 ;; We need to define this as both peepholer and splitter for case
2293 ;; peephole2 pass is not run.
2294 ;; "&& 1" is needed to keep it from matching the previous pattern.
2296 [(set (match_operand:DI 0 "memory_operand" "")
2297 (match_operand:DI 1 "immediate_operand" ""))]
2298 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2299 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2300 [(set (match_dup 2) (match_dup 3))
2301 (set (match_dup 4) (match_dup 5))]
2302 "split_di (operands, 2, operands + 2, operands + 4);")
2305 [(set (match_operand:DI 0 "memory_operand" "")
2306 (match_operand:DI 1 "immediate_operand" ""))]
2307 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2308 ? epilogue_completed : reload_completed)
2309 && !symbolic_operand (operands[1], DImode)
2310 && !x86_64_immediate_operand (operands[1], DImode)"
2311 [(set (match_dup 2) (match_dup 3))
2312 (set (match_dup 4) (match_dup 5))]
2313 "split_di (operands, 2, operands + 2, operands + 4);")
2315 (define_insn "*swapdi_rex64"
2316 [(set (match_operand:DI 0 "register_operand" "+r")
2317 (match_operand:DI 1 "register_operand" "+r"))
2322 [(set_attr "type" "imov")
2323 (set_attr "mode" "DI")
2324 (set_attr "pent_pair" "np")
2325 (set_attr "athlon_decode" "vector")
2326 (set_attr "amdfam10_decode" "double")])
2328 (define_expand "movti"
2329 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2330 (match_operand:TI 1 "nonimmediate_operand" ""))]
2331 "TARGET_SSE || TARGET_64BIT"
2334 ix86_expand_move (TImode, operands);
2335 else if (push_operand (operands[0], TImode))
2336 ix86_expand_push (TImode, operands[1]);
2338 ix86_expand_vector_move (TImode, operands);
2342 (define_insn "*movti_internal"
2343 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2344 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2345 "TARGET_SSE && !TARGET_64BIT
2346 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2348 switch (which_alternative)
2351 if (get_attr_mode (insn) == MODE_V4SF)
2352 return "xorps\t%0, %0";
2354 return "pxor\t%0, %0";
2357 if (get_attr_mode (insn) == MODE_V4SF)
2358 return "movaps\t{%1, %0|%0, %1}";
2360 return "movdqa\t{%1, %0|%0, %1}";
2365 [(set_attr "type" "sselog1,ssemov,ssemov")
2367 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2368 (ne (symbol_ref "optimize_size") (const_int 0)))
2369 (const_string "V4SF")
2370 (and (eq_attr "alternative" "2")
2371 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2373 (const_string "V4SF")]
2374 (const_string "TI")))])
2376 (define_insn "*movti_rex64"
2377 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2378 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2380 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2382 switch (which_alternative)
2388 if (get_attr_mode (insn) == MODE_V4SF)
2389 return "xorps\t%0, %0";
2391 return "pxor\t%0, %0";
2394 if (get_attr_mode (insn) == MODE_V4SF)
2395 return "movaps\t{%1, %0|%0, %1}";
2397 return "movdqa\t{%1, %0|%0, %1}";
2402 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2404 (cond [(eq_attr "alternative" "2,3")
2406 (ne (symbol_ref "optimize_size")
2408 (const_string "V4SF")
2409 (const_string "TI"))
2410 (eq_attr "alternative" "4")
2412 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2414 (ne (symbol_ref "optimize_size")
2416 (const_string "V4SF")
2417 (const_string "TI"))]
2418 (const_string "DI")))])
2421 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2422 (match_operand:TI 1 "general_operand" ""))]
2423 "reload_completed && !SSE_REG_P (operands[0])
2424 && !SSE_REG_P (operands[1])"
2426 "ix86_split_long_move (operands); DONE;")
2428 ;; This expands to what emit_move_complex would generate if we didn't
2429 ;; have a movti pattern. Having this avoids problems with reload on
2430 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2431 ;; to have around all the time.
2432 (define_expand "movcdi"
2433 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2434 (match_operand:CDI 1 "general_operand" ""))]
2437 if (push_operand (operands[0], CDImode))
2438 emit_move_complex_push (CDImode, operands[0], operands[1]);
2440 emit_move_complex_parts (operands[0], operands[1]);
2444 (define_expand "movsf"
2445 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2446 (match_operand:SF 1 "general_operand" ""))]
2448 "ix86_expand_move (SFmode, operands); DONE;")
2450 (define_insn "*pushsf"
2451 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2452 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2455 /* Anything else should be already split before reg-stack. */
2456 gcc_assert (which_alternative == 1);
2457 return "push{l}\t%1";
2459 [(set_attr "type" "multi,push,multi")
2460 (set_attr "unit" "i387,*,*")
2461 (set_attr "mode" "SF,SI,SF")])
2463 (define_insn "*pushsf_rex64"
2464 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2465 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2468 /* Anything else should be already split before reg-stack. */
2469 gcc_assert (which_alternative == 1);
2470 return "push{q}\t%q1";
2472 [(set_attr "type" "multi,push,multi")
2473 (set_attr "unit" "i387,*,*")
2474 (set_attr "mode" "SF,DI,SF")])
2477 [(set (match_operand:SF 0 "push_operand" "")
2478 (match_operand:SF 1 "memory_operand" ""))]
2480 && MEM_P (operands[1])
2481 && (operands[2] = find_constant_src (insn))"
2486 ;; %%% Kill this when call knows how to work this out.
2488 [(set (match_operand:SF 0 "push_operand" "")
2489 (match_operand:SF 1 "any_fp_register_operand" ""))]
2491 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2492 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2495 [(set (match_operand:SF 0 "push_operand" "")
2496 (match_operand:SF 1 "any_fp_register_operand" ""))]
2498 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2499 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2501 (define_insn "*movsf_1"
2502 [(set (match_operand:SF 0 "nonimmediate_operand"
2503 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2504 (match_operand:SF 1 "general_operand"
2505 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2506 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2507 && (reload_in_progress || reload_completed
2508 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2509 || (!TARGET_SSE_MATH && optimize_size
2510 && standard_80387_constant_p (operands[1]))
2511 || GET_CODE (operands[1]) != CONST_DOUBLE
2512 || memory_operand (operands[0], SFmode))"
2514 switch (which_alternative)
2518 return output_387_reg_move (insn, operands);
2521 return standard_80387_constant_opcode (operands[1]);
2525 return "mov{l}\t{%1, %0|%0, %1}";
2527 if (get_attr_mode (insn) == MODE_TI)
2528 return "pxor\t%0, %0";
2530 return "xorps\t%0, %0";
2532 if (get_attr_mode (insn) == MODE_V4SF)
2533 return "movaps\t{%1, %0|%0, %1}";
2535 return "movss\t{%1, %0|%0, %1}";
2537 return "movss\t{%1, %0|%0, %1}";
2540 case 12: case 13: case 14: case 15:
2541 return "movd\t{%1, %0|%0, %1}";
2544 return "movq\t{%1, %0|%0, %1}";
2550 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2552 (cond [(eq_attr "alternative" "3,4,9,10")
2554 (eq_attr "alternative" "5")
2556 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2558 (ne (symbol_ref "TARGET_SSE2")
2560 (eq (symbol_ref "optimize_size")
2563 (const_string "V4SF"))
2564 /* For architectures resolving dependencies on
2565 whole SSE registers use APS move to break dependency
2566 chains, otherwise use short move to avoid extra work.
2568 Do the same for architectures resolving dependencies on
2569 the parts. While in DF mode it is better to always handle
2570 just register parts, the SF mode is different due to lack
2571 of instructions to load just part of the register. It is
2572 better to maintain the whole registers in single format
2573 to avoid problems on using packed logical operations. */
2574 (eq_attr "alternative" "6")
2576 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2578 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2580 (const_string "V4SF")
2581 (const_string "SF"))
2582 (eq_attr "alternative" "11")
2583 (const_string "DI")]
2584 (const_string "SF")))])
2586 (define_insn "*swapsf"
2587 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2588 (match_operand:SF 1 "fp_register_operand" "+f"))
2591 "reload_completed || TARGET_80387"
2593 if (STACK_TOP_P (operands[0]))
2598 [(set_attr "type" "fxch")
2599 (set_attr "mode" "SF")])
2601 (define_expand "movdf"
2602 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2603 (match_operand:DF 1 "general_operand" ""))]
2605 "ix86_expand_move (DFmode, operands); DONE;")
2607 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2608 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2609 ;; On the average, pushdf using integers can be still shorter. Allow this
2610 ;; pattern for optimize_size too.
2612 (define_insn "*pushdf_nointeger"
2613 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2614 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Yt"))]
2615 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2617 /* This insn should be already split before reg-stack. */
2620 [(set_attr "type" "multi")
2621 (set_attr "unit" "i387,*,*,*")
2622 (set_attr "mode" "DF,SI,SI,DF")])
2624 (define_insn "*pushdf_integer"
2625 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2626 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Yt"))]
2627 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2629 /* This insn should be already split before reg-stack. */
2632 [(set_attr "type" "multi")
2633 (set_attr "unit" "i387,*,*")
2634 (set_attr "mode" "DF,SI,DF")])
2636 ;; %%% Kill this when call knows how to work this out.
2638 [(set (match_operand:DF 0 "push_operand" "")
2639 (match_operand:DF 1 "any_fp_register_operand" ""))]
2640 "!TARGET_64BIT && reload_completed"
2641 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2642 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2646 [(set (match_operand:DF 0 "push_operand" "")
2647 (match_operand:DF 1 "any_fp_register_operand" ""))]
2648 "TARGET_64BIT && reload_completed"
2649 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2650 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2654 [(set (match_operand:DF 0 "push_operand" "")
2655 (match_operand:DF 1 "general_operand" ""))]
2658 "ix86_split_long_move (operands); DONE;")
2660 ;; Moving is usually shorter when only FP registers are used. This separate
2661 ;; movdf pattern avoids the use of integer registers for FP operations
2662 ;; when optimizing for size.
2664 (define_insn "*movdf_nointeger"
2665 [(set (match_operand:DF 0 "nonimmediate_operand"
2666 "=f,m,f,*r ,o ,Yt*x,Yt*x,Yt*x ,m ")
2667 (match_operand:DF 1 "general_operand"
2668 "fm,f,G,*roF,F*r,C ,Yt*x,mYt*x,Yt*x"))]
2669 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2670 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2671 && (reload_in_progress || reload_completed
2672 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2673 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2674 && standard_80387_constant_p (operands[1]))
2675 || GET_CODE (operands[1]) != CONST_DOUBLE
2676 || memory_operand (operands[0], DFmode))"
2678 switch (which_alternative)
2682 return output_387_reg_move (insn, operands);
2685 return standard_80387_constant_opcode (operands[1]);
2691 switch (get_attr_mode (insn))
2694 return "xorps\t%0, %0";
2696 return "xorpd\t%0, %0";
2698 return "pxor\t%0, %0";
2705 switch (get_attr_mode (insn))
2708 return "movaps\t{%1, %0|%0, %1}";
2710 return "movapd\t{%1, %0|%0, %1}";
2712 return "movdqa\t{%1, %0|%0, %1}";
2714 return "movq\t{%1, %0|%0, %1}";
2716 return "movsd\t{%1, %0|%0, %1}";
2718 return "movlpd\t{%1, %0|%0, %1}";
2720 return "movlps\t{%1, %0|%0, %1}";
2729 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2731 (cond [(eq_attr "alternative" "0,1,2")
2733 (eq_attr "alternative" "3,4")
2736 /* For SSE1, we have many fewer alternatives. */
2737 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2738 (cond [(eq_attr "alternative" "5,6")
2739 (const_string "V4SF")
2741 (const_string "V2SF"))
2743 /* xorps is one byte shorter. */
2744 (eq_attr "alternative" "5")
2745 (cond [(ne (symbol_ref "optimize_size")
2747 (const_string "V4SF")
2748 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2752 (const_string "V2DF"))
2754 /* For architectures resolving dependencies on
2755 whole SSE registers use APD move to break dependency
2756 chains, otherwise use short move to avoid extra work.
2758 movaps encodes one byte shorter. */
2759 (eq_attr "alternative" "6")
2761 [(ne (symbol_ref "optimize_size")
2763 (const_string "V4SF")
2764 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2766 (const_string "V2DF")
2768 (const_string "DF"))
2769 /* For architectures resolving dependencies on register
2770 parts we may avoid extra work to zero out upper part
2772 (eq_attr "alternative" "7")
2774 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2776 (const_string "V1DF")
2777 (const_string "DF"))
2779 (const_string "DF")))])
2781 (define_insn "*movdf_integer_rex64"
2782 [(set (match_operand:DF 0 "nonimmediate_operand"
2783 "=f,m,f,r ,m ,Yt*x,Yt*x,Yt*x,m ,Yi,r ")
2784 (match_operand:DF 1 "general_operand"
2785 "fm,f,G,rmF,Fr,C ,Yt*x,m ,Yt*x,r ,Yi"))]
2786 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2787 && (reload_in_progress || reload_completed
2788 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2789 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2790 && standard_80387_constant_p (operands[1]))
2791 || GET_CODE (operands[1]) != CONST_DOUBLE
2792 || memory_operand (operands[0], DFmode))"
2794 switch (which_alternative)
2798 return output_387_reg_move (insn, operands);
2801 return standard_80387_constant_opcode (operands[1]);
2808 switch (get_attr_mode (insn))
2811 return "xorps\t%0, %0";
2813 return "xorpd\t%0, %0";
2815 return "pxor\t%0, %0";
2822 switch (get_attr_mode (insn))
2825 return "movaps\t{%1, %0|%0, %1}";
2827 return "movapd\t{%1, %0|%0, %1}";
2829 return "movdqa\t{%1, %0|%0, %1}";
2831 return "movq\t{%1, %0|%0, %1}";
2833 return "movsd\t{%1, %0|%0, %1}";
2835 return "movlpd\t{%1, %0|%0, %1}";
2837 return "movlps\t{%1, %0|%0, %1}";
2844 return "movd\t{%1, %0|%0, %1}";
2850 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2852 (cond [(eq_attr "alternative" "0,1,2")
2854 (eq_attr "alternative" "3,4,9,10")
2857 /* For SSE1, we have many fewer alternatives. */
2858 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2859 (cond [(eq_attr "alternative" "5,6")
2860 (const_string "V4SF")
2862 (const_string "V2SF"))
2864 /* xorps is one byte shorter. */
2865 (eq_attr "alternative" "5")
2866 (cond [(ne (symbol_ref "optimize_size")
2868 (const_string "V4SF")
2869 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2873 (const_string "V2DF"))
2875 /* For architectures resolving dependencies on
2876 whole SSE registers use APD move to break dependency
2877 chains, otherwise use short move to avoid extra work.
2879 movaps encodes one byte shorter. */
2880 (eq_attr "alternative" "6")
2882 [(ne (symbol_ref "optimize_size")
2884 (const_string "V4SF")
2885 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2887 (const_string "V2DF")
2889 (const_string "DF"))
2890 /* For architectures resolving dependencies on register
2891 parts we may avoid extra work to zero out upper part
2893 (eq_attr "alternative" "7")
2895 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2897 (const_string "V1DF")
2898 (const_string "DF"))
2900 (const_string "DF")))])
2902 (define_insn "*movdf_integer"
2903 [(set (match_operand:DF 0 "nonimmediate_operand"
2904 "=f,m,f,r ,o ,Yt*x,Yt*x,Yt*x,m ")
2905 (match_operand:DF 1 "general_operand"
2906 "fm,f,G,roF,Fr,C ,Yt*x,m ,Yt*x"))]
2907 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2908 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2909 && (reload_in_progress || reload_completed
2910 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2911 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2912 && standard_80387_constant_p (operands[1]))
2913 || GET_CODE (operands[1]) != CONST_DOUBLE
2914 || memory_operand (operands[0], DFmode))"
2916 switch (which_alternative)
2920 return output_387_reg_move (insn, operands);
2923 return standard_80387_constant_opcode (operands[1]);
2930 switch (get_attr_mode (insn))
2933 return "xorps\t%0, %0";
2935 return "xorpd\t%0, %0";
2937 return "pxor\t%0, %0";
2944 switch (get_attr_mode (insn))
2947 return "movaps\t{%1, %0|%0, %1}";
2949 return "movapd\t{%1, %0|%0, %1}";
2951 return "movdqa\t{%1, %0|%0, %1}";
2953 return "movq\t{%1, %0|%0, %1}";
2955 return "movsd\t{%1, %0|%0, %1}";
2957 return "movlpd\t{%1, %0|%0, %1}";
2959 return "movlps\t{%1, %0|%0, %1}";
2968 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2970 (cond [(eq_attr "alternative" "0,1,2")
2972 (eq_attr "alternative" "3,4")
2975 /* For SSE1, we have many fewer alternatives. */
2976 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2977 (cond [(eq_attr "alternative" "5,6")
2978 (const_string "V4SF")
2980 (const_string "V2SF"))
2982 /* xorps is one byte shorter. */
2983 (eq_attr "alternative" "5")
2984 (cond [(ne (symbol_ref "optimize_size")
2986 (const_string "V4SF")
2987 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2991 (const_string "V2DF"))
2993 /* For architectures resolving dependencies on
2994 whole SSE registers use APD move to break dependency
2995 chains, otherwise use short move to avoid extra work.
2997 movaps encodes one byte shorter. */
2998 (eq_attr "alternative" "6")
3000 [(ne (symbol_ref "optimize_size")
3002 (const_string "V4SF")
3003 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3005 (const_string "V2DF")
3007 (const_string "DF"))
3008 /* For architectures resolving dependencies on register
3009 parts we may avoid extra work to zero out upper part
3011 (eq_attr "alternative" "7")
3013 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3015 (const_string "V1DF")
3016 (const_string "DF"))
3018 (const_string "DF")))])
3021 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3022 (match_operand:DF 1 "general_operand" ""))]
3024 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3025 && ! (ANY_FP_REG_P (operands[0]) ||
3026 (GET_CODE (operands[0]) == SUBREG
3027 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3028 && ! (ANY_FP_REG_P (operands[1]) ||
3029 (GET_CODE (operands[1]) == SUBREG
3030 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3032 "ix86_split_long_move (operands); DONE;")
3034 (define_insn "*swapdf"
3035 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3036 (match_operand:DF 1 "fp_register_operand" "+f"))
3039 "reload_completed || TARGET_80387"
3041 if (STACK_TOP_P (operands[0]))
3046 [(set_attr "type" "fxch")
3047 (set_attr "mode" "DF")])
3049 (define_expand "movxf"
3050 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3051 (match_operand:XF 1 "general_operand" ""))]
3053 "ix86_expand_move (XFmode, operands); DONE;")
3055 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3056 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3057 ;; Pushing using integer instructions is longer except for constants
3058 ;; and direct memory references.
3059 ;; (assuming that any given constant is pushed only once, but this ought to be
3060 ;; handled elsewhere).
3062 (define_insn "*pushxf_nointeger"
3063 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3064 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3067 /* This insn should be already split before reg-stack. */
3070 [(set_attr "type" "multi")
3071 (set_attr "unit" "i387,*,*")
3072 (set_attr "mode" "XF,SI,SI")])
3074 (define_insn "*pushxf_integer"
3075 [(set (match_operand:XF 0 "push_operand" "=<,<")
3076 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3079 /* This insn should be already split before reg-stack. */
3082 [(set_attr "type" "multi")
3083 (set_attr "unit" "i387,*")
3084 (set_attr "mode" "XF,SI")])
3087 [(set (match_operand 0 "push_operand" "")
3088 (match_operand 1 "general_operand" ""))]
3090 && (GET_MODE (operands[0]) == XFmode
3091 || GET_MODE (operands[0]) == DFmode)
3092 && !ANY_FP_REG_P (operands[1])"
3094 "ix86_split_long_move (operands); DONE;")
3097 [(set (match_operand:XF 0 "push_operand" "")
3098 (match_operand:XF 1 "any_fp_register_operand" ""))]
3100 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3101 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3102 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3105 [(set (match_operand:XF 0 "push_operand" "")
3106 (match_operand:XF 1 "any_fp_register_operand" ""))]
3108 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3109 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3110 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3112 ;; Do not use integer registers when optimizing for size
3113 (define_insn "*movxf_nointeger"
3114 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3115 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3117 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3118 && (reload_in_progress || reload_completed
3119 || (optimize_size && standard_80387_constant_p (operands[1]))
3120 || GET_CODE (operands[1]) != CONST_DOUBLE
3121 || memory_operand (operands[0], XFmode))"
3123 switch (which_alternative)
3127 return output_387_reg_move (insn, operands);
3130 return standard_80387_constant_opcode (operands[1]);
3138 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3139 (set_attr "mode" "XF,XF,XF,SI,SI")])
3141 (define_insn "*movxf_integer"
3142 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3143 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3145 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3146 && (reload_in_progress || reload_completed
3147 || (optimize_size && standard_80387_constant_p (operands[1]))
3148 || GET_CODE (operands[1]) != CONST_DOUBLE
3149 || memory_operand (operands[0], XFmode))"
3151 switch (which_alternative)
3155 return output_387_reg_move (insn, operands);
3158 return standard_80387_constant_opcode (operands[1]);
3167 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3168 (set_attr "mode" "XF,XF,XF,SI,SI")])
3170 (define_expand "movtf"
3171 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3172 (match_operand:TF 1 "nonimmediate_operand" ""))]
3175 ix86_expand_move (TFmode, operands);
3179 (define_insn "*movtf_internal"
3180 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3181 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3183 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3185 switch (which_alternative)
3189 if (get_attr_mode (insn) == MODE_V4SF)
3190 return "movaps\t{%1, %0|%0, %1}";
3192 return "movdqa\t{%1, %0|%0, %1}";
3194 if (get_attr_mode (insn) == MODE_V4SF)
3195 return "xorps\t%0, %0";
3197 return "pxor\t%0, %0";
3205 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3207 (cond [(eq_attr "alternative" "0,2")
3209 (ne (symbol_ref "optimize_size")
3211 (const_string "V4SF")
3212 (const_string "TI"))
3213 (eq_attr "alternative" "1")
3215 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3217 (ne (symbol_ref "optimize_size")
3219 (const_string "V4SF")
3220 (const_string "TI"))]
3221 (const_string "DI")))])
3224 [(set (match_operand 0 "nonimmediate_operand" "")
3225 (match_operand 1 "general_operand" ""))]
3227 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3228 && GET_MODE (operands[0]) == XFmode
3229 && ! (ANY_FP_REG_P (operands[0]) ||
3230 (GET_CODE (operands[0]) == SUBREG
3231 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3232 && ! (ANY_FP_REG_P (operands[1]) ||
3233 (GET_CODE (operands[1]) == SUBREG
3234 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3236 "ix86_split_long_move (operands); DONE;")
3239 [(set (match_operand 0 "register_operand" "")
3240 (match_operand 1 "memory_operand" ""))]
3242 && MEM_P (operands[1])
3243 && (GET_MODE (operands[0]) == TFmode
3244 || GET_MODE (operands[0]) == XFmode
3245 || GET_MODE (operands[0]) == SFmode
3246 || GET_MODE (operands[0]) == DFmode)
3247 && (operands[2] = find_constant_src (insn))"
3248 [(set (match_dup 0) (match_dup 2))]
3250 rtx c = operands[2];
3251 rtx r = operands[0];
3253 if (GET_CODE (r) == SUBREG)
3258 if (!standard_sse_constant_p (c))
3261 else if (FP_REG_P (r))
3263 if (!standard_80387_constant_p (c))
3266 else if (MMX_REG_P (r))
3271 [(set (match_operand 0 "register_operand" "")
3272 (float_extend (match_operand 1 "memory_operand" "")))]
3274 && MEM_P (operands[1])
3275 && (GET_MODE (operands[0]) == TFmode
3276 || GET_MODE (operands[0]) == XFmode
3277 || GET_MODE (operands[0]) == SFmode
3278 || GET_MODE (operands[0]) == DFmode)
3279 && (operands[2] = find_constant_src (insn))"
3280 [(set (match_dup 0) (match_dup 2))]
3282 rtx c = operands[2];
3283 rtx r = operands[0];
3285 if (GET_CODE (r) == SUBREG)
3290 if (!standard_sse_constant_p (c))
3293 else if (FP_REG_P (r))
3295 if (!standard_80387_constant_p (c))
3298 else if (MMX_REG_P (r))
3302 (define_insn "swapxf"
3303 [(set (match_operand:XF 0 "register_operand" "+f")
3304 (match_operand:XF 1 "register_operand" "+f"))
3309 if (STACK_TOP_P (operands[0]))
3314 [(set_attr "type" "fxch")
3315 (set_attr "mode" "XF")])
3317 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3319 [(set (match_operand:X87MODEF 0 "register_operand" "")
3320 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3321 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3322 && (standard_80387_constant_p (operands[1]) == 8
3323 || standard_80387_constant_p (operands[1]) == 9)"
3324 [(set (match_dup 0)(match_dup 1))
3326 (neg:X87MODEF (match_dup 0)))]
3330 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3331 if (real_isnegzero (&r))
3332 operands[1] = CONST0_RTX (<MODE>mode);
3334 operands[1] = CONST1_RTX (<MODE>mode);
3338 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3339 (match_operand:TF 1 "general_operand" ""))]
3341 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3343 "ix86_split_long_move (operands); DONE;")
3345 ;; Zero extension instructions
3347 (define_expand "zero_extendhisi2"
3348 [(set (match_operand:SI 0 "register_operand" "")
3349 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3352 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3354 operands[1] = force_reg (HImode, operands[1]);
3355 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3360 (define_insn "zero_extendhisi2_and"
3361 [(set (match_operand:SI 0 "register_operand" "=r")
3362 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3363 (clobber (reg:CC FLAGS_REG))]
3364 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3366 [(set_attr "type" "alu1")
3367 (set_attr "mode" "SI")])
3370 [(set (match_operand:SI 0 "register_operand" "")
3371 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3372 (clobber (reg:CC FLAGS_REG))]
3373 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3374 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3375 (clobber (reg:CC FLAGS_REG))])]
3378 (define_insn "*zero_extendhisi2_movzwl"
3379 [(set (match_operand:SI 0 "register_operand" "=r")
3380 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3381 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3382 "movz{wl|x}\t{%1, %0|%0, %1}"
3383 [(set_attr "type" "imovx")
3384 (set_attr "mode" "SI")])
3386 (define_expand "zero_extendqihi2"
3388 [(set (match_operand:HI 0 "register_operand" "")
3389 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3390 (clobber (reg:CC FLAGS_REG))])]
3394 (define_insn "*zero_extendqihi2_and"
3395 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3396 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3397 (clobber (reg:CC FLAGS_REG))]
3398 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3400 [(set_attr "type" "alu1")
3401 (set_attr "mode" "HI")])
3403 (define_insn "*zero_extendqihi2_movzbw_and"
3404 [(set (match_operand:HI 0 "register_operand" "=r,r")
3405 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3406 (clobber (reg:CC FLAGS_REG))]
3407 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3409 [(set_attr "type" "imovx,alu1")
3410 (set_attr "mode" "HI")])
3412 ; zero extend to SImode here to avoid partial register stalls
3413 (define_insn "*zero_extendqihi2_movzbl"
3414 [(set (match_operand:HI 0 "register_operand" "=r")
3415 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3416 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3417 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3418 [(set_attr "type" "imovx")
3419 (set_attr "mode" "SI")])
3421 ;; For the movzbw case strip only the clobber
3423 [(set (match_operand:HI 0 "register_operand" "")
3424 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3425 (clobber (reg:CC FLAGS_REG))]
3427 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3428 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3429 [(set (match_operand:HI 0 "register_operand" "")
3430 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3432 ;; When source and destination does not overlap, clear destination
3433 ;; first and then do the movb
3435 [(set (match_operand:HI 0 "register_operand" "")
3436 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3437 (clobber (reg:CC FLAGS_REG))]
3439 && ANY_QI_REG_P (operands[0])
3440 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3441 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3442 [(set (match_dup 0) (const_int 0))
3443 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3444 "operands[2] = gen_lowpart (QImode, operands[0]);")
3446 ;; Rest is handled by single and.
3448 [(set (match_operand:HI 0 "register_operand" "")
3449 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3450 (clobber (reg:CC FLAGS_REG))]
3452 && true_regnum (operands[0]) == true_regnum (operands[1])"
3453 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3454 (clobber (reg:CC FLAGS_REG))])]
3457 (define_expand "zero_extendqisi2"
3459 [(set (match_operand:SI 0 "register_operand" "")
3460 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3461 (clobber (reg:CC FLAGS_REG))])]
3465 (define_insn "*zero_extendqisi2_and"
3466 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3467 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3468 (clobber (reg:CC FLAGS_REG))]
3469 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3471 [(set_attr "type" "alu1")
3472 (set_attr "mode" "SI")])
3474 (define_insn "*zero_extendqisi2_movzbw_and"
3475 [(set (match_operand:SI 0 "register_operand" "=r,r")
3476 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3477 (clobber (reg:CC FLAGS_REG))]
3478 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3480 [(set_attr "type" "imovx,alu1")
3481 (set_attr "mode" "SI")])
3483 (define_insn "*zero_extendqisi2_movzbw"
3484 [(set (match_operand:SI 0 "register_operand" "=r")
3485 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3486 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3487 "movz{bl|x}\t{%1, %0|%0, %1}"
3488 [(set_attr "type" "imovx")
3489 (set_attr "mode" "SI")])
3491 ;; For the movzbl case strip only the clobber
3493 [(set (match_operand:SI 0 "register_operand" "")
3494 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3495 (clobber (reg:CC FLAGS_REG))]
3497 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3498 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3500 (zero_extend:SI (match_dup 1)))])
3502 ;; When source and destination does not overlap, clear destination
3503 ;; first and then do the movb
3505 [(set (match_operand:SI 0 "register_operand" "")
3506 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3507 (clobber (reg:CC FLAGS_REG))]
3509 && ANY_QI_REG_P (operands[0])
3510 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3511 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3512 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3513 [(set (match_dup 0) (const_int 0))
3514 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3515 "operands[2] = gen_lowpart (QImode, operands[0]);")
3517 ;; Rest is handled by single and.
3519 [(set (match_operand:SI 0 "register_operand" "")
3520 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3521 (clobber (reg:CC FLAGS_REG))]
3523 && true_regnum (operands[0]) == true_regnum (operands[1])"
3524 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3525 (clobber (reg:CC FLAGS_REG))])]
3528 ;; %%% Kill me once multi-word ops are sane.
3529 (define_expand "zero_extendsidi2"
3530 [(set (match_operand:DI 0 "register_operand" "=r")
3531 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3536 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3541 (define_insn "zero_extendsidi2_32"
3542 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Yt")
3544 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3545 (clobber (reg:CC FLAGS_REG))]
3551 movd\t{%1, %0|%0, %1}
3552 movd\t{%1, %0|%0, %1}
3553 movd\t{%1, %0|%0, %1}
3554 movd\t{%1, %0|%0, %1}"
3555 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3556 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3558 (define_insn "zero_extendsidi2_rex64"
3559 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Yt")
3561 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3564 mov\t{%k1, %k0|%k0, %k1}
3566 movd\t{%1, %0|%0, %1}
3567 movd\t{%1, %0|%0, %1}
3568 movd\t{%1, %0|%0, %1}
3569 movd\t{%1, %0|%0, %1}"
3570 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3571 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3574 [(set (match_operand:DI 0 "memory_operand" "")
3575 (zero_extend:DI (match_dup 0)))]
3577 [(set (match_dup 4) (const_int 0))]
3578 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3581 [(set (match_operand:DI 0 "register_operand" "")
3582 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3583 (clobber (reg:CC FLAGS_REG))]
3584 "!TARGET_64BIT && reload_completed
3585 && true_regnum (operands[0]) == true_regnum (operands[1])"
3586 [(set (match_dup 4) (const_int 0))]
3587 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3590 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3591 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3592 (clobber (reg:CC FLAGS_REG))]
3593 "!TARGET_64BIT && reload_completed
3594 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3595 [(set (match_dup 3) (match_dup 1))
3596 (set (match_dup 4) (const_int 0))]
3597 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3599 (define_insn "zero_extendhidi2"
3600 [(set (match_operand:DI 0 "register_operand" "=r")
3601 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3603 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3604 [(set_attr "type" "imovx")
3605 (set_attr "mode" "DI")])
3607 (define_insn "zero_extendqidi2"
3608 [(set (match_operand:DI 0 "register_operand" "=r")
3609 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3611 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3612 [(set_attr "type" "imovx")
3613 (set_attr "mode" "DI")])
3615 ;; Sign extension instructions
3617 (define_expand "extendsidi2"
3618 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3619 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3620 (clobber (reg:CC FLAGS_REG))
3621 (clobber (match_scratch:SI 2 ""))])]
3626 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3631 (define_insn "*extendsidi2_1"
3632 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3633 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3634 (clobber (reg:CC FLAGS_REG))
3635 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3639 (define_insn "extendsidi2_rex64"
3640 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3641 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3645 movs{lq|x}\t{%1,%0|%0, %1}"
3646 [(set_attr "type" "imovx")
3647 (set_attr "mode" "DI")
3648 (set_attr "prefix_0f" "0")
3649 (set_attr "modrm" "0,1")])
3651 (define_insn "extendhidi2"
3652 [(set (match_operand:DI 0 "register_operand" "=r")
3653 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3655 "movs{wq|x}\t{%1,%0|%0, %1}"
3656 [(set_attr "type" "imovx")
3657 (set_attr "mode" "DI")])
3659 (define_insn "extendqidi2"
3660 [(set (match_operand:DI 0 "register_operand" "=r")
3661 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3663 "movs{bq|x}\t{%1,%0|%0, %1}"
3664 [(set_attr "type" "imovx")
3665 (set_attr "mode" "DI")])
3667 ;; Extend to memory case when source register does die.
3669 [(set (match_operand:DI 0 "memory_operand" "")
3670 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3671 (clobber (reg:CC FLAGS_REG))
3672 (clobber (match_operand:SI 2 "register_operand" ""))]
3674 && dead_or_set_p (insn, operands[1])
3675 && !reg_mentioned_p (operands[1], operands[0]))"
3676 [(set (match_dup 3) (match_dup 1))
3677 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3678 (clobber (reg:CC FLAGS_REG))])
3679 (set (match_dup 4) (match_dup 1))]
3680 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3682 ;; Extend to memory case when source register does not die.
3684 [(set (match_operand:DI 0 "memory_operand" "")
3685 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3686 (clobber (reg:CC FLAGS_REG))
3687 (clobber (match_operand:SI 2 "register_operand" ""))]
3691 split_di (&operands[0], 1, &operands[3], &operands[4]);
3693 emit_move_insn (operands[3], operands[1]);
3695 /* Generate a cltd if possible and doing so it profitable. */
3696 if ((optimize_size || TARGET_USE_CLTD)
3697 && true_regnum (operands[1]) == 0
3698 && true_regnum (operands[2]) == 1)
3700 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3704 emit_move_insn (operands[2], operands[1]);
3705 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3707 emit_move_insn (operands[4], operands[2]);
3711 ;; Extend to register case. Optimize case where source and destination
3712 ;; registers match and cases where we can use cltd.
3714 [(set (match_operand:DI 0 "register_operand" "")
3715 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3716 (clobber (reg:CC FLAGS_REG))
3717 (clobber (match_scratch:SI 2 ""))]
3721 split_di (&operands[0], 1, &operands[3], &operands[4]);
3723 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3724 emit_move_insn (operands[3], operands[1]);
3726 /* Generate a cltd if possible and doing so it profitable. */
3727 if ((optimize_size || TARGET_USE_CLTD)
3728 && true_regnum (operands[3]) == 0)
3730 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3734 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3735 emit_move_insn (operands[4], operands[1]);
3737 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3741 (define_insn "extendhisi2"
3742 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3743 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3746 switch (get_attr_prefix_0f (insn))
3749 return "{cwtl|cwde}";
3751 return "movs{wl|x}\t{%1,%0|%0, %1}";
3754 [(set_attr "type" "imovx")
3755 (set_attr "mode" "SI")
3756 (set (attr "prefix_0f")
3757 ;; movsx is short decodable while cwtl is vector decoded.
3758 (if_then_else (and (eq_attr "cpu" "!k6")
3759 (eq_attr "alternative" "0"))
3761 (const_string "1")))
3763 (if_then_else (eq_attr "prefix_0f" "0")
3765 (const_string "1")))])
3767 (define_insn "*extendhisi2_zext"
3768 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3770 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3773 switch (get_attr_prefix_0f (insn))
3776 return "{cwtl|cwde}";
3778 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3781 [(set_attr "type" "imovx")
3782 (set_attr "mode" "SI")
3783 (set (attr "prefix_0f")
3784 ;; movsx is short decodable while cwtl is vector decoded.
3785 (if_then_else (and (eq_attr "cpu" "!k6")
3786 (eq_attr "alternative" "0"))
3788 (const_string "1")))
3790 (if_then_else (eq_attr "prefix_0f" "0")
3792 (const_string "1")))])
3794 (define_insn "extendqihi2"
3795 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3796 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3799 switch (get_attr_prefix_0f (insn))
3802 return "{cbtw|cbw}";
3804 return "movs{bw|x}\t{%1,%0|%0, %1}";
3807 [(set_attr "type" "imovx")
3808 (set_attr "mode" "HI")
3809 (set (attr "prefix_0f")
3810 ;; movsx is short decodable while cwtl is vector decoded.
3811 (if_then_else (and (eq_attr "cpu" "!k6")
3812 (eq_attr "alternative" "0"))
3814 (const_string "1")))
3816 (if_then_else (eq_attr "prefix_0f" "0")
3818 (const_string "1")))])
3820 (define_insn "extendqisi2"
3821 [(set (match_operand:SI 0 "register_operand" "=r")
3822 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3824 "movs{bl|x}\t{%1,%0|%0, %1}"
3825 [(set_attr "type" "imovx")
3826 (set_attr "mode" "SI")])
3828 (define_insn "*extendqisi2_zext"
3829 [(set (match_operand:DI 0 "register_operand" "=r")
3831 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3833 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3834 [(set_attr "type" "imovx")
3835 (set_attr "mode" "SI")])
3837 ;; Conversions between float and double.
3839 ;; These are all no-ops in the model used for the 80387. So just
3842 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3843 (define_insn "*dummy_extendsfdf2"
3844 [(set (match_operand:DF 0 "push_operand" "=<")
3845 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3850 [(set (match_operand:DF 0 "push_operand" "")
3851 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3853 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3854 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3857 [(set (match_operand:DF 0 "push_operand" "")
3858 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3860 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3861 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3863 (define_insn "*dummy_extendsfxf2"
3864 [(set (match_operand:XF 0 "push_operand" "=<")
3865 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3870 [(set (match_operand:XF 0 "push_operand" "")
3871 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3873 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3874 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3875 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3878 [(set (match_operand:XF 0 "push_operand" "")
3879 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3881 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3882 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3883 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3886 [(set (match_operand:XF 0 "push_operand" "")
3887 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3889 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3890 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3891 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3894 [(set (match_operand:XF 0 "push_operand" "")
3895 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3897 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3898 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3899 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3901 (define_expand "extendsfdf2"
3902 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3903 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3904 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3906 /* ??? Needed for compress_float_constant since all fp constants
3907 are LEGITIMATE_CONSTANT_P. */
3908 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3910 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3911 && standard_80387_constant_p (operands[1]) > 0)
3913 operands[1] = simplify_const_unary_operation
3914 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3915 emit_move_insn_1 (operands[0], operands[1]);
3918 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3922 (define_insn "*extendsfdf2_mixed"
3923 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3925 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3926 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3928 switch (which_alternative)
3932 return output_387_reg_move (insn, operands);
3935 return "cvtss2sd\t{%1, %0|%0, %1}";
3941 [(set_attr "type" "fmov,fmov,ssecvt")
3942 (set_attr "mode" "SF,XF,DF")])
3944 (define_insn "*extendsfdf2_sse"
3945 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3946 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3947 "TARGET_SSE2 && TARGET_SSE_MATH"
3948 "cvtss2sd\t{%1, %0|%0, %1}"
3949 [(set_attr "type" "ssecvt")
3950 (set_attr "mode" "DF")])
3952 (define_insn "*extendsfdf2_i387"
3953 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3954 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3956 "* return output_387_reg_move (insn, operands);"
3957 [(set_attr "type" "fmov")
3958 (set_attr "mode" "SF,XF")])
3960 (define_expand "extend<mode>xf2"
3961 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3962 (float_extend:XF (match_operand:X87MODEF12 1 "general_operand" "")))]
3965 /* ??? Needed for compress_float_constant since all fp constants
3966 are LEGITIMATE_CONSTANT_P. */
3967 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3969 if (standard_80387_constant_p (operands[1]) > 0)
3971 operands[1] = simplify_const_unary_operation
3972 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3973 emit_move_insn_1 (operands[0], operands[1]);
3976 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3980 (define_insn "*extend<mode>xf2_i387"
3981 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3983 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,f")))]
3985 "* return output_387_reg_move (insn, operands);"
3986 [(set_attr "type" "fmov")
3987 (set_attr "mode" "<MODE>,XF")])
3989 ;; %%% This seems bad bad news.
3990 ;; This cannot output into an f-reg because there is no way to be sure
3991 ;; of truncating in that case. Otherwise this is just like a simple move
3992 ;; insn. So we pretend we can output to a reg in order to get better
3993 ;; register preferencing, but we really use a stack slot.
3995 ;; Conversion from DFmode to SFmode.
3997 (define_expand "truncdfsf2"
3998 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4000 (match_operand:DF 1 "nonimmediate_operand" "")))]
4001 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4003 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4005 else if (flag_unsafe_math_optimizations)
4009 rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
4010 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4015 (define_expand "truncdfsf2_with_temp"
4016 [(parallel [(set (match_operand:SF 0 "" "")
4017 (float_truncate:SF (match_operand:DF 1 "" "")))
4018 (clobber (match_operand:SF 2 "" ""))])]
4021 (define_insn "*truncdfsf_fast_mixed"
4022 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
4024 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
4025 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4027 switch (which_alternative)
4031 return output_387_reg_move (insn, operands);
4033 return "cvtsd2ss\t{%1, %0|%0, %1}";
4038 [(set_attr "type" "fmov,fmov,ssecvt")
4039 (set_attr "mode" "SF")])
4041 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4042 ;; because nothing we do here is unsafe.
4043 (define_insn "*truncdfsf_fast_sse"
4044 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4046 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4047 "TARGET_SSE2 && TARGET_SSE_MATH"
4048 "cvtsd2ss\t{%1, %0|%0, %1}"
4049 [(set_attr "type" "ssecvt")
4050 (set_attr "mode" "SF")])
4052 (define_insn "*truncdfsf_fast_i387"
4053 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4055 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4056 "TARGET_80387 && flag_unsafe_math_optimizations"
4057 "* return output_387_reg_move (insn, operands);"
4058 [(set_attr "type" "fmov")
4059 (set_attr "mode" "SF")])
4061 (define_insn "*truncdfsf_mixed"
4062 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Yt")
4064 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ytm")))
4065 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4066 "TARGET_MIX_SSE_I387"
4068 switch (which_alternative)
4071 return output_387_reg_move (insn, operands);
4076 return "cvtsd2ss\t{%1, %0|%0, %1}";
4081 [(set_attr "type" "fmov,multi,ssecvt")
4082 (set_attr "unit" "*,i387,*")
4083 (set_attr "mode" "SF")])
4085 (define_insn "*truncdfsf_i387"
4086 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4088 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4089 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4092 switch (which_alternative)
4095 return output_387_reg_move (insn, operands);
4103 [(set_attr "type" "fmov,multi")
4104 (set_attr "unit" "*,i387")
4105 (set_attr "mode" "SF")])
4107 (define_insn "*truncdfsf2_i387_1"
4108 [(set (match_operand:SF 0 "memory_operand" "=m")
4110 (match_operand:DF 1 "register_operand" "f")))]
4112 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4113 && !TARGET_MIX_SSE_I387"
4114 "* return output_387_reg_move (insn, operands);"
4115 [(set_attr "type" "fmov")
4116 (set_attr "mode" "SF")])
4119 [(set (match_operand:SF 0 "register_operand" "")
4121 (match_operand:DF 1 "fp_register_operand" "")))
4122 (clobber (match_operand 2 "" ""))]
4124 [(set (match_dup 2) (match_dup 1))
4125 (set (match_dup 0) (match_dup 2))]
4127 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4130 ;; Conversion from XFmode to {SF,DF}mode
4132 (define_expand "truncxf<mode>2"
4133 [(parallel [(set (match_operand:X87MODEF12 0 "nonimmediate_operand" "")
4134 (float_truncate:X87MODEF12
4135 (match_operand:XF 1 "register_operand" "")))
4136 (clobber (match_dup 2))])]
4139 if (flag_unsafe_math_optimizations)
4141 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4142 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4143 if (reg != operands[0])
4144 emit_move_insn (operands[0], reg);
4148 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_VIRTUAL);
4151 (define_insn "*truncxfsf2_mixed"
4152 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4154 (match_operand:XF 1 "register_operand" "f,f")))
4155 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4158 gcc_assert (!which_alternative);
4159 return output_387_reg_move (insn, operands);
4161 [(set_attr "type" "fmov,multi")
4162 (set_attr "unit" "*,i387")
4163 (set_attr "mode" "SF")])
4165 (define_insn "*truncxfdf2_mixed"
4166 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fYt*r")
4168 (match_operand:XF 1 "register_operand" "f,f")))
4169 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4172 gcc_assert (!which_alternative);
4173 return output_387_reg_move (insn, operands);
4175 [(set_attr "type" "fmov,multi")
4176 (set_attr "unit" "*,i387")
4177 (set_attr "mode" "DF")])
4179 (define_insn "truncxf<mode>2_i387_noop"
4180 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
4181 (float_truncate:X87MODEF12
4182 (match_operand:XF 1 "register_operand" "f")))]
4183 "TARGET_80387 && flag_unsafe_math_optimizations"
4184 "* return output_387_reg_move (insn, operands);"
4185 [(set_attr "type" "fmov")
4186 (set_attr "mode" "<MODE>")])
4188 (define_insn "*truncxf<mode>2_i387"
4189 [(set (match_operand:X87MODEF12 0 "memory_operand" "=m")
4190 (float_truncate:X87MODEF12
4191 (match_operand:XF 1 "register_operand" "f")))]
4193 "* return output_387_reg_move (insn, operands);"
4194 [(set_attr "type" "fmov")
4195 (set_attr "mode" "<MODE>")])
4198 [(set (match_operand:X87MODEF12 0 "register_operand" "")
4199 (float_truncate:X87MODEF12
4200 (match_operand:XF 1 "register_operand" "")))
4201 (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4202 "TARGET_80387 && reload_completed"
4203 [(set (match_dup 2) (float_truncate:X87MODEF12 (match_dup 1)))
4204 (set (match_dup 0) (match_dup 2))]
4208 [(set (match_operand:X87MODEF12 0 "memory_operand" "")
4209 (float_truncate:X87MODEF12
4210 (match_operand:XF 1 "register_operand" "")))
4211 (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4213 [(set (match_dup 0) (float_truncate:X87MODEF12 (match_dup 1)))]
4216 ;; Signed conversion to DImode.
4218 (define_expand "fix_truncxfdi2"
4219 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4220 (fix:DI (match_operand:XF 1 "register_operand" "")))
4221 (clobber (reg:CC FLAGS_REG))])]
4226 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4231 (define_expand "fix_trunc<mode>di2"
4232 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4233 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4234 (clobber (reg:CC FLAGS_REG))])]
4235 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4238 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4240 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4243 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4245 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4246 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4247 if (out != operands[0])
4248 emit_move_insn (operands[0], out);
4253 ;; Signed conversion to SImode.
4255 (define_expand "fix_truncxfsi2"
4256 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4257 (fix:SI (match_operand:XF 1 "register_operand" "")))
4258 (clobber (reg:CC FLAGS_REG))])]
4263 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4268 (define_expand "fix_trunc<mode>si2"
4269 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4270 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4271 (clobber (reg:CC FLAGS_REG))])]
4272 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4275 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4277 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4280 if (SSE_FLOAT_MODE_P (<MODE>mode))
4282 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4283 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4284 if (out != operands[0])
4285 emit_move_insn (operands[0], out);
4290 ;; Signed conversion to HImode.
4292 (define_expand "fix_trunc<mode>hi2"
4293 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4294 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4295 (clobber (reg:CC FLAGS_REG))])]
4297 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4301 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4306 ;; Unsigned conversion to SImode.
4308 (define_expand "fixuns_trunc<mode>si2"
4310 [(set (match_operand:SI 0 "register_operand" "")
4312 (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4314 (clobber (match_scratch:<ssevecmode> 3 ""))
4315 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4316 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4318 enum machine_mode mode = <MODE>mode;
4319 enum machine_mode vecmode = <ssevecmode>mode;
4320 REAL_VALUE_TYPE TWO31r;
4323 real_ldexp (&TWO31r, &dconst1, 31);
4324 two31 = const_double_from_real_value (TWO31r, mode);
4325 two31 = ix86_build_const_vector (mode, true, two31);
4326 operands[2] = force_reg (vecmode, two31);
4329 (define_insn_and_split "*fixuns_trunc<mode>_1"
4330 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4332 (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4333 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4334 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4335 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4336 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4338 "&& reload_completed"
4341 ix86_split_convert_uns_si_sse (operands);
4345 ;; Unsigned conversion to HImode.
4346 ;; Without these patterns, we'll try the unsigned SI conversion which
4347 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4349 (define_expand "fixuns_trunc<mode>hi2"
4351 (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4352 (set (match_operand:HI 0 "nonimmediate_operand" "")
4353 (subreg:HI (match_dup 2) 0))]
4354 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4355 "operands[2] = gen_reg_rtx (SImode);")
4357 ;; When SSE is available, it is always faster to use it!
4358 (define_insn "fix_trunc<mode>di_sse"
4359 [(set (match_operand:DI 0 "register_operand" "=r,r")
4360 (fix:DI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4361 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4362 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4363 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4364 [(set_attr "type" "sseicvt")
4365 (set_attr "mode" "<MODE>")
4366 (set_attr "athlon_decode" "double,vector")
4367 (set_attr "amdfam10_decode" "double,double")])
4369 (define_insn "fix_trunc<mode>si_sse"
4370 [(set (match_operand:SI 0 "register_operand" "=r,r")
4371 (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4372 "SSE_FLOAT_MODE_P (<MODE>mode)
4373 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4374 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4375 [(set_attr "type" "sseicvt")
4376 (set_attr "mode" "<MODE>")
4377 (set_attr "athlon_decode" "double,vector")
4378 (set_attr "amdfam10_decode" "double,double")])
4380 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4382 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4383 (match_operand:SSEMODEF 1 "memory_operand" ""))
4384 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4385 (fix:SSEMODEI24 (match_dup 0)))]
4386 "TARGET_SHORTEN_X87_SSE
4387 && peep2_reg_dead_p (2, operands[0])"
4388 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4391 ;; Avoid vector decoded forms of the instruction.
4393 [(match_scratch:DF 2 "Yt")
4394 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4395 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4396 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4397 [(set (match_dup 2) (match_dup 1))
4398 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4402 [(match_scratch:SF 2 "x")
4403 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4404 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4405 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4406 [(set (match_dup 2) (match_dup 1))
4407 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4410 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4411 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4412 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4413 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4415 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4416 && (TARGET_64BIT || <MODE>mode != DImode))
4418 && !(reload_completed || reload_in_progress)"
4423 if (memory_operand (operands[0], VOIDmode))
4424 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4427 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4428 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4434 [(set_attr "type" "fisttp")
4435 (set_attr "mode" "<MODE>")])
4437 (define_insn "fix_trunc<mode>_i387_fisttp"
4438 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4439 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4440 (clobber (match_scratch:XF 2 "=&1f"))]
4441 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4443 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4444 && (TARGET_64BIT || <MODE>mode != DImode))
4445 && TARGET_SSE_MATH)"
4446 "* return output_fix_trunc (insn, operands, 1);"
4447 [(set_attr "type" "fisttp")
4448 (set_attr "mode" "<MODE>")])
4450 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4451 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4452 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4453 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4454 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4455 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4457 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4458 && (TARGET_64BIT || <MODE>mode != DImode))
4459 && TARGET_SSE_MATH)"
4461 [(set_attr "type" "fisttp")
4462 (set_attr "mode" "<MODE>")])
4465 [(set (match_operand:X87MODEI 0 "register_operand" "")
4466 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4467 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4468 (clobber (match_scratch 3 ""))]
4470 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4471 (clobber (match_dup 3))])
4472 (set (match_dup 0) (match_dup 2))]
4476 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4477 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4478 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4479 (clobber (match_scratch 3 ""))]
4481 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4482 (clobber (match_dup 3))])]
4485 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4486 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4487 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4488 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4489 ;; function in i386.c.
4490 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4491 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4492 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4493 (clobber (reg:CC FLAGS_REG))]
4494 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4496 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4497 && (TARGET_64BIT || <MODE>mode != DImode))
4498 && !(reload_completed || reload_in_progress)"
4503 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4505 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4506 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4507 if (memory_operand (operands[0], VOIDmode))
4508 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4509 operands[2], operands[3]));
4512 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4513 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4514 operands[2], operands[3],
4519 [(set_attr "type" "fistp")
4520 (set_attr "i387_cw" "trunc")
4521 (set_attr "mode" "<MODE>")])
4523 (define_insn "fix_truncdi_i387"
4524 [(set (match_operand:DI 0 "memory_operand" "=m")
4525 (fix:DI (match_operand 1 "register_operand" "f")))
4526 (use (match_operand:HI 2 "memory_operand" "m"))
4527 (use (match_operand:HI 3 "memory_operand" "m"))
4528 (clobber (match_scratch:XF 4 "=&1f"))]
4529 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4531 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4532 "* return output_fix_trunc (insn, operands, 0);"
4533 [(set_attr "type" "fistp")
4534 (set_attr "i387_cw" "trunc")
4535 (set_attr "mode" "DI")])
4537 (define_insn "fix_truncdi_i387_with_temp"
4538 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4539 (fix:DI (match_operand 1 "register_operand" "f,f")))
4540 (use (match_operand:HI 2 "memory_operand" "m,m"))
4541 (use (match_operand:HI 3 "memory_operand" "m,m"))
4542 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4543 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4544 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4546 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4548 [(set_attr "type" "fistp")
4549 (set_attr "i387_cw" "trunc")
4550 (set_attr "mode" "DI")])
4553 [(set (match_operand:DI 0 "register_operand" "")
4554 (fix:DI (match_operand 1 "register_operand" "")))
4555 (use (match_operand:HI 2 "memory_operand" ""))
4556 (use (match_operand:HI 3 "memory_operand" ""))
4557 (clobber (match_operand:DI 4 "memory_operand" ""))
4558 (clobber (match_scratch 5 ""))]
4560 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4563 (clobber (match_dup 5))])
4564 (set (match_dup 0) (match_dup 4))]
4568 [(set (match_operand:DI 0 "memory_operand" "")
4569 (fix:DI (match_operand 1 "register_operand" "")))
4570 (use (match_operand:HI 2 "memory_operand" ""))
4571 (use (match_operand:HI 3 "memory_operand" ""))
4572 (clobber (match_operand:DI 4 "memory_operand" ""))
4573 (clobber (match_scratch 5 ""))]
4575 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4578 (clobber (match_dup 5))])]
4581 (define_insn "fix_trunc<mode>_i387"
4582 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4583 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4584 (use (match_operand:HI 2 "memory_operand" "m"))
4585 (use (match_operand:HI 3 "memory_operand" "m"))]
4586 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4588 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4589 "* return output_fix_trunc (insn, operands, 0);"
4590 [(set_attr "type" "fistp")
4591 (set_attr "i387_cw" "trunc")
4592 (set_attr "mode" "<MODE>")])
4594 (define_insn "fix_trunc<mode>_i387_with_temp"
4595 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4596 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4597 (use (match_operand:HI 2 "memory_operand" "m,m"))
4598 (use (match_operand:HI 3 "memory_operand" "m,m"))
4599 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4600 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4602 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4604 [(set_attr "type" "fistp")
4605 (set_attr "i387_cw" "trunc")
4606 (set_attr "mode" "<MODE>")])
4609 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4610 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4611 (use (match_operand:HI 2 "memory_operand" ""))
4612 (use (match_operand:HI 3 "memory_operand" ""))
4613 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4615 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4617 (use (match_dup 3))])
4618 (set (match_dup 0) (match_dup 4))]
4622 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4623 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4624 (use (match_operand:HI 2 "memory_operand" ""))
4625 (use (match_operand:HI 3 "memory_operand" ""))
4626 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4628 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4630 (use (match_dup 3))])]
4633 (define_insn "x86_fnstcw_1"
4634 [(set (match_operand:HI 0 "memory_operand" "=m")
4635 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4638 [(set_attr "length" "2")
4639 (set_attr "mode" "HI")
4640 (set_attr "unit" "i387")])
4642 (define_insn "x86_fldcw_1"
4643 [(set (reg:HI FPCR_REG)
4644 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4647 [(set_attr "length" "2")
4648 (set_attr "mode" "HI")
4649 (set_attr "unit" "i387")
4650 (set_attr "athlon_decode" "vector")
4651 (set_attr "amdfam10_decode" "vector")])
4653 ;; Conversion between fixed point and floating point.
4655 ;; Even though we only accept memory inputs, the backend _really_
4656 ;; wants to be able to do this between registers.
4658 (define_expand "floathi<mode>2"
4659 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4660 (float:SSEMODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4661 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4663 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4666 (gen_floatsi<mode>2 (operands[0],
4667 convert_to_mode (SImode, operands[1], 0)));
4672 (define_insn "*floathi<mode>2_i387"
4673 [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4675 (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4677 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4678 || TARGET_MIX_SSE_I387)"
4682 [(set_attr "type" "fmov,multi")
4683 (set_attr "mode" "<MODE>")
4684 (set_attr "unit" "*,i387")
4685 (set_attr "fp_int_src" "true")])
4687 (define_expand "floatsi<mode>2"
4688 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4689 (float:SSEMODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4690 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4693 (define_insn "*floatsisf2_mixed"
4694 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4695 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4696 "TARGET_MIX_SSE_I387"
4700 cvtsi2ss\t{%1, %0|%0, %1}
4701 cvtsi2ss\t{%1, %0|%0, %1}"
4702 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4703 (set_attr "mode" "SF")
4704 (set_attr "unit" "*,i387,*,*")
4705 (set_attr "athlon_decode" "*,*,vector,double")
4706 (set_attr "amdfam10_decode" "*,*,vector,double")
4707 (set_attr "fp_int_src" "true")])
4709 (define_insn "*floatsisf2_sse"
4710 [(set (match_operand:SF 0 "register_operand" "=x,x")
4711 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4713 "cvtsi2ss\t{%1, %0|%0, %1}"
4714 [(set_attr "type" "sseicvt")
4715 (set_attr "mode" "SF")
4716 (set_attr "athlon_decode" "vector,double")
4717 (set_attr "amdfam10_decode" "vector,double")
4718 (set_attr "fp_int_src" "true")])
4720 (define_insn "*floatsidf2_mixed"
4721 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4722 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4723 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4727 cvtsi2sd\t{%1, %0|%0, %1}
4728 cvtsi2sd\t{%1, %0|%0, %1}"
4729 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4730 (set_attr "mode" "DF")
4731 (set_attr "unit" "*,i387,*,*")
4732 (set_attr "athlon_decode" "*,*,double,direct")
4733 (set_attr "amdfam10_decode" "*,*,vector,double")
4734 (set_attr "fp_int_src" "true")])
4736 (define_insn "*floatsidf2_sse"
4737 [(set (match_operand:DF 0 "register_operand" "=x,x")
4738 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4739 "TARGET_SSE2 && TARGET_SSE_MATH"
4740 "cvtsi2sd\t{%1, %0|%0, %1}"
4741 [(set_attr "type" "sseicvt")
4742 (set_attr "mode" "DF")
4743 (set_attr "athlon_decode" "double,direct")
4744 (set_attr "amdfam10_decode" "vector,double")
4745 (set_attr "fp_int_src" "true")])
4747 (define_insn "*floatsi<mode>2_i387"
4748 [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4750 (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4755 [(set_attr "type" "fmov,multi")
4756 (set_attr "mode" "<MODE>")
4757 (set_attr "unit" "*,i387")
4758 (set_attr "fp_int_src" "true")])
4760 (define_expand "floatdisf2"
4761 [(set (match_operand:SF 0 "register_operand" "")
4762 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4763 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4766 (define_insn "*floatdisf2_mixed"
4767 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4768 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4769 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4773 cvtsi2ss{q}\t{%1, %0|%0, %1}
4774 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4775 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4776 (set_attr "mode" "SF")
4777 (set_attr "unit" "*,i387,*,*")
4778 (set_attr "athlon_decode" "*,*,vector,double")
4779 (set_attr "amdfam10_decode" "*,*,vector,double")
4780 (set_attr "fp_int_src" "true")])
4782 (define_insn "*floatdisf2_sse"
4783 [(set (match_operand:SF 0 "register_operand" "=x,x")
4784 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4785 "TARGET_64BIT && TARGET_SSE_MATH"
4786 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4787 [(set_attr "type" "sseicvt")
4788 (set_attr "mode" "SF")
4789 (set_attr "athlon_decode" "vector,double")
4790 (set_attr "amdfam10_decode" "vector,double")
4791 (set_attr "fp_int_src" "true")])
4793 (define_expand "floatdidf2"
4794 [(set (match_operand:DF 0 "register_operand" "")
4795 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4796 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4798 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4800 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4805 (define_insn "*floatdidf2_mixed"
4806 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4807 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4808 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4812 cvtsi2sd{q}\t{%1, %0|%0, %1}
4813 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4814 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4815 (set_attr "mode" "DF")
4816 (set_attr "unit" "*,i387,*,*")
4817 (set_attr "athlon_decode" "*,*,double,direct")
4818 (set_attr "amdfam10_decode" "*,*,vector,double")
4819 (set_attr "fp_int_src" "true")])
4821 (define_insn "*floatdidf2_sse"
4822 [(set (match_operand:DF 0 "register_operand" "=x,x")
4823 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4824 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4825 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4826 [(set_attr "type" "sseicvt")
4827 (set_attr "mode" "DF")
4828 (set_attr "athlon_decode" "double,direct")
4829 (set_attr "amdfam10_decode" "vector,double")
4830 (set_attr "fp_int_src" "true")])
4832 (define_insn "*floatdi<mode>2_i387"
4833 [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4835 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4840 [(set_attr "type" "fmov,multi")
4841 (set_attr "mode" "<MODE>")
4842 (set_attr "unit" "*,i387")
4843 (set_attr "fp_int_src" "true")])
4845 (define_insn "float<mode>xf2"
4846 [(set (match_operand:XF 0 "register_operand" "=f,f")
4847 (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
4852 [(set_attr "type" "fmov,multi")
4853 (set_attr "mode" "XF")
4854 (set_attr "unit" "*,i387")
4855 (set_attr "fp_int_src" "true")])
4857 ;; %%% Kill these when reload knows how to do it.
4859 [(set (match_operand 0 "fp_register_operand" "")
4860 (float (match_operand 1 "register_operand" "")))]
4862 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
4865 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4866 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4867 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4868 ix86_free_from_memory (GET_MODE (operands[1]));
4872 (define_expand "floatunssisf2"
4873 [(use (match_operand:SF 0 "register_operand" ""))
4874 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4877 if (TARGET_SSE_MATH && TARGET_SSE2)
4878 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
4880 x86_emit_floatuns (operands);
4884 (define_expand "floatunssidf2"
4885 [(use (match_operand:DF 0 "register_operand" ""))
4886 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4887 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
4888 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
4890 (define_expand "floatunsdisf2"
4891 [(use (match_operand:SF 0 "register_operand" ""))
4892 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4893 "TARGET_64BIT && TARGET_SSE_MATH"
4894 "x86_emit_floatuns (operands); DONE;")
4896 (define_expand "floatunsdidf2"
4897 [(use (match_operand:DF 0 "register_operand" ""))
4898 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4899 "TARGET_SSE_MATH && TARGET_SSE2
4900 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
4903 x86_emit_floatuns (operands);
4905 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
4911 ;; %%% splits for addditi3
4913 (define_expand "addti3"
4914 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4915 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4916 (match_operand:TI 2 "x86_64_general_operand" "")))
4917 (clobber (reg:CC FLAGS_REG))]
4919 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4921 (define_insn "*addti3_1"
4922 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4923 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4924 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4925 (clobber (reg:CC FLAGS_REG))]
4926 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4930 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4931 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4932 (match_operand:TI 2 "x86_64_general_operand" "")))
4933 (clobber (reg:CC FLAGS_REG))]
4934 "TARGET_64BIT && reload_completed"
4935 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4937 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4938 (parallel [(set (match_dup 3)
4939 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4942 (clobber (reg:CC FLAGS_REG))])]
4943 "split_ti (operands+0, 1, operands+0, operands+3);
4944 split_ti (operands+1, 1, operands+1, operands+4);
4945 split_ti (operands+2, 1, operands+2, operands+5);")
4947 ;; %%% splits for addsidi3
4948 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4949 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4950 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4952 (define_expand "adddi3"
4953 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4954 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4955 (match_operand:DI 2 "x86_64_general_operand" "")))
4956 (clobber (reg:CC FLAGS_REG))]
4958 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4960 (define_insn "*adddi3_1"
4961 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4962 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4963 (match_operand:DI 2 "general_operand" "roiF,riF")))
4964 (clobber (reg:CC FLAGS_REG))]
4965 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4969 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4970 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4971 (match_operand:DI 2 "general_operand" "")))
4972 (clobber (reg:CC FLAGS_REG))]
4973 "!TARGET_64BIT && reload_completed"
4974 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4976 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4977 (parallel [(set (match_dup 3)
4978 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4981 (clobber (reg:CC FLAGS_REG))])]
4982 "split_di (operands+0, 1, operands+0, operands+3);
4983 split_di (operands+1, 1, operands+1, operands+4);
4984 split_di (operands+2, 1, operands+2, operands+5);")
4986 (define_insn "adddi3_carry_rex64"
4987 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4988 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4989 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4990 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4991 (clobber (reg:CC FLAGS_REG))]
4992 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4993 "adc{q}\t{%2, %0|%0, %2}"
4994 [(set_attr "type" "alu")
4995 (set_attr "pent_pair" "pu")
4996 (set_attr "mode" "DI")])
4998 (define_insn "*adddi3_cc_rex64"
4999 [(set (reg:CC FLAGS_REG)
5000 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5001 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5003 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5004 (plus:DI (match_dup 1) (match_dup 2)))]
5005 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5006 "add{q}\t{%2, %0|%0, %2}"
5007 [(set_attr "type" "alu")
5008 (set_attr "mode" "DI")])
5010 (define_insn "*<addsub><mode>3_cc_overflow"
5011 [(set (reg:CCC FLAGS_REG)
5014 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5015 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5017 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5018 (plusminus:SWI (match_dup 1) (match_dup 2)))]
5019 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5020 "<addsub>{<imodesuffix>}\t{%2, %0|%0, %2}"
5021 [(set_attr "type" "alu")
5022 (set_attr "mode" "<MODE>")])
5024 (define_insn "*add<mode>3_cconly_overflow"
5025 [(set (reg:CCC FLAGS_REG)
5027 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5028 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5030 (clobber (match_scratch:SWI 0 "=<r>"))]
5031 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5032 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5033 [(set_attr "type" "alu")
5034 (set_attr "mode" "<MODE>")])
5036 (define_insn "*sub<mode>3_cconly_overflow"
5037 [(set (reg:CCC FLAGS_REG)
5039 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5040 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5043 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5044 [(set_attr "type" "icmp")
5045 (set_attr "mode" "<MODE>")])
5047 (define_insn "*<addsub>si3_zext_cc_overflow"
5048 [(set (reg:CCC FLAGS_REG)
5050 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5051 (match_operand:SI 2 "general_operand" "g"))
5053 (set (match_operand:DI 0 "register_operand" "=r")
5054 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5055 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5056 "<addsub>{l}\t{%2, %k0|%k0, %2}"
5057 [(set_attr "type" "alu")
5058 (set_attr "mode" "SI")])
5060 (define_insn "addqi3_carry"
5061 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5062 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5063 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5064 (match_operand:QI 2 "general_operand" "qi,qm")))
5065 (clobber (reg:CC FLAGS_REG))]
5066 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5067 "adc{b}\t{%2, %0|%0, %2}"
5068 [(set_attr "type" "alu")
5069 (set_attr "pent_pair" "pu")
5070 (set_attr "mode" "QI")])
5072 (define_insn "addhi3_carry"
5073 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5074 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5075 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5076 (match_operand:HI 2 "general_operand" "ri,rm")))
5077 (clobber (reg:CC FLAGS_REG))]
5078 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5079 "adc{w}\t{%2, %0|%0, %2}"
5080 [(set_attr "type" "alu")
5081 (set_attr "pent_pair" "pu")
5082 (set_attr "mode" "HI")])
5084 (define_insn "addsi3_carry"
5085 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5086 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5087 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5088 (match_operand:SI 2 "general_operand" "ri,rm")))
5089 (clobber (reg:CC FLAGS_REG))]
5090 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5091 "adc{l}\t{%2, %0|%0, %2}"
5092 [(set_attr "type" "alu")
5093 (set_attr "pent_pair" "pu")
5094 (set_attr "mode" "SI")])
5096 (define_insn "*addsi3_carry_zext"
5097 [(set (match_operand:DI 0 "register_operand" "=r")
5099 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5100 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5101 (match_operand:SI 2 "general_operand" "g"))))
5102 (clobber (reg:CC FLAGS_REG))]
5103 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5104 "adc{l}\t{%2, %k0|%k0, %2}"
5105 [(set_attr "type" "alu")
5106 (set_attr "pent_pair" "pu")
5107 (set_attr "mode" "SI")])
5109 (define_insn "*addsi3_cc"
5110 [(set (reg:CC FLAGS_REG)
5111 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5112 (match_operand:SI 2 "general_operand" "ri,rm")]
5114 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5115 (plus:SI (match_dup 1) (match_dup 2)))]
5116 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5117 "add{l}\t{%2, %0|%0, %2}"
5118 [(set_attr "type" "alu")
5119 (set_attr "mode" "SI")])
5121 (define_insn "addqi3_cc"
5122 [(set (reg:CC FLAGS_REG)
5123 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5124 (match_operand:QI 2 "general_operand" "qi,qm")]
5126 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5127 (plus:QI (match_dup 1) (match_dup 2)))]
5128 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5129 "add{b}\t{%2, %0|%0, %2}"
5130 [(set_attr "type" "alu")
5131 (set_attr "mode" "QI")])
5133 (define_expand "addsi3"
5134 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5135 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5136 (match_operand:SI 2 "general_operand" "")))
5137 (clobber (reg:CC FLAGS_REG))])]
5139 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5141 (define_insn "*lea_1"
5142 [(set (match_operand:SI 0 "register_operand" "=r")
5143 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5145 "lea{l}\t{%a1, %0|%0, %a1}"
5146 [(set_attr "type" "lea")
5147 (set_attr "mode" "SI")])
5149 (define_insn "*lea_1_rex64"
5150 [(set (match_operand:SI 0 "register_operand" "=r")
5151 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5153 "lea{l}\t{%a1, %0|%0, %a1}"
5154 [(set_attr "type" "lea")
5155 (set_attr "mode" "SI")])
5157 (define_insn "*lea_1_zext"
5158 [(set (match_operand:DI 0 "register_operand" "=r")
5160 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5162 "lea{l}\t{%a1, %k0|%k0, %a1}"
5163 [(set_attr "type" "lea")
5164 (set_attr "mode" "SI")])
5166 (define_insn "*lea_2_rex64"
5167 [(set (match_operand:DI 0 "register_operand" "=r")
5168 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5170 "lea{q}\t{%a1, %0|%0, %a1}"
5171 [(set_attr "type" "lea")
5172 (set_attr "mode" "DI")])
5174 ;; The lea patterns for non-Pmodes needs to be matched by several
5175 ;; insns converted to real lea by splitters.
5177 (define_insn_and_split "*lea_general_1"
5178 [(set (match_operand 0 "register_operand" "=r")
5179 (plus (plus (match_operand 1 "index_register_operand" "l")
5180 (match_operand 2 "register_operand" "r"))
5181 (match_operand 3 "immediate_operand" "i")))]
5182 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5183 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5184 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5185 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5186 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5187 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5188 || GET_MODE (operands[3]) == VOIDmode)"
5190 "&& reload_completed"
5194 operands[0] = gen_lowpart (SImode, operands[0]);
5195 operands[1] = gen_lowpart (Pmode, operands[1]);
5196 operands[2] = gen_lowpart (Pmode, operands[2]);
5197 operands[3] = gen_lowpart (Pmode, operands[3]);
5198 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5200 if (Pmode != SImode)
5201 pat = gen_rtx_SUBREG (SImode, pat, 0);
5202 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5205 [(set_attr "type" "lea")
5206 (set_attr "mode" "SI")])
5208 (define_insn_and_split "*lea_general_1_zext"
5209 [(set (match_operand:DI 0 "register_operand" "=r")
5211 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5212 (match_operand:SI 2 "register_operand" "r"))
5213 (match_operand:SI 3 "immediate_operand" "i"))))]
5216 "&& reload_completed"
5218 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5220 (match_dup 3)) 0)))]
5222 operands[1] = gen_lowpart (Pmode, operands[1]);
5223 operands[2] = gen_lowpart (Pmode, operands[2]);
5224 operands[3] = gen_lowpart (Pmode, operands[3]);
5226 [(set_attr "type" "lea")
5227 (set_attr "mode" "SI")])
5229 (define_insn_and_split "*lea_general_2"
5230 [(set (match_operand 0 "register_operand" "=r")
5231 (plus (mult (match_operand 1 "index_register_operand" "l")
5232 (match_operand 2 "const248_operand" "i"))
5233 (match_operand 3 "nonmemory_operand" "ri")))]
5234 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5235 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5236 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5237 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5238 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5239 || GET_MODE (operands[3]) == VOIDmode)"
5241 "&& reload_completed"
5245 operands[0] = gen_lowpart (SImode, operands[0]);
5246 operands[1] = gen_lowpart (Pmode, operands[1]);
5247 operands[3] = gen_lowpart (Pmode, operands[3]);
5248 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5250 if (Pmode != SImode)
5251 pat = gen_rtx_SUBREG (SImode, pat, 0);
5252 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5255 [(set_attr "type" "lea")
5256 (set_attr "mode" "SI")])
5258 (define_insn_and_split "*lea_general_2_zext"
5259 [(set (match_operand:DI 0 "register_operand" "=r")
5261 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5262 (match_operand:SI 2 "const248_operand" "n"))
5263 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5266 "&& reload_completed"
5268 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5270 (match_dup 3)) 0)))]
5272 operands[1] = gen_lowpart (Pmode, operands[1]);
5273 operands[3] = gen_lowpart (Pmode, operands[3]);
5275 [(set_attr "type" "lea")
5276 (set_attr "mode" "SI")])
5278 (define_insn_and_split "*lea_general_3"
5279 [(set (match_operand 0 "register_operand" "=r")
5280 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5281 (match_operand 2 "const248_operand" "i"))
5282 (match_operand 3 "register_operand" "r"))
5283 (match_operand 4 "immediate_operand" "i")))]
5284 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5285 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5286 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5287 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5288 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5290 "&& reload_completed"
5294 operands[0] = gen_lowpart (SImode, operands[0]);
5295 operands[1] = gen_lowpart (Pmode, operands[1]);
5296 operands[3] = gen_lowpart (Pmode, operands[3]);
5297 operands[4] = gen_lowpart (Pmode, operands[4]);
5298 pat = gen_rtx_PLUS (Pmode,
5299 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5303 if (Pmode != SImode)
5304 pat = gen_rtx_SUBREG (SImode, pat, 0);
5305 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5308 [(set_attr "type" "lea")
5309 (set_attr "mode" "SI")])
5311 (define_insn_and_split "*lea_general_3_zext"
5312 [(set (match_operand:DI 0 "register_operand" "=r")
5314 (plus:SI (plus:SI (mult:SI
5315 (match_operand:SI 1 "index_register_operand" "l")
5316 (match_operand:SI 2 "const248_operand" "n"))
5317 (match_operand:SI 3 "register_operand" "r"))
5318 (match_operand:SI 4 "immediate_operand" "i"))))]
5321 "&& reload_completed"
5323 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5326 (match_dup 4)) 0)))]
5328 operands[1] = gen_lowpart (Pmode, operands[1]);
5329 operands[3] = gen_lowpart (Pmode, operands[3]);
5330 operands[4] = gen_lowpart (Pmode, operands[4]);
5332 [(set_attr "type" "lea")
5333 (set_attr "mode" "SI")])
5335 (define_insn "*adddi_1_rex64"
5336 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5337 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5338 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5339 (clobber (reg:CC FLAGS_REG))]
5340 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5342 switch (get_attr_type (insn))
5345 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5346 return "lea{q}\t{%a2, %0|%0, %a2}";
5349 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5350 if (operands[2] == const1_rtx)
5351 return "inc{q}\t%0";
5354 gcc_assert (operands[2] == constm1_rtx);
5355 return "dec{q}\t%0";
5359 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5361 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5362 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5363 if (CONST_INT_P (operands[2])
5364 /* Avoid overflows. */
5365 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5366 && (INTVAL (operands[2]) == 128
5367 || (INTVAL (operands[2]) < 0
5368 && INTVAL (operands[2]) != -128)))
5370 operands[2] = GEN_INT (-INTVAL (operands[2]));
5371 return "sub{q}\t{%2, %0|%0, %2}";
5373 return "add{q}\t{%2, %0|%0, %2}";
5377 (cond [(eq_attr "alternative" "2")
5378 (const_string "lea")
5379 ; Current assemblers are broken and do not allow @GOTOFF in
5380 ; ought but a memory context.
5381 (match_operand:DI 2 "pic_symbolic_operand" "")
5382 (const_string "lea")
5383 (match_operand:DI 2 "incdec_operand" "")
5384 (const_string "incdec")
5386 (const_string "alu")))
5387 (set_attr "mode" "DI")])
5389 ;; Convert lea to the lea pattern to avoid flags dependency.
5391 [(set (match_operand:DI 0 "register_operand" "")
5392 (plus:DI (match_operand:DI 1 "register_operand" "")
5393 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5394 (clobber (reg:CC FLAGS_REG))]
5395 "TARGET_64BIT && reload_completed
5396 && true_regnum (operands[0]) != true_regnum (operands[1])"
5398 (plus:DI (match_dup 1)
5402 (define_insn "*adddi_2_rex64"
5403 [(set (reg FLAGS_REG)
5405 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5406 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5408 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5409 (plus:DI (match_dup 1) (match_dup 2)))]
5410 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5411 && ix86_binary_operator_ok (PLUS, DImode, operands)
5412 /* Current assemblers are broken and do not allow @GOTOFF in
5413 ought but a memory context. */
5414 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5416 switch (get_attr_type (insn))
5419 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5420 if (operands[2] == const1_rtx)
5421 return "inc{q}\t%0";
5424 gcc_assert (operands[2] == constm1_rtx);
5425 return "dec{q}\t%0";
5429 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5430 /* ???? We ought to handle there the 32bit case too
5431 - do we need new constraint? */
5432 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5433 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5434 if (CONST_INT_P (operands[2])
5435 /* Avoid overflows. */
5436 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5437 && (INTVAL (operands[2]) == 128
5438 || (INTVAL (operands[2]) < 0
5439 && INTVAL (operands[2]) != -128)))
5441 operands[2] = GEN_INT (-INTVAL (operands[2]));
5442 return "sub{q}\t{%2, %0|%0, %2}";
5444 return "add{q}\t{%2, %0|%0, %2}";
5448 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5449 (const_string "incdec")
5450 (const_string "alu")))
5451 (set_attr "mode" "DI")])
5453 (define_insn "*adddi_3_rex64"
5454 [(set (reg FLAGS_REG)
5455 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5456 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5457 (clobber (match_scratch:DI 0 "=r"))]
5459 && ix86_match_ccmode (insn, CCZmode)
5460 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5461 /* Current assemblers are broken and do not allow @GOTOFF in
5462 ought but a memory context. */
5463 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5465 switch (get_attr_type (insn))
5468 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5469 if (operands[2] == const1_rtx)
5470 return "inc{q}\t%0";
5473 gcc_assert (operands[2] == constm1_rtx);
5474 return "dec{q}\t%0";
5478 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5479 /* ???? We ought to handle there the 32bit case too
5480 - do we need new constraint? */
5481 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5482 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5483 if (CONST_INT_P (operands[2])
5484 /* Avoid overflows. */
5485 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5486 && (INTVAL (operands[2]) == 128
5487 || (INTVAL (operands[2]) < 0
5488 && INTVAL (operands[2]) != -128)))
5490 operands[2] = GEN_INT (-INTVAL (operands[2]));
5491 return "sub{q}\t{%2, %0|%0, %2}";
5493 return "add{q}\t{%2, %0|%0, %2}";
5497 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5498 (const_string "incdec")
5499 (const_string "alu")))
5500 (set_attr "mode" "DI")])
5502 ; For comparisons against 1, -1 and 128, we may generate better code
5503 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5504 ; is matched then. We can't accept general immediate, because for
5505 ; case of overflows, the result is messed up.
5506 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5508 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5509 ; only for comparisons not depending on it.
5510 (define_insn "*adddi_4_rex64"
5511 [(set (reg FLAGS_REG)
5512 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5513 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5514 (clobber (match_scratch:DI 0 "=rm"))]
5516 && ix86_match_ccmode (insn, CCGCmode)"
5518 switch (get_attr_type (insn))
5521 if (operands[2] == constm1_rtx)
5522 return "inc{q}\t%0";
5525 gcc_assert (operands[2] == const1_rtx);
5526 return "dec{q}\t%0";
5530 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5531 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5532 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5533 if ((INTVAL (operands[2]) == -128
5534 || (INTVAL (operands[2]) > 0
5535 && INTVAL (operands[2]) != 128))
5536 /* Avoid overflows. */
5537 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5538 return "sub{q}\t{%2, %0|%0, %2}";
5539 operands[2] = GEN_INT (-INTVAL (operands[2]));
5540 return "add{q}\t{%2, %0|%0, %2}";
5544 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5545 (const_string "incdec")
5546 (const_string "alu")))
5547 (set_attr "mode" "DI")])
5549 (define_insn "*adddi_5_rex64"
5550 [(set (reg FLAGS_REG)
5552 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5553 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5555 (clobber (match_scratch:DI 0 "=r"))]
5557 && ix86_match_ccmode (insn, CCGOCmode)
5558 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5559 /* Current assemblers are broken and do not allow @GOTOFF in
5560 ought but a memory context. */
5561 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5563 switch (get_attr_type (insn))
5566 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5567 if (operands[2] == const1_rtx)
5568 return "inc{q}\t%0";
5571 gcc_assert (operands[2] == constm1_rtx);
5572 return "dec{q}\t%0";
5576 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5577 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5578 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5579 if (CONST_INT_P (operands[2])
5580 /* Avoid overflows. */
5581 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5582 && (INTVAL (operands[2]) == 128
5583 || (INTVAL (operands[2]) < 0
5584 && INTVAL (operands[2]) != -128)))
5586 operands[2] = GEN_INT (-INTVAL (operands[2]));
5587 return "sub{q}\t{%2, %0|%0, %2}";
5589 return "add{q}\t{%2, %0|%0, %2}";
5593 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5594 (const_string "incdec")
5595 (const_string "alu")))
5596 (set_attr "mode" "DI")])
5599 (define_insn "*addsi_1"
5600 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5601 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5602 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5603 (clobber (reg:CC FLAGS_REG))]
5604 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5606 switch (get_attr_type (insn))
5609 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5610 return "lea{l}\t{%a2, %0|%0, %a2}";
5613 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5614 if (operands[2] == const1_rtx)
5615 return "inc{l}\t%0";
5618 gcc_assert (operands[2] == constm1_rtx);
5619 return "dec{l}\t%0";
5623 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5625 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5626 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5627 if (CONST_INT_P (operands[2])
5628 && (INTVAL (operands[2]) == 128
5629 || (INTVAL (operands[2]) < 0
5630 && INTVAL (operands[2]) != -128)))
5632 operands[2] = GEN_INT (-INTVAL (operands[2]));
5633 return "sub{l}\t{%2, %0|%0, %2}";
5635 return "add{l}\t{%2, %0|%0, %2}";
5639 (cond [(eq_attr "alternative" "2")
5640 (const_string "lea")
5641 ; Current assemblers are broken and do not allow @GOTOFF in
5642 ; ought but a memory context.
5643 (match_operand:SI 2 "pic_symbolic_operand" "")
5644 (const_string "lea")
5645 (match_operand:SI 2 "incdec_operand" "")
5646 (const_string "incdec")
5648 (const_string "alu")))
5649 (set_attr "mode" "SI")])
5651 ;; Convert lea to the lea pattern to avoid flags dependency.
5653 [(set (match_operand 0 "register_operand" "")
5654 (plus (match_operand 1 "register_operand" "")
5655 (match_operand 2 "nonmemory_operand" "")))
5656 (clobber (reg:CC FLAGS_REG))]
5658 && true_regnum (operands[0]) != true_regnum (operands[1])"
5662 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5663 may confuse gen_lowpart. */
5664 if (GET_MODE (operands[0]) != Pmode)
5666 operands[1] = gen_lowpart (Pmode, operands[1]);
5667 operands[2] = gen_lowpart (Pmode, operands[2]);
5669 operands[0] = gen_lowpart (SImode, operands[0]);
5670 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5671 if (Pmode != SImode)
5672 pat = gen_rtx_SUBREG (SImode, pat, 0);
5673 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5677 ;; It may seem that nonimmediate operand is proper one for operand 1.
5678 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5679 ;; we take care in ix86_binary_operator_ok to not allow two memory
5680 ;; operands so proper swapping will be done in reload. This allow
5681 ;; patterns constructed from addsi_1 to match.
5682 (define_insn "addsi_1_zext"
5683 [(set (match_operand:DI 0 "register_operand" "=r,r")
5685 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5686 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5687 (clobber (reg:CC FLAGS_REG))]
5688 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5690 switch (get_attr_type (insn))
5693 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5694 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5697 if (operands[2] == const1_rtx)
5698 return "inc{l}\t%k0";
5701 gcc_assert (operands[2] == constm1_rtx);
5702 return "dec{l}\t%k0";
5706 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5707 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5708 if (CONST_INT_P (operands[2])
5709 && (INTVAL (operands[2]) == 128
5710 || (INTVAL (operands[2]) < 0
5711 && INTVAL (operands[2]) != -128)))
5713 operands[2] = GEN_INT (-INTVAL (operands[2]));
5714 return "sub{l}\t{%2, %k0|%k0, %2}";
5716 return "add{l}\t{%2, %k0|%k0, %2}";
5720 (cond [(eq_attr "alternative" "1")
5721 (const_string "lea")
5722 ; Current assemblers are broken and do not allow @GOTOFF in
5723 ; ought but a memory context.
5724 (match_operand:SI 2 "pic_symbolic_operand" "")
5725 (const_string "lea")
5726 (match_operand:SI 2 "incdec_operand" "")
5727 (const_string "incdec")
5729 (const_string "alu")))
5730 (set_attr "mode" "SI")])
5732 ;; Convert lea to the lea pattern to avoid flags dependency.
5734 [(set (match_operand:DI 0 "register_operand" "")
5736 (plus:SI (match_operand:SI 1 "register_operand" "")
5737 (match_operand:SI 2 "nonmemory_operand" ""))))
5738 (clobber (reg:CC FLAGS_REG))]
5739 "TARGET_64BIT && reload_completed
5740 && true_regnum (operands[0]) != true_regnum (operands[1])"
5742 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5744 operands[1] = gen_lowpart (Pmode, operands[1]);
5745 operands[2] = gen_lowpart (Pmode, operands[2]);
5748 (define_insn "*addsi_2"
5749 [(set (reg FLAGS_REG)
5751 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5752 (match_operand:SI 2 "general_operand" "rmni,rni"))
5754 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5755 (plus:SI (match_dup 1) (match_dup 2)))]
5756 "ix86_match_ccmode (insn, CCGOCmode)
5757 && ix86_binary_operator_ok (PLUS, SImode, operands)
5758 /* Current assemblers are broken and do not allow @GOTOFF in
5759 ought but a memory context. */
5760 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5762 switch (get_attr_type (insn))
5765 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5766 if (operands[2] == const1_rtx)
5767 return "inc{l}\t%0";
5770 gcc_assert (operands[2] == constm1_rtx);
5771 return "dec{l}\t%0";
5775 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5776 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5777 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5778 if (CONST_INT_P (operands[2])
5779 && (INTVAL (operands[2]) == 128
5780 || (INTVAL (operands[2]) < 0
5781 && INTVAL (operands[2]) != -128)))
5783 operands[2] = GEN_INT (-INTVAL (operands[2]));
5784 return "sub{l}\t{%2, %0|%0, %2}";
5786 return "add{l}\t{%2, %0|%0, %2}";
5790 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5791 (const_string "incdec")
5792 (const_string "alu")))
5793 (set_attr "mode" "SI")])
5795 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5796 (define_insn "*addsi_2_zext"
5797 [(set (reg FLAGS_REG)
5799 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5800 (match_operand:SI 2 "general_operand" "rmni"))
5802 (set (match_operand:DI 0 "register_operand" "=r")
5803 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5804 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5805 && ix86_binary_operator_ok (PLUS, SImode, operands)
5806 /* Current assemblers are broken and do not allow @GOTOFF in
5807 ought but a memory context. */
5808 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5810 switch (get_attr_type (insn))
5813 if (operands[2] == const1_rtx)
5814 return "inc{l}\t%k0";
5817 gcc_assert (operands[2] == constm1_rtx);
5818 return "dec{l}\t%k0";
5822 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5823 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5824 if (CONST_INT_P (operands[2])
5825 && (INTVAL (operands[2]) == 128
5826 || (INTVAL (operands[2]) < 0
5827 && INTVAL (operands[2]) != -128)))
5829 operands[2] = GEN_INT (-INTVAL (operands[2]));
5830 return "sub{l}\t{%2, %k0|%k0, %2}";
5832 return "add{l}\t{%2, %k0|%k0, %2}";
5836 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5837 (const_string "incdec")
5838 (const_string "alu")))
5839 (set_attr "mode" "SI")])
5841 (define_insn "*addsi_3"
5842 [(set (reg FLAGS_REG)
5843 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5844 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5845 (clobber (match_scratch:SI 0 "=r"))]
5846 "ix86_match_ccmode (insn, CCZmode)
5847 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5848 /* Current assemblers are broken and do not allow @GOTOFF in
5849 ought but a memory context. */
5850 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5852 switch (get_attr_type (insn))
5855 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5856 if (operands[2] == const1_rtx)
5857 return "inc{l}\t%0";
5860 gcc_assert (operands[2] == constm1_rtx);
5861 return "dec{l}\t%0";
5865 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5866 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5867 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5868 if (CONST_INT_P (operands[2])
5869 && (INTVAL (operands[2]) == 128
5870 || (INTVAL (operands[2]) < 0
5871 && INTVAL (operands[2]) != -128)))
5873 operands[2] = GEN_INT (-INTVAL (operands[2]));
5874 return "sub{l}\t{%2, %0|%0, %2}";
5876 return "add{l}\t{%2, %0|%0, %2}";
5880 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5881 (const_string "incdec")
5882 (const_string "alu")))
5883 (set_attr "mode" "SI")])
5885 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5886 (define_insn "*addsi_3_zext"
5887 [(set (reg FLAGS_REG)
5888 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5889 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5890 (set (match_operand:DI 0 "register_operand" "=r")
5891 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5892 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5893 && ix86_binary_operator_ok (PLUS, SImode, operands)
5894 /* Current assemblers are broken and do not allow @GOTOFF in
5895 ought but a memory context. */
5896 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5898 switch (get_attr_type (insn))
5901 if (operands[2] == const1_rtx)
5902 return "inc{l}\t%k0";
5905 gcc_assert (operands[2] == constm1_rtx);
5906 return "dec{l}\t%k0";
5910 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5911 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5912 if (CONST_INT_P (operands[2])
5913 && (INTVAL (operands[2]) == 128
5914 || (INTVAL (operands[2]) < 0
5915 && INTVAL (operands[2]) != -128)))
5917 operands[2] = GEN_INT (-INTVAL (operands[2]));
5918 return "sub{l}\t{%2, %k0|%k0, %2}";
5920 return "add{l}\t{%2, %k0|%k0, %2}";
5924 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5925 (const_string "incdec")
5926 (const_string "alu")))
5927 (set_attr "mode" "SI")])
5929 ; For comparisons against 1, -1 and 128, we may generate better code
5930 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5931 ; is matched then. We can't accept general immediate, because for
5932 ; case of overflows, the result is messed up.
5933 ; This pattern also don't hold of 0x80000000, since the value overflows
5935 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5936 ; only for comparisons not depending on it.
5937 (define_insn "*addsi_4"
5938 [(set (reg FLAGS_REG)
5939 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5940 (match_operand:SI 2 "const_int_operand" "n")))
5941 (clobber (match_scratch:SI 0 "=rm"))]
5942 "ix86_match_ccmode (insn, CCGCmode)
5943 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5945 switch (get_attr_type (insn))
5948 if (operands[2] == constm1_rtx)
5949 return "inc{l}\t%0";
5952 gcc_assert (operands[2] == const1_rtx);
5953 return "dec{l}\t%0";
5957 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5958 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5959 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5960 if ((INTVAL (operands[2]) == -128
5961 || (INTVAL (operands[2]) > 0
5962 && INTVAL (operands[2]) != 128)))
5963 return "sub{l}\t{%2, %0|%0, %2}";
5964 operands[2] = GEN_INT (-INTVAL (operands[2]));
5965 return "add{l}\t{%2, %0|%0, %2}";
5969 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5970 (const_string "incdec")
5971 (const_string "alu")))
5972 (set_attr "mode" "SI")])
5974 (define_insn "*addsi_5"
5975 [(set (reg FLAGS_REG)
5977 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5978 (match_operand:SI 2 "general_operand" "rmni"))
5980 (clobber (match_scratch:SI 0 "=r"))]
5981 "ix86_match_ccmode (insn, CCGOCmode)
5982 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5983 /* Current assemblers are broken and do not allow @GOTOFF in
5984 ought but a memory context. */
5985 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5987 switch (get_attr_type (insn))
5990 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5991 if (operands[2] == const1_rtx)
5992 return "inc{l}\t%0";
5995 gcc_assert (operands[2] == constm1_rtx);
5996 return "dec{l}\t%0";
6000 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6001 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6003 if (CONST_INT_P (operands[2])
6004 && (INTVAL (operands[2]) == 128
6005 || (INTVAL (operands[2]) < 0
6006 && INTVAL (operands[2]) != -128)))
6008 operands[2] = GEN_INT (-INTVAL (operands[2]));
6009 return "sub{l}\t{%2, %0|%0, %2}";
6011 return "add{l}\t{%2, %0|%0, %2}";
6015 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6016 (const_string "incdec")
6017 (const_string "alu")))
6018 (set_attr "mode" "SI")])
6020 (define_expand "addhi3"
6021 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6022 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6023 (match_operand:HI 2 "general_operand" "")))
6024 (clobber (reg:CC FLAGS_REG))])]
6025 "TARGET_HIMODE_MATH"
6026 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6028 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6029 ;; type optimizations enabled by define-splits. This is not important
6030 ;; for PII, and in fact harmful because of partial register stalls.
6032 (define_insn "*addhi_1_lea"
6033 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6034 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6035 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6036 (clobber (reg:CC FLAGS_REG))]
6037 "!TARGET_PARTIAL_REG_STALL
6038 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6040 switch (get_attr_type (insn))
6045 if (operands[2] == const1_rtx)
6046 return "inc{w}\t%0";
6049 gcc_assert (operands[2] == constm1_rtx);
6050 return "dec{w}\t%0";
6054 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6055 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6056 if (CONST_INT_P (operands[2])
6057 && (INTVAL (operands[2]) == 128
6058 || (INTVAL (operands[2]) < 0
6059 && INTVAL (operands[2]) != -128)))
6061 operands[2] = GEN_INT (-INTVAL (operands[2]));
6062 return "sub{w}\t{%2, %0|%0, %2}";
6064 return "add{w}\t{%2, %0|%0, %2}";
6068 (if_then_else (eq_attr "alternative" "2")
6069 (const_string "lea")
6070 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6071 (const_string "incdec")
6072 (const_string "alu"))))
6073 (set_attr "mode" "HI,HI,SI")])
6075 (define_insn "*addhi_1"
6076 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6077 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6078 (match_operand:HI 2 "general_operand" "ri,rm")))
6079 (clobber (reg:CC FLAGS_REG))]
6080 "TARGET_PARTIAL_REG_STALL
6081 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6083 switch (get_attr_type (insn))
6086 if (operands[2] == const1_rtx)
6087 return "inc{w}\t%0";
6090 gcc_assert (operands[2] == constm1_rtx);
6091 return "dec{w}\t%0";
6095 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6096 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6097 if (CONST_INT_P (operands[2])
6098 && (INTVAL (operands[2]) == 128
6099 || (INTVAL (operands[2]) < 0
6100 && INTVAL (operands[2]) != -128)))
6102 operands[2] = GEN_INT (-INTVAL (operands[2]));
6103 return "sub{w}\t{%2, %0|%0, %2}";
6105 return "add{w}\t{%2, %0|%0, %2}";
6109 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6110 (const_string "incdec")
6111 (const_string "alu")))
6112 (set_attr "mode" "HI")])
6114 (define_insn "*addhi_2"
6115 [(set (reg FLAGS_REG)
6117 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6118 (match_operand:HI 2 "general_operand" "rmni,rni"))
6120 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6121 (plus:HI (match_dup 1) (match_dup 2)))]
6122 "ix86_match_ccmode (insn, CCGOCmode)
6123 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6125 switch (get_attr_type (insn))
6128 if (operands[2] == const1_rtx)
6129 return "inc{w}\t%0";
6132 gcc_assert (operands[2] == constm1_rtx);
6133 return "dec{w}\t%0";
6137 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6138 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6139 if (CONST_INT_P (operands[2])
6140 && (INTVAL (operands[2]) == 128
6141 || (INTVAL (operands[2]) < 0
6142 && INTVAL (operands[2]) != -128)))
6144 operands[2] = GEN_INT (-INTVAL (operands[2]));
6145 return "sub{w}\t{%2, %0|%0, %2}";
6147 return "add{w}\t{%2, %0|%0, %2}";
6151 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6152 (const_string "incdec")
6153 (const_string "alu")))
6154 (set_attr "mode" "HI")])
6156 (define_insn "*addhi_3"
6157 [(set (reg FLAGS_REG)
6158 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6159 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6160 (clobber (match_scratch:HI 0 "=r"))]
6161 "ix86_match_ccmode (insn, CCZmode)
6162 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6164 switch (get_attr_type (insn))
6167 if (operands[2] == const1_rtx)
6168 return "inc{w}\t%0";
6171 gcc_assert (operands[2] == constm1_rtx);
6172 return "dec{w}\t%0";
6176 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6177 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6178 if (CONST_INT_P (operands[2])
6179 && (INTVAL (operands[2]) == 128
6180 || (INTVAL (operands[2]) < 0
6181 && INTVAL (operands[2]) != -128)))
6183 operands[2] = GEN_INT (-INTVAL (operands[2]));
6184 return "sub{w}\t{%2, %0|%0, %2}";
6186 return "add{w}\t{%2, %0|%0, %2}";
6190 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6191 (const_string "incdec")
6192 (const_string "alu")))
6193 (set_attr "mode" "HI")])
6195 ; See comments above addsi_4 for details.
6196 (define_insn "*addhi_4"
6197 [(set (reg FLAGS_REG)
6198 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6199 (match_operand:HI 2 "const_int_operand" "n")))
6200 (clobber (match_scratch:HI 0 "=rm"))]
6201 "ix86_match_ccmode (insn, CCGCmode)
6202 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6204 switch (get_attr_type (insn))
6207 if (operands[2] == constm1_rtx)
6208 return "inc{w}\t%0";
6211 gcc_assert (operands[2] == const1_rtx);
6212 return "dec{w}\t%0";
6216 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6217 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6218 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6219 if ((INTVAL (operands[2]) == -128
6220 || (INTVAL (operands[2]) > 0
6221 && INTVAL (operands[2]) != 128)))
6222 return "sub{w}\t{%2, %0|%0, %2}";
6223 operands[2] = GEN_INT (-INTVAL (operands[2]));
6224 return "add{w}\t{%2, %0|%0, %2}";
6228 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6229 (const_string "incdec")
6230 (const_string "alu")))
6231 (set_attr "mode" "SI")])
6234 (define_insn "*addhi_5"
6235 [(set (reg FLAGS_REG)
6237 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6238 (match_operand:HI 2 "general_operand" "rmni"))
6240 (clobber (match_scratch:HI 0 "=r"))]
6241 "ix86_match_ccmode (insn, CCGOCmode)
6242 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6244 switch (get_attr_type (insn))
6247 if (operands[2] == const1_rtx)
6248 return "inc{w}\t%0";
6251 gcc_assert (operands[2] == constm1_rtx);
6252 return "dec{w}\t%0";
6256 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6257 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6258 if (CONST_INT_P (operands[2])
6259 && (INTVAL (operands[2]) == 128
6260 || (INTVAL (operands[2]) < 0
6261 && INTVAL (operands[2]) != -128)))
6263 operands[2] = GEN_INT (-INTVAL (operands[2]));
6264 return "sub{w}\t{%2, %0|%0, %2}";
6266 return "add{w}\t{%2, %0|%0, %2}";
6270 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6271 (const_string "incdec")
6272 (const_string "alu")))
6273 (set_attr "mode" "HI")])
6275 (define_expand "addqi3"
6276 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6277 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6278 (match_operand:QI 2 "general_operand" "")))
6279 (clobber (reg:CC FLAGS_REG))])]
6280 "TARGET_QIMODE_MATH"
6281 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6283 ;; %%% Potential partial reg stall on alternative 2. What to do?
6284 (define_insn "*addqi_1_lea"
6285 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6286 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6287 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6288 (clobber (reg:CC FLAGS_REG))]
6289 "!TARGET_PARTIAL_REG_STALL
6290 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6292 int widen = (which_alternative == 2);
6293 switch (get_attr_type (insn))
6298 if (operands[2] == const1_rtx)
6299 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6302 gcc_assert (operands[2] == constm1_rtx);
6303 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
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]));
6316 return "sub{l}\t{%2, %k0|%k0, %2}";
6318 return "sub{b}\t{%2, %0|%0, %2}";
6321 return "add{l}\t{%k2, %k0|%k0, %k2}";
6323 return "add{b}\t{%2, %0|%0, %2}";
6327 (if_then_else (eq_attr "alternative" "3")
6328 (const_string "lea")
6329 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6330 (const_string "incdec")
6331 (const_string "alu"))))
6332 (set_attr "mode" "QI,QI,SI,SI")])
6334 (define_insn "*addqi_1"
6335 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6336 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6337 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6338 (clobber (reg:CC FLAGS_REG))]
6339 "TARGET_PARTIAL_REG_STALL
6340 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6342 int widen = (which_alternative == 2);
6343 switch (get_attr_type (insn))
6346 if (operands[2] == const1_rtx)
6347 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6350 gcc_assert (operands[2] == constm1_rtx);
6351 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
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 (CONST_INT_P (operands[2])
6358 && (INTVAL (operands[2]) == 128
6359 || (INTVAL (operands[2]) < 0
6360 && INTVAL (operands[2]) != -128)))
6362 operands[2] = GEN_INT (-INTVAL (operands[2]));
6364 return "sub{l}\t{%2, %k0|%k0, %2}";
6366 return "sub{b}\t{%2, %0|%0, %2}";
6369 return "add{l}\t{%k2, %k0|%k0, %k2}";
6371 return "add{b}\t{%2, %0|%0, %2}";
6375 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6376 (const_string "incdec")
6377 (const_string "alu")))
6378 (set_attr "mode" "QI,QI,SI")])
6380 (define_insn "*addqi_1_slp"
6381 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6382 (plus:QI (match_dup 0)
6383 (match_operand:QI 1 "general_operand" "qn,qnm")))
6384 (clobber (reg:CC FLAGS_REG))]
6385 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6386 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6388 switch (get_attr_type (insn))
6391 if (operands[1] == const1_rtx)
6392 return "inc{b}\t%0";
6395 gcc_assert (operands[1] == constm1_rtx);
6396 return "dec{b}\t%0";
6400 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6401 if (CONST_INT_P (operands[1])
6402 && INTVAL (operands[1]) < 0)
6404 operands[1] = GEN_INT (-INTVAL (operands[1]));
6405 return "sub{b}\t{%1, %0|%0, %1}";
6407 return "add{b}\t{%1, %0|%0, %1}";
6411 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6412 (const_string "incdec")
6413 (const_string "alu1")))
6414 (set (attr "memory")
6415 (if_then_else (match_operand 1 "memory_operand" "")
6416 (const_string "load")
6417 (const_string "none")))
6418 (set_attr "mode" "QI")])
6420 (define_insn "*addqi_2"
6421 [(set (reg FLAGS_REG)
6423 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6424 (match_operand:QI 2 "general_operand" "qmni,qni"))
6426 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6427 (plus:QI (match_dup 1) (match_dup 2)))]
6428 "ix86_match_ccmode (insn, CCGOCmode)
6429 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6431 switch (get_attr_type (insn))
6434 if (operands[2] == const1_rtx)
6435 return "inc{b}\t%0";
6438 gcc_assert (operands[2] == constm1_rtx
6439 || (CONST_INT_P (operands[2])
6440 && INTVAL (operands[2]) == 255));
6441 return "dec{b}\t%0";
6445 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6446 if (CONST_INT_P (operands[2])
6447 && INTVAL (operands[2]) < 0)
6449 operands[2] = GEN_INT (-INTVAL (operands[2]));
6450 return "sub{b}\t{%2, %0|%0, %2}";
6452 return "add{b}\t{%2, %0|%0, %2}";
6456 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6457 (const_string "incdec")
6458 (const_string "alu")))
6459 (set_attr "mode" "QI")])
6461 (define_insn "*addqi_3"
6462 [(set (reg FLAGS_REG)
6463 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6464 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6465 (clobber (match_scratch:QI 0 "=q"))]
6466 "ix86_match_ccmode (insn, CCZmode)
6467 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6469 switch (get_attr_type (insn))
6472 if (operands[2] == const1_rtx)
6473 return "inc{b}\t%0";
6476 gcc_assert (operands[2] == constm1_rtx
6477 || (CONST_INT_P (operands[2])
6478 && INTVAL (operands[2]) == 255));
6479 return "dec{b}\t%0";
6483 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6484 if (CONST_INT_P (operands[2])
6485 && INTVAL (operands[2]) < 0)
6487 operands[2] = GEN_INT (-INTVAL (operands[2]));
6488 return "sub{b}\t{%2, %0|%0, %2}";
6490 return "add{b}\t{%2, %0|%0, %2}";
6494 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6495 (const_string "incdec")
6496 (const_string "alu")))
6497 (set_attr "mode" "QI")])
6499 ; See comments above addsi_4 for details.
6500 (define_insn "*addqi_4"
6501 [(set (reg FLAGS_REG)
6502 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6503 (match_operand:QI 2 "const_int_operand" "n")))
6504 (clobber (match_scratch:QI 0 "=qm"))]
6505 "ix86_match_ccmode (insn, CCGCmode)
6506 && (INTVAL (operands[2]) & 0xff) != 0x80"
6508 switch (get_attr_type (insn))
6511 if (operands[2] == constm1_rtx
6512 || (CONST_INT_P (operands[2])
6513 && INTVAL (operands[2]) == 255))
6514 return "inc{b}\t%0";
6517 gcc_assert (operands[2] == const1_rtx);
6518 return "dec{b}\t%0";
6522 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6523 if (INTVAL (operands[2]) < 0)
6525 operands[2] = GEN_INT (-INTVAL (operands[2]));
6526 return "add{b}\t{%2, %0|%0, %2}";
6528 return "sub{b}\t{%2, %0|%0, %2}";
6532 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6533 (const_string "incdec")
6534 (const_string "alu")))
6535 (set_attr "mode" "QI")])
6538 (define_insn "*addqi_5"
6539 [(set (reg FLAGS_REG)
6541 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6542 (match_operand:QI 2 "general_operand" "qmni"))
6544 (clobber (match_scratch:QI 0 "=q"))]
6545 "ix86_match_ccmode (insn, CCGOCmode)
6546 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6548 switch (get_attr_type (insn))
6551 if (operands[2] == const1_rtx)
6552 return "inc{b}\t%0";
6555 gcc_assert (operands[2] == constm1_rtx
6556 || (CONST_INT_P (operands[2])
6557 && INTVAL (operands[2]) == 255));
6558 return "dec{b}\t%0";
6562 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6563 if (CONST_INT_P (operands[2])
6564 && INTVAL (operands[2]) < 0)
6566 operands[2] = GEN_INT (-INTVAL (operands[2]));
6567 return "sub{b}\t{%2, %0|%0, %2}";
6569 return "add{b}\t{%2, %0|%0, %2}";
6573 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6574 (const_string "incdec")
6575 (const_string "alu")))
6576 (set_attr "mode" "QI")])
6579 (define_insn "addqi_ext_1"
6580 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6585 (match_operand 1 "ext_register_operand" "0")
6588 (match_operand:QI 2 "general_operand" "Qmn")))
6589 (clobber (reg:CC FLAGS_REG))]
6592 switch (get_attr_type (insn))
6595 if (operands[2] == const1_rtx)
6596 return "inc{b}\t%h0";
6599 gcc_assert (operands[2] == constm1_rtx
6600 || (CONST_INT_P (operands[2])
6601 && INTVAL (operands[2]) == 255));
6602 return "dec{b}\t%h0";
6606 return "add{b}\t{%2, %h0|%h0, %2}";
6610 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6611 (const_string "incdec")
6612 (const_string "alu")))
6613 (set_attr "mode" "QI")])
6615 (define_insn "*addqi_ext_1_rex64"
6616 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6621 (match_operand 1 "ext_register_operand" "0")
6624 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6625 (clobber (reg:CC FLAGS_REG))]
6628 switch (get_attr_type (insn))
6631 if (operands[2] == const1_rtx)
6632 return "inc{b}\t%h0";
6635 gcc_assert (operands[2] == constm1_rtx
6636 || (CONST_INT_P (operands[2])
6637 && INTVAL (operands[2]) == 255));
6638 return "dec{b}\t%h0";
6642 return "add{b}\t{%2, %h0|%h0, %2}";
6646 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6647 (const_string "incdec")
6648 (const_string "alu")))
6649 (set_attr "mode" "QI")])
6651 (define_insn "*addqi_ext_2"
6652 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6657 (match_operand 1 "ext_register_operand" "%0")
6661 (match_operand 2 "ext_register_operand" "Q")
6664 (clobber (reg:CC FLAGS_REG))]
6666 "add{b}\t{%h2, %h0|%h0, %h2}"
6667 [(set_attr "type" "alu")
6668 (set_attr "mode" "QI")])
6670 ;; The patterns that match these are at the end of this file.
6672 (define_expand "addxf3"
6673 [(set (match_operand:XF 0 "register_operand" "")
6674 (plus:XF (match_operand:XF 1 "register_operand" "")
6675 (match_operand:XF 2 "register_operand" "")))]
6679 (define_expand "adddf3"
6680 [(set (match_operand:DF 0 "register_operand" "")
6681 (plus:DF (match_operand:DF 1 "register_operand" "")
6682 (match_operand:DF 2 "nonimmediate_operand" "")))]
6683 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6686 (define_expand "addsf3"
6687 [(set (match_operand:SF 0 "register_operand" "")
6688 (plus:SF (match_operand:SF 1 "register_operand" "")
6689 (match_operand:SF 2 "nonimmediate_operand" "")))]
6690 "TARGET_80387 || TARGET_SSE_MATH"
6693 ;; Subtract instructions
6695 ;; %%% splits for subditi3
6697 (define_expand "subti3"
6698 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6699 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6700 (match_operand:TI 2 "x86_64_general_operand" "")))
6701 (clobber (reg:CC FLAGS_REG))])]
6703 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6705 (define_insn "*subti3_1"
6706 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6707 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6708 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6709 (clobber (reg:CC FLAGS_REG))]
6710 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6714 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6715 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6716 (match_operand:TI 2 "x86_64_general_operand" "")))
6717 (clobber (reg:CC FLAGS_REG))]
6718 "TARGET_64BIT && reload_completed"
6719 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6720 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6721 (parallel [(set (match_dup 3)
6722 (minus:DI (match_dup 4)
6723 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6725 (clobber (reg:CC FLAGS_REG))])]
6726 "split_ti (operands+0, 1, operands+0, operands+3);
6727 split_ti (operands+1, 1, operands+1, operands+4);
6728 split_ti (operands+2, 1, operands+2, operands+5);")
6730 ;; %%% splits for subsidi3
6732 (define_expand "subdi3"
6733 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6734 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6735 (match_operand:DI 2 "x86_64_general_operand" "")))
6736 (clobber (reg:CC FLAGS_REG))])]
6738 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6740 (define_insn "*subdi3_1"
6741 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6742 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6743 (match_operand:DI 2 "general_operand" "roiF,riF")))
6744 (clobber (reg:CC FLAGS_REG))]
6745 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6749 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6750 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6751 (match_operand:DI 2 "general_operand" "")))
6752 (clobber (reg:CC FLAGS_REG))]
6753 "!TARGET_64BIT && reload_completed"
6754 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6755 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6756 (parallel [(set (match_dup 3)
6757 (minus:SI (match_dup 4)
6758 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6760 (clobber (reg:CC FLAGS_REG))])]
6761 "split_di (operands+0, 1, operands+0, operands+3);
6762 split_di (operands+1, 1, operands+1, operands+4);
6763 split_di (operands+2, 1, operands+2, operands+5);")
6765 (define_insn "subdi3_carry_rex64"
6766 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6767 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6768 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6769 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6770 (clobber (reg:CC FLAGS_REG))]
6771 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6772 "sbb{q}\t{%2, %0|%0, %2}"
6773 [(set_attr "type" "alu")
6774 (set_attr "pent_pair" "pu")
6775 (set_attr "mode" "DI")])
6777 (define_insn "*subdi_1_rex64"
6778 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6779 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6780 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6781 (clobber (reg:CC FLAGS_REG))]
6782 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6783 "sub{q}\t{%2, %0|%0, %2}"
6784 [(set_attr "type" "alu")
6785 (set_attr "mode" "DI")])
6787 (define_insn "*subdi_2_rex64"
6788 [(set (reg FLAGS_REG)
6790 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6791 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6793 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6794 (minus:DI (match_dup 1) (match_dup 2)))]
6795 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6796 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6797 "sub{q}\t{%2, %0|%0, %2}"
6798 [(set_attr "type" "alu")
6799 (set_attr "mode" "DI")])
6801 (define_insn "*subdi_3_rex63"
6802 [(set (reg FLAGS_REG)
6803 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6804 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6805 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6806 (minus:DI (match_dup 1) (match_dup 2)))]
6807 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6808 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6809 "sub{q}\t{%2, %0|%0, %2}"
6810 [(set_attr "type" "alu")
6811 (set_attr "mode" "DI")])
6813 (define_insn "subqi3_carry"
6814 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6815 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6816 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6817 (match_operand:QI 2 "general_operand" "qi,qm"))))
6818 (clobber (reg:CC FLAGS_REG))]
6819 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6820 "sbb{b}\t{%2, %0|%0, %2}"
6821 [(set_attr "type" "alu")
6822 (set_attr "pent_pair" "pu")
6823 (set_attr "mode" "QI")])
6825 (define_insn "subhi3_carry"
6826 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6827 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6828 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6829 (match_operand:HI 2 "general_operand" "ri,rm"))))
6830 (clobber (reg:CC FLAGS_REG))]
6831 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6832 "sbb{w}\t{%2, %0|%0, %2}"
6833 [(set_attr "type" "alu")
6834 (set_attr "pent_pair" "pu")
6835 (set_attr "mode" "HI")])
6837 (define_insn "subsi3_carry"
6838 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6839 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6840 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6841 (match_operand:SI 2 "general_operand" "ri,rm"))))
6842 (clobber (reg:CC FLAGS_REG))]
6843 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6844 "sbb{l}\t{%2, %0|%0, %2}"
6845 [(set_attr "type" "alu")
6846 (set_attr "pent_pair" "pu")
6847 (set_attr "mode" "SI")])
6849 (define_insn "subsi3_carry_zext"
6850 [(set (match_operand:DI 0 "register_operand" "=r")
6852 (minus:SI (match_operand:SI 1 "register_operand" "0")
6853 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6854 (match_operand:SI 2 "general_operand" "g")))))
6855 (clobber (reg:CC FLAGS_REG))]
6856 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6857 "sbb{l}\t{%2, %k0|%k0, %2}"
6858 [(set_attr "type" "alu")
6859 (set_attr "pent_pair" "pu")
6860 (set_attr "mode" "SI")])
6862 (define_expand "subsi3"
6863 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6864 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6865 (match_operand:SI 2 "general_operand" "")))
6866 (clobber (reg:CC FLAGS_REG))])]
6868 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6870 (define_insn "*subsi_1"
6871 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6872 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6873 (match_operand:SI 2 "general_operand" "ri,rm")))
6874 (clobber (reg:CC FLAGS_REG))]
6875 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6876 "sub{l}\t{%2, %0|%0, %2}"
6877 [(set_attr "type" "alu")
6878 (set_attr "mode" "SI")])
6880 (define_insn "*subsi_1_zext"
6881 [(set (match_operand:DI 0 "register_operand" "=r")
6883 (minus:SI (match_operand:SI 1 "register_operand" "0")
6884 (match_operand:SI 2 "general_operand" "g"))))
6885 (clobber (reg:CC FLAGS_REG))]
6886 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6887 "sub{l}\t{%2, %k0|%k0, %2}"
6888 [(set_attr "type" "alu")
6889 (set_attr "mode" "SI")])
6891 (define_insn "*subsi_2"
6892 [(set (reg FLAGS_REG)
6894 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6895 (match_operand:SI 2 "general_operand" "ri,rm"))
6897 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6898 (minus:SI (match_dup 1) (match_dup 2)))]
6899 "ix86_match_ccmode (insn, CCGOCmode)
6900 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6901 "sub{l}\t{%2, %0|%0, %2}"
6902 [(set_attr "type" "alu")
6903 (set_attr "mode" "SI")])
6905 (define_insn "*subsi_2_zext"
6906 [(set (reg FLAGS_REG)
6908 (minus:SI (match_operand:SI 1 "register_operand" "0")
6909 (match_operand:SI 2 "general_operand" "g"))
6911 (set (match_operand:DI 0 "register_operand" "=r")
6913 (minus:SI (match_dup 1)
6915 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6916 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6917 "sub{l}\t{%2, %k0|%k0, %2}"
6918 [(set_attr "type" "alu")
6919 (set_attr "mode" "SI")])
6921 (define_insn "*subsi_3"
6922 [(set (reg FLAGS_REG)
6923 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6924 (match_operand:SI 2 "general_operand" "ri,rm")))
6925 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6926 (minus:SI (match_dup 1) (match_dup 2)))]
6927 "ix86_match_ccmode (insn, CCmode)
6928 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6929 "sub{l}\t{%2, %0|%0, %2}"
6930 [(set_attr "type" "alu")
6931 (set_attr "mode" "SI")])
6933 (define_insn "*subsi_3_zext"
6934 [(set (reg FLAGS_REG)
6935 (compare (match_operand:SI 1 "register_operand" "0")
6936 (match_operand:SI 2 "general_operand" "g")))
6937 (set (match_operand:DI 0 "register_operand" "=r")
6939 (minus:SI (match_dup 1)
6941 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6942 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6943 "sub{l}\t{%2, %1|%1, %2}"
6944 [(set_attr "type" "alu")
6945 (set_attr "mode" "DI")])
6947 (define_expand "subhi3"
6948 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6949 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6950 (match_operand:HI 2 "general_operand" "")))
6951 (clobber (reg:CC FLAGS_REG))])]
6952 "TARGET_HIMODE_MATH"
6953 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6955 (define_insn "*subhi_1"
6956 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6957 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6958 (match_operand:HI 2 "general_operand" "ri,rm")))
6959 (clobber (reg:CC FLAGS_REG))]
6960 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6961 "sub{w}\t{%2, %0|%0, %2}"
6962 [(set_attr "type" "alu")
6963 (set_attr "mode" "HI")])
6965 (define_insn "*subhi_2"
6966 [(set (reg FLAGS_REG)
6968 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6969 (match_operand:HI 2 "general_operand" "ri,rm"))
6971 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6972 (minus:HI (match_dup 1) (match_dup 2)))]
6973 "ix86_match_ccmode (insn, CCGOCmode)
6974 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6975 "sub{w}\t{%2, %0|%0, %2}"
6976 [(set_attr "type" "alu")
6977 (set_attr "mode" "HI")])
6979 (define_insn "*subhi_3"
6980 [(set (reg FLAGS_REG)
6981 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6982 (match_operand:HI 2 "general_operand" "ri,rm")))
6983 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6984 (minus:HI (match_dup 1) (match_dup 2)))]
6985 "ix86_match_ccmode (insn, CCmode)
6986 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6987 "sub{w}\t{%2, %0|%0, %2}"
6988 [(set_attr "type" "alu")
6989 (set_attr "mode" "HI")])
6991 (define_expand "subqi3"
6992 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6993 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6994 (match_operand:QI 2 "general_operand" "")))
6995 (clobber (reg:CC FLAGS_REG))])]
6996 "TARGET_QIMODE_MATH"
6997 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6999 (define_insn "*subqi_1"
7000 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7001 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7002 (match_operand:QI 2 "general_operand" "qn,qmn")))
7003 (clobber (reg:CC FLAGS_REG))]
7004 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7005 "sub{b}\t{%2, %0|%0, %2}"
7006 [(set_attr "type" "alu")
7007 (set_attr "mode" "QI")])
7009 (define_insn "*subqi_1_slp"
7010 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7011 (minus:QI (match_dup 0)
7012 (match_operand:QI 1 "general_operand" "qn,qmn")))
7013 (clobber (reg:CC FLAGS_REG))]
7014 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7015 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7016 "sub{b}\t{%1, %0|%0, %1}"
7017 [(set_attr "type" "alu1")
7018 (set_attr "mode" "QI")])
7020 (define_insn "*subqi_2"
7021 [(set (reg FLAGS_REG)
7023 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7024 (match_operand:QI 2 "general_operand" "qi,qm"))
7026 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7027 (minus:HI (match_dup 1) (match_dup 2)))]
7028 "ix86_match_ccmode (insn, CCGOCmode)
7029 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7030 "sub{b}\t{%2, %0|%0, %2}"
7031 [(set_attr "type" "alu")
7032 (set_attr "mode" "QI")])
7034 (define_insn "*subqi_3"
7035 [(set (reg FLAGS_REG)
7036 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7037 (match_operand:QI 2 "general_operand" "qi,qm")))
7038 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7039 (minus:HI (match_dup 1) (match_dup 2)))]
7040 "ix86_match_ccmode (insn, CCmode)
7041 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7042 "sub{b}\t{%2, %0|%0, %2}"
7043 [(set_attr "type" "alu")
7044 (set_attr "mode" "QI")])
7046 ;; The patterns that match these are at the end of this file.
7048 (define_expand "subxf3"
7049 [(set (match_operand:XF 0 "register_operand" "")
7050 (minus:XF (match_operand:XF 1 "register_operand" "")
7051 (match_operand:XF 2 "register_operand" "")))]
7055 (define_expand "subdf3"
7056 [(set (match_operand:DF 0 "register_operand" "")
7057 (minus:DF (match_operand:DF 1 "register_operand" "")
7058 (match_operand:DF 2 "nonimmediate_operand" "")))]
7059 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7062 (define_expand "subsf3"
7063 [(set (match_operand:SF 0 "register_operand" "")
7064 (minus:SF (match_operand:SF 1 "register_operand" "")
7065 (match_operand:SF 2 "nonimmediate_operand" "")))]
7066 "TARGET_80387 || TARGET_SSE_MATH"
7069 ;; Multiply instructions
7071 (define_expand "muldi3"
7072 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7073 (mult:DI (match_operand:DI 1 "register_operand" "")
7074 (match_operand:DI 2 "x86_64_general_operand" "")))
7075 (clobber (reg:CC FLAGS_REG))])]
7080 ;; IMUL reg64, reg64, imm8 Direct
7081 ;; IMUL reg64, mem64, imm8 VectorPath
7082 ;; IMUL reg64, reg64, imm32 Direct
7083 ;; IMUL reg64, mem64, imm32 VectorPath
7084 ;; IMUL reg64, reg64 Direct
7085 ;; IMUL reg64, mem64 Direct
7087 (define_insn "*muldi3_1_rex64"
7088 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7089 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7090 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7091 (clobber (reg:CC FLAGS_REG))]
7093 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7095 imul{q}\t{%2, %1, %0|%0, %1, %2}
7096 imul{q}\t{%2, %1, %0|%0, %1, %2}
7097 imul{q}\t{%2, %0|%0, %2}"
7098 [(set_attr "type" "imul")
7099 (set_attr "prefix_0f" "0,0,1")
7100 (set (attr "athlon_decode")
7101 (cond [(eq_attr "cpu" "athlon")
7102 (const_string "vector")
7103 (eq_attr "alternative" "1")
7104 (const_string "vector")
7105 (and (eq_attr "alternative" "2")
7106 (match_operand 1 "memory_operand" ""))
7107 (const_string "vector")]
7108 (const_string "direct")))
7109 (set (attr "amdfam10_decode")
7110 (cond [(and (eq_attr "alternative" "0,1")
7111 (match_operand 1 "memory_operand" ""))
7112 (const_string "vector")]
7113 (const_string "direct")))
7114 (set_attr "mode" "DI")])
7116 (define_expand "mulsi3"
7117 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7118 (mult:SI (match_operand:SI 1 "register_operand" "")
7119 (match_operand:SI 2 "general_operand" "")))
7120 (clobber (reg:CC FLAGS_REG))])]
7125 ;; IMUL reg32, reg32, imm8 Direct
7126 ;; IMUL reg32, mem32, imm8 VectorPath
7127 ;; IMUL reg32, reg32, imm32 Direct
7128 ;; IMUL reg32, mem32, imm32 VectorPath
7129 ;; IMUL reg32, reg32 Direct
7130 ;; IMUL reg32, mem32 Direct
7132 (define_insn "*mulsi3_1"
7133 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7134 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7135 (match_operand:SI 2 "general_operand" "K,i,mr")))
7136 (clobber (reg:CC FLAGS_REG))]
7137 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7139 imul{l}\t{%2, %1, %0|%0, %1, %2}
7140 imul{l}\t{%2, %1, %0|%0, %1, %2}
7141 imul{l}\t{%2, %0|%0, %2}"
7142 [(set_attr "type" "imul")
7143 (set_attr "prefix_0f" "0,0,1")
7144 (set (attr "athlon_decode")
7145 (cond [(eq_attr "cpu" "athlon")
7146 (const_string "vector")
7147 (eq_attr "alternative" "1")
7148 (const_string "vector")
7149 (and (eq_attr "alternative" "2")
7150 (match_operand 1 "memory_operand" ""))
7151 (const_string "vector")]
7152 (const_string "direct")))
7153 (set (attr "amdfam10_decode")
7154 (cond [(and (eq_attr "alternative" "0,1")
7155 (match_operand 1 "memory_operand" ""))
7156 (const_string "vector")]
7157 (const_string "direct")))
7158 (set_attr "mode" "SI")])
7160 (define_insn "*mulsi3_1_zext"
7161 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7163 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7164 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7165 (clobber (reg:CC FLAGS_REG))]
7167 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7169 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7170 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7171 imul{l}\t{%2, %k0|%k0, %2}"
7172 [(set_attr "type" "imul")
7173 (set_attr "prefix_0f" "0,0,1")
7174 (set (attr "athlon_decode")
7175 (cond [(eq_attr "cpu" "athlon")
7176 (const_string "vector")
7177 (eq_attr "alternative" "1")
7178 (const_string "vector")
7179 (and (eq_attr "alternative" "2")
7180 (match_operand 1 "memory_operand" ""))
7181 (const_string "vector")]
7182 (const_string "direct")))
7183 (set (attr "amdfam10_decode")
7184 (cond [(and (eq_attr "alternative" "0,1")
7185 (match_operand 1 "memory_operand" ""))
7186 (const_string "vector")]
7187 (const_string "direct")))
7188 (set_attr "mode" "SI")])
7190 (define_expand "mulhi3"
7191 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7192 (mult:HI (match_operand:HI 1 "register_operand" "")
7193 (match_operand:HI 2 "general_operand" "")))
7194 (clobber (reg:CC FLAGS_REG))])]
7195 "TARGET_HIMODE_MATH"
7199 ;; IMUL reg16, reg16, imm8 VectorPath
7200 ;; IMUL reg16, mem16, imm8 VectorPath
7201 ;; IMUL reg16, reg16, imm16 VectorPath
7202 ;; IMUL reg16, mem16, imm16 VectorPath
7203 ;; IMUL reg16, reg16 Direct
7204 ;; IMUL reg16, mem16 Direct
7205 (define_insn "*mulhi3_1"
7206 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7207 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7208 (match_operand:HI 2 "general_operand" "K,i,mr")))
7209 (clobber (reg:CC FLAGS_REG))]
7210 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7212 imul{w}\t{%2, %1, %0|%0, %1, %2}
7213 imul{w}\t{%2, %1, %0|%0, %1, %2}
7214 imul{w}\t{%2, %0|%0, %2}"
7215 [(set_attr "type" "imul")
7216 (set_attr "prefix_0f" "0,0,1")
7217 (set (attr "athlon_decode")
7218 (cond [(eq_attr "cpu" "athlon")
7219 (const_string "vector")
7220 (eq_attr "alternative" "1,2")
7221 (const_string "vector")]
7222 (const_string "direct")))
7223 (set (attr "amdfam10_decode")
7224 (cond [(eq_attr "alternative" "0,1")
7225 (const_string "vector")]
7226 (const_string "direct")))
7227 (set_attr "mode" "HI")])
7229 (define_expand "mulqi3"
7230 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7231 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7232 (match_operand:QI 2 "register_operand" "")))
7233 (clobber (reg:CC FLAGS_REG))])]
7234 "TARGET_QIMODE_MATH"
7241 (define_insn "*mulqi3_1"
7242 [(set (match_operand:QI 0 "register_operand" "=a")
7243 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7244 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7245 (clobber (reg:CC FLAGS_REG))]
7247 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7249 [(set_attr "type" "imul")
7250 (set_attr "length_immediate" "0")
7251 (set (attr "athlon_decode")
7252 (if_then_else (eq_attr "cpu" "athlon")
7253 (const_string "vector")
7254 (const_string "direct")))
7255 (set_attr "amdfam10_decode" "direct")
7256 (set_attr "mode" "QI")])
7258 (define_expand "umulqihi3"
7259 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7260 (mult:HI (zero_extend:HI
7261 (match_operand:QI 1 "nonimmediate_operand" ""))
7263 (match_operand:QI 2 "register_operand" ""))))
7264 (clobber (reg:CC FLAGS_REG))])]
7265 "TARGET_QIMODE_MATH"
7268 (define_insn "*umulqihi3_1"
7269 [(set (match_operand:HI 0 "register_operand" "=a")
7270 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7271 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7272 (clobber (reg:CC FLAGS_REG))]
7274 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7276 [(set_attr "type" "imul")
7277 (set_attr "length_immediate" "0")
7278 (set (attr "athlon_decode")
7279 (if_then_else (eq_attr "cpu" "athlon")
7280 (const_string "vector")
7281 (const_string "direct")))
7282 (set_attr "amdfam10_decode" "direct")
7283 (set_attr "mode" "QI")])
7285 (define_expand "mulqihi3"
7286 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7287 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7288 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7289 (clobber (reg:CC FLAGS_REG))])]
7290 "TARGET_QIMODE_MATH"
7293 (define_insn "*mulqihi3_insn"
7294 [(set (match_operand:HI 0 "register_operand" "=a")
7295 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7296 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7297 (clobber (reg:CC FLAGS_REG))]
7299 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7301 [(set_attr "type" "imul")
7302 (set_attr "length_immediate" "0")
7303 (set (attr "athlon_decode")
7304 (if_then_else (eq_attr "cpu" "athlon")
7305 (const_string "vector")
7306 (const_string "direct")))
7307 (set_attr "amdfam10_decode" "direct")
7308 (set_attr "mode" "QI")])
7310 (define_expand "umulditi3"
7311 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7312 (mult:TI (zero_extend:TI
7313 (match_operand:DI 1 "nonimmediate_operand" ""))
7315 (match_operand:DI 2 "register_operand" ""))))
7316 (clobber (reg:CC FLAGS_REG))])]
7320 (define_insn "*umulditi3_insn"
7321 [(set (match_operand:TI 0 "register_operand" "=A")
7322 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7323 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7324 (clobber (reg:CC FLAGS_REG))]
7326 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7328 [(set_attr "type" "imul")
7329 (set_attr "length_immediate" "0")
7330 (set (attr "athlon_decode")
7331 (if_then_else (eq_attr "cpu" "athlon")
7332 (const_string "vector")
7333 (const_string "double")))
7334 (set_attr "amdfam10_decode" "double")
7335 (set_attr "mode" "DI")])
7337 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7338 (define_expand "umulsidi3"
7339 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7340 (mult:DI (zero_extend:DI
7341 (match_operand:SI 1 "nonimmediate_operand" ""))
7343 (match_operand:SI 2 "register_operand" ""))))
7344 (clobber (reg:CC FLAGS_REG))])]
7348 (define_insn "*umulsidi3_insn"
7349 [(set (match_operand:DI 0 "register_operand" "=A")
7350 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7351 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7352 (clobber (reg:CC FLAGS_REG))]
7354 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7356 [(set_attr "type" "imul")
7357 (set_attr "length_immediate" "0")
7358 (set (attr "athlon_decode")
7359 (if_then_else (eq_attr "cpu" "athlon")
7360 (const_string "vector")
7361 (const_string "double")))
7362 (set_attr "amdfam10_decode" "double")
7363 (set_attr "mode" "SI")])
7365 (define_expand "mulditi3"
7366 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7367 (mult:TI (sign_extend:TI
7368 (match_operand:DI 1 "nonimmediate_operand" ""))
7370 (match_operand:DI 2 "register_operand" ""))))
7371 (clobber (reg:CC FLAGS_REG))])]
7375 (define_insn "*mulditi3_insn"
7376 [(set (match_operand:TI 0 "register_operand" "=A")
7377 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7378 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7379 (clobber (reg:CC FLAGS_REG))]
7381 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7383 [(set_attr "type" "imul")
7384 (set_attr "length_immediate" "0")
7385 (set (attr "athlon_decode")
7386 (if_then_else (eq_attr "cpu" "athlon")
7387 (const_string "vector")
7388 (const_string "double")))
7389 (set_attr "amdfam10_decode" "double")
7390 (set_attr "mode" "DI")])
7392 (define_expand "mulsidi3"
7393 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7394 (mult:DI (sign_extend:DI
7395 (match_operand:SI 1 "nonimmediate_operand" ""))
7397 (match_operand:SI 2 "register_operand" ""))))
7398 (clobber (reg:CC FLAGS_REG))])]
7402 (define_insn "*mulsidi3_insn"
7403 [(set (match_operand:DI 0 "register_operand" "=A")
7404 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7405 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7406 (clobber (reg:CC FLAGS_REG))]
7408 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7410 [(set_attr "type" "imul")
7411 (set_attr "length_immediate" "0")
7412 (set (attr "athlon_decode")
7413 (if_then_else (eq_attr "cpu" "athlon")
7414 (const_string "vector")
7415 (const_string "double")))
7416 (set_attr "amdfam10_decode" "double")
7417 (set_attr "mode" "SI")])
7419 (define_expand "umuldi3_highpart"
7420 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7423 (mult:TI (zero_extend:TI
7424 (match_operand:DI 1 "nonimmediate_operand" ""))
7426 (match_operand:DI 2 "register_operand" "")))
7428 (clobber (match_scratch:DI 3 ""))
7429 (clobber (reg:CC FLAGS_REG))])]
7433 (define_insn "*umuldi3_highpart_rex64"
7434 [(set (match_operand:DI 0 "register_operand" "=d")
7437 (mult:TI (zero_extend:TI
7438 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7440 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7442 (clobber (match_scratch:DI 3 "=1"))
7443 (clobber (reg:CC FLAGS_REG))]
7445 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7447 [(set_attr "type" "imul")
7448 (set_attr "length_immediate" "0")
7449 (set (attr "athlon_decode")
7450 (if_then_else (eq_attr "cpu" "athlon")
7451 (const_string "vector")
7452 (const_string "double")))
7453 (set_attr "amdfam10_decode" "double")
7454 (set_attr "mode" "DI")])
7456 (define_expand "umulsi3_highpart"
7457 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7460 (mult:DI (zero_extend:DI
7461 (match_operand:SI 1 "nonimmediate_operand" ""))
7463 (match_operand:SI 2 "register_operand" "")))
7465 (clobber (match_scratch:SI 3 ""))
7466 (clobber (reg:CC FLAGS_REG))])]
7470 (define_insn "*umulsi3_highpart_insn"
7471 [(set (match_operand:SI 0 "register_operand" "=d")
7474 (mult:DI (zero_extend:DI
7475 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7477 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7479 (clobber (match_scratch:SI 3 "=1"))
7480 (clobber (reg:CC FLAGS_REG))]
7481 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7483 [(set_attr "type" "imul")
7484 (set_attr "length_immediate" "0")
7485 (set (attr "athlon_decode")
7486 (if_then_else (eq_attr "cpu" "athlon")
7487 (const_string "vector")
7488 (const_string "double")))
7489 (set_attr "amdfam10_decode" "double")
7490 (set_attr "mode" "SI")])
7492 (define_insn "*umulsi3_highpart_zext"
7493 [(set (match_operand:DI 0 "register_operand" "=d")
7494 (zero_extend:DI (truncate:SI
7496 (mult:DI (zero_extend:DI
7497 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7499 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7501 (clobber (match_scratch:SI 3 "=1"))
7502 (clobber (reg:CC FLAGS_REG))]
7504 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7506 [(set_attr "type" "imul")
7507 (set_attr "length_immediate" "0")
7508 (set (attr "athlon_decode")
7509 (if_then_else (eq_attr "cpu" "athlon")
7510 (const_string "vector")
7511 (const_string "double")))
7512 (set_attr "amdfam10_decode" "double")
7513 (set_attr "mode" "SI")])
7515 (define_expand "smuldi3_highpart"
7516 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7519 (mult:TI (sign_extend:TI
7520 (match_operand:DI 1 "nonimmediate_operand" ""))
7522 (match_operand:DI 2 "register_operand" "")))
7524 (clobber (match_scratch:DI 3 ""))
7525 (clobber (reg:CC FLAGS_REG))])]
7529 (define_insn "*smuldi3_highpart_rex64"
7530 [(set (match_operand:DI 0 "register_operand" "=d")
7533 (mult:TI (sign_extend:TI
7534 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7536 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7538 (clobber (match_scratch:DI 3 "=1"))
7539 (clobber (reg:CC FLAGS_REG))]
7541 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7543 [(set_attr "type" "imul")
7544 (set (attr "athlon_decode")
7545 (if_then_else (eq_attr "cpu" "athlon")
7546 (const_string "vector")
7547 (const_string "double")))
7548 (set_attr "amdfam10_decode" "double")
7549 (set_attr "mode" "DI")])
7551 (define_expand "smulsi3_highpart"
7552 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7555 (mult:DI (sign_extend:DI
7556 (match_operand:SI 1 "nonimmediate_operand" ""))
7558 (match_operand:SI 2 "register_operand" "")))
7560 (clobber (match_scratch:SI 3 ""))
7561 (clobber (reg:CC FLAGS_REG))])]
7565 (define_insn "*smulsi3_highpart_insn"
7566 [(set (match_operand:SI 0 "register_operand" "=d")
7569 (mult:DI (sign_extend:DI
7570 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7572 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7574 (clobber (match_scratch:SI 3 "=1"))
7575 (clobber (reg:CC FLAGS_REG))]
7576 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7578 [(set_attr "type" "imul")
7579 (set (attr "athlon_decode")
7580 (if_then_else (eq_attr "cpu" "athlon")
7581 (const_string "vector")
7582 (const_string "double")))
7583 (set_attr "amdfam10_decode" "double")
7584 (set_attr "mode" "SI")])
7586 (define_insn "*smulsi3_highpart_zext"
7587 [(set (match_operand:DI 0 "register_operand" "=d")
7588 (zero_extend:DI (truncate:SI
7590 (mult:DI (sign_extend:DI
7591 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7593 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7595 (clobber (match_scratch:SI 3 "=1"))
7596 (clobber (reg:CC FLAGS_REG))]
7598 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7600 [(set_attr "type" "imul")
7601 (set (attr "athlon_decode")
7602 (if_then_else (eq_attr "cpu" "athlon")
7603 (const_string "vector")
7604 (const_string "double")))
7605 (set_attr "amdfam10_decode" "double")
7606 (set_attr "mode" "SI")])
7608 ;; The patterns that match these are at the end of this file.
7610 (define_expand "mulxf3"
7611 [(set (match_operand:XF 0 "register_operand" "")
7612 (mult:XF (match_operand:XF 1 "register_operand" "")
7613 (match_operand:XF 2 "register_operand" "")))]
7617 (define_expand "muldf3"
7618 [(set (match_operand:DF 0 "register_operand" "")
7619 (mult:DF (match_operand:DF 1 "register_operand" "")
7620 (match_operand:DF 2 "nonimmediate_operand" "")))]
7621 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7624 (define_expand "mulsf3"
7625 [(set (match_operand:SF 0 "register_operand" "")
7626 (mult:SF (match_operand:SF 1 "register_operand" "")
7627 (match_operand:SF 2 "nonimmediate_operand" "")))]
7628 "TARGET_80387 || TARGET_SSE_MATH"
7631 ;; Divide instructions
7633 (define_insn "divqi3"
7634 [(set (match_operand:QI 0 "register_operand" "=a")
7635 (div:QI (match_operand:HI 1 "register_operand" "0")
7636 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7637 (clobber (reg:CC FLAGS_REG))]
7638 "TARGET_QIMODE_MATH"
7640 [(set_attr "type" "idiv")
7641 (set_attr "mode" "QI")])
7643 (define_insn "udivqi3"
7644 [(set (match_operand:QI 0 "register_operand" "=a")
7645 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7646 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7647 (clobber (reg:CC FLAGS_REG))]
7648 "TARGET_QIMODE_MATH"
7650 [(set_attr "type" "idiv")
7651 (set_attr "mode" "QI")])
7653 ;; The patterns that match these are at the end of this file.
7655 (define_expand "divxf3"
7656 [(set (match_operand:XF 0 "register_operand" "")
7657 (div:XF (match_operand:XF 1 "register_operand" "")
7658 (match_operand:XF 2 "register_operand" "")))]
7662 (define_expand "divdf3"
7663 [(set (match_operand:DF 0 "register_operand" "")
7664 (div:DF (match_operand:DF 1 "register_operand" "")
7665 (match_operand:DF 2 "nonimmediate_operand" "")))]
7666 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7669 (define_expand "divsf3"
7670 [(set (match_operand:SF 0 "register_operand" "")
7671 (div:SF (match_operand:SF 1 "register_operand" "")
7672 (match_operand:SF 2 "nonimmediate_operand" "")))]
7673 "TARGET_80387 || TARGET_SSE_MATH"
7675 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
7676 && flag_finite_math_only && !flag_trapping_math
7677 && flag_unsafe_math_optimizations)
7679 ix86_emit_swdivsf (operands[0], operands[1],
7680 operands[2], SFmode);
7685 ;; Remainder instructions.
7687 (define_expand "divmoddi4"
7688 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7689 (div:DI (match_operand:DI 1 "register_operand" "")
7690 (match_operand:DI 2 "nonimmediate_operand" "")))
7691 (set (match_operand:DI 3 "register_operand" "")
7692 (mod:DI (match_dup 1) (match_dup 2)))
7693 (clobber (reg:CC FLAGS_REG))])]
7697 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7698 ;; Penalize eax case slightly because it results in worse scheduling
7700 (define_insn "*divmoddi4_nocltd_rex64"
7701 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7702 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7703 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7704 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7705 (mod:DI (match_dup 2) (match_dup 3)))
7706 (clobber (reg:CC FLAGS_REG))]
7707 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7709 [(set_attr "type" "multi")])
7711 (define_insn "*divmoddi4_cltd_rex64"
7712 [(set (match_operand:DI 0 "register_operand" "=a")
7713 (div:DI (match_operand:DI 2 "register_operand" "a")
7714 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7715 (set (match_operand:DI 1 "register_operand" "=&d")
7716 (mod:DI (match_dup 2) (match_dup 3)))
7717 (clobber (reg:CC FLAGS_REG))]
7718 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7720 [(set_attr "type" "multi")])
7722 (define_insn "*divmoddi_noext_rex64"
7723 [(set (match_operand:DI 0 "register_operand" "=a")
7724 (div:DI (match_operand:DI 1 "register_operand" "0")
7725 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7726 (set (match_operand:DI 3 "register_operand" "=d")
7727 (mod:DI (match_dup 1) (match_dup 2)))
7728 (use (match_operand:DI 4 "register_operand" "3"))
7729 (clobber (reg:CC FLAGS_REG))]
7732 [(set_attr "type" "idiv")
7733 (set_attr "mode" "DI")])
7736 [(set (match_operand:DI 0 "register_operand" "")
7737 (div:DI (match_operand:DI 1 "register_operand" "")
7738 (match_operand:DI 2 "nonimmediate_operand" "")))
7739 (set (match_operand:DI 3 "register_operand" "")
7740 (mod:DI (match_dup 1) (match_dup 2)))
7741 (clobber (reg:CC FLAGS_REG))]
7742 "TARGET_64BIT && reload_completed"
7743 [(parallel [(set (match_dup 3)
7744 (ashiftrt:DI (match_dup 4) (const_int 63)))
7745 (clobber (reg:CC FLAGS_REG))])
7746 (parallel [(set (match_dup 0)
7747 (div:DI (reg:DI 0) (match_dup 2)))
7749 (mod:DI (reg:DI 0) (match_dup 2)))
7751 (clobber (reg:CC FLAGS_REG))])]
7753 /* Avoid use of cltd in favor of a mov+shift. */
7754 if (!TARGET_USE_CLTD && !optimize_size)
7756 if (true_regnum (operands[1]))
7757 emit_move_insn (operands[0], operands[1]);
7759 emit_move_insn (operands[3], operands[1]);
7760 operands[4] = operands[3];
7764 gcc_assert (!true_regnum (operands[1]));
7765 operands[4] = operands[1];
7770 (define_expand "divmodsi4"
7771 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7772 (div:SI (match_operand:SI 1 "register_operand" "")
7773 (match_operand:SI 2 "nonimmediate_operand" "")))
7774 (set (match_operand:SI 3 "register_operand" "")
7775 (mod:SI (match_dup 1) (match_dup 2)))
7776 (clobber (reg:CC FLAGS_REG))])]
7780 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7781 ;; Penalize eax case slightly because it results in worse scheduling
7783 (define_insn "*divmodsi4_nocltd"
7784 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7785 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7786 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7787 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7788 (mod:SI (match_dup 2) (match_dup 3)))
7789 (clobber (reg:CC FLAGS_REG))]
7790 "!optimize_size && !TARGET_USE_CLTD"
7792 [(set_attr "type" "multi")])
7794 (define_insn "*divmodsi4_cltd"
7795 [(set (match_operand:SI 0 "register_operand" "=a")
7796 (div:SI (match_operand:SI 2 "register_operand" "a")
7797 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7798 (set (match_operand:SI 1 "register_operand" "=&d")
7799 (mod:SI (match_dup 2) (match_dup 3)))
7800 (clobber (reg:CC FLAGS_REG))]
7801 "optimize_size || TARGET_USE_CLTD"
7803 [(set_attr "type" "multi")])
7805 (define_insn "*divmodsi_noext"
7806 [(set (match_operand:SI 0 "register_operand" "=a")
7807 (div:SI (match_operand:SI 1 "register_operand" "0")
7808 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7809 (set (match_operand:SI 3 "register_operand" "=d")
7810 (mod:SI (match_dup 1) (match_dup 2)))
7811 (use (match_operand:SI 4 "register_operand" "3"))
7812 (clobber (reg:CC FLAGS_REG))]
7815 [(set_attr "type" "idiv")
7816 (set_attr "mode" "SI")])
7819 [(set (match_operand:SI 0 "register_operand" "")
7820 (div:SI (match_operand:SI 1 "register_operand" "")
7821 (match_operand:SI 2 "nonimmediate_operand" "")))
7822 (set (match_operand:SI 3 "register_operand" "")
7823 (mod:SI (match_dup 1) (match_dup 2)))
7824 (clobber (reg:CC FLAGS_REG))]
7826 [(parallel [(set (match_dup 3)
7827 (ashiftrt:SI (match_dup 4) (const_int 31)))
7828 (clobber (reg:CC FLAGS_REG))])
7829 (parallel [(set (match_dup 0)
7830 (div:SI (reg:SI 0) (match_dup 2)))
7832 (mod:SI (reg:SI 0) (match_dup 2)))
7834 (clobber (reg:CC FLAGS_REG))])]
7836 /* Avoid use of cltd in favor of a mov+shift. */
7837 if (!TARGET_USE_CLTD && !optimize_size)
7839 if (true_regnum (operands[1]))
7840 emit_move_insn (operands[0], operands[1]);
7842 emit_move_insn (operands[3], operands[1]);
7843 operands[4] = operands[3];
7847 gcc_assert (!true_regnum (operands[1]));
7848 operands[4] = operands[1];
7852 (define_insn "divmodhi4"
7853 [(set (match_operand:HI 0 "register_operand" "=a")
7854 (div:HI (match_operand:HI 1 "register_operand" "0")
7855 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7856 (set (match_operand:HI 3 "register_operand" "=&d")
7857 (mod:HI (match_dup 1) (match_dup 2)))
7858 (clobber (reg:CC FLAGS_REG))]
7859 "TARGET_HIMODE_MATH"
7861 [(set_attr "type" "multi")
7862 (set_attr "length_immediate" "0")
7863 (set_attr "mode" "SI")])
7865 (define_insn "udivmoddi4"
7866 [(set (match_operand:DI 0 "register_operand" "=a")
7867 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7868 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7869 (set (match_operand:DI 3 "register_operand" "=&d")
7870 (umod:DI (match_dup 1) (match_dup 2)))
7871 (clobber (reg:CC FLAGS_REG))]
7873 "xor{q}\t%3, %3\;div{q}\t%2"
7874 [(set_attr "type" "multi")
7875 (set_attr "length_immediate" "0")
7876 (set_attr "mode" "DI")])
7878 (define_insn "*udivmoddi4_noext"
7879 [(set (match_operand:DI 0 "register_operand" "=a")
7880 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7881 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7882 (set (match_operand:DI 3 "register_operand" "=d")
7883 (umod:DI (match_dup 1) (match_dup 2)))
7885 (clobber (reg:CC FLAGS_REG))]
7888 [(set_attr "type" "idiv")
7889 (set_attr "mode" "DI")])
7892 [(set (match_operand:DI 0 "register_operand" "")
7893 (udiv:DI (match_operand:DI 1 "register_operand" "")
7894 (match_operand:DI 2 "nonimmediate_operand" "")))
7895 (set (match_operand:DI 3 "register_operand" "")
7896 (umod:DI (match_dup 1) (match_dup 2)))
7897 (clobber (reg:CC FLAGS_REG))]
7898 "TARGET_64BIT && reload_completed"
7899 [(set (match_dup 3) (const_int 0))
7900 (parallel [(set (match_dup 0)
7901 (udiv:DI (match_dup 1) (match_dup 2)))
7903 (umod:DI (match_dup 1) (match_dup 2)))
7905 (clobber (reg:CC FLAGS_REG))])]
7908 (define_insn "udivmodsi4"
7909 [(set (match_operand:SI 0 "register_operand" "=a")
7910 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7911 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7912 (set (match_operand:SI 3 "register_operand" "=&d")
7913 (umod:SI (match_dup 1) (match_dup 2)))
7914 (clobber (reg:CC FLAGS_REG))]
7916 "xor{l}\t%3, %3\;div{l}\t%2"
7917 [(set_attr "type" "multi")
7918 (set_attr "length_immediate" "0")
7919 (set_attr "mode" "SI")])
7921 (define_insn "*udivmodsi4_noext"
7922 [(set (match_operand:SI 0 "register_operand" "=a")
7923 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7924 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7925 (set (match_operand:SI 3 "register_operand" "=d")
7926 (umod:SI (match_dup 1) (match_dup 2)))
7928 (clobber (reg:CC FLAGS_REG))]
7931 [(set_attr "type" "idiv")
7932 (set_attr "mode" "SI")])
7935 [(set (match_operand:SI 0 "register_operand" "")
7936 (udiv:SI (match_operand:SI 1 "register_operand" "")
7937 (match_operand:SI 2 "nonimmediate_operand" "")))
7938 (set (match_operand:SI 3 "register_operand" "")
7939 (umod:SI (match_dup 1) (match_dup 2)))
7940 (clobber (reg:CC FLAGS_REG))]
7942 [(set (match_dup 3) (const_int 0))
7943 (parallel [(set (match_dup 0)
7944 (udiv:SI (match_dup 1) (match_dup 2)))
7946 (umod:SI (match_dup 1) (match_dup 2)))
7948 (clobber (reg:CC FLAGS_REG))])]
7951 (define_expand "udivmodhi4"
7952 [(set (match_dup 4) (const_int 0))
7953 (parallel [(set (match_operand:HI 0 "register_operand" "")
7954 (udiv:HI (match_operand:HI 1 "register_operand" "")
7955 (match_operand:HI 2 "nonimmediate_operand" "")))
7956 (set (match_operand:HI 3 "register_operand" "")
7957 (umod:HI (match_dup 1) (match_dup 2)))
7959 (clobber (reg:CC FLAGS_REG))])]
7960 "TARGET_HIMODE_MATH"
7961 "operands[4] = gen_reg_rtx (HImode);")
7963 (define_insn "*udivmodhi_noext"
7964 [(set (match_operand:HI 0 "register_operand" "=a")
7965 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7966 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7967 (set (match_operand:HI 3 "register_operand" "=d")
7968 (umod:HI (match_dup 1) (match_dup 2)))
7969 (use (match_operand:HI 4 "register_operand" "3"))
7970 (clobber (reg:CC FLAGS_REG))]
7973 [(set_attr "type" "idiv")
7974 (set_attr "mode" "HI")])
7976 ;; We cannot use div/idiv for double division, because it causes
7977 ;; "division by zero" on the overflow and that's not what we expect
7978 ;; from truncate. Because true (non truncating) double division is
7979 ;; never generated, we can't create this insn anyway.
7982 ; [(set (match_operand:SI 0 "register_operand" "=a")
7984 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7986 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7987 ; (set (match_operand:SI 3 "register_operand" "=d")
7989 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7990 ; (clobber (reg:CC FLAGS_REG))]
7992 ; "div{l}\t{%2, %0|%0, %2}"
7993 ; [(set_attr "type" "idiv")])
7995 ;;- Logical AND instructions
7997 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7998 ;; Note that this excludes ah.
8000 (define_insn "*testdi_1_rex64"
8001 [(set (reg FLAGS_REG)
8003 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8004 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8006 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8007 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8009 test{l}\t{%k1, %k0|%k0, %k1}
8010 test{l}\t{%k1, %k0|%k0, %k1}
8011 test{q}\t{%1, %0|%0, %1}
8012 test{q}\t{%1, %0|%0, %1}
8013 test{q}\t{%1, %0|%0, %1}"
8014 [(set_attr "type" "test")
8015 (set_attr "modrm" "0,1,0,1,1")
8016 (set_attr "mode" "SI,SI,DI,DI,DI")
8017 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8019 (define_insn "testsi_1"
8020 [(set (reg FLAGS_REG)
8022 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8023 (match_operand:SI 1 "general_operand" "in,in,rin"))
8025 "ix86_match_ccmode (insn, CCNOmode)
8026 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8027 "test{l}\t{%1, %0|%0, %1}"
8028 [(set_attr "type" "test")
8029 (set_attr "modrm" "0,1,1")
8030 (set_attr "mode" "SI")
8031 (set_attr "pent_pair" "uv,np,uv")])
8033 (define_expand "testsi_ccno_1"
8034 [(set (reg:CCNO FLAGS_REG)
8036 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8037 (match_operand:SI 1 "nonmemory_operand" ""))
8042 (define_insn "*testhi_1"
8043 [(set (reg FLAGS_REG)
8044 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8045 (match_operand:HI 1 "general_operand" "n,n,rn"))
8047 "ix86_match_ccmode (insn, CCNOmode)
8048 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8049 "test{w}\t{%1, %0|%0, %1}"
8050 [(set_attr "type" "test")
8051 (set_attr "modrm" "0,1,1")
8052 (set_attr "mode" "HI")
8053 (set_attr "pent_pair" "uv,np,uv")])
8055 (define_expand "testqi_ccz_1"
8056 [(set (reg:CCZ FLAGS_REG)
8057 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8058 (match_operand:QI 1 "nonmemory_operand" ""))
8063 (define_insn "*testqi_1_maybe_si"
8064 [(set (reg FLAGS_REG)
8067 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8068 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8070 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8071 && ix86_match_ccmode (insn,
8072 CONST_INT_P (operands[1])
8073 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8075 if (which_alternative == 3)
8077 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8078 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8079 return "test{l}\t{%1, %k0|%k0, %1}";
8081 return "test{b}\t{%1, %0|%0, %1}";
8083 [(set_attr "type" "test")
8084 (set_attr "modrm" "0,1,1,1")
8085 (set_attr "mode" "QI,QI,QI,SI")
8086 (set_attr "pent_pair" "uv,np,uv,np")])
8088 (define_insn "*testqi_1"
8089 [(set (reg FLAGS_REG)
8092 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8093 (match_operand:QI 1 "general_operand" "n,n,qn"))
8095 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8096 && ix86_match_ccmode (insn, CCNOmode)"
8097 "test{b}\t{%1, %0|%0, %1}"
8098 [(set_attr "type" "test")
8099 (set_attr "modrm" "0,1,1")
8100 (set_attr "mode" "QI")
8101 (set_attr "pent_pair" "uv,np,uv")])
8103 (define_expand "testqi_ext_ccno_0"
8104 [(set (reg:CCNO FLAGS_REG)
8108 (match_operand 0 "ext_register_operand" "")
8111 (match_operand 1 "const_int_operand" ""))
8116 (define_insn "*testqi_ext_0"
8117 [(set (reg FLAGS_REG)
8121 (match_operand 0 "ext_register_operand" "Q")
8124 (match_operand 1 "const_int_operand" "n"))
8126 "ix86_match_ccmode (insn, CCNOmode)"
8127 "test{b}\t{%1, %h0|%h0, %1}"
8128 [(set_attr "type" "test")
8129 (set_attr "mode" "QI")
8130 (set_attr "length_immediate" "1")
8131 (set_attr "pent_pair" "np")])
8133 (define_insn "*testqi_ext_1"
8134 [(set (reg FLAGS_REG)
8138 (match_operand 0 "ext_register_operand" "Q")
8142 (match_operand:QI 1 "general_operand" "Qm")))
8144 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8145 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8146 "test{b}\t{%1, %h0|%h0, %1}"
8147 [(set_attr "type" "test")
8148 (set_attr "mode" "QI")])
8150 (define_insn "*testqi_ext_1_rex64"
8151 [(set (reg FLAGS_REG)
8155 (match_operand 0 "ext_register_operand" "Q")
8159 (match_operand:QI 1 "register_operand" "Q")))
8161 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8162 "test{b}\t{%1, %h0|%h0, %1}"
8163 [(set_attr "type" "test")
8164 (set_attr "mode" "QI")])
8166 (define_insn "*testqi_ext_2"
8167 [(set (reg FLAGS_REG)
8171 (match_operand 0 "ext_register_operand" "Q")
8175 (match_operand 1 "ext_register_operand" "Q")
8179 "ix86_match_ccmode (insn, CCNOmode)"
8180 "test{b}\t{%h1, %h0|%h0, %h1}"
8181 [(set_attr "type" "test")
8182 (set_attr "mode" "QI")])
8184 ;; Combine likes to form bit extractions for some tests. Humor it.
8185 (define_insn "*testqi_ext_3"
8186 [(set (reg FLAGS_REG)
8187 (compare (zero_extract:SI
8188 (match_operand 0 "nonimmediate_operand" "rm")
8189 (match_operand:SI 1 "const_int_operand" "")
8190 (match_operand:SI 2 "const_int_operand" ""))
8192 "ix86_match_ccmode (insn, CCNOmode)
8193 && INTVAL (operands[1]) > 0
8194 && INTVAL (operands[2]) >= 0
8195 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8196 && (GET_MODE (operands[0]) == SImode
8197 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8198 || GET_MODE (operands[0]) == HImode
8199 || GET_MODE (operands[0]) == QImode)"
8202 (define_insn "*testqi_ext_3_rex64"
8203 [(set (reg FLAGS_REG)
8204 (compare (zero_extract:DI
8205 (match_operand 0 "nonimmediate_operand" "rm")
8206 (match_operand:DI 1 "const_int_operand" "")
8207 (match_operand:DI 2 "const_int_operand" ""))
8210 && ix86_match_ccmode (insn, CCNOmode)
8211 && INTVAL (operands[1]) > 0
8212 && INTVAL (operands[2]) >= 0
8213 /* Ensure that resulting mask is zero or sign extended operand. */
8214 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8215 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8216 && INTVAL (operands[1]) > 32))
8217 && (GET_MODE (operands[0]) == SImode
8218 || GET_MODE (operands[0]) == DImode
8219 || GET_MODE (operands[0]) == HImode
8220 || GET_MODE (operands[0]) == QImode)"
8224 [(set (match_operand 0 "flags_reg_operand" "")
8225 (match_operator 1 "compare_operator"
8227 (match_operand 2 "nonimmediate_operand" "")
8228 (match_operand 3 "const_int_operand" "")
8229 (match_operand 4 "const_int_operand" ""))
8231 "ix86_match_ccmode (insn, CCNOmode)"
8232 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8234 rtx val = operands[2];
8235 HOST_WIDE_INT len = INTVAL (operands[3]);
8236 HOST_WIDE_INT pos = INTVAL (operands[4]);
8238 enum machine_mode mode, submode;
8240 mode = GET_MODE (val);
8243 /* ??? Combine likes to put non-volatile mem extractions in QImode
8244 no matter the size of the test. So find a mode that works. */
8245 if (! MEM_VOLATILE_P (val))
8247 mode = smallest_mode_for_size (pos + len, MODE_INT);
8248 val = adjust_address (val, mode, 0);
8251 else if (GET_CODE (val) == SUBREG
8252 && (submode = GET_MODE (SUBREG_REG (val)),
8253 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8254 && pos + len <= GET_MODE_BITSIZE (submode))
8256 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8258 val = SUBREG_REG (val);
8260 else if (mode == HImode && pos + len <= 8)
8262 /* Small HImode tests can be converted to QImode. */
8264 val = gen_lowpart (QImode, val);
8267 if (len == HOST_BITS_PER_WIDE_INT)
8270 mask = ((HOST_WIDE_INT)1 << len) - 1;
8273 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8276 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8277 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8278 ;; this is relatively important trick.
8279 ;; Do the conversion only post-reload to avoid limiting of the register class
8282 [(set (match_operand 0 "flags_reg_operand" "")
8283 (match_operator 1 "compare_operator"
8284 [(and (match_operand 2 "register_operand" "")
8285 (match_operand 3 "const_int_operand" ""))
8288 && QI_REG_P (operands[2])
8289 && GET_MODE (operands[2]) != QImode
8290 && ((ix86_match_ccmode (insn, CCZmode)
8291 && !(INTVAL (operands[3]) & ~(255 << 8)))
8292 || (ix86_match_ccmode (insn, CCNOmode)
8293 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8296 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8299 "operands[2] = gen_lowpart (SImode, operands[2]);
8300 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8303 [(set (match_operand 0 "flags_reg_operand" "")
8304 (match_operator 1 "compare_operator"
8305 [(and (match_operand 2 "nonimmediate_operand" "")
8306 (match_operand 3 "const_int_operand" ""))
8309 && GET_MODE (operands[2]) != QImode
8310 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8311 && ((ix86_match_ccmode (insn, CCZmode)
8312 && !(INTVAL (operands[3]) & ~255))
8313 || (ix86_match_ccmode (insn, CCNOmode)
8314 && !(INTVAL (operands[3]) & ~127)))"
8316 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8318 "operands[2] = gen_lowpart (QImode, operands[2]);
8319 operands[3] = gen_lowpart (QImode, operands[3]);")
8322 ;; %%% This used to optimize known byte-wide and operations to memory,
8323 ;; and sometimes to QImode registers. If this is considered useful,
8324 ;; it should be done with splitters.
8326 (define_expand "anddi3"
8327 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8328 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8329 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8330 (clobber (reg:CC FLAGS_REG))]
8332 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8334 (define_insn "*anddi_1_rex64"
8335 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8336 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8337 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8338 (clobber (reg:CC FLAGS_REG))]
8339 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8341 switch (get_attr_type (insn))
8345 enum machine_mode mode;
8347 gcc_assert (CONST_INT_P (operands[2]));
8348 if (INTVAL (operands[2]) == 0xff)
8352 gcc_assert (INTVAL (operands[2]) == 0xffff);
8356 operands[1] = gen_lowpart (mode, operands[1]);
8358 return "movz{bq|x}\t{%1,%0|%0, %1}";
8360 return "movz{wq|x}\t{%1,%0|%0, %1}";
8364 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8365 if (get_attr_mode (insn) == MODE_SI)
8366 return "and{l}\t{%k2, %k0|%k0, %k2}";
8368 return "and{q}\t{%2, %0|%0, %2}";
8371 [(set_attr "type" "alu,alu,alu,imovx")
8372 (set_attr "length_immediate" "*,*,*,0")
8373 (set_attr "mode" "SI,DI,DI,DI")])
8375 (define_insn "*anddi_2"
8376 [(set (reg FLAGS_REG)
8377 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8378 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8380 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8381 (and:DI (match_dup 1) (match_dup 2)))]
8382 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8383 && ix86_binary_operator_ok (AND, DImode, operands)"
8385 and{l}\t{%k2, %k0|%k0, %k2}
8386 and{q}\t{%2, %0|%0, %2}
8387 and{q}\t{%2, %0|%0, %2}"
8388 [(set_attr "type" "alu")
8389 (set_attr "mode" "SI,DI,DI")])
8391 (define_expand "andsi3"
8392 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8393 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8394 (match_operand:SI 2 "general_operand" "")))
8395 (clobber (reg:CC FLAGS_REG))]
8397 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8399 (define_insn "*andsi_1"
8400 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8401 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8402 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8403 (clobber (reg:CC FLAGS_REG))]
8404 "ix86_binary_operator_ok (AND, SImode, operands)"
8406 switch (get_attr_type (insn))
8410 enum machine_mode mode;
8412 gcc_assert (CONST_INT_P (operands[2]));
8413 if (INTVAL (operands[2]) == 0xff)
8417 gcc_assert (INTVAL (operands[2]) == 0xffff);
8421 operands[1] = gen_lowpart (mode, operands[1]);
8423 return "movz{bl|x}\t{%1,%0|%0, %1}";
8425 return "movz{wl|x}\t{%1,%0|%0, %1}";
8429 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8430 return "and{l}\t{%2, %0|%0, %2}";
8433 [(set_attr "type" "alu,alu,imovx")
8434 (set_attr "length_immediate" "*,*,0")
8435 (set_attr "mode" "SI")])
8438 [(set (match_operand 0 "register_operand" "")
8440 (const_int -65536)))
8441 (clobber (reg:CC FLAGS_REG))]
8442 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8443 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8444 "operands[1] = gen_lowpart (HImode, operands[0]);")
8447 [(set (match_operand 0 "ext_register_operand" "")
8450 (clobber (reg:CC FLAGS_REG))]
8451 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8452 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8453 "operands[1] = gen_lowpart (QImode, operands[0]);")
8456 [(set (match_operand 0 "ext_register_operand" "")
8458 (const_int -65281)))
8459 (clobber (reg:CC FLAGS_REG))]
8460 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8461 [(parallel [(set (zero_extract:SI (match_dup 0)
8465 (zero_extract:SI (match_dup 0)
8468 (zero_extract:SI (match_dup 0)
8471 (clobber (reg:CC FLAGS_REG))])]
8472 "operands[0] = gen_lowpart (SImode, operands[0]);")
8474 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8475 (define_insn "*andsi_1_zext"
8476 [(set (match_operand:DI 0 "register_operand" "=r")
8478 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8479 (match_operand:SI 2 "general_operand" "g"))))
8480 (clobber (reg:CC FLAGS_REG))]
8481 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8482 "and{l}\t{%2, %k0|%k0, %2}"
8483 [(set_attr "type" "alu")
8484 (set_attr "mode" "SI")])
8486 (define_insn "*andsi_2"
8487 [(set (reg FLAGS_REG)
8488 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8489 (match_operand:SI 2 "general_operand" "g,ri"))
8491 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8492 (and:SI (match_dup 1) (match_dup 2)))]
8493 "ix86_match_ccmode (insn, CCNOmode)
8494 && ix86_binary_operator_ok (AND, SImode, operands)"
8495 "and{l}\t{%2, %0|%0, %2}"
8496 [(set_attr "type" "alu")
8497 (set_attr "mode" "SI")])
8499 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8500 (define_insn "*andsi_2_zext"
8501 [(set (reg FLAGS_REG)
8502 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8503 (match_operand:SI 2 "general_operand" "g"))
8505 (set (match_operand:DI 0 "register_operand" "=r")
8506 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8507 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8508 && ix86_binary_operator_ok (AND, SImode, operands)"
8509 "and{l}\t{%2, %k0|%k0, %2}"
8510 [(set_attr "type" "alu")
8511 (set_attr "mode" "SI")])
8513 (define_expand "andhi3"
8514 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8515 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8516 (match_operand:HI 2 "general_operand" "")))
8517 (clobber (reg:CC FLAGS_REG))]
8518 "TARGET_HIMODE_MATH"
8519 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8521 (define_insn "*andhi_1"
8522 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8523 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8524 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8525 (clobber (reg:CC FLAGS_REG))]
8526 "ix86_binary_operator_ok (AND, HImode, operands)"
8528 switch (get_attr_type (insn))
8531 gcc_assert (CONST_INT_P (operands[2]));
8532 gcc_assert (INTVAL (operands[2]) == 0xff);
8533 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8536 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8538 return "and{w}\t{%2, %0|%0, %2}";
8541 [(set_attr "type" "alu,alu,imovx")
8542 (set_attr "length_immediate" "*,*,0")
8543 (set_attr "mode" "HI,HI,SI")])
8545 (define_insn "*andhi_2"
8546 [(set (reg FLAGS_REG)
8547 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8548 (match_operand:HI 2 "general_operand" "g,ri"))
8550 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8551 (and:HI (match_dup 1) (match_dup 2)))]
8552 "ix86_match_ccmode (insn, CCNOmode)
8553 && ix86_binary_operator_ok (AND, HImode, operands)"
8554 "and{w}\t{%2, %0|%0, %2}"
8555 [(set_attr "type" "alu")
8556 (set_attr "mode" "HI")])
8558 (define_expand "andqi3"
8559 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8560 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8561 (match_operand:QI 2 "general_operand" "")))
8562 (clobber (reg:CC FLAGS_REG))]
8563 "TARGET_QIMODE_MATH"
8564 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8566 ;; %%% Potential partial reg stall on alternative 2. What to do?
8567 (define_insn "*andqi_1"
8568 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8569 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8570 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8571 (clobber (reg:CC FLAGS_REG))]
8572 "ix86_binary_operator_ok (AND, QImode, operands)"
8574 and{b}\t{%2, %0|%0, %2}
8575 and{b}\t{%2, %0|%0, %2}
8576 and{l}\t{%k2, %k0|%k0, %k2}"
8577 [(set_attr "type" "alu")
8578 (set_attr "mode" "QI,QI,SI")])
8580 (define_insn "*andqi_1_slp"
8581 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8582 (and:QI (match_dup 0)
8583 (match_operand:QI 1 "general_operand" "qi,qmi")))
8584 (clobber (reg:CC FLAGS_REG))]
8585 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8586 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8587 "and{b}\t{%1, %0|%0, %1}"
8588 [(set_attr "type" "alu1")
8589 (set_attr "mode" "QI")])
8591 (define_insn "*andqi_2_maybe_si"
8592 [(set (reg FLAGS_REG)
8594 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8595 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8597 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8598 (and:QI (match_dup 1) (match_dup 2)))]
8599 "ix86_binary_operator_ok (AND, QImode, operands)
8600 && ix86_match_ccmode (insn,
8601 CONST_INT_P (operands[2])
8602 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8604 if (which_alternative == 2)
8606 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8607 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8608 return "and{l}\t{%2, %k0|%k0, %2}";
8610 return "and{b}\t{%2, %0|%0, %2}";
8612 [(set_attr "type" "alu")
8613 (set_attr "mode" "QI,QI,SI")])
8615 (define_insn "*andqi_2"
8616 [(set (reg FLAGS_REG)
8618 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8619 (match_operand:QI 2 "general_operand" "qim,qi"))
8621 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8622 (and:QI (match_dup 1) (match_dup 2)))]
8623 "ix86_match_ccmode (insn, CCNOmode)
8624 && ix86_binary_operator_ok (AND, QImode, operands)"
8625 "and{b}\t{%2, %0|%0, %2}"
8626 [(set_attr "type" "alu")
8627 (set_attr "mode" "QI")])
8629 (define_insn "*andqi_2_slp"
8630 [(set (reg FLAGS_REG)
8632 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8633 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8635 (set (strict_low_part (match_dup 0))
8636 (and:QI (match_dup 0) (match_dup 1)))]
8637 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8638 && ix86_match_ccmode (insn, CCNOmode)
8639 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8640 "and{b}\t{%1, %0|%0, %1}"
8641 [(set_attr "type" "alu1")
8642 (set_attr "mode" "QI")])
8644 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8645 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8646 ;; for a QImode operand, which of course failed.
8648 (define_insn "andqi_ext_0"
8649 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8654 (match_operand 1 "ext_register_operand" "0")
8657 (match_operand 2 "const_int_operand" "n")))
8658 (clobber (reg:CC FLAGS_REG))]
8660 "and{b}\t{%2, %h0|%h0, %2}"
8661 [(set_attr "type" "alu")
8662 (set_attr "length_immediate" "1")
8663 (set_attr "mode" "QI")])
8665 ;; Generated by peephole translating test to and. This shows up
8666 ;; often in fp comparisons.
8668 (define_insn "*andqi_ext_0_cc"
8669 [(set (reg FLAGS_REG)
8673 (match_operand 1 "ext_register_operand" "0")
8676 (match_operand 2 "const_int_operand" "n"))
8678 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8687 "ix86_match_ccmode (insn, CCNOmode)"
8688 "and{b}\t{%2, %h0|%h0, %2}"
8689 [(set_attr "type" "alu")
8690 (set_attr "length_immediate" "1")
8691 (set_attr "mode" "QI")])
8693 (define_insn "*andqi_ext_1"
8694 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8699 (match_operand 1 "ext_register_operand" "0")
8703 (match_operand:QI 2 "general_operand" "Qm"))))
8704 (clobber (reg:CC FLAGS_REG))]
8706 "and{b}\t{%2, %h0|%h0, %2}"
8707 [(set_attr "type" "alu")
8708 (set_attr "length_immediate" "0")
8709 (set_attr "mode" "QI")])
8711 (define_insn "*andqi_ext_1_rex64"
8712 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8717 (match_operand 1 "ext_register_operand" "0")
8721 (match_operand 2 "ext_register_operand" "Q"))))
8722 (clobber (reg:CC FLAGS_REG))]
8724 "and{b}\t{%2, %h0|%h0, %2}"
8725 [(set_attr "type" "alu")
8726 (set_attr "length_immediate" "0")
8727 (set_attr "mode" "QI")])
8729 (define_insn "*andqi_ext_2"
8730 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8735 (match_operand 1 "ext_register_operand" "%0")
8739 (match_operand 2 "ext_register_operand" "Q")
8742 (clobber (reg:CC FLAGS_REG))]
8744 "and{b}\t{%h2, %h0|%h0, %h2}"
8745 [(set_attr "type" "alu")
8746 (set_attr "length_immediate" "0")
8747 (set_attr "mode" "QI")])
8749 ;; Convert wide AND instructions with immediate operand to shorter QImode
8750 ;; equivalents when possible.
8751 ;; Don't do the splitting with memory operands, since it introduces risk
8752 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8753 ;; for size, but that can (should?) be handled by generic code instead.
8755 [(set (match_operand 0 "register_operand" "")
8756 (and (match_operand 1 "register_operand" "")
8757 (match_operand 2 "const_int_operand" "")))
8758 (clobber (reg:CC FLAGS_REG))]
8760 && QI_REG_P (operands[0])
8761 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8762 && !(~INTVAL (operands[2]) & ~(255 << 8))
8763 && GET_MODE (operands[0]) != QImode"
8764 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8765 (and:SI (zero_extract:SI (match_dup 1)
8766 (const_int 8) (const_int 8))
8768 (clobber (reg:CC FLAGS_REG))])]
8769 "operands[0] = gen_lowpart (SImode, operands[0]);
8770 operands[1] = gen_lowpart (SImode, operands[1]);
8771 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8773 ;; Since AND can be encoded with sign extended immediate, this is only
8774 ;; profitable when 7th bit is not set.
8776 [(set (match_operand 0 "register_operand" "")
8777 (and (match_operand 1 "general_operand" "")
8778 (match_operand 2 "const_int_operand" "")))
8779 (clobber (reg:CC FLAGS_REG))]
8781 && ANY_QI_REG_P (operands[0])
8782 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8783 && !(~INTVAL (operands[2]) & ~255)
8784 && !(INTVAL (operands[2]) & 128)
8785 && GET_MODE (operands[0]) != QImode"
8786 [(parallel [(set (strict_low_part (match_dup 0))
8787 (and:QI (match_dup 1)
8789 (clobber (reg:CC FLAGS_REG))])]
8790 "operands[0] = gen_lowpart (QImode, operands[0]);
8791 operands[1] = gen_lowpart (QImode, operands[1]);
8792 operands[2] = gen_lowpart (QImode, operands[2]);")
8794 ;; Logical inclusive OR instructions
8796 ;; %%% This used to optimize known byte-wide and operations to memory.
8797 ;; If this is considered useful, it should be done with splitters.
8799 (define_expand "iordi3"
8800 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8801 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8802 (match_operand:DI 2 "x86_64_general_operand" "")))
8803 (clobber (reg:CC FLAGS_REG))]
8805 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8807 (define_insn "*iordi_1_rex64"
8808 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8809 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8810 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8811 (clobber (reg:CC FLAGS_REG))]
8813 && ix86_binary_operator_ok (IOR, DImode, operands)"
8814 "or{q}\t{%2, %0|%0, %2}"
8815 [(set_attr "type" "alu")
8816 (set_attr "mode" "DI")])
8818 (define_insn "*iordi_2_rex64"
8819 [(set (reg FLAGS_REG)
8820 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8821 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8823 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8824 (ior:DI (match_dup 1) (match_dup 2)))]
8826 && ix86_match_ccmode (insn, CCNOmode)
8827 && ix86_binary_operator_ok (IOR, DImode, operands)"
8828 "or{q}\t{%2, %0|%0, %2}"
8829 [(set_attr "type" "alu")
8830 (set_attr "mode" "DI")])
8832 (define_insn "*iordi_3_rex64"
8833 [(set (reg FLAGS_REG)
8834 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8835 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8837 (clobber (match_scratch:DI 0 "=r"))]
8839 && ix86_match_ccmode (insn, CCNOmode)
8840 && ix86_binary_operator_ok (IOR, DImode, operands)"
8841 "or{q}\t{%2, %0|%0, %2}"
8842 [(set_attr "type" "alu")
8843 (set_attr "mode" "DI")])
8846 (define_expand "iorsi3"
8847 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8848 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8849 (match_operand:SI 2 "general_operand" "")))
8850 (clobber (reg:CC FLAGS_REG))]
8852 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8854 (define_insn "*iorsi_1"
8855 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8856 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8857 (match_operand:SI 2 "general_operand" "ri,g")))
8858 (clobber (reg:CC FLAGS_REG))]
8859 "ix86_binary_operator_ok (IOR, SImode, operands)"
8860 "or{l}\t{%2, %0|%0, %2}"
8861 [(set_attr "type" "alu")
8862 (set_attr "mode" "SI")])
8864 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8865 (define_insn "*iorsi_1_zext"
8866 [(set (match_operand:DI 0 "register_operand" "=r")
8868 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8869 (match_operand:SI 2 "general_operand" "g"))))
8870 (clobber (reg:CC FLAGS_REG))]
8871 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8872 "or{l}\t{%2, %k0|%k0, %2}"
8873 [(set_attr "type" "alu")
8874 (set_attr "mode" "SI")])
8876 (define_insn "*iorsi_1_zext_imm"
8877 [(set (match_operand:DI 0 "register_operand" "=r")
8878 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8879 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8880 (clobber (reg:CC FLAGS_REG))]
8882 "or{l}\t{%2, %k0|%k0, %2}"
8883 [(set_attr "type" "alu")
8884 (set_attr "mode" "SI")])
8886 (define_insn "*iorsi_2"
8887 [(set (reg FLAGS_REG)
8888 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8889 (match_operand:SI 2 "general_operand" "g,ri"))
8891 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8892 (ior:SI (match_dup 1) (match_dup 2)))]
8893 "ix86_match_ccmode (insn, CCNOmode)
8894 && ix86_binary_operator_ok (IOR, SImode, operands)"
8895 "or{l}\t{%2, %0|%0, %2}"
8896 [(set_attr "type" "alu")
8897 (set_attr "mode" "SI")])
8899 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8900 ;; ??? Special case for immediate operand is missing - it is tricky.
8901 (define_insn "*iorsi_2_zext"
8902 [(set (reg FLAGS_REG)
8903 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8904 (match_operand:SI 2 "general_operand" "g"))
8906 (set (match_operand:DI 0 "register_operand" "=r")
8907 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8908 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8909 && ix86_binary_operator_ok (IOR, SImode, operands)"
8910 "or{l}\t{%2, %k0|%k0, %2}"
8911 [(set_attr "type" "alu")
8912 (set_attr "mode" "SI")])
8914 (define_insn "*iorsi_2_zext_imm"
8915 [(set (reg FLAGS_REG)
8916 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8917 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8919 (set (match_operand:DI 0 "register_operand" "=r")
8920 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8921 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8922 && ix86_binary_operator_ok (IOR, SImode, operands)"
8923 "or{l}\t{%2, %k0|%k0, %2}"
8924 [(set_attr "type" "alu")
8925 (set_attr "mode" "SI")])
8927 (define_insn "*iorsi_3"
8928 [(set (reg FLAGS_REG)
8929 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8930 (match_operand:SI 2 "general_operand" "g"))
8932 (clobber (match_scratch:SI 0 "=r"))]
8933 "ix86_match_ccmode (insn, CCNOmode)
8934 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8935 "or{l}\t{%2, %0|%0, %2}"
8936 [(set_attr "type" "alu")
8937 (set_attr "mode" "SI")])
8939 (define_expand "iorhi3"
8940 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8941 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8942 (match_operand:HI 2 "general_operand" "")))
8943 (clobber (reg:CC FLAGS_REG))]
8944 "TARGET_HIMODE_MATH"
8945 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8947 (define_insn "*iorhi_1"
8948 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8949 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8950 (match_operand:HI 2 "general_operand" "g,ri")))
8951 (clobber (reg:CC FLAGS_REG))]
8952 "ix86_binary_operator_ok (IOR, HImode, operands)"
8953 "or{w}\t{%2, %0|%0, %2}"
8954 [(set_attr "type" "alu")
8955 (set_attr "mode" "HI")])
8957 (define_insn "*iorhi_2"
8958 [(set (reg FLAGS_REG)
8959 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8960 (match_operand:HI 2 "general_operand" "g,ri"))
8962 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8963 (ior:HI (match_dup 1) (match_dup 2)))]
8964 "ix86_match_ccmode (insn, CCNOmode)
8965 && ix86_binary_operator_ok (IOR, HImode, operands)"
8966 "or{w}\t{%2, %0|%0, %2}"
8967 [(set_attr "type" "alu")
8968 (set_attr "mode" "HI")])
8970 (define_insn "*iorhi_3"
8971 [(set (reg FLAGS_REG)
8972 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8973 (match_operand:HI 2 "general_operand" "g"))
8975 (clobber (match_scratch:HI 0 "=r"))]
8976 "ix86_match_ccmode (insn, CCNOmode)
8977 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8978 "or{w}\t{%2, %0|%0, %2}"
8979 [(set_attr "type" "alu")
8980 (set_attr "mode" "HI")])
8982 (define_expand "iorqi3"
8983 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8984 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8985 (match_operand:QI 2 "general_operand" "")))
8986 (clobber (reg:CC FLAGS_REG))]
8987 "TARGET_QIMODE_MATH"
8988 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8990 ;; %%% Potential partial reg stall on alternative 2. What to do?
8991 (define_insn "*iorqi_1"
8992 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8993 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8994 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8995 (clobber (reg:CC FLAGS_REG))]
8996 "ix86_binary_operator_ok (IOR, QImode, operands)"
8998 or{b}\t{%2, %0|%0, %2}
8999 or{b}\t{%2, %0|%0, %2}
9000 or{l}\t{%k2, %k0|%k0, %k2}"
9001 [(set_attr "type" "alu")
9002 (set_attr "mode" "QI,QI,SI")])
9004 (define_insn "*iorqi_1_slp"
9005 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9006 (ior:QI (match_dup 0)
9007 (match_operand:QI 1 "general_operand" "qmi,qi")))
9008 (clobber (reg:CC FLAGS_REG))]
9009 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9010 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9011 "or{b}\t{%1, %0|%0, %1}"
9012 [(set_attr "type" "alu1")
9013 (set_attr "mode" "QI")])
9015 (define_insn "*iorqi_2"
9016 [(set (reg FLAGS_REG)
9017 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9018 (match_operand:QI 2 "general_operand" "qim,qi"))
9020 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9021 (ior:QI (match_dup 1) (match_dup 2)))]
9022 "ix86_match_ccmode (insn, CCNOmode)
9023 && ix86_binary_operator_ok (IOR, QImode, operands)"
9024 "or{b}\t{%2, %0|%0, %2}"
9025 [(set_attr "type" "alu")
9026 (set_attr "mode" "QI")])
9028 (define_insn "*iorqi_2_slp"
9029 [(set (reg FLAGS_REG)
9030 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9031 (match_operand:QI 1 "general_operand" "qim,qi"))
9033 (set (strict_low_part (match_dup 0))
9034 (ior:QI (match_dup 0) (match_dup 1)))]
9035 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9036 && ix86_match_ccmode (insn, CCNOmode)
9037 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9038 "or{b}\t{%1, %0|%0, %1}"
9039 [(set_attr "type" "alu1")
9040 (set_attr "mode" "QI")])
9042 (define_insn "*iorqi_3"
9043 [(set (reg FLAGS_REG)
9044 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9045 (match_operand:QI 2 "general_operand" "qim"))
9047 (clobber (match_scratch:QI 0 "=q"))]
9048 "ix86_match_ccmode (insn, CCNOmode)
9049 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9050 "or{b}\t{%2, %0|%0, %2}"
9051 [(set_attr "type" "alu")
9052 (set_attr "mode" "QI")])
9054 (define_insn "iorqi_ext_0"
9055 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9060 (match_operand 1 "ext_register_operand" "0")
9063 (match_operand 2 "const_int_operand" "n")))
9064 (clobber (reg:CC FLAGS_REG))]
9065 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9066 "or{b}\t{%2, %h0|%h0, %2}"
9067 [(set_attr "type" "alu")
9068 (set_attr "length_immediate" "1")
9069 (set_attr "mode" "QI")])
9071 (define_insn "*iorqi_ext_1"
9072 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9077 (match_operand 1 "ext_register_operand" "0")
9081 (match_operand:QI 2 "general_operand" "Qm"))))
9082 (clobber (reg:CC FLAGS_REG))]
9084 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9085 "or{b}\t{%2, %h0|%h0, %2}"
9086 [(set_attr "type" "alu")
9087 (set_attr "length_immediate" "0")
9088 (set_attr "mode" "QI")])
9090 (define_insn "*iorqi_ext_1_rex64"
9091 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9096 (match_operand 1 "ext_register_operand" "0")
9100 (match_operand 2 "ext_register_operand" "Q"))))
9101 (clobber (reg:CC FLAGS_REG))]
9103 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9104 "or{b}\t{%2, %h0|%h0, %2}"
9105 [(set_attr "type" "alu")
9106 (set_attr "length_immediate" "0")
9107 (set_attr "mode" "QI")])
9109 (define_insn "*iorqi_ext_2"
9110 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9114 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9117 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9120 (clobber (reg:CC FLAGS_REG))]
9121 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9122 "ior{b}\t{%h2, %h0|%h0, %h2}"
9123 [(set_attr "type" "alu")
9124 (set_attr "length_immediate" "0")
9125 (set_attr "mode" "QI")])
9128 [(set (match_operand 0 "register_operand" "")
9129 (ior (match_operand 1 "register_operand" "")
9130 (match_operand 2 "const_int_operand" "")))
9131 (clobber (reg:CC FLAGS_REG))]
9133 && QI_REG_P (operands[0])
9134 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9135 && !(INTVAL (operands[2]) & ~(255 << 8))
9136 && GET_MODE (operands[0]) != QImode"
9137 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9138 (ior:SI (zero_extract:SI (match_dup 1)
9139 (const_int 8) (const_int 8))
9141 (clobber (reg:CC FLAGS_REG))])]
9142 "operands[0] = gen_lowpart (SImode, operands[0]);
9143 operands[1] = gen_lowpart (SImode, operands[1]);
9144 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9146 ;; Since OR can be encoded with sign extended immediate, this is only
9147 ;; profitable when 7th bit is set.
9149 [(set (match_operand 0 "register_operand" "")
9150 (ior (match_operand 1 "general_operand" "")
9151 (match_operand 2 "const_int_operand" "")))
9152 (clobber (reg:CC FLAGS_REG))]
9154 && ANY_QI_REG_P (operands[0])
9155 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9156 && !(INTVAL (operands[2]) & ~255)
9157 && (INTVAL (operands[2]) & 128)
9158 && GET_MODE (operands[0]) != QImode"
9159 [(parallel [(set (strict_low_part (match_dup 0))
9160 (ior:QI (match_dup 1)
9162 (clobber (reg:CC FLAGS_REG))])]
9163 "operands[0] = gen_lowpart (QImode, operands[0]);
9164 operands[1] = gen_lowpart (QImode, operands[1]);
9165 operands[2] = gen_lowpart (QImode, operands[2]);")
9167 ;; Logical XOR instructions
9169 ;; %%% This used to optimize known byte-wide and operations to memory.
9170 ;; If this is considered useful, it should be done with splitters.
9172 (define_expand "xordi3"
9173 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9174 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9175 (match_operand:DI 2 "x86_64_general_operand" "")))
9176 (clobber (reg:CC FLAGS_REG))]
9178 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9180 (define_insn "*xordi_1_rex64"
9181 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9182 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9183 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9184 (clobber (reg:CC FLAGS_REG))]
9186 && ix86_binary_operator_ok (XOR, DImode, operands)"
9188 xor{q}\t{%2, %0|%0, %2}
9189 xor{q}\t{%2, %0|%0, %2}"
9190 [(set_attr "type" "alu")
9191 (set_attr "mode" "DI,DI")])
9193 (define_insn "*xordi_2_rex64"
9194 [(set (reg FLAGS_REG)
9195 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9196 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9198 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9199 (xor:DI (match_dup 1) (match_dup 2)))]
9201 && ix86_match_ccmode (insn, CCNOmode)
9202 && ix86_binary_operator_ok (XOR, DImode, operands)"
9204 xor{q}\t{%2, %0|%0, %2}
9205 xor{q}\t{%2, %0|%0, %2}"
9206 [(set_attr "type" "alu")
9207 (set_attr "mode" "DI,DI")])
9209 (define_insn "*xordi_3_rex64"
9210 [(set (reg FLAGS_REG)
9211 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9212 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9214 (clobber (match_scratch:DI 0 "=r"))]
9216 && ix86_match_ccmode (insn, CCNOmode)
9217 && ix86_binary_operator_ok (XOR, DImode, operands)"
9218 "xor{q}\t{%2, %0|%0, %2}"
9219 [(set_attr "type" "alu")
9220 (set_attr "mode" "DI")])
9222 (define_expand "xorsi3"
9223 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9224 (xor: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 (XOR, SImode, operands); DONE;")
9230 (define_insn "*xorsi_1"
9231 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9232 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9233 (match_operand:SI 2 "general_operand" "ri,rm")))
9234 (clobber (reg:CC FLAGS_REG))]
9235 "ix86_binary_operator_ok (XOR, SImode, operands)"
9236 "xor{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 ;; Add speccase for immediates
9242 (define_insn "*xorsi_1_zext"
9243 [(set (match_operand:DI 0 "register_operand" "=r")
9245 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9246 (match_operand:SI 2 "general_operand" "g"))))
9247 (clobber (reg:CC FLAGS_REG))]
9248 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9249 "xor{l}\t{%2, %k0|%k0, %2}"
9250 [(set_attr "type" "alu")
9251 (set_attr "mode" "SI")])
9253 (define_insn "*xorsi_1_zext_imm"
9254 [(set (match_operand:DI 0 "register_operand" "=r")
9255 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9256 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9257 (clobber (reg:CC FLAGS_REG))]
9258 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9259 "xor{l}\t{%2, %k0|%k0, %2}"
9260 [(set_attr "type" "alu")
9261 (set_attr "mode" "SI")])
9263 (define_insn "*xorsi_2"
9264 [(set (reg FLAGS_REG)
9265 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9266 (match_operand:SI 2 "general_operand" "g,ri"))
9268 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9269 (xor:SI (match_dup 1) (match_dup 2)))]
9270 "ix86_match_ccmode (insn, CCNOmode)
9271 && ix86_binary_operator_ok (XOR, SImode, operands)"
9272 "xor{l}\t{%2, %0|%0, %2}"
9273 [(set_attr "type" "alu")
9274 (set_attr "mode" "SI")])
9276 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9277 ;; ??? Special case for immediate operand is missing - it is tricky.
9278 (define_insn "*xorsi_2_zext"
9279 [(set (reg FLAGS_REG)
9280 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9281 (match_operand:SI 2 "general_operand" "g"))
9283 (set (match_operand:DI 0 "register_operand" "=r")
9284 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9285 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9286 && ix86_binary_operator_ok (XOR, SImode, operands)"
9287 "xor{l}\t{%2, %k0|%k0, %2}"
9288 [(set_attr "type" "alu")
9289 (set_attr "mode" "SI")])
9291 (define_insn "*xorsi_2_zext_imm"
9292 [(set (reg FLAGS_REG)
9293 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9294 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9296 (set (match_operand:DI 0 "register_operand" "=r")
9297 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9298 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9299 && ix86_binary_operator_ok (XOR, SImode, operands)"
9300 "xor{l}\t{%2, %k0|%k0, %2}"
9301 [(set_attr "type" "alu")
9302 (set_attr "mode" "SI")])
9304 (define_insn "*xorsi_3"
9305 [(set (reg FLAGS_REG)
9306 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9307 (match_operand:SI 2 "general_operand" "g"))
9309 (clobber (match_scratch:SI 0 "=r"))]
9310 "ix86_match_ccmode (insn, CCNOmode)
9311 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9312 "xor{l}\t{%2, %0|%0, %2}"
9313 [(set_attr "type" "alu")
9314 (set_attr "mode" "SI")])
9316 (define_expand "xorhi3"
9317 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9318 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9319 (match_operand:HI 2 "general_operand" "")))
9320 (clobber (reg:CC FLAGS_REG))]
9321 "TARGET_HIMODE_MATH"
9322 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9324 (define_insn "*xorhi_1"
9325 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9326 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9327 (match_operand:HI 2 "general_operand" "g,ri")))
9328 (clobber (reg:CC FLAGS_REG))]
9329 "ix86_binary_operator_ok (XOR, HImode, operands)"
9330 "xor{w}\t{%2, %0|%0, %2}"
9331 [(set_attr "type" "alu")
9332 (set_attr "mode" "HI")])
9334 (define_insn "*xorhi_2"
9335 [(set (reg FLAGS_REG)
9336 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9337 (match_operand:HI 2 "general_operand" "g,ri"))
9339 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9340 (xor:HI (match_dup 1) (match_dup 2)))]
9341 "ix86_match_ccmode (insn, CCNOmode)
9342 && ix86_binary_operator_ok (XOR, HImode, operands)"
9343 "xor{w}\t{%2, %0|%0, %2}"
9344 [(set_attr "type" "alu")
9345 (set_attr "mode" "HI")])
9347 (define_insn "*xorhi_3"
9348 [(set (reg FLAGS_REG)
9349 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9350 (match_operand:HI 2 "general_operand" "g"))
9352 (clobber (match_scratch:HI 0 "=r"))]
9353 "ix86_match_ccmode (insn, CCNOmode)
9354 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9355 "xor{w}\t{%2, %0|%0, %2}"
9356 [(set_attr "type" "alu")
9357 (set_attr "mode" "HI")])
9359 (define_expand "xorqi3"
9360 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9361 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9362 (match_operand:QI 2 "general_operand" "")))
9363 (clobber (reg:CC FLAGS_REG))]
9364 "TARGET_QIMODE_MATH"
9365 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9367 ;; %%% Potential partial reg stall on alternative 2. What to do?
9368 (define_insn "*xorqi_1"
9369 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9370 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9371 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9372 (clobber (reg:CC FLAGS_REG))]
9373 "ix86_binary_operator_ok (XOR, QImode, operands)"
9375 xor{b}\t{%2, %0|%0, %2}
9376 xor{b}\t{%2, %0|%0, %2}
9377 xor{l}\t{%k2, %k0|%k0, %k2}"
9378 [(set_attr "type" "alu")
9379 (set_attr "mode" "QI,QI,SI")])
9381 (define_insn "*xorqi_1_slp"
9382 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9383 (xor:QI (match_dup 0)
9384 (match_operand:QI 1 "general_operand" "qi,qmi")))
9385 (clobber (reg:CC FLAGS_REG))]
9386 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9387 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9388 "xor{b}\t{%1, %0|%0, %1}"
9389 [(set_attr "type" "alu1")
9390 (set_attr "mode" "QI")])
9392 (define_insn "xorqi_ext_0"
9393 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9398 (match_operand 1 "ext_register_operand" "0")
9401 (match_operand 2 "const_int_operand" "n")))
9402 (clobber (reg:CC FLAGS_REG))]
9403 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9404 "xor{b}\t{%2, %h0|%h0, %2}"
9405 [(set_attr "type" "alu")
9406 (set_attr "length_immediate" "1")
9407 (set_attr "mode" "QI")])
9409 (define_insn "*xorqi_ext_1"
9410 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9415 (match_operand 1 "ext_register_operand" "0")
9419 (match_operand:QI 2 "general_operand" "Qm"))))
9420 (clobber (reg:CC FLAGS_REG))]
9422 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9423 "xor{b}\t{%2, %h0|%h0, %2}"
9424 [(set_attr "type" "alu")
9425 (set_attr "length_immediate" "0")
9426 (set_attr "mode" "QI")])
9428 (define_insn "*xorqi_ext_1_rex64"
9429 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9434 (match_operand 1 "ext_register_operand" "0")
9438 (match_operand 2 "ext_register_operand" "Q"))))
9439 (clobber (reg:CC FLAGS_REG))]
9441 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9442 "xor{b}\t{%2, %h0|%h0, %2}"
9443 [(set_attr "type" "alu")
9444 (set_attr "length_immediate" "0")
9445 (set_attr "mode" "QI")])
9447 (define_insn "*xorqi_ext_2"
9448 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9452 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9455 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9458 (clobber (reg:CC FLAGS_REG))]
9459 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9460 "xor{b}\t{%h2, %h0|%h0, %h2}"
9461 [(set_attr "type" "alu")
9462 (set_attr "length_immediate" "0")
9463 (set_attr "mode" "QI")])
9465 (define_insn "*xorqi_cc_1"
9466 [(set (reg FLAGS_REG)
9468 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9469 (match_operand:QI 2 "general_operand" "qim,qi"))
9471 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9472 (xor:QI (match_dup 1) (match_dup 2)))]
9473 "ix86_match_ccmode (insn, CCNOmode)
9474 && ix86_binary_operator_ok (XOR, QImode, operands)"
9475 "xor{b}\t{%2, %0|%0, %2}"
9476 [(set_attr "type" "alu")
9477 (set_attr "mode" "QI")])
9479 (define_insn "*xorqi_2_slp"
9480 [(set (reg FLAGS_REG)
9481 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9482 (match_operand:QI 1 "general_operand" "qim,qi"))
9484 (set (strict_low_part (match_dup 0))
9485 (xor:QI (match_dup 0) (match_dup 1)))]
9486 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9487 && ix86_match_ccmode (insn, CCNOmode)
9488 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9489 "xor{b}\t{%1, %0|%0, %1}"
9490 [(set_attr "type" "alu1")
9491 (set_attr "mode" "QI")])
9493 (define_insn "*xorqi_cc_2"
9494 [(set (reg FLAGS_REG)
9496 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9497 (match_operand:QI 2 "general_operand" "qim"))
9499 (clobber (match_scratch:QI 0 "=q"))]
9500 "ix86_match_ccmode (insn, CCNOmode)
9501 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9502 "xor{b}\t{%2, %0|%0, %2}"
9503 [(set_attr "type" "alu")
9504 (set_attr "mode" "QI")])
9506 (define_insn "*xorqi_cc_ext_1"
9507 [(set (reg FLAGS_REG)
9511 (match_operand 1 "ext_register_operand" "0")
9514 (match_operand:QI 2 "general_operand" "qmn"))
9516 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9520 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9522 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9523 "xor{b}\t{%2, %h0|%h0, %2}"
9524 [(set_attr "type" "alu")
9525 (set_attr "mode" "QI")])
9527 (define_insn "*xorqi_cc_ext_1_rex64"
9528 [(set (reg FLAGS_REG)
9532 (match_operand 1 "ext_register_operand" "0")
9535 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9537 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9541 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9543 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9544 "xor{b}\t{%2, %h0|%h0, %2}"
9545 [(set_attr "type" "alu")
9546 (set_attr "mode" "QI")])
9548 (define_expand "xorqi_cc_ext_1"
9550 (set (reg:CCNO FLAGS_REG)
9554 (match_operand 1 "ext_register_operand" "")
9557 (match_operand:QI 2 "general_operand" ""))
9559 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9563 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9569 [(set (match_operand 0 "register_operand" "")
9570 (xor (match_operand 1 "register_operand" "")
9571 (match_operand 2 "const_int_operand" "")))
9572 (clobber (reg:CC FLAGS_REG))]
9574 && QI_REG_P (operands[0])
9575 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9576 && !(INTVAL (operands[2]) & ~(255 << 8))
9577 && GET_MODE (operands[0]) != QImode"
9578 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9579 (xor:SI (zero_extract:SI (match_dup 1)
9580 (const_int 8) (const_int 8))
9582 (clobber (reg:CC FLAGS_REG))])]
9583 "operands[0] = gen_lowpart (SImode, operands[0]);
9584 operands[1] = gen_lowpart (SImode, operands[1]);
9585 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9587 ;; Since XOR can be encoded with sign extended immediate, this is only
9588 ;; profitable when 7th bit is set.
9590 [(set (match_operand 0 "register_operand" "")
9591 (xor (match_operand 1 "general_operand" "")
9592 (match_operand 2 "const_int_operand" "")))
9593 (clobber (reg:CC FLAGS_REG))]
9595 && ANY_QI_REG_P (operands[0])
9596 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9597 && !(INTVAL (operands[2]) & ~255)
9598 && (INTVAL (operands[2]) & 128)
9599 && GET_MODE (operands[0]) != QImode"
9600 [(parallel [(set (strict_low_part (match_dup 0))
9601 (xor:QI (match_dup 1)
9603 (clobber (reg:CC FLAGS_REG))])]
9604 "operands[0] = gen_lowpart (QImode, operands[0]);
9605 operands[1] = gen_lowpart (QImode, operands[1]);
9606 operands[2] = gen_lowpart (QImode, operands[2]);")
9608 ;; Negation instructions
9610 (define_expand "negti2"
9611 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9612 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9613 (clobber (reg:CC FLAGS_REG))])]
9615 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9617 (define_insn "*negti2_1"
9618 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9619 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9620 (clobber (reg:CC FLAGS_REG))]
9622 && ix86_unary_operator_ok (NEG, TImode, operands)"
9626 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9627 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9628 (clobber (reg:CC FLAGS_REG))]
9629 "TARGET_64BIT && reload_completed"
9631 [(set (reg:CCZ FLAGS_REG)
9632 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9633 (set (match_dup 0) (neg:DI (match_dup 2)))])
9636 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9639 (clobber (reg:CC FLAGS_REG))])
9642 (neg:DI (match_dup 1)))
9643 (clobber (reg:CC FLAGS_REG))])]
9644 "split_ti (operands+1, 1, operands+2, operands+3);
9645 split_ti (operands+0, 1, operands+0, operands+1);")
9647 (define_expand "negdi2"
9648 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9649 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9650 (clobber (reg:CC FLAGS_REG))])]
9652 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9654 (define_insn "*negdi2_1"
9655 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9656 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9657 (clobber (reg:CC FLAGS_REG))]
9659 && ix86_unary_operator_ok (NEG, DImode, operands)"
9663 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9664 (neg:DI (match_operand:DI 1 "general_operand" "")))
9665 (clobber (reg:CC FLAGS_REG))]
9666 "!TARGET_64BIT && reload_completed"
9668 [(set (reg:CCZ FLAGS_REG)
9669 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9670 (set (match_dup 0) (neg:SI (match_dup 2)))])
9673 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9676 (clobber (reg:CC FLAGS_REG))])
9679 (neg:SI (match_dup 1)))
9680 (clobber (reg:CC FLAGS_REG))])]
9681 "split_di (operands+1, 1, operands+2, operands+3);
9682 split_di (operands+0, 1, operands+0, operands+1);")
9684 (define_insn "*negdi2_1_rex64"
9685 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9686 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9687 (clobber (reg:CC FLAGS_REG))]
9688 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9690 [(set_attr "type" "negnot")
9691 (set_attr "mode" "DI")])
9693 ;; The problem with neg is that it does not perform (compare x 0),
9694 ;; it really performs (compare 0 x), which leaves us with the zero
9695 ;; flag being the only useful item.
9697 (define_insn "*negdi2_cmpz_rex64"
9698 [(set (reg:CCZ FLAGS_REG)
9699 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9701 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9702 (neg:DI (match_dup 1)))]
9703 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9705 [(set_attr "type" "negnot")
9706 (set_attr "mode" "DI")])
9709 (define_expand "negsi2"
9710 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9711 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9712 (clobber (reg:CC FLAGS_REG))])]
9714 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9716 (define_insn "*negsi2_1"
9717 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9718 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9719 (clobber (reg:CC FLAGS_REG))]
9720 "ix86_unary_operator_ok (NEG, SImode, operands)"
9722 [(set_attr "type" "negnot")
9723 (set_attr "mode" "SI")])
9725 ;; Combine is quite creative about this pattern.
9726 (define_insn "*negsi2_1_zext"
9727 [(set (match_operand:DI 0 "register_operand" "=r")
9728 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9731 (clobber (reg:CC FLAGS_REG))]
9732 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9734 [(set_attr "type" "negnot")
9735 (set_attr "mode" "SI")])
9737 ;; The problem with neg is that it does not perform (compare x 0),
9738 ;; it really performs (compare 0 x), which leaves us with the zero
9739 ;; flag being the only useful item.
9741 (define_insn "*negsi2_cmpz"
9742 [(set (reg:CCZ FLAGS_REG)
9743 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9745 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9746 (neg:SI (match_dup 1)))]
9747 "ix86_unary_operator_ok (NEG, SImode, operands)"
9749 [(set_attr "type" "negnot")
9750 (set_attr "mode" "SI")])
9752 (define_insn "*negsi2_cmpz_zext"
9753 [(set (reg:CCZ FLAGS_REG)
9754 (compare:CCZ (lshiftrt:DI
9756 (match_operand:DI 1 "register_operand" "0")
9760 (set (match_operand:DI 0 "register_operand" "=r")
9761 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9764 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9766 [(set_attr "type" "negnot")
9767 (set_attr "mode" "SI")])
9769 (define_expand "neghi2"
9770 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9771 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9772 (clobber (reg:CC FLAGS_REG))])]
9773 "TARGET_HIMODE_MATH"
9774 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9776 (define_insn "*neghi2_1"
9777 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9778 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9779 (clobber (reg:CC FLAGS_REG))]
9780 "ix86_unary_operator_ok (NEG, HImode, operands)"
9782 [(set_attr "type" "negnot")
9783 (set_attr "mode" "HI")])
9785 (define_insn "*neghi2_cmpz"
9786 [(set (reg:CCZ FLAGS_REG)
9787 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9789 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9790 (neg:HI (match_dup 1)))]
9791 "ix86_unary_operator_ok (NEG, HImode, operands)"
9793 [(set_attr "type" "negnot")
9794 (set_attr "mode" "HI")])
9796 (define_expand "negqi2"
9797 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9798 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9799 (clobber (reg:CC FLAGS_REG))])]
9800 "TARGET_QIMODE_MATH"
9801 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9803 (define_insn "*negqi2_1"
9804 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9805 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9806 (clobber (reg:CC FLAGS_REG))]
9807 "ix86_unary_operator_ok (NEG, QImode, operands)"
9809 [(set_attr "type" "negnot")
9810 (set_attr "mode" "QI")])
9812 (define_insn "*negqi2_cmpz"
9813 [(set (reg:CCZ FLAGS_REG)
9814 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9816 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9817 (neg:QI (match_dup 1)))]
9818 "ix86_unary_operator_ok (NEG, QImode, operands)"
9820 [(set_attr "type" "negnot")
9821 (set_attr "mode" "QI")])
9823 ;; Changing of sign for FP values is doable using integer unit too.
9825 (define_expand "negsf2"
9826 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9827 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9828 "TARGET_80387 || TARGET_SSE_MATH"
9829 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9831 (define_expand "abssf2"
9832 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9833 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9834 "TARGET_80387 || TARGET_SSE_MATH"
9835 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9837 (define_insn "*absnegsf2_mixed"
9838 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9839 (match_operator:SF 3 "absneg_operator"
9840 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9841 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9842 (clobber (reg:CC FLAGS_REG))]
9843 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9844 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9847 (define_insn "*absnegsf2_sse"
9848 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9849 (match_operator:SF 3 "absneg_operator"
9850 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9851 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9852 (clobber (reg:CC FLAGS_REG))]
9854 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9857 (define_insn "*absnegsf2_i387"
9858 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9859 (match_operator:SF 3 "absneg_operator"
9860 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9861 (use (match_operand 2 "" ""))
9862 (clobber (reg:CC FLAGS_REG))]
9863 "TARGET_80387 && !TARGET_SSE_MATH
9864 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9867 (define_expand "negdf2"
9868 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9869 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9870 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9871 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9873 (define_expand "absdf2"
9874 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9875 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9876 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9877 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9879 (define_insn "*absnegdf2_mixed"
9880 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
9881 (match_operator:DF 3 "absneg_operator"
9882 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9883 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
9884 (clobber (reg:CC FLAGS_REG))]
9885 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9886 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9889 (define_insn "*absnegdf2_sse"
9890 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
9891 (match_operator:DF 3 "absneg_operator"
9892 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
9893 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
9894 (clobber (reg:CC FLAGS_REG))]
9895 "TARGET_SSE2 && TARGET_SSE_MATH
9896 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9899 (define_insn "*absnegdf2_i387"
9900 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9901 (match_operator:DF 3 "absneg_operator"
9902 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9903 (use (match_operand 2 "" ""))
9904 (clobber (reg:CC FLAGS_REG))]
9905 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9906 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9909 (define_expand "negxf2"
9910 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9911 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9913 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9915 (define_expand "absxf2"
9916 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9917 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9919 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9921 (define_insn "*absnegxf2_i387"
9922 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9923 (match_operator:XF 3 "absneg_operator"
9924 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9925 (use (match_operand 2 "" ""))
9926 (clobber (reg:CC FLAGS_REG))]
9928 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9931 (define_expand "negtf2"
9932 [(set (match_operand:TF 0 "nonimmediate_operand" "")
9933 (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
9935 "ix86_expand_fp_absneg_operator (NEG, TFmode, operands); DONE;")
9937 (define_expand "abstf2"
9938 [(set (match_operand:TF 0 "nonimmediate_operand" "")
9939 (abs:TF (match_operand:TF 1 "nonimmediate_operand" "")))]
9941 "ix86_expand_fp_absneg_operator (ABS, TFmode, operands); DONE;")
9943 (define_insn "*absnegtf2_sse"
9944 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x,m")
9945 (match_operator:TF 3 "absneg_operator"
9946 [(match_operand:TF 1 "nonimmediate_operand" "0, x,0")]))
9947 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0,X"))
9948 (clobber (reg:CC FLAGS_REG))]
9950 && ix86_unary_operator_ok (GET_CODE (operands[3]), TFmode, operands)"
9953 ;; Splitters for fp abs and neg.
9956 [(set (match_operand 0 "fp_register_operand" "")
9957 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9958 (use (match_operand 2 "" ""))
9959 (clobber (reg:CC FLAGS_REG))]
9961 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9964 [(set (match_operand 0 "register_operand" "")
9965 (match_operator 3 "absneg_operator"
9966 [(match_operand 1 "register_operand" "")]))
9967 (use (match_operand 2 "nonimmediate_operand" ""))
9968 (clobber (reg:CC FLAGS_REG))]
9969 "reload_completed && SSE_REG_P (operands[0])"
9970 [(set (match_dup 0) (match_dup 3))]
9972 enum machine_mode mode = GET_MODE (operands[0]);
9973 enum machine_mode vmode = GET_MODE (operands[2]);
9976 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9977 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9978 if (operands_match_p (operands[0], operands[2]))
9981 operands[1] = operands[2];
9984 if (GET_CODE (operands[3]) == ABS)
9985 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9987 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9992 [(set (match_operand:SF 0 "register_operand" "")
9993 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9994 (use (match_operand:V4SF 2 "" ""))
9995 (clobber (reg:CC FLAGS_REG))]
9997 [(parallel [(set (match_dup 0) (match_dup 1))
9998 (clobber (reg:CC FLAGS_REG))])]
10001 operands[0] = gen_lowpart (SImode, operands[0]);
10002 if (GET_CODE (operands[1]) == ABS)
10004 tmp = gen_int_mode (0x7fffffff, SImode);
10005 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10009 tmp = gen_int_mode (0x80000000, SImode);
10010 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10016 [(set (match_operand:DF 0 "register_operand" "")
10017 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10018 (use (match_operand 2 "" ""))
10019 (clobber (reg:CC FLAGS_REG))]
10021 [(parallel [(set (match_dup 0) (match_dup 1))
10022 (clobber (reg:CC FLAGS_REG))])]
10027 tmp = gen_lowpart (DImode, operands[0]);
10028 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10031 if (GET_CODE (operands[1]) == ABS)
10034 tmp = gen_rtx_NOT (DImode, tmp);
10038 operands[0] = gen_highpart (SImode, operands[0]);
10039 if (GET_CODE (operands[1]) == ABS)
10041 tmp = gen_int_mode (0x7fffffff, SImode);
10042 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10046 tmp = gen_int_mode (0x80000000, SImode);
10047 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10054 [(set (match_operand:XF 0 "register_operand" "")
10055 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10056 (use (match_operand 2 "" ""))
10057 (clobber (reg:CC FLAGS_REG))]
10059 [(parallel [(set (match_dup 0) (match_dup 1))
10060 (clobber (reg:CC FLAGS_REG))])]
10063 operands[0] = gen_rtx_REG (SImode,
10064 true_regnum (operands[0])
10065 + (TARGET_64BIT ? 1 : 2));
10066 if (GET_CODE (operands[1]) == ABS)
10068 tmp = GEN_INT (0x7fff);
10069 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10073 tmp = GEN_INT (0x8000);
10074 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10080 [(set (match_operand 0 "memory_operand" "")
10081 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10082 (use (match_operand 2 "" ""))
10083 (clobber (reg:CC FLAGS_REG))]
10085 [(parallel [(set (match_dup 0) (match_dup 1))
10086 (clobber (reg:CC FLAGS_REG))])]
10088 enum machine_mode mode = GET_MODE (operands[0]);
10089 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10092 operands[0] = adjust_address (operands[0], QImode, size - 1);
10093 if (GET_CODE (operands[1]) == ABS)
10095 tmp = gen_int_mode (0x7f, QImode);
10096 tmp = gen_rtx_AND (QImode, operands[0], tmp);
10100 tmp = gen_int_mode (0x80, QImode);
10101 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10106 ;; Conditionalize these after reload. If they match before reload, we
10107 ;; lose the clobber and ability to use integer instructions.
10109 (define_insn "*negsf2_1"
10110 [(set (match_operand:SF 0 "register_operand" "=f")
10111 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10112 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10114 [(set_attr "type" "fsgn")
10115 (set_attr "mode" "SF")])
10117 (define_insn "*negdf2_1"
10118 [(set (match_operand:DF 0 "register_operand" "=f")
10119 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10120 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10122 [(set_attr "type" "fsgn")
10123 (set_attr "mode" "DF")])
10125 (define_insn "*negxf2_1"
10126 [(set (match_operand:XF 0 "register_operand" "=f")
10127 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10130 [(set_attr "type" "fsgn")
10131 (set_attr "mode" "XF")])
10133 (define_insn "*abssf2_1"
10134 [(set (match_operand:SF 0 "register_operand" "=f")
10135 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10136 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10138 [(set_attr "type" "fsgn")
10139 (set_attr "mode" "SF")])
10141 (define_insn "*absdf2_1"
10142 [(set (match_operand:DF 0 "register_operand" "=f")
10143 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10144 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10146 [(set_attr "type" "fsgn")
10147 (set_attr "mode" "DF")])
10149 (define_insn "*absxf2_1"
10150 [(set (match_operand:XF 0 "register_operand" "=f")
10151 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10154 [(set_attr "type" "fsgn")
10155 (set_attr "mode" "DF")])
10157 (define_insn "*negextendsfdf2"
10158 [(set (match_operand:DF 0 "register_operand" "=f")
10159 (neg:DF (float_extend:DF
10160 (match_operand:SF 1 "register_operand" "0"))))]
10161 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10163 [(set_attr "type" "fsgn")
10164 (set_attr "mode" "DF")])
10166 (define_insn "*negextenddfxf2"
10167 [(set (match_operand:XF 0 "register_operand" "=f")
10168 (neg:XF (float_extend:XF
10169 (match_operand:DF 1 "register_operand" "0"))))]
10172 [(set_attr "type" "fsgn")
10173 (set_attr "mode" "XF")])
10175 (define_insn "*negextendsfxf2"
10176 [(set (match_operand:XF 0 "register_operand" "=f")
10177 (neg:XF (float_extend:XF
10178 (match_operand:SF 1 "register_operand" "0"))))]
10181 [(set_attr "type" "fsgn")
10182 (set_attr "mode" "XF")])
10184 (define_insn "*absextendsfdf2"
10185 [(set (match_operand:DF 0 "register_operand" "=f")
10186 (abs:DF (float_extend:DF
10187 (match_operand:SF 1 "register_operand" "0"))))]
10188 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10190 [(set_attr "type" "fsgn")
10191 (set_attr "mode" "DF")])
10193 (define_insn "*absextenddfxf2"
10194 [(set (match_operand:XF 0 "register_operand" "=f")
10195 (abs:XF (float_extend:XF
10196 (match_operand:DF 1 "register_operand" "0"))))]
10199 [(set_attr "type" "fsgn")
10200 (set_attr "mode" "XF")])
10202 (define_insn "*absextendsfxf2"
10203 [(set (match_operand:XF 0 "register_operand" "=f")
10204 (abs:XF (float_extend:XF
10205 (match_operand:SF 1 "register_operand" "0"))))]
10208 [(set_attr "type" "fsgn")
10209 (set_attr "mode" "XF")])
10211 ;; Copysign instructions
10213 (define_mode_iterator CSGNMODE [SF DF TF])
10214 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10216 (define_expand "copysign<mode>3"
10217 [(match_operand:CSGNMODE 0 "register_operand" "")
10218 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10219 (match_operand:CSGNMODE 2 "register_operand" "")]
10220 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10221 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10223 ix86_expand_copysign (operands);
10227 (define_insn_and_split "copysign<mode>3_const"
10228 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10230 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10231 (match_operand:CSGNMODE 2 "register_operand" "0")
10232 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10234 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10235 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10237 "&& reload_completed"
10240 ix86_split_copysign_const (operands);
10244 (define_insn "copysign<mode>3_var"
10245 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10247 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10248 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10249 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10250 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10252 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10253 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10254 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10258 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10260 [(match_operand:CSGNMODE 2 "register_operand" "")
10261 (match_operand:CSGNMODE 3 "register_operand" "")
10262 (match_operand:<CSGNVMODE> 4 "" "")
10263 (match_operand:<CSGNVMODE> 5 "" "")]
10265 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10266 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10267 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10268 && reload_completed"
10271 ix86_split_copysign_var (operands);
10275 ;; One complement instructions
10277 (define_expand "one_cmpldi2"
10278 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10279 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10281 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10283 (define_insn "*one_cmpldi2_1_rex64"
10284 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10285 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10286 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10288 [(set_attr "type" "negnot")
10289 (set_attr "mode" "DI")])
10291 (define_insn "*one_cmpldi2_2_rex64"
10292 [(set (reg FLAGS_REG)
10293 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10295 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10296 (not:DI (match_dup 1)))]
10297 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10298 && ix86_unary_operator_ok (NOT, DImode, operands)"
10300 [(set_attr "type" "alu1")
10301 (set_attr "mode" "DI")])
10304 [(set (match_operand 0 "flags_reg_operand" "")
10305 (match_operator 2 "compare_operator"
10306 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10308 (set (match_operand:DI 1 "nonimmediate_operand" "")
10309 (not:DI (match_dup 3)))]
10310 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10311 [(parallel [(set (match_dup 0)
10313 [(xor:DI (match_dup 3) (const_int -1))
10316 (xor:DI (match_dup 3) (const_int -1)))])]
10319 (define_expand "one_cmplsi2"
10320 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10321 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10323 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10325 (define_insn "*one_cmplsi2_1"
10326 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10327 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10328 "ix86_unary_operator_ok (NOT, SImode, operands)"
10330 [(set_attr "type" "negnot")
10331 (set_attr "mode" "SI")])
10333 ;; ??? Currently never generated - xor is used instead.
10334 (define_insn "*one_cmplsi2_1_zext"
10335 [(set (match_operand:DI 0 "register_operand" "=r")
10336 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10337 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10339 [(set_attr "type" "negnot")
10340 (set_attr "mode" "SI")])
10342 (define_insn "*one_cmplsi2_2"
10343 [(set (reg FLAGS_REG)
10344 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10346 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10347 (not:SI (match_dup 1)))]
10348 "ix86_match_ccmode (insn, CCNOmode)
10349 && ix86_unary_operator_ok (NOT, SImode, operands)"
10351 [(set_attr "type" "alu1")
10352 (set_attr "mode" "SI")])
10355 [(set (match_operand 0 "flags_reg_operand" "")
10356 (match_operator 2 "compare_operator"
10357 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10359 (set (match_operand:SI 1 "nonimmediate_operand" "")
10360 (not:SI (match_dup 3)))]
10361 "ix86_match_ccmode (insn, CCNOmode)"
10362 [(parallel [(set (match_dup 0)
10363 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10366 (xor:SI (match_dup 3) (const_int -1)))])]
10369 ;; ??? Currently never generated - xor is used instead.
10370 (define_insn "*one_cmplsi2_2_zext"
10371 [(set (reg FLAGS_REG)
10372 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10374 (set (match_operand:DI 0 "register_operand" "=r")
10375 (zero_extend:DI (not:SI (match_dup 1))))]
10376 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10377 && ix86_unary_operator_ok (NOT, SImode, operands)"
10379 [(set_attr "type" "alu1")
10380 (set_attr "mode" "SI")])
10383 [(set (match_operand 0 "flags_reg_operand" "")
10384 (match_operator 2 "compare_operator"
10385 [(not:SI (match_operand:SI 3 "register_operand" ""))
10387 (set (match_operand:DI 1 "register_operand" "")
10388 (zero_extend:DI (not:SI (match_dup 3))))]
10389 "ix86_match_ccmode (insn, CCNOmode)"
10390 [(parallel [(set (match_dup 0)
10391 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10394 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10397 (define_expand "one_cmplhi2"
10398 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10399 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10400 "TARGET_HIMODE_MATH"
10401 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10403 (define_insn "*one_cmplhi2_1"
10404 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10405 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10406 "ix86_unary_operator_ok (NOT, HImode, operands)"
10408 [(set_attr "type" "negnot")
10409 (set_attr "mode" "HI")])
10411 (define_insn "*one_cmplhi2_2"
10412 [(set (reg FLAGS_REG)
10413 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10415 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10416 (not:HI (match_dup 1)))]
10417 "ix86_match_ccmode (insn, CCNOmode)
10418 && ix86_unary_operator_ok (NEG, HImode, operands)"
10420 [(set_attr "type" "alu1")
10421 (set_attr "mode" "HI")])
10424 [(set (match_operand 0 "flags_reg_operand" "")
10425 (match_operator 2 "compare_operator"
10426 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10428 (set (match_operand:HI 1 "nonimmediate_operand" "")
10429 (not:HI (match_dup 3)))]
10430 "ix86_match_ccmode (insn, CCNOmode)"
10431 [(parallel [(set (match_dup 0)
10432 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10435 (xor:HI (match_dup 3) (const_int -1)))])]
10438 ;; %%% Potential partial reg stall on alternative 1. What to do?
10439 (define_expand "one_cmplqi2"
10440 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10441 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10442 "TARGET_QIMODE_MATH"
10443 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10445 (define_insn "*one_cmplqi2_1"
10446 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10447 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10448 "ix86_unary_operator_ok (NOT, QImode, operands)"
10452 [(set_attr "type" "negnot")
10453 (set_attr "mode" "QI,SI")])
10455 (define_insn "*one_cmplqi2_2"
10456 [(set (reg FLAGS_REG)
10457 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10459 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10460 (not:QI (match_dup 1)))]
10461 "ix86_match_ccmode (insn, CCNOmode)
10462 && ix86_unary_operator_ok (NOT, QImode, operands)"
10464 [(set_attr "type" "alu1")
10465 (set_attr "mode" "QI")])
10468 [(set (match_operand 0 "flags_reg_operand" "")
10469 (match_operator 2 "compare_operator"
10470 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10472 (set (match_operand:QI 1 "nonimmediate_operand" "")
10473 (not:QI (match_dup 3)))]
10474 "ix86_match_ccmode (insn, CCNOmode)"
10475 [(parallel [(set (match_dup 0)
10476 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10479 (xor:QI (match_dup 3) (const_int -1)))])]
10482 ;; Arithmetic shift instructions
10484 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10485 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10486 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10487 ;; from the assembler input.
10489 ;; This instruction shifts the target reg/mem as usual, but instead of
10490 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10491 ;; is a left shift double, bits are taken from the high order bits of
10492 ;; reg, else if the insn is a shift right double, bits are taken from the
10493 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10494 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10496 ;; Since sh[lr]d does not change the `reg' operand, that is done
10497 ;; separately, making all shifts emit pairs of shift double and normal
10498 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10499 ;; support a 63 bit shift, each shift where the count is in a reg expands
10500 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10502 ;; If the shift count is a constant, we need never emit more than one
10503 ;; shift pair, instead using moves and sign extension for counts greater
10506 (define_expand "ashlti3"
10507 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10508 (ashift:TI (match_operand:TI 1 "register_operand" "")
10509 (match_operand:QI 2 "nonmemory_operand" "")))
10510 (clobber (reg:CC FLAGS_REG))])]
10513 if (! immediate_operand (operands[2], QImode))
10515 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10518 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10522 (define_insn "ashlti3_1"
10523 [(set (match_operand:TI 0 "register_operand" "=r")
10524 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10525 (match_operand:QI 2 "register_operand" "c")))
10526 (clobber (match_scratch:DI 3 "=&r"))
10527 (clobber (reg:CC FLAGS_REG))]
10530 [(set_attr "type" "multi")])
10532 ;; This pattern must be defined before *ashlti3_2 to prevent
10533 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10535 (define_insn "sse2_ashlti3"
10536 [(set (match_operand:TI 0 "register_operand" "=x")
10537 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10538 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10541 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10542 return "pslldq\t{%2, %0|%0, %2}";
10544 [(set_attr "type" "sseishft")
10545 (set_attr "prefix_data16" "1")
10546 (set_attr "mode" "TI")])
10548 (define_insn "*ashlti3_2"
10549 [(set (match_operand:TI 0 "register_operand" "=r")
10550 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10551 (match_operand:QI 2 "immediate_operand" "O")))
10552 (clobber (reg:CC FLAGS_REG))]
10555 [(set_attr "type" "multi")])
10558 [(set (match_operand:TI 0 "register_operand" "")
10559 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10560 (match_operand:QI 2 "register_operand" "")))
10561 (clobber (match_scratch:DI 3 ""))
10562 (clobber (reg:CC FLAGS_REG))]
10563 "TARGET_64BIT && reload_completed"
10565 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10568 [(set (match_operand:TI 0 "register_operand" "")
10569 (ashift:TI (match_operand:TI 1 "register_operand" "")
10570 (match_operand:QI 2 "immediate_operand" "")))
10571 (clobber (reg:CC FLAGS_REG))]
10572 "TARGET_64BIT && reload_completed"
10574 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10576 (define_insn "x86_64_shld"
10577 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10578 (ior:DI (ashift:DI (match_dup 0)
10579 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10580 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10581 (minus:QI (const_int 64) (match_dup 2)))))
10582 (clobber (reg:CC FLAGS_REG))]
10585 shld{q}\t{%2, %1, %0|%0, %1, %2}
10586 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10587 [(set_attr "type" "ishift")
10588 (set_attr "prefix_0f" "1")
10589 (set_attr "mode" "DI")
10590 (set_attr "athlon_decode" "vector")
10591 (set_attr "amdfam10_decode" "vector")])
10593 (define_expand "x86_64_shift_adj"
10594 [(set (reg:CCZ FLAGS_REG)
10595 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10598 (set (match_operand:DI 0 "register_operand" "")
10599 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10600 (match_operand:DI 1 "register_operand" "")
10603 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10604 (match_operand:DI 3 "register_operand" "r")
10609 (define_expand "ashldi3"
10610 [(set (match_operand:DI 0 "shiftdi_operand" "")
10611 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10612 (match_operand:QI 2 "nonmemory_operand" "")))]
10614 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10616 (define_insn "*ashldi3_1_rex64"
10617 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10618 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10619 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10620 (clobber (reg:CC FLAGS_REG))]
10621 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10623 switch (get_attr_type (insn))
10626 gcc_assert (operands[2] == const1_rtx);
10627 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10628 return "add{q}\t%0, %0";
10631 gcc_assert (CONST_INT_P (operands[2]));
10632 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10633 operands[1] = gen_rtx_MULT (DImode, operands[1],
10634 GEN_INT (1 << INTVAL (operands[2])));
10635 return "lea{q}\t{%a1, %0|%0, %a1}";
10638 if (REG_P (operands[2]))
10639 return "sal{q}\t{%b2, %0|%0, %b2}";
10640 else if (operands[2] == const1_rtx
10641 && (TARGET_SHIFT1 || optimize_size))
10642 return "sal{q}\t%0";
10644 return "sal{q}\t{%2, %0|%0, %2}";
10647 [(set (attr "type")
10648 (cond [(eq_attr "alternative" "1")
10649 (const_string "lea")
10650 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10652 (match_operand 0 "register_operand" ""))
10653 (match_operand 2 "const1_operand" ""))
10654 (const_string "alu")
10656 (const_string "ishift")))
10657 (set_attr "mode" "DI")])
10659 ;; Convert lea to the lea pattern to avoid flags dependency.
10661 [(set (match_operand:DI 0 "register_operand" "")
10662 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10663 (match_operand:QI 2 "immediate_operand" "")))
10664 (clobber (reg:CC FLAGS_REG))]
10665 "TARGET_64BIT && reload_completed
10666 && true_regnum (operands[0]) != true_regnum (operands[1])"
10667 [(set (match_dup 0)
10668 (mult:DI (match_dup 1)
10670 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10672 ;; This pattern can't accept a variable shift count, since shifts by
10673 ;; zero don't affect the flags. We assume that shifts by constant
10674 ;; zero are optimized away.
10675 (define_insn "*ashldi3_cmp_rex64"
10676 [(set (reg FLAGS_REG)
10678 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10679 (match_operand:QI 2 "immediate_operand" "e"))
10681 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10682 (ashift:DI (match_dup 1) (match_dup 2)))]
10685 || !TARGET_PARTIAL_FLAG_REG_STALL
10686 || (operands[2] == const1_rtx
10688 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10689 && ix86_match_ccmode (insn, CCGOCmode)
10690 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10692 switch (get_attr_type (insn))
10695 gcc_assert (operands[2] == const1_rtx);
10696 return "add{q}\t%0, %0";
10699 if (REG_P (operands[2]))
10700 return "sal{q}\t{%b2, %0|%0, %b2}";
10701 else if (operands[2] == const1_rtx
10702 && (TARGET_SHIFT1 || optimize_size))
10703 return "sal{q}\t%0";
10705 return "sal{q}\t{%2, %0|%0, %2}";
10708 [(set (attr "type")
10709 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10711 (match_operand 0 "register_operand" ""))
10712 (match_operand 2 "const1_operand" ""))
10713 (const_string "alu")
10715 (const_string "ishift")))
10716 (set_attr "mode" "DI")])
10718 (define_insn "*ashldi3_cconly_rex64"
10719 [(set (reg FLAGS_REG)
10721 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10722 (match_operand:QI 2 "immediate_operand" "e"))
10724 (clobber (match_scratch:DI 0 "=r"))]
10727 || !TARGET_PARTIAL_FLAG_REG_STALL
10728 || (operands[2] == const1_rtx
10730 || TARGET_DOUBLE_WITH_ADD)))
10731 && ix86_match_ccmode (insn, CCGOCmode)
10732 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10734 switch (get_attr_type (insn))
10737 gcc_assert (operands[2] == const1_rtx);
10738 return "add{q}\t%0, %0";
10741 if (REG_P (operands[2]))
10742 return "sal{q}\t{%b2, %0|%0, %b2}";
10743 else if (operands[2] == const1_rtx
10744 && (TARGET_SHIFT1 || optimize_size))
10745 return "sal{q}\t%0";
10747 return "sal{q}\t{%2, %0|%0, %2}";
10750 [(set (attr "type")
10751 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10753 (match_operand 0 "register_operand" ""))
10754 (match_operand 2 "const1_operand" ""))
10755 (const_string "alu")
10757 (const_string "ishift")))
10758 (set_attr "mode" "DI")])
10760 (define_insn "*ashldi3_1"
10761 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10762 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10763 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10764 (clobber (reg:CC FLAGS_REG))]
10767 [(set_attr "type" "multi")])
10769 ;; By default we don't ask for a scratch register, because when DImode
10770 ;; values are manipulated, registers are already at a premium. But if
10771 ;; we have one handy, we won't turn it away.
10773 [(match_scratch:SI 3 "r")
10774 (parallel [(set (match_operand:DI 0 "register_operand" "")
10775 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10776 (match_operand:QI 2 "nonmemory_operand" "")))
10777 (clobber (reg:CC FLAGS_REG))])
10779 "!TARGET_64BIT && TARGET_CMOVE"
10781 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10784 [(set (match_operand:DI 0 "register_operand" "")
10785 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10786 (match_operand:QI 2 "nonmemory_operand" "")))
10787 (clobber (reg:CC FLAGS_REG))]
10788 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10789 ? epilogue_completed : reload_completed)"
10791 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10793 (define_insn "x86_shld_1"
10794 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10795 (ior:SI (ashift:SI (match_dup 0)
10796 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10797 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10798 (minus:QI (const_int 32) (match_dup 2)))))
10799 (clobber (reg:CC FLAGS_REG))]
10802 shld{l}\t{%2, %1, %0|%0, %1, %2}
10803 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10804 [(set_attr "type" "ishift")
10805 (set_attr "prefix_0f" "1")
10806 (set_attr "mode" "SI")
10807 (set_attr "pent_pair" "np")
10808 (set_attr "athlon_decode" "vector")
10809 (set_attr "amdfam10_decode" "vector")])
10811 (define_expand "x86_shift_adj_1"
10812 [(set (reg:CCZ FLAGS_REG)
10813 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10816 (set (match_operand:SI 0 "register_operand" "")
10817 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10818 (match_operand:SI 1 "register_operand" "")
10821 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10822 (match_operand:SI 3 "register_operand" "r")
10827 (define_expand "x86_shift_adj_2"
10828 [(use (match_operand:SI 0 "register_operand" ""))
10829 (use (match_operand:SI 1 "register_operand" ""))
10830 (use (match_operand:QI 2 "register_operand" ""))]
10833 rtx label = gen_label_rtx ();
10836 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10838 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10839 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10840 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10841 gen_rtx_LABEL_REF (VOIDmode, label),
10843 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10844 JUMP_LABEL (tmp) = label;
10846 emit_move_insn (operands[0], operands[1]);
10847 ix86_expand_clear (operands[1]);
10849 emit_label (label);
10850 LABEL_NUSES (label) = 1;
10855 (define_expand "ashlsi3"
10856 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10857 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10858 (match_operand:QI 2 "nonmemory_operand" "")))
10859 (clobber (reg:CC FLAGS_REG))]
10861 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10863 (define_insn "*ashlsi3_1"
10864 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10865 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10866 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10867 (clobber (reg:CC FLAGS_REG))]
10868 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10870 switch (get_attr_type (insn))
10873 gcc_assert (operands[2] == const1_rtx);
10874 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10875 return "add{l}\t%0, %0";
10881 if (REG_P (operands[2]))
10882 return "sal{l}\t{%b2, %0|%0, %b2}";
10883 else if (operands[2] == const1_rtx
10884 && (TARGET_SHIFT1 || optimize_size))
10885 return "sal{l}\t%0";
10887 return "sal{l}\t{%2, %0|%0, %2}";
10890 [(set (attr "type")
10891 (cond [(eq_attr "alternative" "1")
10892 (const_string "lea")
10893 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10895 (match_operand 0 "register_operand" ""))
10896 (match_operand 2 "const1_operand" ""))
10897 (const_string "alu")
10899 (const_string "ishift")))
10900 (set_attr "mode" "SI")])
10902 ;; Convert lea to the lea pattern to avoid flags dependency.
10904 [(set (match_operand 0 "register_operand" "")
10905 (ashift (match_operand 1 "index_register_operand" "")
10906 (match_operand:QI 2 "const_int_operand" "")))
10907 (clobber (reg:CC FLAGS_REG))]
10909 && true_regnum (operands[0]) != true_regnum (operands[1])
10910 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10914 enum machine_mode mode = GET_MODE (operands[0]);
10916 if (GET_MODE_SIZE (mode) < 4)
10917 operands[0] = gen_lowpart (SImode, operands[0]);
10919 operands[1] = gen_lowpart (Pmode, operands[1]);
10920 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10922 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10923 if (Pmode != SImode)
10924 pat = gen_rtx_SUBREG (SImode, pat, 0);
10925 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10929 ;; Rare case of shifting RSP is handled by generating move and shift
10931 [(set (match_operand 0 "register_operand" "")
10932 (ashift (match_operand 1 "register_operand" "")
10933 (match_operand:QI 2 "const_int_operand" "")))
10934 (clobber (reg:CC FLAGS_REG))]
10936 && true_regnum (operands[0]) != true_regnum (operands[1])"
10940 emit_move_insn (operands[0], operands[1]);
10941 pat = gen_rtx_SET (VOIDmode, operands[0],
10942 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10943 operands[0], operands[2]));
10944 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10945 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10949 (define_insn "*ashlsi3_1_zext"
10950 [(set (match_operand:DI 0 "register_operand" "=r,r")
10951 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10952 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10953 (clobber (reg:CC FLAGS_REG))]
10954 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10956 switch (get_attr_type (insn))
10959 gcc_assert (operands[2] == const1_rtx);
10960 return "add{l}\t%k0, %k0";
10966 if (REG_P (operands[2]))
10967 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10968 else if (operands[2] == const1_rtx
10969 && (TARGET_SHIFT1 || optimize_size))
10970 return "sal{l}\t%k0";
10972 return "sal{l}\t{%2, %k0|%k0, %2}";
10975 [(set (attr "type")
10976 (cond [(eq_attr "alternative" "1")
10977 (const_string "lea")
10978 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980 (match_operand 2 "const1_operand" ""))
10981 (const_string "alu")
10983 (const_string "ishift")))
10984 (set_attr "mode" "SI")])
10986 ;; Convert lea to the lea pattern to avoid flags dependency.
10988 [(set (match_operand:DI 0 "register_operand" "")
10989 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10990 (match_operand:QI 2 "const_int_operand" ""))))
10991 (clobber (reg:CC FLAGS_REG))]
10992 "TARGET_64BIT && reload_completed
10993 && true_regnum (operands[0]) != true_regnum (operands[1])"
10994 [(set (match_dup 0) (zero_extend:DI
10995 (subreg:SI (mult:SI (match_dup 1)
10996 (match_dup 2)) 0)))]
10998 operands[1] = gen_lowpart (Pmode, operands[1]);
10999 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11002 ;; This pattern can't accept a variable shift count, since shifts by
11003 ;; zero don't affect the flags. We assume that shifts by constant
11004 ;; zero are optimized away.
11005 (define_insn "*ashlsi3_cmp"
11006 [(set (reg FLAGS_REG)
11008 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11009 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11011 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11012 (ashift:SI (match_dup 1) (match_dup 2)))]
11014 || !TARGET_PARTIAL_FLAG_REG_STALL
11015 || (operands[2] == const1_rtx
11017 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11018 && ix86_match_ccmode (insn, CCGOCmode)
11019 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11021 switch (get_attr_type (insn))
11024 gcc_assert (operands[2] == const1_rtx);
11025 return "add{l}\t%0, %0";
11028 if (REG_P (operands[2]))
11029 return "sal{l}\t{%b2, %0|%0, %b2}";
11030 else if (operands[2] == const1_rtx
11031 && (TARGET_SHIFT1 || optimize_size))
11032 return "sal{l}\t%0";
11034 return "sal{l}\t{%2, %0|%0, %2}";
11037 [(set (attr "type")
11038 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11040 (match_operand 0 "register_operand" ""))
11041 (match_operand 2 "const1_operand" ""))
11042 (const_string "alu")
11044 (const_string "ishift")))
11045 (set_attr "mode" "SI")])
11047 (define_insn "*ashlsi3_cconly"
11048 [(set (reg FLAGS_REG)
11050 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11051 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11053 (clobber (match_scratch:SI 0 "=r"))]
11055 || !TARGET_PARTIAL_FLAG_REG_STALL
11056 || (operands[2] == const1_rtx
11058 || TARGET_DOUBLE_WITH_ADD)))
11059 && ix86_match_ccmode (insn, CCGOCmode)
11060 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11062 switch (get_attr_type (insn))
11065 gcc_assert (operands[2] == const1_rtx);
11066 return "add{l}\t%0, %0";
11069 if (REG_P (operands[2]))
11070 return "sal{l}\t{%b2, %0|%0, %b2}";
11071 else if (operands[2] == const1_rtx
11072 && (TARGET_SHIFT1 || optimize_size))
11073 return "sal{l}\t%0";
11075 return "sal{l}\t{%2, %0|%0, %2}";
11078 [(set (attr "type")
11079 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11081 (match_operand 0 "register_operand" ""))
11082 (match_operand 2 "const1_operand" ""))
11083 (const_string "alu")
11085 (const_string "ishift")))
11086 (set_attr "mode" "SI")])
11088 (define_insn "*ashlsi3_cmp_zext"
11089 [(set (reg FLAGS_REG)
11091 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11092 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11094 (set (match_operand:DI 0 "register_operand" "=r")
11095 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11098 || !TARGET_PARTIAL_FLAG_REG_STALL
11099 || (operands[2] == const1_rtx
11101 || TARGET_DOUBLE_WITH_ADD)))
11102 && ix86_match_ccmode (insn, CCGOCmode)
11103 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11105 switch (get_attr_type (insn))
11108 gcc_assert (operands[2] == const1_rtx);
11109 return "add{l}\t%k0, %k0";
11112 if (REG_P (operands[2]))
11113 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11114 else if (operands[2] == const1_rtx
11115 && (TARGET_SHIFT1 || optimize_size))
11116 return "sal{l}\t%k0";
11118 return "sal{l}\t{%2, %k0|%k0, %2}";
11121 [(set (attr "type")
11122 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11124 (match_operand 2 "const1_operand" ""))
11125 (const_string "alu")
11127 (const_string "ishift")))
11128 (set_attr "mode" "SI")])
11130 (define_expand "ashlhi3"
11131 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11132 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11133 (match_operand:QI 2 "nonmemory_operand" "")))
11134 (clobber (reg:CC FLAGS_REG))]
11135 "TARGET_HIMODE_MATH"
11136 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11138 (define_insn "*ashlhi3_1_lea"
11139 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11140 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11141 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11142 (clobber (reg:CC FLAGS_REG))]
11143 "!TARGET_PARTIAL_REG_STALL
11144 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11146 switch (get_attr_type (insn))
11151 gcc_assert (operands[2] == const1_rtx);
11152 return "add{w}\t%0, %0";
11155 if (REG_P (operands[2]))
11156 return "sal{w}\t{%b2, %0|%0, %b2}";
11157 else if (operands[2] == const1_rtx
11158 && (TARGET_SHIFT1 || optimize_size))
11159 return "sal{w}\t%0";
11161 return "sal{w}\t{%2, %0|%0, %2}";
11164 [(set (attr "type")
11165 (cond [(eq_attr "alternative" "1")
11166 (const_string "lea")
11167 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11169 (match_operand 0 "register_operand" ""))
11170 (match_operand 2 "const1_operand" ""))
11171 (const_string "alu")
11173 (const_string "ishift")))
11174 (set_attr "mode" "HI,SI")])
11176 (define_insn "*ashlhi3_1"
11177 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11178 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11179 (match_operand:QI 2 "nonmemory_operand" "cI")))
11180 (clobber (reg:CC FLAGS_REG))]
11181 "TARGET_PARTIAL_REG_STALL
11182 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11184 switch (get_attr_type (insn))
11187 gcc_assert (operands[2] == const1_rtx);
11188 return "add{w}\t%0, %0";
11191 if (REG_P (operands[2]))
11192 return "sal{w}\t{%b2, %0|%0, %b2}";
11193 else if (operands[2] == const1_rtx
11194 && (TARGET_SHIFT1 || optimize_size))
11195 return "sal{w}\t%0";
11197 return "sal{w}\t{%2, %0|%0, %2}";
11200 [(set (attr "type")
11201 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11203 (match_operand 0 "register_operand" ""))
11204 (match_operand 2 "const1_operand" ""))
11205 (const_string "alu")
11207 (const_string "ishift")))
11208 (set_attr "mode" "HI")])
11210 ;; This pattern can't accept a variable shift count, since shifts by
11211 ;; zero don't affect the flags. We assume that shifts by constant
11212 ;; zero are optimized away.
11213 (define_insn "*ashlhi3_cmp"
11214 [(set (reg FLAGS_REG)
11216 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11217 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11219 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11220 (ashift:HI (match_dup 1) (match_dup 2)))]
11222 || !TARGET_PARTIAL_FLAG_REG_STALL
11223 || (operands[2] == const1_rtx
11225 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11226 && ix86_match_ccmode (insn, CCGOCmode)
11227 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11229 switch (get_attr_type (insn))
11232 gcc_assert (operands[2] == const1_rtx);
11233 return "add{w}\t%0, %0";
11236 if (REG_P (operands[2]))
11237 return "sal{w}\t{%b2, %0|%0, %b2}";
11238 else if (operands[2] == const1_rtx
11239 && (TARGET_SHIFT1 || optimize_size))
11240 return "sal{w}\t%0";
11242 return "sal{w}\t{%2, %0|%0, %2}";
11245 [(set (attr "type")
11246 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11248 (match_operand 0 "register_operand" ""))
11249 (match_operand 2 "const1_operand" ""))
11250 (const_string "alu")
11252 (const_string "ishift")))
11253 (set_attr "mode" "HI")])
11255 (define_insn "*ashlhi3_cconly"
11256 [(set (reg FLAGS_REG)
11258 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11259 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11261 (clobber (match_scratch:HI 0 "=r"))]
11263 || !TARGET_PARTIAL_FLAG_REG_STALL
11264 || (operands[2] == const1_rtx
11266 || TARGET_DOUBLE_WITH_ADD)))
11267 && ix86_match_ccmode (insn, CCGOCmode)
11268 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11270 switch (get_attr_type (insn))
11273 gcc_assert (operands[2] == const1_rtx);
11274 return "add{w}\t%0, %0";
11277 if (REG_P (operands[2]))
11278 return "sal{w}\t{%b2, %0|%0, %b2}";
11279 else if (operands[2] == const1_rtx
11280 && (TARGET_SHIFT1 || optimize_size))
11281 return "sal{w}\t%0";
11283 return "sal{w}\t{%2, %0|%0, %2}";
11286 [(set (attr "type")
11287 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11289 (match_operand 0 "register_operand" ""))
11290 (match_operand 2 "const1_operand" ""))
11291 (const_string "alu")
11293 (const_string "ishift")))
11294 (set_attr "mode" "HI")])
11296 (define_expand "ashlqi3"
11297 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11298 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11299 (match_operand:QI 2 "nonmemory_operand" "")))
11300 (clobber (reg:CC FLAGS_REG))]
11301 "TARGET_QIMODE_MATH"
11302 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11304 ;; %%% Potential partial reg stall on alternative 2. What to do?
11306 (define_insn "*ashlqi3_1_lea"
11307 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11308 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11309 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11310 (clobber (reg:CC FLAGS_REG))]
11311 "!TARGET_PARTIAL_REG_STALL
11312 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11314 switch (get_attr_type (insn))
11319 gcc_assert (operands[2] == const1_rtx);
11320 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11321 return "add{l}\t%k0, %k0";
11323 return "add{b}\t%0, %0";
11326 if (REG_P (operands[2]))
11328 if (get_attr_mode (insn) == MODE_SI)
11329 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11331 return "sal{b}\t{%b2, %0|%0, %b2}";
11333 else if (operands[2] == const1_rtx
11334 && (TARGET_SHIFT1 || optimize_size))
11336 if (get_attr_mode (insn) == MODE_SI)
11337 return "sal{l}\t%0";
11339 return "sal{b}\t%0";
11343 if (get_attr_mode (insn) == MODE_SI)
11344 return "sal{l}\t{%2, %k0|%k0, %2}";
11346 return "sal{b}\t{%2, %0|%0, %2}";
11350 [(set (attr "type")
11351 (cond [(eq_attr "alternative" "2")
11352 (const_string "lea")
11353 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11355 (match_operand 0 "register_operand" ""))
11356 (match_operand 2 "const1_operand" ""))
11357 (const_string "alu")
11359 (const_string "ishift")))
11360 (set_attr "mode" "QI,SI,SI")])
11362 (define_insn "*ashlqi3_1"
11363 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11364 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11365 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11366 (clobber (reg:CC FLAGS_REG))]
11367 "TARGET_PARTIAL_REG_STALL
11368 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11370 switch (get_attr_type (insn))
11373 gcc_assert (operands[2] == const1_rtx);
11374 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11375 return "add{l}\t%k0, %k0";
11377 return "add{b}\t%0, %0";
11380 if (REG_P (operands[2]))
11382 if (get_attr_mode (insn) == MODE_SI)
11383 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11385 return "sal{b}\t{%b2, %0|%0, %b2}";
11387 else if (operands[2] == const1_rtx
11388 && (TARGET_SHIFT1 || optimize_size))
11390 if (get_attr_mode (insn) == MODE_SI)
11391 return "sal{l}\t%0";
11393 return "sal{b}\t%0";
11397 if (get_attr_mode (insn) == MODE_SI)
11398 return "sal{l}\t{%2, %k0|%k0, %2}";
11400 return "sal{b}\t{%2, %0|%0, %2}";
11404 [(set (attr "type")
11405 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11407 (match_operand 0 "register_operand" ""))
11408 (match_operand 2 "const1_operand" ""))
11409 (const_string "alu")
11411 (const_string "ishift")))
11412 (set_attr "mode" "QI,SI")])
11414 ;; This pattern can't accept a variable shift count, since shifts by
11415 ;; zero don't affect the flags. We assume that shifts by constant
11416 ;; zero are optimized away.
11417 (define_insn "*ashlqi3_cmp"
11418 [(set (reg FLAGS_REG)
11420 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11421 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11423 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11424 (ashift:QI (match_dup 1) (match_dup 2)))]
11426 || !TARGET_PARTIAL_FLAG_REG_STALL
11427 || (operands[2] == const1_rtx
11429 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11430 && ix86_match_ccmode (insn, CCGOCmode)
11431 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11433 switch (get_attr_type (insn))
11436 gcc_assert (operands[2] == const1_rtx);
11437 return "add{b}\t%0, %0";
11440 if (REG_P (operands[2]))
11441 return "sal{b}\t{%b2, %0|%0, %b2}";
11442 else if (operands[2] == const1_rtx
11443 && (TARGET_SHIFT1 || optimize_size))
11444 return "sal{b}\t%0";
11446 return "sal{b}\t{%2, %0|%0, %2}";
11449 [(set (attr "type")
11450 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11452 (match_operand 0 "register_operand" ""))
11453 (match_operand 2 "const1_operand" ""))
11454 (const_string "alu")
11456 (const_string "ishift")))
11457 (set_attr "mode" "QI")])
11459 (define_insn "*ashlqi3_cconly"
11460 [(set (reg FLAGS_REG)
11462 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11463 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11465 (clobber (match_scratch:QI 0 "=q"))]
11467 || !TARGET_PARTIAL_FLAG_REG_STALL
11468 || (operands[2] == const1_rtx
11470 || TARGET_DOUBLE_WITH_ADD)))
11471 && ix86_match_ccmode (insn, CCGOCmode)
11472 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11474 switch (get_attr_type (insn))
11477 gcc_assert (operands[2] == const1_rtx);
11478 return "add{b}\t%0, %0";
11481 if (REG_P (operands[2]))
11482 return "sal{b}\t{%b2, %0|%0, %b2}";
11483 else if (operands[2] == const1_rtx
11484 && (TARGET_SHIFT1 || optimize_size))
11485 return "sal{b}\t%0";
11487 return "sal{b}\t{%2, %0|%0, %2}";
11490 [(set (attr "type")
11491 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11493 (match_operand 0 "register_operand" ""))
11494 (match_operand 2 "const1_operand" ""))
11495 (const_string "alu")
11497 (const_string "ishift")))
11498 (set_attr "mode" "QI")])
11500 ;; See comment above `ashldi3' about how this works.
11502 (define_expand "ashrti3"
11503 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11504 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11505 (match_operand:QI 2 "nonmemory_operand" "")))
11506 (clobber (reg:CC FLAGS_REG))])]
11509 if (! immediate_operand (operands[2], QImode))
11511 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11514 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11518 (define_insn "ashrti3_1"
11519 [(set (match_operand:TI 0 "register_operand" "=r")
11520 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11521 (match_operand:QI 2 "register_operand" "c")))
11522 (clobber (match_scratch:DI 3 "=&r"))
11523 (clobber (reg:CC FLAGS_REG))]
11526 [(set_attr "type" "multi")])
11528 (define_insn "*ashrti3_2"
11529 [(set (match_operand:TI 0 "register_operand" "=r")
11530 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11531 (match_operand:QI 2 "immediate_operand" "O")))
11532 (clobber (reg:CC FLAGS_REG))]
11535 [(set_attr "type" "multi")])
11538 [(set (match_operand:TI 0 "register_operand" "")
11539 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11540 (match_operand:QI 2 "register_operand" "")))
11541 (clobber (match_scratch:DI 3 ""))
11542 (clobber (reg:CC FLAGS_REG))]
11543 "TARGET_64BIT && reload_completed"
11545 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11548 [(set (match_operand:TI 0 "register_operand" "")
11549 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11550 (match_operand:QI 2 "immediate_operand" "")))
11551 (clobber (reg:CC FLAGS_REG))]
11552 "TARGET_64BIT && reload_completed"
11554 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11556 (define_insn "x86_64_shrd"
11557 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11558 (ior:DI (ashiftrt:DI (match_dup 0)
11559 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11560 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11561 (minus:QI (const_int 64) (match_dup 2)))))
11562 (clobber (reg:CC FLAGS_REG))]
11565 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11566 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11567 [(set_attr "type" "ishift")
11568 (set_attr "prefix_0f" "1")
11569 (set_attr "mode" "DI")
11570 (set_attr "athlon_decode" "vector")
11571 (set_attr "amdfam10_decode" "vector")])
11573 (define_expand "ashrdi3"
11574 [(set (match_operand:DI 0 "shiftdi_operand" "")
11575 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11576 (match_operand:QI 2 "nonmemory_operand" "")))]
11578 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11580 (define_insn "*ashrdi3_63_rex64"
11581 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11582 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11583 (match_operand:DI 2 "const_int_operand" "i,i")))
11584 (clobber (reg:CC FLAGS_REG))]
11585 "TARGET_64BIT && INTVAL (operands[2]) == 63
11586 && (TARGET_USE_CLTD || optimize_size)
11587 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11590 sar{q}\t{%2, %0|%0, %2}"
11591 [(set_attr "type" "imovx,ishift")
11592 (set_attr "prefix_0f" "0,*")
11593 (set_attr "length_immediate" "0,*")
11594 (set_attr "modrm" "0,1")
11595 (set_attr "mode" "DI")])
11597 (define_insn "*ashrdi3_1_one_bit_rex64"
11598 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11599 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11600 (match_operand:QI 2 "const1_operand" "")))
11601 (clobber (reg:CC FLAGS_REG))]
11603 && (TARGET_SHIFT1 || optimize_size)
11604 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11606 [(set_attr "type" "ishift")
11607 (set (attr "length")
11608 (if_then_else (match_operand:DI 0 "register_operand" "")
11610 (const_string "*")))])
11612 (define_insn "*ashrdi3_1_rex64"
11613 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11614 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11615 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11616 (clobber (reg:CC FLAGS_REG))]
11617 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11619 sar{q}\t{%2, %0|%0, %2}
11620 sar{q}\t{%b2, %0|%0, %b2}"
11621 [(set_attr "type" "ishift")
11622 (set_attr "mode" "DI")])
11624 ;; This pattern can't accept a variable shift count, since shifts by
11625 ;; zero don't affect the flags. We assume that shifts by constant
11626 ;; zero are optimized away.
11627 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11628 [(set (reg FLAGS_REG)
11630 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11631 (match_operand:QI 2 "const1_operand" ""))
11633 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11634 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11636 && (TARGET_SHIFT1 || optimize_size)
11637 && ix86_match_ccmode (insn, CCGOCmode)
11638 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11640 [(set_attr "type" "ishift")
11641 (set (attr "length")
11642 (if_then_else (match_operand:DI 0 "register_operand" "")
11644 (const_string "*")))])
11646 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11647 [(set (reg FLAGS_REG)
11649 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11650 (match_operand:QI 2 "const1_operand" ""))
11652 (clobber (match_scratch:DI 0 "=r"))]
11654 && (TARGET_SHIFT1 || optimize_size)
11655 && ix86_match_ccmode (insn, CCGOCmode)
11656 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11658 [(set_attr "type" "ishift")
11659 (set_attr "length" "2")])
11661 ;; This pattern can't accept a variable shift count, since shifts by
11662 ;; zero don't affect the flags. We assume that shifts by constant
11663 ;; zero are optimized away.
11664 (define_insn "*ashrdi3_cmp_rex64"
11665 [(set (reg FLAGS_REG)
11667 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11668 (match_operand:QI 2 "const_int_operand" "n"))
11670 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11671 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11673 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11674 && ix86_match_ccmode (insn, CCGOCmode)
11675 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11676 "sar{q}\t{%2, %0|%0, %2}"
11677 [(set_attr "type" "ishift")
11678 (set_attr "mode" "DI")])
11680 (define_insn "*ashrdi3_cconly_rex64"
11681 [(set (reg FLAGS_REG)
11683 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11684 (match_operand:QI 2 "const_int_operand" "n"))
11686 (clobber (match_scratch:DI 0 "=r"))]
11688 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11689 && ix86_match_ccmode (insn, CCGOCmode)
11690 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11691 "sar{q}\t{%2, %0|%0, %2}"
11692 [(set_attr "type" "ishift")
11693 (set_attr "mode" "DI")])
11695 (define_insn "*ashrdi3_1"
11696 [(set (match_operand:DI 0 "register_operand" "=r")
11697 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11698 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11699 (clobber (reg:CC FLAGS_REG))]
11702 [(set_attr "type" "multi")])
11704 ;; By default we don't ask for a scratch register, because when DImode
11705 ;; values are manipulated, registers are already at a premium. But if
11706 ;; we have one handy, we won't turn it away.
11708 [(match_scratch:SI 3 "r")
11709 (parallel [(set (match_operand:DI 0 "register_operand" "")
11710 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11711 (match_operand:QI 2 "nonmemory_operand" "")))
11712 (clobber (reg:CC FLAGS_REG))])
11714 "!TARGET_64BIT && TARGET_CMOVE"
11716 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11719 [(set (match_operand:DI 0 "register_operand" "")
11720 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11721 (match_operand:QI 2 "nonmemory_operand" "")))
11722 (clobber (reg:CC FLAGS_REG))]
11723 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11724 ? epilogue_completed : reload_completed)"
11726 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11728 (define_insn "x86_shrd_1"
11729 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11730 (ior:SI (ashiftrt:SI (match_dup 0)
11731 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11732 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11733 (minus:QI (const_int 32) (match_dup 2)))))
11734 (clobber (reg:CC FLAGS_REG))]
11737 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11738 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11739 [(set_attr "type" "ishift")
11740 (set_attr "prefix_0f" "1")
11741 (set_attr "pent_pair" "np")
11742 (set_attr "mode" "SI")])
11744 (define_expand "x86_shift_adj_3"
11745 [(use (match_operand:SI 0 "register_operand" ""))
11746 (use (match_operand:SI 1 "register_operand" ""))
11747 (use (match_operand:QI 2 "register_operand" ""))]
11750 rtx label = gen_label_rtx ();
11753 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11755 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11756 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11757 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11758 gen_rtx_LABEL_REF (VOIDmode, label),
11760 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11761 JUMP_LABEL (tmp) = label;
11763 emit_move_insn (operands[0], operands[1]);
11764 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11766 emit_label (label);
11767 LABEL_NUSES (label) = 1;
11772 (define_insn "ashrsi3_31"
11773 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11774 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11775 (match_operand:SI 2 "const_int_operand" "i,i")))
11776 (clobber (reg:CC FLAGS_REG))]
11777 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11778 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11781 sar{l}\t{%2, %0|%0, %2}"
11782 [(set_attr "type" "imovx,ishift")
11783 (set_attr "prefix_0f" "0,*")
11784 (set_attr "length_immediate" "0,*")
11785 (set_attr "modrm" "0,1")
11786 (set_attr "mode" "SI")])
11788 (define_insn "*ashrsi3_31_zext"
11789 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11790 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11791 (match_operand:SI 2 "const_int_operand" "i,i"))))
11792 (clobber (reg:CC FLAGS_REG))]
11793 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11794 && INTVAL (operands[2]) == 31
11795 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11798 sar{l}\t{%2, %k0|%k0, %2}"
11799 [(set_attr "type" "imovx,ishift")
11800 (set_attr "prefix_0f" "0,*")
11801 (set_attr "length_immediate" "0,*")
11802 (set_attr "modrm" "0,1")
11803 (set_attr "mode" "SI")])
11805 (define_expand "ashrsi3"
11806 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11807 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11808 (match_operand:QI 2 "nonmemory_operand" "")))
11809 (clobber (reg:CC FLAGS_REG))]
11811 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11813 (define_insn "*ashrsi3_1_one_bit"
11814 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11815 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11816 (match_operand:QI 2 "const1_operand" "")))
11817 (clobber (reg:CC FLAGS_REG))]
11818 "(TARGET_SHIFT1 || optimize_size)
11819 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11821 [(set_attr "type" "ishift")
11822 (set (attr "length")
11823 (if_then_else (match_operand:SI 0 "register_operand" "")
11825 (const_string "*")))])
11827 (define_insn "*ashrsi3_1_one_bit_zext"
11828 [(set (match_operand:DI 0 "register_operand" "=r")
11829 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11830 (match_operand:QI 2 "const1_operand" ""))))
11831 (clobber (reg:CC FLAGS_REG))]
11833 && (TARGET_SHIFT1 || optimize_size)
11834 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11836 [(set_attr "type" "ishift")
11837 (set_attr "length" "2")])
11839 (define_insn "*ashrsi3_1"
11840 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11841 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11842 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11843 (clobber (reg:CC FLAGS_REG))]
11844 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11846 sar{l}\t{%2, %0|%0, %2}
11847 sar{l}\t{%b2, %0|%0, %b2}"
11848 [(set_attr "type" "ishift")
11849 (set_attr "mode" "SI")])
11851 (define_insn "*ashrsi3_1_zext"
11852 [(set (match_operand:DI 0 "register_operand" "=r,r")
11853 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11854 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11855 (clobber (reg:CC FLAGS_REG))]
11856 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11858 sar{l}\t{%2, %k0|%k0, %2}
11859 sar{l}\t{%b2, %k0|%k0, %b2}"
11860 [(set_attr "type" "ishift")
11861 (set_attr "mode" "SI")])
11863 ;; This pattern can't accept a variable shift count, since shifts by
11864 ;; zero don't affect the flags. We assume that shifts by constant
11865 ;; zero are optimized away.
11866 (define_insn "*ashrsi3_one_bit_cmp"
11867 [(set (reg FLAGS_REG)
11869 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11870 (match_operand:QI 2 "const1_operand" ""))
11872 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11873 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11874 "(TARGET_SHIFT1 || optimize_size)
11875 && ix86_match_ccmode (insn, CCGOCmode)
11876 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11878 [(set_attr "type" "ishift")
11879 (set (attr "length")
11880 (if_then_else (match_operand:SI 0 "register_operand" "")
11882 (const_string "*")))])
11884 (define_insn "*ashrsi3_one_bit_cconly"
11885 [(set (reg FLAGS_REG)
11887 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11888 (match_operand:QI 2 "const1_operand" ""))
11890 (clobber (match_scratch:SI 0 "=r"))]
11891 "(TARGET_SHIFT1 || optimize_size)
11892 && ix86_match_ccmode (insn, CCGOCmode)
11893 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11895 [(set_attr "type" "ishift")
11896 (set_attr "length" "2")])
11898 (define_insn "*ashrsi3_one_bit_cmp_zext"
11899 [(set (reg FLAGS_REG)
11901 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11902 (match_operand:QI 2 "const1_operand" ""))
11904 (set (match_operand:DI 0 "register_operand" "=r")
11905 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11907 && (TARGET_SHIFT1 || optimize_size)
11908 && ix86_match_ccmode (insn, CCmode)
11909 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11911 [(set_attr "type" "ishift")
11912 (set_attr "length" "2")])
11914 ;; This pattern can't accept a variable shift count, since shifts by
11915 ;; zero don't affect the flags. We assume that shifts by constant
11916 ;; zero are optimized away.
11917 (define_insn "*ashrsi3_cmp"
11918 [(set (reg FLAGS_REG)
11920 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11921 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11923 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11924 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11925 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11926 && ix86_match_ccmode (insn, CCGOCmode)
11927 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11928 "sar{l}\t{%2, %0|%0, %2}"
11929 [(set_attr "type" "ishift")
11930 (set_attr "mode" "SI")])
11932 (define_insn "*ashrsi3_cconly"
11933 [(set (reg FLAGS_REG)
11935 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11936 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11938 (clobber (match_scratch:SI 0 "=r"))]
11939 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11940 && ix86_match_ccmode (insn, CCGOCmode)
11941 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11942 "sar{l}\t{%2, %0|%0, %2}"
11943 [(set_attr "type" "ishift")
11944 (set_attr "mode" "SI")])
11946 (define_insn "*ashrsi3_cmp_zext"
11947 [(set (reg FLAGS_REG)
11949 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11950 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11952 (set (match_operand:DI 0 "register_operand" "=r")
11953 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11955 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11956 && ix86_match_ccmode (insn, CCGOCmode)
11957 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11958 "sar{l}\t{%2, %k0|%k0, %2}"
11959 [(set_attr "type" "ishift")
11960 (set_attr "mode" "SI")])
11962 (define_expand "ashrhi3"
11963 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11964 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11965 (match_operand:QI 2 "nonmemory_operand" "")))
11966 (clobber (reg:CC FLAGS_REG))]
11967 "TARGET_HIMODE_MATH"
11968 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11970 (define_insn "*ashrhi3_1_one_bit"
11971 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11972 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11973 (match_operand:QI 2 "const1_operand" "")))
11974 (clobber (reg:CC FLAGS_REG))]
11975 "(TARGET_SHIFT1 || optimize_size)
11976 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11978 [(set_attr "type" "ishift")
11979 (set (attr "length")
11980 (if_then_else (match_operand 0 "register_operand" "")
11982 (const_string "*")))])
11984 (define_insn "*ashrhi3_1"
11985 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11986 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11987 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11988 (clobber (reg:CC FLAGS_REG))]
11989 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11991 sar{w}\t{%2, %0|%0, %2}
11992 sar{w}\t{%b2, %0|%0, %b2}"
11993 [(set_attr "type" "ishift")
11994 (set_attr "mode" "HI")])
11996 ;; This pattern can't accept a variable shift count, since shifts by
11997 ;; zero don't affect the flags. We assume that shifts by constant
11998 ;; zero are optimized away.
11999 (define_insn "*ashrhi3_one_bit_cmp"
12000 [(set (reg FLAGS_REG)
12002 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12003 (match_operand:QI 2 "const1_operand" ""))
12005 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12006 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12007 "(TARGET_SHIFT1 || optimize_size)
12008 && ix86_match_ccmode (insn, CCGOCmode)
12009 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12011 [(set_attr "type" "ishift")
12012 (set (attr "length")
12013 (if_then_else (match_operand 0 "register_operand" "")
12015 (const_string "*")))])
12017 (define_insn "*ashrhi3_one_bit_cconly"
12018 [(set (reg FLAGS_REG)
12020 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12021 (match_operand:QI 2 "const1_operand" ""))
12023 (clobber (match_scratch:HI 0 "=r"))]
12024 "(TARGET_SHIFT1 || optimize_size)
12025 && ix86_match_ccmode (insn, CCGOCmode)
12026 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12028 [(set_attr "type" "ishift")
12029 (set_attr "length" "2")])
12031 ;; This pattern can't accept a variable shift count, since shifts by
12032 ;; zero don't affect the flags. We assume that shifts by constant
12033 ;; zero are optimized away.
12034 (define_insn "*ashrhi3_cmp"
12035 [(set (reg FLAGS_REG)
12037 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12038 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12040 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12041 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12042 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12043 && ix86_match_ccmode (insn, CCGOCmode)
12044 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12045 "sar{w}\t{%2, %0|%0, %2}"
12046 [(set_attr "type" "ishift")
12047 (set_attr "mode" "HI")])
12049 (define_insn "*ashrhi3_cconly"
12050 [(set (reg FLAGS_REG)
12052 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12053 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12055 (clobber (match_scratch:HI 0 "=r"))]
12056 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12057 && ix86_match_ccmode (insn, CCGOCmode)
12058 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12059 "sar{w}\t{%2, %0|%0, %2}"
12060 [(set_attr "type" "ishift")
12061 (set_attr "mode" "HI")])
12063 (define_expand "ashrqi3"
12064 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12065 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12066 (match_operand:QI 2 "nonmemory_operand" "")))
12067 (clobber (reg:CC FLAGS_REG))]
12068 "TARGET_QIMODE_MATH"
12069 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12071 (define_insn "*ashrqi3_1_one_bit"
12072 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12073 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12074 (match_operand:QI 2 "const1_operand" "")))
12075 (clobber (reg:CC FLAGS_REG))]
12076 "(TARGET_SHIFT1 || optimize_size)
12077 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12079 [(set_attr "type" "ishift")
12080 (set (attr "length")
12081 (if_then_else (match_operand 0 "register_operand" "")
12083 (const_string "*")))])
12085 (define_insn "*ashrqi3_1_one_bit_slp"
12086 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12087 (ashiftrt:QI (match_dup 0)
12088 (match_operand:QI 1 "const1_operand" "")))
12089 (clobber (reg:CC FLAGS_REG))]
12090 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12091 && (TARGET_SHIFT1 || optimize_size)
12092 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12094 [(set_attr "type" "ishift1")
12095 (set (attr "length")
12096 (if_then_else (match_operand 0 "register_operand" "")
12098 (const_string "*")))])
12100 (define_insn "*ashrqi3_1"
12101 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12102 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12103 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12104 (clobber (reg:CC FLAGS_REG))]
12105 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12107 sar{b}\t{%2, %0|%0, %2}
12108 sar{b}\t{%b2, %0|%0, %b2}"
12109 [(set_attr "type" "ishift")
12110 (set_attr "mode" "QI")])
12112 (define_insn "*ashrqi3_1_slp"
12113 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12114 (ashiftrt:QI (match_dup 0)
12115 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12116 (clobber (reg:CC FLAGS_REG))]
12117 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12118 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12120 sar{b}\t{%1, %0|%0, %1}
12121 sar{b}\t{%b1, %0|%0, %b1}"
12122 [(set_attr "type" "ishift1")
12123 (set_attr "mode" "QI")])
12125 ;; This pattern can't accept a variable shift count, since shifts by
12126 ;; zero don't affect the flags. We assume that shifts by constant
12127 ;; zero are optimized away.
12128 (define_insn "*ashrqi3_one_bit_cmp"
12129 [(set (reg FLAGS_REG)
12131 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12132 (match_operand:QI 2 "const1_operand" "I"))
12134 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12135 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12136 "(TARGET_SHIFT1 || optimize_size)
12137 && ix86_match_ccmode (insn, CCGOCmode)
12138 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12140 [(set_attr "type" "ishift")
12141 (set (attr "length")
12142 (if_then_else (match_operand 0 "register_operand" "")
12144 (const_string "*")))])
12146 (define_insn "*ashrqi3_one_bit_cconly"
12147 [(set (reg FLAGS_REG)
12149 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12150 (match_operand:QI 2 "const1_operand" "I"))
12152 (clobber (match_scratch:QI 0 "=q"))]
12153 "(TARGET_SHIFT1 || optimize_size)
12154 && ix86_match_ccmode (insn, CCGOCmode)
12155 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12157 [(set_attr "type" "ishift")
12158 (set_attr "length" "2")])
12160 ;; This pattern can't accept a variable shift count, since shifts by
12161 ;; zero don't affect the flags. We assume that shifts by constant
12162 ;; zero are optimized away.
12163 (define_insn "*ashrqi3_cmp"
12164 [(set (reg FLAGS_REG)
12166 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12167 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12169 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12170 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12171 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12172 && ix86_match_ccmode (insn, CCGOCmode)
12173 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12174 "sar{b}\t{%2, %0|%0, %2}"
12175 [(set_attr "type" "ishift")
12176 (set_attr "mode" "QI")])
12178 (define_insn "*ashrqi3_cconly"
12179 [(set (reg FLAGS_REG)
12181 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12182 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12184 (clobber (match_scratch:QI 0 "=q"))]
12185 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12186 && ix86_match_ccmode (insn, CCGOCmode)
12187 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12188 "sar{b}\t{%2, %0|%0, %2}"
12189 [(set_attr "type" "ishift")
12190 (set_attr "mode" "QI")])
12193 ;; Logical shift instructions
12195 ;; See comment above `ashldi3' about how this works.
12197 (define_expand "lshrti3"
12198 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12199 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12200 (match_operand:QI 2 "nonmemory_operand" "")))
12201 (clobber (reg:CC FLAGS_REG))])]
12204 if (! immediate_operand (operands[2], QImode))
12206 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12209 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12213 (define_insn "lshrti3_1"
12214 [(set (match_operand:TI 0 "register_operand" "=r")
12215 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12216 (match_operand:QI 2 "register_operand" "c")))
12217 (clobber (match_scratch:DI 3 "=&r"))
12218 (clobber (reg:CC FLAGS_REG))]
12221 [(set_attr "type" "multi")])
12223 ;; This pattern must be defined before *lshrti3_2 to prevent
12224 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12226 (define_insn "sse2_lshrti3"
12227 [(set (match_operand:TI 0 "register_operand" "=x")
12228 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12229 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12232 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12233 return "psrldq\t{%2, %0|%0, %2}";
12235 [(set_attr "type" "sseishft")
12236 (set_attr "prefix_data16" "1")
12237 (set_attr "mode" "TI")])
12239 (define_insn "*lshrti3_2"
12240 [(set (match_operand:TI 0 "register_operand" "=r")
12241 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12242 (match_operand:QI 2 "immediate_operand" "O")))
12243 (clobber (reg:CC FLAGS_REG))]
12246 [(set_attr "type" "multi")])
12249 [(set (match_operand:TI 0 "register_operand" "")
12250 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12251 (match_operand:QI 2 "register_operand" "")))
12252 (clobber (match_scratch:DI 3 ""))
12253 (clobber (reg:CC FLAGS_REG))]
12254 "TARGET_64BIT && reload_completed"
12256 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12259 [(set (match_operand:TI 0 "register_operand" "")
12260 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12261 (match_operand:QI 2 "immediate_operand" "")))
12262 (clobber (reg:CC FLAGS_REG))]
12263 "TARGET_64BIT && reload_completed"
12265 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12267 (define_expand "lshrdi3"
12268 [(set (match_operand:DI 0 "shiftdi_operand" "")
12269 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12270 (match_operand:QI 2 "nonmemory_operand" "")))]
12272 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12274 (define_insn "*lshrdi3_1_one_bit_rex64"
12275 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12276 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12277 (match_operand:QI 2 "const1_operand" "")))
12278 (clobber (reg:CC FLAGS_REG))]
12280 && (TARGET_SHIFT1 || optimize_size)
12281 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12283 [(set_attr "type" "ishift")
12284 (set (attr "length")
12285 (if_then_else (match_operand:DI 0 "register_operand" "")
12287 (const_string "*")))])
12289 (define_insn "*lshrdi3_1_rex64"
12290 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12291 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12292 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12293 (clobber (reg:CC FLAGS_REG))]
12294 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12296 shr{q}\t{%2, %0|%0, %2}
12297 shr{q}\t{%b2, %0|%0, %b2}"
12298 [(set_attr "type" "ishift")
12299 (set_attr "mode" "DI")])
12301 ;; This pattern can't accept a variable shift count, since shifts by
12302 ;; zero don't affect the flags. We assume that shifts by constant
12303 ;; zero are optimized away.
12304 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12305 [(set (reg FLAGS_REG)
12307 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12308 (match_operand:QI 2 "const1_operand" ""))
12310 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12311 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12313 && (TARGET_SHIFT1 || optimize_size)
12314 && ix86_match_ccmode (insn, CCGOCmode)
12315 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12317 [(set_attr "type" "ishift")
12318 (set (attr "length")
12319 (if_then_else (match_operand:DI 0 "register_operand" "")
12321 (const_string "*")))])
12323 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12324 [(set (reg FLAGS_REG)
12326 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12327 (match_operand:QI 2 "const1_operand" ""))
12329 (clobber (match_scratch:DI 0 "=r"))]
12331 && (TARGET_SHIFT1 || optimize_size)
12332 && ix86_match_ccmode (insn, CCGOCmode)
12333 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12335 [(set_attr "type" "ishift")
12336 (set_attr "length" "2")])
12338 ;; This pattern can't accept a variable shift count, since shifts by
12339 ;; zero don't affect the flags. We assume that shifts by constant
12340 ;; zero are optimized away.
12341 (define_insn "*lshrdi3_cmp_rex64"
12342 [(set (reg FLAGS_REG)
12344 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12345 (match_operand:QI 2 "const_int_operand" "e"))
12347 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12348 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12350 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12351 && ix86_match_ccmode (insn, CCGOCmode)
12352 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12353 "shr{q}\t{%2, %0|%0, %2}"
12354 [(set_attr "type" "ishift")
12355 (set_attr "mode" "DI")])
12357 (define_insn "*lshrdi3_cconly_rex64"
12358 [(set (reg FLAGS_REG)
12360 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12361 (match_operand:QI 2 "const_int_operand" "e"))
12363 (clobber (match_scratch:DI 0 "=r"))]
12365 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12366 && ix86_match_ccmode (insn, CCGOCmode)
12367 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12368 "shr{q}\t{%2, %0|%0, %2}"
12369 [(set_attr "type" "ishift")
12370 (set_attr "mode" "DI")])
12372 (define_insn "*lshrdi3_1"
12373 [(set (match_operand:DI 0 "register_operand" "=r")
12374 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12375 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12376 (clobber (reg:CC FLAGS_REG))]
12379 [(set_attr "type" "multi")])
12381 ;; By default we don't ask for a scratch register, because when DImode
12382 ;; values are manipulated, registers are already at a premium. But if
12383 ;; we have one handy, we won't turn it away.
12385 [(match_scratch:SI 3 "r")
12386 (parallel [(set (match_operand:DI 0 "register_operand" "")
12387 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12388 (match_operand:QI 2 "nonmemory_operand" "")))
12389 (clobber (reg:CC FLAGS_REG))])
12391 "!TARGET_64BIT && TARGET_CMOVE"
12393 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12396 [(set (match_operand:DI 0 "register_operand" "")
12397 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12398 (match_operand:QI 2 "nonmemory_operand" "")))
12399 (clobber (reg:CC FLAGS_REG))]
12400 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12401 ? epilogue_completed : reload_completed)"
12403 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12405 (define_expand "lshrsi3"
12406 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12407 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12408 (match_operand:QI 2 "nonmemory_operand" "")))
12409 (clobber (reg:CC FLAGS_REG))]
12411 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12413 (define_insn "*lshrsi3_1_one_bit"
12414 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12415 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12416 (match_operand:QI 2 "const1_operand" "")))
12417 (clobber (reg:CC FLAGS_REG))]
12418 "(TARGET_SHIFT1 || optimize_size)
12419 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12421 [(set_attr "type" "ishift")
12422 (set (attr "length")
12423 (if_then_else (match_operand:SI 0 "register_operand" "")
12425 (const_string "*")))])
12427 (define_insn "*lshrsi3_1_one_bit_zext"
12428 [(set (match_operand:DI 0 "register_operand" "=r")
12429 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12430 (match_operand:QI 2 "const1_operand" "")))
12431 (clobber (reg:CC FLAGS_REG))]
12433 && (TARGET_SHIFT1 || optimize_size)
12434 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12436 [(set_attr "type" "ishift")
12437 (set_attr "length" "2")])
12439 (define_insn "*lshrsi3_1"
12440 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12441 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12442 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12443 (clobber (reg:CC FLAGS_REG))]
12444 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12446 shr{l}\t{%2, %0|%0, %2}
12447 shr{l}\t{%b2, %0|%0, %b2}"
12448 [(set_attr "type" "ishift")
12449 (set_attr "mode" "SI")])
12451 (define_insn "*lshrsi3_1_zext"
12452 [(set (match_operand:DI 0 "register_operand" "=r,r")
12454 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12455 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12456 (clobber (reg:CC FLAGS_REG))]
12457 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12459 shr{l}\t{%2, %k0|%k0, %2}
12460 shr{l}\t{%b2, %k0|%k0, %b2}"
12461 [(set_attr "type" "ishift")
12462 (set_attr "mode" "SI")])
12464 ;; This pattern can't accept a variable shift count, since shifts by
12465 ;; zero don't affect the flags. We assume that shifts by constant
12466 ;; zero are optimized away.
12467 (define_insn "*lshrsi3_one_bit_cmp"
12468 [(set (reg FLAGS_REG)
12470 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12471 (match_operand:QI 2 "const1_operand" ""))
12473 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12474 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12475 "(TARGET_SHIFT1 || optimize_size)
12476 && ix86_match_ccmode (insn, CCGOCmode)
12477 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12479 [(set_attr "type" "ishift")
12480 (set (attr "length")
12481 (if_then_else (match_operand:SI 0 "register_operand" "")
12483 (const_string "*")))])
12485 (define_insn "*lshrsi3_one_bit_cconly"
12486 [(set (reg FLAGS_REG)
12488 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12489 (match_operand:QI 2 "const1_operand" ""))
12491 (clobber (match_scratch:SI 0 "=r"))]
12492 "(TARGET_SHIFT1 || optimize_size)
12493 && ix86_match_ccmode (insn, CCGOCmode)
12494 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12496 [(set_attr "type" "ishift")
12497 (set_attr "length" "2")])
12499 (define_insn "*lshrsi3_cmp_one_bit_zext"
12500 [(set (reg FLAGS_REG)
12502 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12503 (match_operand:QI 2 "const1_operand" ""))
12505 (set (match_operand:DI 0 "register_operand" "=r")
12506 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12508 && (TARGET_SHIFT1 || optimize_size)
12509 && ix86_match_ccmode (insn, CCGOCmode)
12510 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12512 [(set_attr "type" "ishift")
12513 (set_attr "length" "2")])
12515 ;; This pattern can't accept a variable shift count, since shifts by
12516 ;; zero don't affect the flags. We assume that shifts by constant
12517 ;; zero are optimized away.
12518 (define_insn "*lshrsi3_cmp"
12519 [(set (reg FLAGS_REG)
12521 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12522 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12524 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12525 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12526 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12527 && ix86_match_ccmode (insn, CCGOCmode)
12528 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12529 "shr{l}\t{%2, %0|%0, %2}"
12530 [(set_attr "type" "ishift")
12531 (set_attr "mode" "SI")])
12533 (define_insn "*lshrsi3_cconly"
12534 [(set (reg FLAGS_REG)
12536 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12537 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12539 (clobber (match_scratch:SI 0 "=r"))]
12540 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12541 && ix86_match_ccmode (insn, CCGOCmode)
12542 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12543 "shr{l}\t{%2, %0|%0, %2}"
12544 [(set_attr "type" "ishift")
12545 (set_attr "mode" "SI")])
12547 (define_insn "*lshrsi3_cmp_zext"
12548 [(set (reg FLAGS_REG)
12550 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12551 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12553 (set (match_operand:DI 0 "register_operand" "=r")
12554 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12556 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12557 && ix86_match_ccmode (insn, CCGOCmode)
12558 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12559 "shr{l}\t{%2, %k0|%k0, %2}"
12560 [(set_attr "type" "ishift")
12561 (set_attr "mode" "SI")])
12563 (define_expand "lshrhi3"
12564 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12565 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12566 (match_operand:QI 2 "nonmemory_operand" "")))
12567 (clobber (reg:CC FLAGS_REG))]
12568 "TARGET_HIMODE_MATH"
12569 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12571 (define_insn "*lshrhi3_1_one_bit"
12572 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12573 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12574 (match_operand:QI 2 "const1_operand" "")))
12575 (clobber (reg:CC FLAGS_REG))]
12576 "(TARGET_SHIFT1 || optimize_size)
12577 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12579 [(set_attr "type" "ishift")
12580 (set (attr "length")
12581 (if_then_else (match_operand 0 "register_operand" "")
12583 (const_string "*")))])
12585 (define_insn "*lshrhi3_1"
12586 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12587 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12588 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12589 (clobber (reg:CC FLAGS_REG))]
12590 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12592 shr{w}\t{%2, %0|%0, %2}
12593 shr{w}\t{%b2, %0|%0, %b2}"
12594 [(set_attr "type" "ishift")
12595 (set_attr "mode" "HI")])
12597 ;; This pattern can't accept a variable shift count, since shifts by
12598 ;; zero don't affect the flags. We assume that shifts by constant
12599 ;; zero are optimized away.
12600 (define_insn "*lshrhi3_one_bit_cmp"
12601 [(set (reg FLAGS_REG)
12603 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12604 (match_operand:QI 2 "const1_operand" ""))
12606 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12607 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12608 "(TARGET_SHIFT1 || optimize_size)
12609 && ix86_match_ccmode (insn, CCGOCmode)
12610 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12612 [(set_attr "type" "ishift")
12613 (set (attr "length")
12614 (if_then_else (match_operand:SI 0 "register_operand" "")
12616 (const_string "*")))])
12618 (define_insn "*lshrhi3_one_bit_cconly"
12619 [(set (reg FLAGS_REG)
12621 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12622 (match_operand:QI 2 "const1_operand" ""))
12624 (clobber (match_scratch:HI 0 "=r"))]
12625 "(TARGET_SHIFT1 || optimize_size)
12626 && ix86_match_ccmode (insn, CCGOCmode)
12627 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12629 [(set_attr "type" "ishift")
12630 (set_attr "length" "2")])
12632 ;; This pattern can't accept a variable shift count, since shifts by
12633 ;; zero don't affect the flags. We assume that shifts by constant
12634 ;; zero are optimized away.
12635 (define_insn "*lshrhi3_cmp"
12636 [(set (reg FLAGS_REG)
12638 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12639 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12641 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12642 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12643 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12644 && ix86_match_ccmode (insn, CCGOCmode)
12645 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12646 "shr{w}\t{%2, %0|%0, %2}"
12647 [(set_attr "type" "ishift")
12648 (set_attr "mode" "HI")])
12650 (define_insn "*lshrhi3_cconly"
12651 [(set (reg FLAGS_REG)
12653 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12654 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12656 (clobber (match_scratch:HI 0 "=r"))]
12657 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12658 && ix86_match_ccmode (insn, CCGOCmode)
12659 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12660 "shr{w}\t{%2, %0|%0, %2}"
12661 [(set_attr "type" "ishift")
12662 (set_attr "mode" "HI")])
12664 (define_expand "lshrqi3"
12665 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12666 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12667 (match_operand:QI 2 "nonmemory_operand" "")))
12668 (clobber (reg:CC FLAGS_REG))]
12669 "TARGET_QIMODE_MATH"
12670 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12672 (define_insn "*lshrqi3_1_one_bit"
12673 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12674 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12675 (match_operand:QI 2 "const1_operand" "")))
12676 (clobber (reg:CC FLAGS_REG))]
12677 "(TARGET_SHIFT1 || optimize_size)
12678 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12680 [(set_attr "type" "ishift")
12681 (set (attr "length")
12682 (if_then_else (match_operand 0 "register_operand" "")
12684 (const_string "*")))])
12686 (define_insn "*lshrqi3_1_one_bit_slp"
12687 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12688 (lshiftrt:QI (match_dup 0)
12689 (match_operand:QI 1 "const1_operand" "")))
12690 (clobber (reg:CC FLAGS_REG))]
12691 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12692 && (TARGET_SHIFT1 || optimize_size)"
12694 [(set_attr "type" "ishift1")
12695 (set (attr "length")
12696 (if_then_else (match_operand 0 "register_operand" "")
12698 (const_string "*")))])
12700 (define_insn "*lshrqi3_1"
12701 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12702 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12703 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12704 (clobber (reg:CC FLAGS_REG))]
12705 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12707 shr{b}\t{%2, %0|%0, %2}
12708 shr{b}\t{%b2, %0|%0, %b2}"
12709 [(set_attr "type" "ishift")
12710 (set_attr "mode" "QI")])
12712 (define_insn "*lshrqi3_1_slp"
12713 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12714 (lshiftrt:QI (match_dup 0)
12715 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12716 (clobber (reg:CC FLAGS_REG))]
12717 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12718 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12720 shr{b}\t{%1, %0|%0, %1}
12721 shr{b}\t{%b1, %0|%0, %b1}"
12722 [(set_attr "type" "ishift1")
12723 (set_attr "mode" "QI")])
12725 ;; This pattern can't accept a variable shift count, since shifts by
12726 ;; zero don't affect the flags. We assume that shifts by constant
12727 ;; zero are optimized away.
12728 (define_insn "*lshrqi2_one_bit_cmp"
12729 [(set (reg FLAGS_REG)
12731 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12732 (match_operand:QI 2 "const1_operand" ""))
12734 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12735 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12736 "(TARGET_SHIFT1 || optimize_size)
12737 && ix86_match_ccmode (insn, CCGOCmode)
12738 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12740 [(set_attr "type" "ishift")
12741 (set (attr "length")
12742 (if_then_else (match_operand:SI 0 "register_operand" "")
12744 (const_string "*")))])
12746 (define_insn "*lshrqi2_one_bit_cconly"
12747 [(set (reg FLAGS_REG)
12749 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12750 (match_operand:QI 2 "const1_operand" ""))
12752 (clobber (match_scratch:QI 0 "=q"))]
12753 "(TARGET_SHIFT1 || optimize_size)
12754 && ix86_match_ccmode (insn, CCGOCmode)
12755 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12757 [(set_attr "type" "ishift")
12758 (set_attr "length" "2")])
12760 ;; This pattern can't accept a variable shift count, since shifts by
12761 ;; zero don't affect the flags. We assume that shifts by constant
12762 ;; zero are optimized away.
12763 (define_insn "*lshrqi2_cmp"
12764 [(set (reg FLAGS_REG)
12766 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12767 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12769 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12770 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12771 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12772 && ix86_match_ccmode (insn, CCGOCmode)
12773 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12774 "shr{b}\t{%2, %0|%0, %2}"
12775 [(set_attr "type" "ishift")
12776 (set_attr "mode" "QI")])
12778 (define_insn "*lshrqi2_cconly"
12779 [(set (reg FLAGS_REG)
12781 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12782 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12784 (clobber (match_scratch:QI 0 "=q"))]
12785 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12786 && ix86_match_ccmode (insn, CCGOCmode)
12787 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12788 "shr{b}\t{%2, %0|%0, %2}"
12789 [(set_attr "type" "ishift")
12790 (set_attr "mode" "QI")])
12792 ;; Rotate instructions
12794 (define_expand "rotldi3"
12795 [(set (match_operand:DI 0 "shiftdi_operand" "")
12796 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12797 (match_operand:QI 2 "nonmemory_operand" "")))
12798 (clobber (reg:CC FLAGS_REG))]
12803 ix86_expand_binary_operator (ROTATE, DImode, operands);
12806 if (!const_1_to_31_operand (operands[2], VOIDmode))
12808 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12812 ;; Implement rotation using two double-precision shift instructions
12813 ;; and a scratch register.
12814 (define_insn_and_split "ix86_rotldi3"
12815 [(set (match_operand:DI 0 "register_operand" "=r")
12816 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12817 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12818 (clobber (reg:CC FLAGS_REG))
12819 (clobber (match_scratch:SI 3 "=&r"))]
12822 "&& reload_completed"
12823 [(set (match_dup 3) (match_dup 4))
12825 [(set (match_dup 4)
12826 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12827 (lshiftrt:SI (match_dup 5)
12828 (minus:QI (const_int 32) (match_dup 2)))))
12829 (clobber (reg:CC FLAGS_REG))])
12831 [(set (match_dup 5)
12832 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12833 (lshiftrt:SI (match_dup 3)
12834 (minus:QI (const_int 32) (match_dup 2)))))
12835 (clobber (reg:CC FLAGS_REG))])]
12836 "split_di (operands, 1, operands + 4, operands + 5);")
12838 (define_insn "*rotlsi3_1_one_bit_rex64"
12839 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12840 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12841 (match_operand:QI 2 "const1_operand" "")))
12842 (clobber (reg:CC FLAGS_REG))]
12844 && (TARGET_SHIFT1 || optimize_size)
12845 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12847 [(set_attr "type" "rotate")
12848 (set (attr "length")
12849 (if_then_else (match_operand:DI 0 "register_operand" "")
12851 (const_string "*")))])
12853 (define_insn "*rotldi3_1_rex64"
12854 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12855 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12856 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12857 (clobber (reg:CC FLAGS_REG))]
12858 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12860 rol{q}\t{%2, %0|%0, %2}
12861 rol{q}\t{%b2, %0|%0, %b2}"
12862 [(set_attr "type" "rotate")
12863 (set_attr "mode" "DI")])
12865 (define_expand "rotlsi3"
12866 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12867 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12868 (match_operand:QI 2 "nonmemory_operand" "")))
12869 (clobber (reg:CC FLAGS_REG))]
12871 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12873 (define_insn "*rotlsi3_1_one_bit"
12874 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12875 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12876 (match_operand:QI 2 "const1_operand" "")))
12877 (clobber (reg:CC FLAGS_REG))]
12878 "(TARGET_SHIFT1 || optimize_size)
12879 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12881 [(set_attr "type" "rotate")
12882 (set (attr "length")
12883 (if_then_else (match_operand:SI 0 "register_operand" "")
12885 (const_string "*")))])
12887 (define_insn "*rotlsi3_1_one_bit_zext"
12888 [(set (match_operand:DI 0 "register_operand" "=r")
12890 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12891 (match_operand:QI 2 "const1_operand" ""))))
12892 (clobber (reg:CC FLAGS_REG))]
12894 && (TARGET_SHIFT1 || optimize_size)
12895 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12897 [(set_attr "type" "rotate")
12898 (set_attr "length" "2")])
12900 (define_insn "*rotlsi3_1"
12901 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12902 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12903 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12904 (clobber (reg:CC FLAGS_REG))]
12905 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12907 rol{l}\t{%2, %0|%0, %2}
12908 rol{l}\t{%b2, %0|%0, %b2}"
12909 [(set_attr "type" "rotate")
12910 (set_attr "mode" "SI")])
12912 (define_insn "*rotlsi3_1_zext"
12913 [(set (match_operand:DI 0 "register_operand" "=r,r")
12915 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12916 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12917 (clobber (reg:CC FLAGS_REG))]
12918 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12920 rol{l}\t{%2, %k0|%k0, %2}
12921 rol{l}\t{%b2, %k0|%k0, %b2}"
12922 [(set_attr "type" "rotate")
12923 (set_attr "mode" "SI")])
12925 (define_expand "rotlhi3"
12926 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12927 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12928 (match_operand:QI 2 "nonmemory_operand" "")))
12929 (clobber (reg:CC FLAGS_REG))]
12930 "TARGET_HIMODE_MATH"
12931 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12933 (define_insn "*rotlhi3_1_one_bit"
12934 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12935 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12936 (match_operand:QI 2 "const1_operand" "")))
12937 (clobber (reg:CC FLAGS_REG))]
12938 "(TARGET_SHIFT1 || optimize_size)
12939 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12941 [(set_attr "type" "rotate")
12942 (set (attr "length")
12943 (if_then_else (match_operand 0 "register_operand" "")
12945 (const_string "*")))])
12947 (define_insn "*rotlhi3_1"
12948 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12949 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12950 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12951 (clobber (reg:CC FLAGS_REG))]
12952 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12954 rol{w}\t{%2, %0|%0, %2}
12955 rol{w}\t{%b2, %0|%0, %b2}"
12956 [(set_attr "type" "rotate")
12957 (set_attr "mode" "HI")])
12960 [(set (match_operand:HI 0 "register_operand" "")
12961 (rotate:HI (match_dup 0) (const_int 8)))
12962 (clobber (reg:CC FLAGS_REG))]
12964 [(parallel [(set (strict_low_part (match_dup 0))
12965 (bswap:HI (match_dup 0)))
12966 (clobber (reg:CC FLAGS_REG))])]
12969 (define_expand "rotlqi3"
12970 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12971 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12972 (match_operand:QI 2 "nonmemory_operand" "")))
12973 (clobber (reg:CC FLAGS_REG))]
12974 "TARGET_QIMODE_MATH"
12975 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12977 (define_insn "*rotlqi3_1_one_bit_slp"
12978 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12979 (rotate:QI (match_dup 0)
12980 (match_operand:QI 1 "const1_operand" "")))
12981 (clobber (reg:CC FLAGS_REG))]
12982 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12983 && (TARGET_SHIFT1 || optimize_size)"
12985 [(set_attr "type" "rotate1")
12986 (set (attr "length")
12987 (if_then_else (match_operand 0 "register_operand" "")
12989 (const_string "*")))])
12991 (define_insn "*rotlqi3_1_one_bit"
12992 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12993 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12994 (match_operand:QI 2 "const1_operand" "")))
12995 (clobber (reg:CC FLAGS_REG))]
12996 "(TARGET_SHIFT1 || optimize_size)
12997 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12999 [(set_attr "type" "rotate")
13000 (set (attr "length")
13001 (if_then_else (match_operand 0 "register_operand" "")
13003 (const_string "*")))])
13005 (define_insn "*rotlqi3_1_slp"
13006 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13007 (rotate:QI (match_dup 0)
13008 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13009 (clobber (reg:CC FLAGS_REG))]
13010 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13011 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13013 rol{b}\t{%1, %0|%0, %1}
13014 rol{b}\t{%b1, %0|%0, %b1}"
13015 [(set_attr "type" "rotate1")
13016 (set_attr "mode" "QI")])
13018 (define_insn "*rotlqi3_1"
13019 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13020 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13021 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13022 (clobber (reg:CC FLAGS_REG))]
13023 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13025 rol{b}\t{%2, %0|%0, %2}
13026 rol{b}\t{%b2, %0|%0, %b2}"
13027 [(set_attr "type" "rotate")
13028 (set_attr "mode" "QI")])
13030 (define_expand "rotrdi3"
13031 [(set (match_operand:DI 0 "shiftdi_operand" "")
13032 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13033 (match_operand:QI 2 "nonmemory_operand" "")))
13034 (clobber (reg:CC FLAGS_REG))]
13039 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13042 if (!const_1_to_31_operand (operands[2], VOIDmode))
13044 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13048 ;; Implement rotation using two double-precision shift instructions
13049 ;; and a scratch register.
13050 (define_insn_and_split "ix86_rotrdi3"
13051 [(set (match_operand:DI 0 "register_operand" "=r")
13052 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13053 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13054 (clobber (reg:CC FLAGS_REG))
13055 (clobber (match_scratch:SI 3 "=&r"))]
13058 "&& reload_completed"
13059 [(set (match_dup 3) (match_dup 4))
13061 [(set (match_dup 4)
13062 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13063 (ashift:SI (match_dup 5)
13064 (minus:QI (const_int 32) (match_dup 2)))))
13065 (clobber (reg:CC FLAGS_REG))])
13067 [(set (match_dup 5)
13068 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13069 (ashift:SI (match_dup 3)
13070 (minus:QI (const_int 32) (match_dup 2)))))
13071 (clobber (reg:CC FLAGS_REG))])]
13072 "split_di (operands, 1, operands + 4, operands + 5);")
13074 (define_insn "*rotrdi3_1_one_bit_rex64"
13075 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13076 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13077 (match_operand:QI 2 "const1_operand" "")))
13078 (clobber (reg:CC FLAGS_REG))]
13080 && (TARGET_SHIFT1 || optimize_size)
13081 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13083 [(set_attr "type" "rotate")
13084 (set (attr "length")
13085 (if_then_else (match_operand:DI 0 "register_operand" "")
13087 (const_string "*")))])
13089 (define_insn "*rotrdi3_1_rex64"
13090 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13091 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13092 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13093 (clobber (reg:CC FLAGS_REG))]
13094 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13096 ror{q}\t{%2, %0|%0, %2}
13097 ror{q}\t{%b2, %0|%0, %b2}"
13098 [(set_attr "type" "rotate")
13099 (set_attr "mode" "DI")])
13101 (define_expand "rotrsi3"
13102 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13103 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13104 (match_operand:QI 2 "nonmemory_operand" "")))
13105 (clobber (reg:CC FLAGS_REG))]
13107 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13109 (define_insn "*rotrsi3_1_one_bit"
13110 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13111 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13112 (match_operand:QI 2 "const1_operand" "")))
13113 (clobber (reg:CC FLAGS_REG))]
13114 "(TARGET_SHIFT1 || optimize_size)
13115 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13117 [(set_attr "type" "rotate")
13118 (set (attr "length")
13119 (if_then_else (match_operand:SI 0 "register_operand" "")
13121 (const_string "*")))])
13123 (define_insn "*rotrsi3_1_one_bit_zext"
13124 [(set (match_operand:DI 0 "register_operand" "=r")
13126 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13127 (match_operand:QI 2 "const1_operand" ""))))
13128 (clobber (reg:CC FLAGS_REG))]
13130 && (TARGET_SHIFT1 || optimize_size)
13131 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13133 [(set_attr "type" "rotate")
13134 (set (attr "length")
13135 (if_then_else (match_operand:SI 0 "register_operand" "")
13137 (const_string "*")))])
13139 (define_insn "*rotrsi3_1"
13140 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13141 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13142 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13143 (clobber (reg:CC FLAGS_REG))]
13144 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13146 ror{l}\t{%2, %0|%0, %2}
13147 ror{l}\t{%b2, %0|%0, %b2}"
13148 [(set_attr "type" "rotate")
13149 (set_attr "mode" "SI")])
13151 (define_insn "*rotrsi3_1_zext"
13152 [(set (match_operand:DI 0 "register_operand" "=r,r")
13154 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13155 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13156 (clobber (reg:CC FLAGS_REG))]
13157 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13159 ror{l}\t{%2, %k0|%k0, %2}
13160 ror{l}\t{%b2, %k0|%k0, %b2}"
13161 [(set_attr "type" "rotate")
13162 (set_attr "mode" "SI")])
13164 (define_expand "rotrhi3"
13165 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13166 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13167 (match_operand:QI 2 "nonmemory_operand" "")))
13168 (clobber (reg:CC FLAGS_REG))]
13169 "TARGET_HIMODE_MATH"
13170 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13172 (define_insn "*rotrhi3_one_bit"
13173 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13174 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13175 (match_operand:QI 2 "const1_operand" "")))
13176 (clobber (reg:CC FLAGS_REG))]
13177 "(TARGET_SHIFT1 || optimize_size)
13178 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13180 [(set_attr "type" "rotate")
13181 (set (attr "length")
13182 (if_then_else (match_operand 0 "register_operand" "")
13184 (const_string "*")))])
13186 (define_insn "*rotrhi3_1"
13187 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13188 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13189 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13190 (clobber (reg:CC FLAGS_REG))]
13191 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13193 ror{w}\t{%2, %0|%0, %2}
13194 ror{w}\t{%b2, %0|%0, %b2}"
13195 [(set_attr "type" "rotate")
13196 (set_attr "mode" "HI")])
13199 [(set (match_operand:HI 0 "register_operand" "")
13200 (rotatert:HI (match_dup 0) (const_int 8)))
13201 (clobber (reg:CC FLAGS_REG))]
13203 [(parallel [(set (strict_low_part (match_dup 0))
13204 (bswap:HI (match_dup 0)))
13205 (clobber (reg:CC FLAGS_REG))])]
13208 (define_expand "rotrqi3"
13209 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13210 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13211 (match_operand:QI 2 "nonmemory_operand" "")))
13212 (clobber (reg:CC FLAGS_REG))]
13213 "TARGET_QIMODE_MATH"
13214 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13216 (define_insn "*rotrqi3_1_one_bit"
13217 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13218 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13219 (match_operand:QI 2 "const1_operand" "")))
13220 (clobber (reg:CC FLAGS_REG))]
13221 "(TARGET_SHIFT1 || optimize_size)
13222 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13224 [(set_attr "type" "rotate")
13225 (set (attr "length")
13226 (if_then_else (match_operand 0 "register_operand" "")
13228 (const_string "*")))])
13230 (define_insn "*rotrqi3_1_one_bit_slp"
13231 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13232 (rotatert:QI (match_dup 0)
13233 (match_operand:QI 1 "const1_operand" "")))
13234 (clobber (reg:CC FLAGS_REG))]
13235 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13236 && (TARGET_SHIFT1 || optimize_size)"
13238 [(set_attr "type" "rotate1")
13239 (set (attr "length")
13240 (if_then_else (match_operand 0 "register_operand" "")
13242 (const_string "*")))])
13244 (define_insn "*rotrqi3_1"
13245 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13246 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13247 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13248 (clobber (reg:CC FLAGS_REG))]
13249 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13251 ror{b}\t{%2, %0|%0, %2}
13252 ror{b}\t{%b2, %0|%0, %b2}"
13253 [(set_attr "type" "rotate")
13254 (set_attr "mode" "QI")])
13256 (define_insn "*rotrqi3_1_slp"
13257 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13258 (rotatert:QI (match_dup 0)
13259 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13260 (clobber (reg:CC FLAGS_REG))]
13261 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13262 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13264 ror{b}\t{%1, %0|%0, %1}
13265 ror{b}\t{%b1, %0|%0, %b1}"
13266 [(set_attr "type" "rotate1")
13267 (set_attr "mode" "QI")])
13269 ;; Bit set / bit test instructions
13271 (define_expand "extv"
13272 [(set (match_operand:SI 0 "register_operand" "")
13273 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13274 (match_operand:SI 2 "const8_operand" "")
13275 (match_operand:SI 3 "const8_operand" "")))]
13278 /* Handle extractions from %ah et al. */
13279 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13282 /* From mips.md: extract_bit_field doesn't verify that our source
13283 matches the predicate, so check it again here. */
13284 if (! ext_register_operand (operands[1], VOIDmode))
13288 (define_expand "extzv"
13289 [(set (match_operand:SI 0 "register_operand" "")
13290 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13291 (match_operand:SI 2 "const8_operand" "")
13292 (match_operand:SI 3 "const8_operand" "")))]
13295 /* Handle extractions from %ah et al. */
13296 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13299 /* From mips.md: extract_bit_field doesn't verify that our source
13300 matches the predicate, so check it again here. */
13301 if (! ext_register_operand (operands[1], VOIDmode))
13305 (define_expand "insv"
13306 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13307 (match_operand 1 "const8_operand" "")
13308 (match_operand 2 "const8_operand" ""))
13309 (match_operand 3 "register_operand" ""))]
13312 /* Handle insertions to %ah et al. */
13313 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13316 /* From mips.md: insert_bit_field doesn't verify that our source
13317 matches the predicate, so check it again here. */
13318 if (! ext_register_operand (operands[0], VOIDmode))
13322 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13324 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13329 ;; %%% bts, btr, btc, bt.
13330 ;; In general these instructions are *slow* when applied to memory,
13331 ;; since they enforce atomic operation. When applied to registers,
13332 ;; it depends on the cpu implementation. They're never faster than
13333 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13334 ;; no point. But in 64-bit, we can't hold the relevant immediates
13335 ;; within the instruction itself, so operating on bits in the high
13336 ;; 32-bits of a register becomes easier.
13338 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13339 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13340 ;; negdf respectively, so they can never be disabled entirely.
13342 (define_insn "*btsq"
13343 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13345 (match_operand:DI 1 "const_0_to_63_operand" ""))
13347 (clobber (reg:CC FLAGS_REG))]
13348 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13350 [(set_attr "type" "alu1")])
13352 (define_insn "*btrq"
13353 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13355 (match_operand:DI 1 "const_0_to_63_operand" ""))
13357 (clobber (reg:CC FLAGS_REG))]
13358 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13360 [(set_attr "type" "alu1")])
13362 (define_insn "*btcq"
13363 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13365 (match_operand:DI 1 "const_0_to_63_operand" ""))
13366 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13367 (clobber (reg:CC FLAGS_REG))]
13368 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13370 [(set_attr "type" "alu1")])
13372 ;; Allow Nocona to avoid these instructions if a register is available.
13375 [(match_scratch:DI 2 "r")
13376 (parallel [(set (zero_extract:DI
13377 (match_operand:DI 0 "register_operand" "")
13379 (match_operand:DI 1 "const_0_to_63_operand" ""))
13381 (clobber (reg:CC FLAGS_REG))])]
13382 "TARGET_64BIT && !TARGET_USE_BT"
13385 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13388 if (HOST_BITS_PER_WIDE_INT >= 64)
13389 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13390 else if (i < HOST_BITS_PER_WIDE_INT)
13391 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13393 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13395 op1 = immed_double_const (lo, hi, DImode);
13398 emit_move_insn (operands[2], op1);
13402 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13407 [(match_scratch:DI 2 "r")
13408 (parallel [(set (zero_extract:DI
13409 (match_operand:DI 0 "register_operand" "")
13411 (match_operand:DI 1 "const_0_to_63_operand" ""))
13413 (clobber (reg:CC FLAGS_REG))])]
13414 "TARGET_64BIT && !TARGET_USE_BT"
13417 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13420 if (HOST_BITS_PER_WIDE_INT >= 64)
13421 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13422 else if (i < HOST_BITS_PER_WIDE_INT)
13423 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13425 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13427 op1 = immed_double_const (~lo, ~hi, DImode);
13430 emit_move_insn (operands[2], op1);
13434 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13439 [(match_scratch:DI 2 "r")
13440 (parallel [(set (zero_extract:DI
13441 (match_operand:DI 0 "register_operand" "")
13443 (match_operand:DI 1 "const_0_to_63_operand" ""))
13444 (not:DI (zero_extract:DI
13445 (match_dup 0) (const_int 1) (match_dup 1))))
13446 (clobber (reg:CC FLAGS_REG))])]
13447 "TARGET_64BIT && !TARGET_USE_BT"
13450 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13453 if (HOST_BITS_PER_WIDE_INT >= 64)
13454 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13455 else if (i < HOST_BITS_PER_WIDE_INT)
13456 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13458 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13460 op1 = immed_double_const (lo, hi, DImode);
13463 emit_move_insn (operands[2], op1);
13467 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13471 ;; Store-flag instructions.
13473 ;; For all sCOND expanders, also expand the compare or test insn that
13474 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13476 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13477 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13478 ;; way, which can later delete the movzx if only QImode is needed.
13480 (define_expand "seq"
13481 [(set (match_operand:QI 0 "register_operand" "")
13482 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13484 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13486 (define_expand "sne"
13487 [(set (match_operand:QI 0 "register_operand" "")
13488 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13490 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13492 (define_expand "sgt"
13493 [(set (match_operand:QI 0 "register_operand" "")
13494 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13496 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13498 (define_expand "sgtu"
13499 [(set (match_operand:QI 0 "register_operand" "")
13500 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13502 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13504 (define_expand "slt"
13505 [(set (match_operand:QI 0 "register_operand" "")
13506 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13508 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13510 (define_expand "sltu"
13511 [(set (match_operand:QI 0 "register_operand" "")
13512 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13514 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13516 (define_expand "sge"
13517 [(set (match_operand:QI 0 "register_operand" "")
13518 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13520 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13522 (define_expand "sgeu"
13523 [(set (match_operand:QI 0 "register_operand" "")
13524 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13526 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13528 (define_expand "sle"
13529 [(set (match_operand:QI 0 "register_operand" "")
13530 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13532 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13534 (define_expand "sleu"
13535 [(set (match_operand:QI 0 "register_operand" "")
13536 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13538 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13540 (define_expand "sunordered"
13541 [(set (match_operand:QI 0 "register_operand" "")
13542 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13543 "TARGET_80387 || TARGET_SSE"
13544 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13546 (define_expand "sordered"
13547 [(set (match_operand:QI 0 "register_operand" "")
13548 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13550 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13552 (define_expand "suneq"
13553 [(set (match_operand:QI 0 "register_operand" "")
13554 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13555 "TARGET_80387 || TARGET_SSE"
13556 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13558 (define_expand "sunge"
13559 [(set (match_operand:QI 0 "register_operand" "")
13560 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13561 "TARGET_80387 || TARGET_SSE"
13562 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13564 (define_expand "sungt"
13565 [(set (match_operand:QI 0 "register_operand" "")
13566 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13567 "TARGET_80387 || TARGET_SSE"
13568 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13570 (define_expand "sunle"
13571 [(set (match_operand:QI 0 "register_operand" "")
13572 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13573 "TARGET_80387 || TARGET_SSE"
13574 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13576 (define_expand "sunlt"
13577 [(set (match_operand:QI 0 "register_operand" "")
13578 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13579 "TARGET_80387 || TARGET_SSE"
13580 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13582 (define_expand "sltgt"
13583 [(set (match_operand:QI 0 "register_operand" "")
13584 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13585 "TARGET_80387 || TARGET_SSE"
13586 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13588 (define_insn "*setcc_1"
13589 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13590 (match_operator:QI 1 "ix86_comparison_operator"
13591 [(reg FLAGS_REG) (const_int 0)]))]
13594 [(set_attr "type" "setcc")
13595 (set_attr "mode" "QI")])
13597 (define_insn "*setcc_2"
13598 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13599 (match_operator:QI 1 "ix86_comparison_operator"
13600 [(reg FLAGS_REG) (const_int 0)]))]
13603 [(set_attr "type" "setcc")
13604 (set_attr "mode" "QI")])
13606 ;; In general it is not safe to assume too much about CCmode registers,
13607 ;; so simplify-rtx stops when it sees a second one. Under certain
13608 ;; conditions this is safe on x86, so help combine not create
13615 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13616 (ne:QI (match_operator 1 "ix86_comparison_operator"
13617 [(reg FLAGS_REG) (const_int 0)])
13620 [(set (match_dup 0) (match_dup 1))]
13622 PUT_MODE (operands[1], QImode);
13626 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13627 (ne:QI (match_operator 1 "ix86_comparison_operator"
13628 [(reg FLAGS_REG) (const_int 0)])
13631 [(set (match_dup 0) (match_dup 1))]
13633 PUT_MODE (operands[1], QImode);
13637 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13638 (eq:QI (match_operator 1 "ix86_comparison_operator"
13639 [(reg FLAGS_REG) (const_int 0)])
13642 [(set (match_dup 0) (match_dup 1))]
13644 rtx new_op1 = copy_rtx (operands[1]);
13645 operands[1] = new_op1;
13646 PUT_MODE (new_op1, QImode);
13647 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13648 GET_MODE (XEXP (new_op1, 0))));
13650 /* Make sure that (a) the CCmode we have for the flags is strong
13651 enough for the reversed compare or (b) we have a valid FP compare. */
13652 if (! ix86_comparison_operator (new_op1, VOIDmode))
13657 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13658 (eq:QI (match_operator 1 "ix86_comparison_operator"
13659 [(reg FLAGS_REG) (const_int 0)])
13662 [(set (match_dup 0) (match_dup 1))]
13664 rtx new_op1 = copy_rtx (operands[1]);
13665 operands[1] = new_op1;
13666 PUT_MODE (new_op1, QImode);
13667 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13668 GET_MODE (XEXP (new_op1, 0))));
13670 /* Make sure that (a) the CCmode we have for the flags is strong
13671 enough for the reversed compare or (b) we have a valid FP compare. */
13672 if (! ix86_comparison_operator (new_op1, VOIDmode))
13676 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13677 ;; subsequent logical operations are used to imitate conditional moves.
13678 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13681 (define_insn "*sse_setccsf"
13682 [(set (match_operand:SF 0 "register_operand" "=x")
13683 (match_operator:SF 1 "sse_comparison_operator"
13684 [(match_operand:SF 2 "register_operand" "0")
13685 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13687 "cmp%D1ss\t{%3, %0|%0, %3}"
13688 [(set_attr "type" "ssecmp")
13689 (set_attr "mode" "SF")])
13691 (define_insn "*sse_setccdf"
13692 [(set (match_operand:DF 0 "register_operand" "=x")
13693 (match_operator:DF 1 "sse_comparison_operator"
13694 [(match_operand:DF 2 "register_operand" "0")
13695 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13697 "cmp%D1sd\t{%3, %0|%0, %3}"
13698 [(set_attr "type" "ssecmp")
13699 (set_attr "mode" "DF")])
13701 ;; Basic conditional jump instructions.
13702 ;; We ignore the overflow flag for signed branch instructions.
13704 ;; For all bCOND expanders, also expand the compare or test insn that
13705 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13707 (define_expand "beq"
13709 (if_then_else (match_dup 1)
13710 (label_ref (match_operand 0 "" ""))
13713 "ix86_expand_branch (EQ, operands[0]); DONE;")
13715 (define_expand "bne"
13717 (if_then_else (match_dup 1)
13718 (label_ref (match_operand 0 "" ""))
13721 "ix86_expand_branch (NE, operands[0]); DONE;")
13723 (define_expand "bgt"
13725 (if_then_else (match_dup 1)
13726 (label_ref (match_operand 0 "" ""))
13729 "ix86_expand_branch (GT, operands[0]); DONE;")
13731 (define_expand "bgtu"
13733 (if_then_else (match_dup 1)
13734 (label_ref (match_operand 0 "" ""))
13737 "ix86_expand_branch (GTU, operands[0]); DONE;")
13739 (define_expand "blt"
13741 (if_then_else (match_dup 1)
13742 (label_ref (match_operand 0 "" ""))
13745 "ix86_expand_branch (LT, operands[0]); DONE;")
13747 (define_expand "bltu"
13749 (if_then_else (match_dup 1)
13750 (label_ref (match_operand 0 "" ""))
13753 "ix86_expand_branch (LTU, operands[0]); DONE;")
13755 (define_expand "bge"
13757 (if_then_else (match_dup 1)
13758 (label_ref (match_operand 0 "" ""))
13761 "ix86_expand_branch (GE, operands[0]); DONE;")
13763 (define_expand "bgeu"
13765 (if_then_else (match_dup 1)
13766 (label_ref (match_operand 0 "" ""))
13769 "ix86_expand_branch (GEU, operands[0]); DONE;")
13771 (define_expand "ble"
13773 (if_then_else (match_dup 1)
13774 (label_ref (match_operand 0 "" ""))
13777 "ix86_expand_branch (LE, operands[0]); DONE;")
13779 (define_expand "bleu"
13781 (if_then_else (match_dup 1)
13782 (label_ref (match_operand 0 "" ""))
13785 "ix86_expand_branch (LEU, operands[0]); DONE;")
13787 (define_expand "bunordered"
13789 (if_then_else (match_dup 1)
13790 (label_ref (match_operand 0 "" ""))
13792 "TARGET_80387 || TARGET_SSE_MATH"
13793 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13795 (define_expand "bordered"
13797 (if_then_else (match_dup 1)
13798 (label_ref (match_operand 0 "" ""))
13800 "TARGET_80387 || TARGET_SSE_MATH"
13801 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13803 (define_expand "buneq"
13805 (if_then_else (match_dup 1)
13806 (label_ref (match_operand 0 "" ""))
13808 "TARGET_80387 || TARGET_SSE_MATH"
13809 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13811 (define_expand "bunge"
13813 (if_then_else (match_dup 1)
13814 (label_ref (match_operand 0 "" ""))
13816 "TARGET_80387 || TARGET_SSE_MATH"
13817 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13819 (define_expand "bungt"
13821 (if_then_else (match_dup 1)
13822 (label_ref (match_operand 0 "" ""))
13824 "TARGET_80387 || TARGET_SSE_MATH"
13825 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13827 (define_expand "bunle"
13829 (if_then_else (match_dup 1)
13830 (label_ref (match_operand 0 "" ""))
13832 "TARGET_80387 || TARGET_SSE_MATH"
13833 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13835 (define_expand "bunlt"
13837 (if_then_else (match_dup 1)
13838 (label_ref (match_operand 0 "" ""))
13840 "TARGET_80387 || TARGET_SSE_MATH"
13841 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13843 (define_expand "bltgt"
13845 (if_then_else (match_dup 1)
13846 (label_ref (match_operand 0 "" ""))
13848 "TARGET_80387 || TARGET_SSE_MATH"
13849 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13851 (define_insn "*jcc_1"
13853 (if_then_else (match_operator 1 "ix86_comparison_operator"
13854 [(reg FLAGS_REG) (const_int 0)])
13855 (label_ref (match_operand 0 "" ""))
13859 [(set_attr "type" "ibr")
13860 (set_attr "modrm" "0")
13861 (set (attr "length")
13862 (if_then_else (and (ge (minus (match_dup 0) (pc))
13864 (lt (minus (match_dup 0) (pc))
13869 (define_insn "*jcc_2"
13871 (if_then_else (match_operator 1 "ix86_comparison_operator"
13872 [(reg FLAGS_REG) (const_int 0)])
13874 (label_ref (match_operand 0 "" ""))))]
13877 [(set_attr "type" "ibr")
13878 (set_attr "modrm" "0")
13879 (set (attr "length")
13880 (if_then_else (and (ge (minus (match_dup 0) (pc))
13882 (lt (minus (match_dup 0) (pc))
13887 ;; In general it is not safe to assume too much about CCmode registers,
13888 ;; so simplify-rtx stops when it sees a second one. Under certain
13889 ;; conditions this is safe on x86, so help combine not create
13897 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13898 [(reg FLAGS_REG) (const_int 0)])
13900 (label_ref (match_operand 1 "" ""))
13904 (if_then_else (match_dup 0)
13905 (label_ref (match_dup 1))
13908 PUT_MODE (operands[0], VOIDmode);
13913 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13914 [(reg FLAGS_REG) (const_int 0)])
13916 (label_ref (match_operand 1 "" ""))
13920 (if_then_else (match_dup 0)
13921 (label_ref (match_dup 1))
13924 rtx new_op0 = copy_rtx (operands[0]);
13925 operands[0] = new_op0;
13926 PUT_MODE (new_op0, VOIDmode);
13927 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13928 GET_MODE (XEXP (new_op0, 0))));
13930 /* Make sure that (a) the CCmode we have for the flags is strong
13931 enough for the reversed compare or (b) we have a valid FP compare. */
13932 if (! ix86_comparison_operator (new_op0, VOIDmode))
13936 ;; Define combination compare-and-branch fp compare instructions to use
13937 ;; during early optimization. Splitting the operation apart early makes
13938 ;; for bad code when we want to reverse the operation.
13940 (define_insn "*fp_jcc_1_mixed"
13942 (if_then_else (match_operator 0 "comparison_operator"
13943 [(match_operand 1 "register_operand" "f,x")
13944 (match_operand 2 "nonimmediate_operand" "f,xm")])
13945 (label_ref (match_operand 3 "" ""))
13947 (clobber (reg:CCFP FPSR_REG))
13948 (clobber (reg:CCFP FLAGS_REG))]
13949 "TARGET_MIX_SSE_I387
13950 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13951 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13952 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13955 (define_insn "*fp_jcc_1_sse"
13957 (if_then_else (match_operator 0 "comparison_operator"
13958 [(match_operand 1 "register_operand" "x")
13959 (match_operand 2 "nonimmediate_operand" "xm")])
13960 (label_ref (match_operand 3 "" ""))
13962 (clobber (reg:CCFP FPSR_REG))
13963 (clobber (reg:CCFP FLAGS_REG))]
13965 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13966 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13967 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13970 (define_insn "*fp_jcc_1_387"
13972 (if_then_else (match_operator 0 "comparison_operator"
13973 [(match_operand 1 "register_operand" "f")
13974 (match_operand 2 "register_operand" "f")])
13975 (label_ref (match_operand 3 "" ""))
13977 (clobber (reg:CCFP FPSR_REG))
13978 (clobber (reg:CCFP FLAGS_REG))]
13979 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13981 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13982 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13985 (define_insn "*fp_jcc_2_mixed"
13987 (if_then_else (match_operator 0 "comparison_operator"
13988 [(match_operand 1 "register_operand" "f,x")
13989 (match_operand 2 "nonimmediate_operand" "f,xm")])
13991 (label_ref (match_operand 3 "" ""))))
13992 (clobber (reg:CCFP FPSR_REG))
13993 (clobber (reg:CCFP FLAGS_REG))]
13994 "TARGET_MIX_SSE_I387
13995 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13996 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13997 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14000 (define_insn "*fp_jcc_2_sse"
14002 (if_then_else (match_operator 0 "comparison_operator"
14003 [(match_operand 1 "register_operand" "x")
14004 (match_operand 2 "nonimmediate_operand" "xm")])
14006 (label_ref (match_operand 3 "" ""))))
14007 (clobber (reg:CCFP FPSR_REG))
14008 (clobber (reg:CCFP FLAGS_REG))]
14010 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14011 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14012 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14015 (define_insn "*fp_jcc_2_387"
14017 (if_then_else (match_operator 0 "comparison_operator"
14018 [(match_operand 1 "register_operand" "f")
14019 (match_operand 2 "register_operand" "f")])
14021 (label_ref (match_operand 3 "" ""))))
14022 (clobber (reg:CCFP FPSR_REG))
14023 (clobber (reg:CCFP FLAGS_REG))]
14024 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14026 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14027 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14030 (define_insn "*fp_jcc_3_387"
14032 (if_then_else (match_operator 0 "comparison_operator"
14033 [(match_operand 1 "register_operand" "f")
14034 (match_operand 2 "nonimmediate_operand" "fm")])
14035 (label_ref (match_operand 3 "" ""))
14037 (clobber (reg:CCFP FPSR_REG))
14038 (clobber (reg:CCFP FLAGS_REG))
14039 (clobber (match_scratch:HI 4 "=a"))]
14041 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14042 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14043 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14044 && SELECT_CC_MODE (GET_CODE (operands[0]),
14045 operands[1], operands[2]) == CCFPmode
14046 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14049 (define_insn "*fp_jcc_4_387"
14051 (if_then_else (match_operator 0 "comparison_operator"
14052 [(match_operand 1 "register_operand" "f")
14053 (match_operand 2 "nonimmediate_operand" "fm")])
14055 (label_ref (match_operand 3 "" ""))))
14056 (clobber (reg:CCFP FPSR_REG))
14057 (clobber (reg:CCFP FLAGS_REG))
14058 (clobber (match_scratch:HI 4 "=a"))]
14060 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14061 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14062 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14063 && SELECT_CC_MODE (GET_CODE (operands[0]),
14064 operands[1], operands[2]) == CCFPmode
14065 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14068 (define_insn "*fp_jcc_5_387"
14070 (if_then_else (match_operator 0 "comparison_operator"
14071 [(match_operand 1 "register_operand" "f")
14072 (match_operand 2 "register_operand" "f")])
14073 (label_ref (match_operand 3 "" ""))
14075 (clobber (reg:CCFP FPSR_REG))
14076 (clobber (reg:CCFP FLAGS_REG))
14077 (clobber (match_scratch:HI 4 "=a"))]
14078 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14079 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14080 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14083 (define_insn "*fp_jcc_6_387"
14085 (if_then_else (match_operator 0 "comparison_operator"
14086 [(match_operand 1 "register_operand" "f")
14087 (match_operand 2 "register_operand" "f")])
14089 (label_ref (match_operand 3 "" ""))))
14090 (clobber (reg:CCFP FPSR_REG))
14091 (clobber (reg:CCFP FLAGS_REG))
14092 (clobber (match_scratch:HI 4 "=a"))]
14093 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14094 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14095 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14098 (define_insn "*fp_jcc_7_387"
14100 (if_then_else (match_operator 0 "comparison_operator"
14101 [(match_operand 1 "register_operand" "f")
14102 (match_operand 2 "const0_operand" "X")])
14103 (label_ref (match_operand 3 "" ""))
14105 (clobber (reg:CCFP FPSR_REG))
14106 (clobber (reg:CCFP FLAGS_REG))
14107 (clobber (match_scratch:HI 4 "=a"))]
14108 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14109 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14110 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14111 && SELECT_CC_MODE (GET_CODE (operands[0]),
14112 operands[1], operands[2]) == CCFPmode
14113 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14116 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14117 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14118 ;; with a precedence over other operators and is always put in the first
14119 ;; place. Swap condition and operands to match ficom instruction.
14121 (define_insn "*fp_jcc_8<mode>_387"
14123 (if_then_else (match_operator 0 "comparison_operator"
14124 [(match_operator 1 "float_operator"
14125 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14126 (match_operand 3 "register_operand" "f,f")])
14127 (label_ref (match_operand 4 "" ""))
14129 (clobber (reg:CCFP FPSR_REG))
14130 (clobber (reg:CCFP FLAGS_REG))
14131 (clobber (match_scratch:HI 5 "=a,a"))]
14132 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14133 && TARGET_USE_<MODE>MODE_FIOP
14134 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14135 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14136 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14137 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14142 (if_then_else (match_operator 0 "comparison_operator"
14143 [(match_operand 1 "register_operand" "")
14144 (match_operand 2 "nonimmediate_operand" "")])
14145 (match_operand 3 "" "")
14146 (match_operand 4 "" "")))
14147 (clobber (reg:CCFP FPSR_REG))
14148 (clobber (reg:CCFP FLAGS_REG))]
14152 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14153 operands[3], operands[4], NULL_RTX, NULL_RTX);
14159 (if_then_else (match_operator 0 "comparison_operator"
14160 [(match_operand 1 "register_operand" "")
14161 (match_operand 2 "general_operand" "")])
14162 (match_operand 3 "" "")
14163 (match_operand 4 "" "")))
14164 (clobber (reg:CCFP FPSR_REG))
14165 (clobber (reg:CCFP FLAGS_REG))
14166 (clobber (match_scratch:HI 5 "=a"))]
14170 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14171 operands[3], operands[4], operands[5], NULL_RTX);
14177 (if_then_else (match_operator 0 "comparison_operator"
14178 [(match_operator 1 "float_operator"
14179 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14180 (match_operand 3 "register_operand" "")])
14181 (match_operand 4 "" "")
14182 (match_operand 5 "" "")))
14183 (clobber (reg:CCFP FPSR_REG))
14184 (clobber (reg:CCFP FLAGS_REG))
14185 (clobber (match_scratch:HI 6 "=a"))]
14189 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14190 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14191 operands[3], operands[7],
14192 operands[4], operands[5], operands[6], NULL_RTX);
14196 ;; %%% Kill this when reload knows how to do it.
14199 (if_then_else (match_operator 0 "comparison_operator"
14200 [(match_operator 1 "float_operator"
14201 [(match_operand:X87MODEI12 2 "register_operand" "")])
14202 (match_operand 3 "register_operand" "")])
14203 (match_operand 4 "" "")
14204 (match_operand 5 "" "")))
14205 (clobber (reg:CCFP FPSR_REG))
14206 (clobber (reg:CCFP FLAGS_REG))
14207 (clobber (match_scratch:HI 6 "=a"))]
14211 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14212 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14213 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14214 operands[3], operands[7],
14215 operands[4], operands[5], operands[6], operands[2]);
14219 ;; Unconditional and other jump instructions
14221 (define_insn "jump"
14223 (label_ref (match_operand 0 "" "")))]
14226 [(set_attr "type" "ibr")
14227 (set (attr "length")
14228 (if_then_else (and (ge (minus (match_dup 0) (pc))
14230 (lt (minus (match_dup 0) (pc))
14234 (set_attr "modrm" "0")])
14236 (define_expand "indirect_jump"
14237 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14241 (define_insn "*indirect_jump"
14242 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14245 [(set_attr "type" "ibr")
14246 (set_attr "length_immediate" "0")])
14248 (define_insn "*indirect_jump_rtx64"
14249 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14252 [(set_attr "type" "ibr")
14253 (set_attr "length_immediate" "0")])
14255 (define_expand "tablejump"
14256 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14257 (use (label_ref (match_operand 1 "" "")))])]
14260 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14261 relative. Convert the relative address to an absolute address. */
14265 enum rtx_code code;
14267 /* We can't use @GOTOFF for text labels on VxWorks;
14268 see gotoff_operand. */
14269 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14273 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14275 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14279 op1 = pic_offset_table_rtx;
14284 op0 = pic_offset_table_rtx;
14288 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14293 (define_insn "*tablejump_1"
14294 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14295 (use (label_ref (match_operand 1 "" "")))]
14298 [(set_attr "type" "ibr")
14299 (set_attr "length_immediate" "0")])
14301 (define_insn "*tablejump_1_rtx64"
14302 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14303 (use (label_ref (match_operand 1 "" "")))]
14306 [(set_attr "type" "ibr")
14307 (set_attr "length_immediate" "0")])
14309 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14312 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14313 (set (match_operand:QI 1 "register_operand" "")
14314 (match_operator:QI 2 "ix86_comparison_operator"
14315 [(reg FLAGS_REG) (const_int 0)]))
14316 (set (match_operand 3 "q_regs_operand" "")
14317 (zero_extend (match_dup 1)))]
14318 "(peep2_reg_dead_p (3, operands[1])
14319 || operands_match_p (operands[1], operands[3]))
14320 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14321 [(set (match_dup 4) (match_dup 0))
14322 (set (strict_low_part (match_dup 5))
14325 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14326 operands[5] = gen_lowpart (QImode, operands[3]);
14327 ix86_expand_clear (operands[3]);
14330 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14333 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14334 (set (match_operand:QI 1 "register_operand" "")
14335 (match_operator:QI 2 "ix86_comparison_operator"
14336 [(reg FLAGS_REG) (const_int 0)]))
14337 (parallel [(set (match_operand 3 "q_regs_operand" "")
14338 (zero_extend (match_dup 1)))
14339 (clobber (reg:CC FLAGS_REG))])]
14340 "(peep2_reg_dead_p (3, operands[1])
14341 || operands_match_p (operands[1], operands[3]))
14342 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14343 [(set (match_dup 4) (match_dup 0))
14344 (set (strict_low_part (match_dup 5))
14347 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14348 operands[5] = gen_lowpart (QImode, operands[3]);
14349 ix86_expand_clear (operands[3]);
14352 ;; Call instructions.
14354 ;; The predicates normally associated with named expanders are not properly
14355 ;; checked for calls. This is a bug in the generic code, but it isn't that
14356 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14358 ;; Call subroutine returning no value.
14360 (define_expand "call_pop"
14361 [(parallel [(call (match_operand:QI 0 "" "")
14362 (match_operand:SI 1 "" ""))
14363 (set (reg:SI SP_REG)
14364 (plus:SI (reg:SI SP_REG)
14365 (match_operand:SI 3 "" "")))])]
14368 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14372 (define_insn "*call_pop_0"
14373 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14374 (match_operand:SI 1 "" ""))
14375 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14376 (match_operand:SI 2 "immediate_operand" "")))]
14379 if (SIBLING_CALL_P (insn))
14382 return "call\t%P0";
14384 [(set_attr "type" "call")])
14386 (define_insn "*call_pop_1"
14387 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14388 (match_operand:SI 1 "" ""))
14389 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14390 (match_operand:SI 2 "immediate_operand" "i")))]
14393 if (constant_call_address_operand (operands[0], Pmode))
14395 if (SIBLING_CALL_P (insn))
14398 return "call\t%P0";
14400 if (SIBLING_CALL_P (insn))
14403 return "call\t%A0";
14405 [(set_attr "type" "call")])
14407 (define_expand "call"
14408 [(call (match_operand:QI 0 "" "")
14409 (match_operand 1 "" ""))
14410 (use (match_operand 2 "" ""))]
14413 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14417 (define_expand "sibcall"
14418 [(call (match_operand:QI 0 "" "")
14419 (match_operand 1 "" ""))
14420 (use (match_operand 2 "" ""))]
14423 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14427 (define_insn "*call_0"
14428 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14429 (match_operand 1 "" ""))]
14432 if (SIBLING_CALL_P (insn))
14435 return "call\t%P0";
14437 [(set_attr "type" "call")])
14439 (define_insn "*call_1"
14440 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14441 (match_operand 1 "" ""))]
14442 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14444 if (constant_call_address_operand (operands[0], Pmode))
14445 return "call\t%P0";
14446 return "call\t%A0";
14448 [(set_attr "type" "call")])
14450 (define_insn "*sibcall_1"
14451 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14452 (match_operand 1 "" ""))]
14453 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14455 if (constant_call_address_operand (operands[0], Pmode))
14459 [(set_attr "type" "call")])
14461 (define_insn "*call_1_rex64"
14462 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14463 (match_operand 1 "" ""))]
14464 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14465 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14467 if (constant_call_address_operand (operands[0], Pmode))
14468 return "call\t%P0";
14469 return "call\t%A0";
14471 [(set_attr "type" "call")])
14473 (define_insn "*call_1_rex64_large"
14474 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14475 (match_operand 1 "" ""))]
14476 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14478 [(set_attr "type" "call")])
14480 (define_insn "*sibcall_1_rex64"
14481 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14482 (match_operand 1 "" ""))]
14483 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14485 [(set_attr "type" "call")])
14487 (define_insn "*sibcall_1_rex64_v"
14488 [(call (mem:QI (reg:DI R11_REG))
14489 (match_operand 0 "" ""))]
14490 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14492 [(set_attr "type" "call")])
14495 ;; Call subroutine, returning value in operand 0
14497 (define_expand "call_value_pop"
14498 [(parallel [(set (match_operand 0 "" "")
14499 (call (match_operand:QI 1 "" "")
14500 (match_operand:SI 2 "" "")))
14501 (set (reg:SI SP_REG)
14502 (plus:SI (reg:SI SP_REG)
14503 (match_operand:SI 4 "" "")))])]
14506 ix86_expand_call (operands[0], operands[1], operands[2],
14507 operands[3], operands[4], 0);
14511 (define_expand "call_value"
14512 [(set (match_operand 0 "" "")
14513 (call (match_operand:QI 1 "" "")
14514 (match_operand:SI 2 "" "")))
14515 (use (match_operand:SI 3 "" ""))]
14516 ;; Operand 2 not used on the i386.
14519 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14523 (define_expand "sibcall_value"
14524 [(set (match_operand 0 "" "")
14525 (call (match_operand:QI 1 "" "")
14526 (match_operand:SI 2 "" "")))
14527 (use (match_operand:SI 3 "" ""))]
14528 ;; Operand 2 not used on the i386.
14531 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14535 ;; Call subroutine returning any type.
14537 (define_expand "untyped_call"
14538 [(parallel [(call (match_operand 0 "" "")
14540 (match_operand 1 "" "")
14541 (match_operand 2 "" "")])]
14546 /* In order to give reg-stack an easier job in validating two
14547 coprocessor registers as containing a possible return value,
14548 simply pretend the untyped call returns a complex long double
14551 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14552 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14553 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14556 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14558 rtx set = XVECEXP (operands[2], 0, i);
14559 emit_move_insn (SET_DEST (set), SET_SRC (set));
14562 /* The optimizer does not know that the call sets the function value
14563 registers we stored in the result block. We avoid problems by
14564 claiming that all hard registers are used and clobbered at this
14566 emit_insn (gen_blockage ());
14571 ;; Prologue and epilogue instructions
14573 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14574 ;; all of memory. This blocks insns from being moved across this point.
14576 (define_insn "blockage"
14577 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14580 [(set_attr "length" "0")])
14582 ;; As USE insns aren't meaningful after reload, this is used instead
14583 ;; to prevent deleting instructions setting registers for PIC code
14584 (define_insn "prologue_use"
14585 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14588 [(set_attr "length" "0")])
14590 ;; Insn emitted into the body of a function to return from a function.
14591 ;; This is only done if the function's epilogue is known to be simple.
14592 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14594 (define_expand "return"
14596 "ix86_can_use_return_insn_p ()"
14598 if (current_function_pops_args)
14600 rtx popc = GEN_INT (current_function_pops_args);
14601 emit_jump_insn (gen_return_pop_internal (popc));
14606 (define_insn "return_internal"
14610 [(set_attr "length" "1")
14611 (set_attr "length_immediate" "0")
14612 (set_attr "modrm" "0")])
14614 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14615 ;; instruction Athlon and K8 have.
14617 (define_insn "return_internal_long"
14619 (unspec [(const_int 0)] UNSPEC_REP)]
14622 [(set_attr "length" "1")
14623 (set_attr "length_immediate" "0")
14624 (set_attr "prefix_rep" "1")
14625 (set_attr "modrm" "0")])
14627 (define_insn "return_pop_internal"
14629 (use (match_operand:SI 0 "const_int_operand" ""))]
14632 [(set_attr "length" "3")
14633 (set_attr "length_immediate" "2")
14634 (set_attr "modrm" "0")])
14636 (define_insn "return_indirect_internal"
14638 (use (match_operand:SI 0 "register_operand" "r"))]
14641 [(set_attr "type" "ibr")
14642 (set_attr "length_immediate" "0")])
14648 [(set_attr "length" "1")
14649 (set_attr "length_immediate" "0")
14650 (set_attr "modrm" "0")])
14652 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14653 ;; branch prediction penalty for the third jump in a 16-byte
14656 (define_insn "align"
14657 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14660 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14661 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14663 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14664 The align insn is used to avoid 3 jump instructions in the row to improve
14665 branch prediction and the benefits hardly outweigh the cost of extra 8
14666 nops on the average inserted by full alignment pseudo operation. */
14670 [(set_attr "length" "16")])
14672 (define_expand "prologue"
14675 "ix86_expand_prologue (); DONE;")
14677 (define_insn "set_got"
14678 [(set (match_operand:SI 0 "register_operand" "=r")
14679 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14680 (clobber (reg:CC FLAGS_REG))]
14682 { return output_set_got (operands[0], NULL_RTX); }
14683 [(set_attr "type" "multi")
14684 (set_attr "length" "12")])
14686 (define_insn "set_got_labelled"
14687 [(set (match_operand:SI 0 "register_operand" "=r")
14688 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14690 (clobber (reg:CC FLAGS_REG))]
14692 { return output_set_got (operands[0], operands[1]); }
14693 [(set_attr "type" "multi")
14694 (set_attr "length" "12")])
14696 (define_insn "set_got_rex64"
14697 [(set (match_operand:DI 0 "register_operand" "=r")
14698 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14700 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14701 [(set_attr "type" "lea")
14702 (set_attr "length" "6")])
14704 (define_insn "set_rip_rex64"
14705 [(set (match_operand:DI 0 "register_operand" "=r")
14706 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14708 "lea{q}\t%l1(%%rip), %0"
14709 [(set_attr "type" "lea")
14710 (set_attr "length" "6")])
14712 (define_insn "set_got_offset_rex64"
14713 [(set (match_operand:DI 0 "register_operand" "=r")
14714 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14716 "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
14717 [(set_attr "type" "imov")
14718 (set_attr "length" "11")])
14720 (define_expand "epilogue"
14723 "ix86_expand_epilogue (1); DONE;")
14725 (define_expand "sibcall_epilogue"
14728 "ix86_expand_epilogue (0); DONE;")
14730 (define_expand "eh_return"
14731 [(use (match_operand 0 "register_operand" ""))]
14734 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14736 /* Tricky bit: we write the address of the handler to which we will
14737 be returning into someone else's stack frame, one word below the
14738 stack address we wish to restore. */
14739 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14740 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14741 tmp = gen_rtx_MEM (Pmode, tmp);
14742 emit_move_insn (tmp, ra);
14744 if (Pmode == SImode)
14745 emit_jump_insn (gen_eh_return_si (sa));
14747 emit_jump_insn (gen_eh_return_di (sa));
14752 (define_insn_and_split "eh_return_si"
14754 (unspec [(match_operand:SI 0 "register_operand" "c")]
14755 UNSPEC_EH_RETURN))]
14760 "ix86_expand_epilogue (2); DONE;")
14762 (define_insn_and_split "eh_return_di"
14764 (unspec [(match_operand:DI 0 "register_operand" "c")]
14765 UNSPEC_EH_RETURN))]
14770 "ix86_expand_epilogue (2); DONE;")
14772 (define_insn "leave"
14773 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14774 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14775 (clobber (mem:BLK (scratch)))]
14778 [(set_attr "type" "leave")])
14780 (define_insn "leave_rex64"
14781 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14782 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14783 (clobber (mem:BLK (scratch)))]
14786 [(set_attr "type" "leave")])
14788 (define_expand "ffssi2"
14790 [(set (match_operand:SI 0 "register_operand" "")
14791 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14792 (clobber (match_scratch:SI 2 ""))
14793 (clobber (reg:CC FLAGS_REG))])]
14798 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14803 (define_expand "ffs_cmove"
14804 [(set (match_dup 2) (const_int -1))
14805 (parallel [(set (reg:CCZ FLAGS_REG)
14806 (compare:CCZ (match_operand:SI 1 "register_operand" "")
14808 (set (match_operand:SI 0 "nonimmediate_operand" "")
14809 (ctz:SI (match_dup 1)))])
14810 (set (match_dup 0) (if_then_else:SI
14811 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14814 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14815 (clobber (reg:CC FLAGS_REG))])]
14817 "operands[2] = gen_reg_rtx (SImode);")
14819 (define_insn_and_split "*ffs_no_cmove"
14820 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14821 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14822 (clobber (match_scratch:SI 2 "=&q"))
14823 (clobber (reg:CC FLAGS_REG))]
14826 "&& reload_completed"
14827 [(parallel [(set (reg:CCZ FLAGS_REG)
14828 (compare:CCZ (match_dup 1) (const_int 0)))
14829 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14830 (set (strict_low_part (match_dup 3))
14831 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14832 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14833 (clobber (reg:CC FLAGS_REG))])
14834 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14835 (clobber (reg:CC FLAGS_REG))])
14836 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14837 (clobber (reg:CC FLAGS_REG))])]
14839 operands[3] = gen_lowpart (QImode, operands[2]);
14840 ix86_expand_clear (operands[2]);
14843 (define_insn "*ffssi_1"
14844 [(set (reg:CCZ FLAGS_REG)
14845 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14847 (set (match_operand:SI 0 "register_operand" "=r")
14848 (ctz:SI (match_dup 1)))]
14850 "bsf{l}\t{%1, %0|%0, %1}"
14851 [(set_attr "prefix_0f" "1")])
14853 (define_expand "ffsdi2"
14854 [(set (match_dup 2) (const_int -1))
14855 (parallel [(set (reg:CCZ FLAGS_REG)
14856 (compare:CCZ (match_operand:DI 1 "register_operand" "")
14858 (set (match_operand:DI 0 "nonimmediate_operand" "")
14859 (ctz:DI (match_dup 1)))])
14860 (set (match_dup 0) (if_then_else:DI
14861 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14864 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14865 (clobber (reg:CC FLAGS_REG))])]
14867 "operands[2] = gen_reg_rtx (DImode);")
14869 (define_insn "*ffsdi_1"
14870 [(set (reg:CCZ FLAGS_REG)
14871 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14873 (set (match_operand:DI 0 "register_operand" "=r")
14874 (ctz:DI (match_dup 1)))]
14876 "bsf{q}\t{%1, %0|%0, %1}"
14877 [(set_attr "prefix_0f" "1")])
14879 (define_insn "ctzsi2"
14880 [(set (match_operand:SI 0 "register_operand" "=r")
14881 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14882 (clobber (reg:CC FLAGS_REG))]
14884 "bsf{l}\t{%1, %0|%0, %1}"
14885 [(set_attr "prefix_0f" "1")])
14887 (define_insn "ctzdi2"
14888 [(set (match_operand:DI 0 "register_operand" "=r")
14889 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14890 (clobber (reg:CC FLAGS_REG))]
14892 "bsf{q}\t{%1, %0|%0, %1}"
14893 [(set_attr "prefix_0f" "1")])
14895 (define_expand "clzsi2"
14897 [(set (match_operand:SI 0 "register_operand" "")
14898 (minus:SI (const_int 31)
14899 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14900 (clobber (reg:CC FLAGS_REG))])
14902 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14903 (clobber (reg:CC FLAGS_REG))])]
14908 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14913 (define_insn "clzsi2_abm"
14914 [(set (match_operand:SI 0 "register_operand" "=r")
14915 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14916 (clobber (reg:CC FLAGS_REG))]
14918 "lzcnt{l}\t{%1, %0|%0, %1}"
14919 [(set_attr "prefix_rep" "1")
14920 (set_attr "type" "bitmanip")
14921 (set_attr "mode" "SI")])
14923 (define_insn "*bsr"
14924 [(set (match_operand:SI 0 "register_operand" "=r")
14925 (minus:SI (const_int 31)
14926 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14927 (clobber (reg:CC FLAGS_REG))]
14929 "bsr{l}\t{%1, %0|%0, %1}"
14930 [(set_attr "prefix_0f" "1")
14931 (set_attr "mode" "SI")])
14933 (define_insn "popcountsi2"
14934 [(set (match_operand:SI 0 "register_operand" "=r")
14935 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14936 (clobber (reg:CC FLAGS_REG))]
14938 "popcnt{l}\t{%1, %0|%0, %1}"
14939 [(set_attr "prefix_rep" "1")
14940 (set_attr "type" "bitmanip")
14941 (set_attr "mode" "SI")])
14943 (define_insn "*popcountsi2_cmp"
14944 [(set (reg FLAGS_REG)
14946 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14948 (set (match_operand:SI 0 "register_operand" "=r")
14949 (popcount:SI (match_dup 1)))]
14950 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14951 "popcnt{l}\t{%1, %0|%0, %1}"
14952 [(set_attr "prefix_rep" "1")
14953 (set_attr "type" "bitmanip")
14954 (set_attr "mode" "SI")])
14956 (define_insn "*popcountsi2_cmp_zext"
14957 [(set (reg FLAGS_REG)
14959 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14961 (set (match_operand:DI 0 "register_operand" "=r")
14962 (zero_extend:DI(popcount:SI (match_dup 1))))]
14963 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14964 "popcnt{l}\t{%1, %0|%0, %1}"
14965 [(set_attr "prefix_rep" "1")
14966 (set_attr "type" "bitmanip")
14967 (set_attr "mode" "SI")])
14969 (define_expand "bswapsi2"
14970 [(set (match_operand:SI 0 "register_operand" "")
14971 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14976 rtx x = operands[0];
14978 emit_move_insn (x, operands[1]);
14979 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14980 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14981 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14986 (define_insn "*bswapsi_1"
14987 [(set (match_operand:SI 0 "register_operand" "=r")
14988 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14991 [(set_attr "prefix_0f" "1")
14992 (set_attr "length" "2")])
14994 (define_insn "*bswaphi_lowpart_1"
14995 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14996 (bswap:HI (match_dup 0)))
14997 (clobber (reg:CC FLAGS_REG))]
14998 "TARGET_USE_XCHGB || optimize_size"
15000 xchg{b}\t{%h0, %b0|%b0, %h0}
15001 rol{w}\t{$8, %0|%0, 8}"
15002 [(set_attr "length" "2,4")
15003 (set_attr "mode" "QI,HI")])
15005 (define_insn "bswaphi_lowpart"
15006 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15007 (bswap:HI (match_dup 0)))
15008 (clobber (reg:CC FLAGS_REG))]
15010 "rol{w}\t{$8, %0|%0, 8}"
15011 [(set_attr "length" "4")
15012 (set_attr "mode" "HI")])
15014 (define_insn "bswapdi2"
15015 [(set (match_operand:DI 0 "register_operand" "=r")
15016 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15019 [(set_attr "prefix_0f" "1")
15020 (set_attr "length" "3")])
15022 (define_expand "clzdi2"
15024 [(set (match_operand:DI 0 "register_operand" "")
15025 (minus:DI (const_int 63)
15026 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15027 (clobber (reg:CC FLAGS_REG))])
15029 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15030 (clobber (reg:CC FLAGS_REG))])]
15035 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15040 (define_insn "clzdi2_abm"
15041 [(set (match_operand:DI 0 "register_operand" "=r")
15042 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15043 (clobber (reg:CC FLAGS_REG))]
15044 "TARGET_64BIT && TARGET_ABM"
15045 "lzcnt{q}\t{%1, %0|%0, %1}"
15046 [(set_attr "prefix_rep" "1")
15047 (set_attr "type" "bitmanip")
15048 (set_attr "mode" "DI")])
15050 (define_insn "*bsr_rex64"
15051 [(set (match_operand:DI 0 "register_operand" "=r")
15052 (minus:DI (const_int 63)
15053 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15054 (clobber (reg:CC FLAGS_REG))]
15056 "bsr{q}\t{%1, %0|%0, %1}"
15057 [(set_attr "prefix_0f" "1")
15058 (set_attr "mode" "DI")])
15060 (define_insn "popcountdi2"
15061 [(set (match_operand:DI 0 "register_operand" "=r")
15062 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15063 (clobber (reg:CC FLAGS_REG))]
15064 "TARGET_64BIT && TARGET_POPCNT"
15065 "popcnt{q}\t{%1, %0|%0, %1}"
15066 [(set_attr "prefix_rep" "1")
15067 (set_attr "type" "bitmanip")
15068 (set_attr "mode" "DI")])
15070 (define_insn "*popcountdi2_cmp"
15071 [(set (reg FLAGS_REG)
15073 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15075 (set (match_operand:DI 0 "register_operand" "=r")
15076 (popcount:DI (match_dup 1)))]
15077 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15078 "popcnt{q}\t{%1, %0|%0, %1}"
15079 [(set_attr "prefix_rep" "1")
15080 (set_attr "type" "bitmanip")
15081 (set_attr "mode" "DI")])
15083 (define_expand "clzhi2"
15085 [(set (match_operand:HI 0 "register_operand" "")
15086 (minus:HI (const_int 15)
15087 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15088 (clobber (reg:CC FLAGS_REG))])
15090 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15091 (clobber (reg:CC FLAGS_REG))])]
15096 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15101 (define_insn "clzhi2_abm"
15102 [(set (match_operand:HI 0 "register_operand" "=r")
15103 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15104 (clobber (reg:CC FLAGS_REG))]
15106 "lzcnt{w}\t{%1, %0|%0, %1}"
15107 [(set_attr "prefix_rep" "1")
15108 (set_attr "type" "bitmanip")
15109 (set_attr "mode" "HI")])
15111 (define_insn "*bsrhi"
15112 [(set (match_operand:HI 0 "register_operand" "=r")
15113 (minus:HI (const_int 15)
15114 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15115 (clobber (reg:CC FLAGS_REG))]
15117 "bsr{w}\t{%1, %0|%0, %1}"
15118 [(set_attr "prefix_0f" "1")
15119 (set_attr "mode" "HI")])
15121 (define_insn "popcounthi2"
15122 [(set (match_operand:HI 0 "register_operand" "=r")
15123 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15124 (clobber (reg:CC FLAGS_REG))]
15126 "popcnt{w}\t{%1, %0|%0, %1}"
15127 [(set_attr "prefix_rep" "1")
15128 (set_attr "type" "bitmanip")
15129 (set_attr "mode" "HI")])
15131 (define_insn "*popcounthi2_cmp"
15132 [(set (reg FLAGS_REG)
15134 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15136 (set (match_operand:HI 0 "register_operand" "=r")
15137 (popcount:HI (match_dup 1)))]
15138 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15139 "popcnt{w}\t{%1, %0|%0, %1}"
15140 [(set_attr "prefix_rep" "1")
15141 (set_attr "type" "bitmanip")
15142 (set_attr "mode" "HI")])
15144 (define_expand "paritydi2"
15145 [(set (match_operand:DI 0 "register_operand" "")
15146 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15149 rtx scratch = gen_reg_rtx (QImode);
15152 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15153 NULL_RTX, operands[1]));
15155 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15156 gen_rtx_REG (CCmode, FLAGS_REG),
15158 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15161 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15164 rtx tmp = gen_reg_rtx (SImode);
15166 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15167 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15172 (define_insn_and_split "paritydi2_cmp"
15173 [(set (reg:CC FLAGS_REG)
15174 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15175 (clobber (match_scratch:DI 0 "=r,X"))
15176 (clobber (match_scratch:SI 1 "=r,r"))
15177 (clobber (match_scratch:HI 2 "=Q,Q"))]
15180 "&& reload_completed"
15182 [(set (match_dup 1)
15183 (xor:SI (match_dup 1) (match_dup 4)))
15184 (clobber (reg:CC FLAGS_REG))])
15186 [(set (reg:CC FLAGS_REG)
15187 (parity:CC (match_dup 1)))
15188 (clobber (match_dup 1))
15189 (clobber (match_dup 2))])]
15191 operands[4] = gen_lowpart (SImode, operands[3]);
15193 if (MEM_P (operands[3]))
15194 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15195 else if (! TARGET_64BIT)
15196 operands[1] = gen_highpart (SImode, operands[3]);
15199 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15200 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15204 (define_expand "paritysi2"
15205 [(set (match_operand:SI 0 "register_operand" "")
15206 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15209 rtx scratch = gen_reg_rtx (QImode);
15212 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15214 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15215 gen_rtx_REG (CCmode, FLAGS_REG),
15217 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15219 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15223 (define_insn_and_split "paritysi2_cmp"
15224 [(set (reg:CC FLAGS_REG)
15225 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15226 (clobber (match_scratch:SI 0 "=r,X"))
15227 (clobber (match_scratch:HI 1 "=Q,Q"))]
15230 "&& reload_completed"
15232 [(set (match_dup 1)
15233 (xor:HI (match_dup 1) (match_dup 3)))
15234 (clobber (reg:CC FLAGS_REG))])
15236 [(set (reg:CC FLAGS_REG)
15237 (parity:CC (match_dup 1)))
15238 (clobber (match_dup 1))])]
15240 operands[3] = gen_lowpart (HImode, operands[2]);
15242 if (MEM_P (operands[2]))
15243 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15246 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15247 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15251 (define_insn "*parityhi2_cmp"
15252 [(set (reg:CC FLAGS_REG)
15253 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15254 (clobber (match_scratch:HI 0 "=Q"))]
15256 "xor{b}\t{%h0, %b0|%b0, %h0}"
15257 [(set_attr "length" "2")
15258 (set_attr "mode" "HI")])
15260 (define_insn "*parityqi2_cmp"
15261 [(set (reg:CC FLAGS_REG)
15262 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15265 [(set_attr "length" "2")
15266 (set_attr "mode" "QI")])
15268 ;; Thread-local storage patterns for ELF.
15270 ;; Note that these code sequences must appear exactly as shown
15271 ;; in order to allow linker relaxation.
15273 (define_insn "*tls_global_dynamic_32_gnu"
15274 [(set (match_operand:SI 0 "register_operand" "=a")
15275 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15276 (match_operand:SI 2 "tls_symbolic_operand" "")
15277 (match_operand:SI 3 "call_insn_operand" "")]
15279 (clobber (match_scratch:SI 4 "=d"))
15280 (clobber (match_scratch:SI 5 "=c"))
15281 (clobber (reg:CC FLAGS_REG))]
15282 "!TARGET_64BIT && TARGET_GNU_TLS"
15283 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15284 [(set_attr "type" "multi")
15285 (set_attr "length" "12")])
15287 (define_insn "*tls_global_dynamic_32_sun"
15288 [(set (match_operand:SI 0 "register_operand" "=a")
15289 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15290 (match_operand:SI 2 "tls_symbolic_operand" "")
15291 (match_operand:SI 3 "call_insn_operand" "")]
15293 (clobber (match_scratch:SI 4 "=d"))
15294 (clobber (match_scratch:SI 5 "=c"))
15295 (clobber (reg:CC FLAGS_REG))]
15296 "!TARGET_64BIT && TARGET_SUN_TLS"
15297 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15298 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15299 [(set_attr "type" "multi")
15300 (set_attr "length" "14")])
15302 (define_expand "tls_global_dynamic_32"
15303 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15306 (match_operand:SI 1 "tls_symbolic_operand" "")
15309 (clobber (match_scratch:SI 4 ""))
15310 (clobber (match_scratch:SI 5 ""))
15311 (clobber (reg:CC FLAGS_REG))])]
15315 operands[2] = pic_offset_table_rtx;
15318 operands[2] = gen_reg_rtx (Pmode);
15319 emit_insn (gen_set_got (operands[2]));
15321 if (TARGET_GNU2_TLS)
15323 emit_insn (gen_tls_dynamic_gnu2_32
15324 (operands[0], operands[1], operands[2]));
15327 operands[3] = ix86_tls_get_addr ();
15330 (define_insn "*tls_global_dynamic_64"
15331 [(set (match_operand:DI 0 "register_operand" "=a")
15332 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15333 (match_operand:DI 3 "" "")))
15334 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15337 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15338 [(set_attr "type" "multi")
15339 (set_attr "length" "16")])
15341 (define_expand "tls_global_dynamic_64"
15342 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15343 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15344 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15348 if (TARGET_GNU2_TLS)
15350 emit_insn (gen_tls_dynamic_gnu2_64
15351 (operands[0], operands[1]));
15354 operands[2] = ix86_tls_get_addr ();
15357 (define_insn "*tls_local_dynamic_base_32_gnu"
15358 [(set (match_operand:SI 0 "register_operand" "=a")
15359 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15360 (match_operand:SI 2 "call_insn_operand" "")]
15361 UNSPEC_TLS_LD_BASE))
15362 (clobber (match_scratch:SI 3 "=d"))
15363 (clobber (match_scratch:SI 4 "=c"))
15364 (clobber (reg:CC FLAGS_REG))]
15365 "!TARGET_64BIT && TARGET_GNU_TLS"
15366 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15367 [(set_attr "type" "multi")
15368 (set_attr "length" "11")])
15370 (define_insn "*tls_local_dynamic_base_32_sun"
15371 [(set (match_operand:SI 0 "register_operand" "=a")
15372 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15373 (match_operand:SI 2 "call_insn_operand" "")]
15374 UNSPEC_TLS_LD_BASE))
15375 (clobber (match_scratch:SI 3 "=d"))
15376 (clobber (match_scratch:SI 4 "=c"))
15377 (clobber (reg:CC FLAGS_REG))]
15378 "!TARGET_64BIT && TARGET_SUN_TLS"
15379 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15380 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15381 [(set_attr "type" "multi")
15382 (set_attr "length" "13")])
15384 (define_expand "tls_local_dynamic_base_32"
15385 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15386 (unspec:SI [(match_dup 1) (match_dup 2)]
15387 UNSPEC_TLS_LD_BASE))
15388 (clobber (match_scratch:SI 3 ""))
15389 (clobber (match_scratch:SI 4 ""))
15390 (clobber (reg:CC FLAGS_REG))])]
15394 operands[1] = pic_offset_table_rtx;
15397 operands[1] = gen_reg_rtx (Pmode);
15398 emit_insn (gen_set_got (operands[1]));
15400 if (TARGET_GNU2_TLS)
15402 emit_insn (gen_tls_dynamic_gnu2_32
15403 (operands[0], ix86_tls_module_base (), operands[1]));
15406 operands[2] = ix86_tls_get_addr ();
15409 (define_insn "*tls_local_dynamic_base_64"
15410 [(set (match_operand:DI 0 "register_operand" "=a")
15411 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15412 (match_operand:DI 2 "" "")))
15413 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15415 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15416 [(set_attr "type" "multi")
15417 (set_attr "length" "12")])
15419 (define_expand "tls_local_dynamic_base_64"
15420 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15421 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15422 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15425 if (TARGET_GNU2_TLS)
15427 emit_insn (gen_tls_dynamic_gnu2_64
15428 (operands[0], ix86_tls_module_base ()));
15431 operands[1] = ix86_tls_get_addr ();
15434 ;; Local dynamic of a single variable is a lose. Show combine how
15435 ;; to convert that back to global dynamic.
15437 (define_insn_and_split "*tls_local_dynamic_32_once"
15438 [(set (match_operand:SI 0 "register_operand" "=a")
15439 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15440 (match_operand:SI 2 "call_insn_operand" "")]
15441 UNSPEC_TLS_LD_BASE)
15442 (const:SI (unspec:SI
15443 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15445 (clobber (match_scratch:SI 4 "=d"))
15446 (clobber (match_scratch:SI 5 "=c"))
15447 (clobber (reg:CC FLAGS_REG))]
15451 [(parallel [(set (match_dup 0)
15452 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15454 (clobber (match_dup 4))
15455 (clobber (match_dup 5))
15456 (clobber (reg:CC FLAGS_REG))])]
15459 ;; Load and add the thread base pointer from %gs:0.
15461 (define_insn "*load_tp_si"
15462 [(set (match_operand:SI 0 "register_operand" "=r")
15463 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15465 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15466 [(set_attr "type" "imov")
15467 (set_attr "modrm" "0")
15468 (set_attr "length" "7")
15469 (set_attr "memory" "load")
15470 (set_attr "imm_disp" "false")])
15472 (define_insn "*add_tp_si"
15473 [(set (match_operand:SI 0 "register_operand" "=r")
15474 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15475 (match_operand:SI 1 "register_operand" "0")))
15476 (clobber (reg:CC FLAGS_REG))]
15478 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15479 [(set_attr "type" "alu")
15480 (set_attr "modrm" "0")
15481 (set_attr "length" "7")
15482 (set_attr "memory" "load")
15483 (set_attr "imm_disp" "false")])
15485 (define_insn "*load_tp_di"
15486 [(set (match_operand:DI 0 "register_operand" "=r")
15487 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15489 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15490 [(set_attr "type" "imov")
15491 (set_attr "modrm" "0")
15492 (set_attr "length" "7")
15493 (set_attr "memory" "load")
15494 (set_attr "imm_disp" "false")])
15496 (define_insn "*add_tp_di"
15497 [(set (match_operand:DI 0 "register_operand" "=r")
15498 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15499 (match_operand:DI 1 "register_operand" "0")))
15500 (clobber (reg:CC FLAGS_REG))]
15502 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15503 [(set_attr "type" "alu")
15504 (set_attr "modrm" "0")
15505 (set_attr "length" "7")
15506 (set_attr "memory" "load")
15507 (set_attr "imm_disp" "false")])
15509 ;; GNU2 TLS patterns can be split.
15511 (define_expand "tls_dynamic_gnu2_32"
15512 [(set (match_dup 3)
15513 (plus:SI (match_operand:SI 2 "register_operand" "")
15515 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15518 [(set (match_operand:SI 0 "register_operand" "")
15519 (unspec:SI [(match_dup 1) (match_dup 3)
15520 (match_dup 2) (reg:SI SP_REG)]
15522 (clobber (reg:CC FLAGS_REG))])]
15523 "!TARGET_64BIT && TARGET_GNU2_TLS"
15525 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15526 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15529 (define_insn "*tls_dynamic_lea_32"
15530 [(set (match_operand:SI 0 "register_operand" "=r")
15531 (plus:SI (match_operand:SI 1 "register_operand" "b")
15533 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15534 UNSPEC_TLSDESC))))]
15535 "!TARGET_64BIT && TARGET_GNU2_TLS"
15536 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15537 [(set_attr "type" "lea")
15538 (set_attr "mode" "SI")
15539 (set_attr "length" "6")
15540 (set_attr "length_address" "4")])
15542 (define_insn "*tls_dynamic_call_32"
15543 [(set (match_operand:SI 0 "register_operand" "=a")
15544 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15545 (match_operand:SI 2 "register_operand" "0")
15546 ;; we have to make sure %ebx still points to the GOT
15547 (match_operand:SI 3 "register_operand" "b")
15550 (clobber (reg:CC FLAGS_REG))]
15551 "!TARGET_64BIT && TARGET_GNU2_TLS"
15552 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15553 [(set_attr "type" "call")
15554 (set_attr "length" "2")
15555 (set_attr "length_address" "0")])
15557 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15558 [(set (match_operand:SI 0 "register_operand" "=&a")
15560 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15561 (match_operand:SI 4 "" "")
15562 (match_operand:SI 2 "register_operand" "b")
15565 (const:SI (unspec:SI
15566 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15568 (clobber (reg:CC FLAGS_REG))]
15569 "!TARGET_64BIT && TARGET_GNU2_TLS"
15572 [(set (match_dup 0) (match_dup 5))]
15574 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15575 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15578 (define_expand "tls_dynamic_gnu2_64"
15579 [(set (match_dup 2)
15580 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15583 [(set (match_operand:DI 0 "register_operand" "")
15584 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15586 (clobber (reg:CC FLAGS_REG))])]
15587 "TARGET_64BIT && TARGET_GNU2_TLS"
15589 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15590 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15593 (define_insn "*tls_dynamic_lea_64"
15594 [(set (match_operand:DI 0 "register_operand" "=r")
15595 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15597 "TARGET_64BIT && TARGET_GNU2_TLS"
15598 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15599 [(set_attr "type" "lea")
15600 (set_attr "mode" "DI")
15601 (set_attr "length" "7")
15602 (set_attr "length_address" "4")])
15604 (define_insn "*tls_dynamic_call_64"
15605 [(set (match_operand:DI 0 "register_operand" "=a")
15606 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15607 (match_operand:DI 2 "register_operand" "0")
15610 (clobber (reg:CC FLAGS_REG))]
15611 "TARGET_64BIT && TARGET_GNU2_TLS"
15612 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15613 [(set_attr "type" "call")
15614 (set_attr "length" "2")
15615 (set_attr "length_address" "0")])
15617 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15618 [(set (match_operand:DI 0 "register_operand" "=&a")
15620 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15621 (match_operand:DI 3 "" "")
15624 (const:DI (unspec:DI
15625 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15627 (clobber (reg:CC FLAGS_REG))]
15628 "TARGET_64BIT && TARGET_GNU2_TLS"
15631 [(set (match_dup 0) (match_dup 4))]
15633 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15634 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15639 ;; These patterns match the binary 387 instructions for addM3, subM3,
15640 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15641 ;; SFmode. The first is the normal insn, the second the same insn but
15642 ;; with one operand a conversion, and the third the same insn but with
15643 ;; the other operand a conversion. The conversion may be SFmode or
15644 ;; SImode if the target mode DFmode, but only SImode if the target mode
15647 ;; Gcc is slightly more smart about handling normal two address instructions
15648 ;; so use special patterns for add and mull.
15650 (define_insn "*fop_sf_comm_mixed"
15651 [(set (match_operand:SF 0 "register_operand" "=f,x")
15652 (match_operator:SF 3 "binary_fp_operator"
15653 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15654 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15655 "TARGET_MIX_SSE_I387
15656 && COMMUTATIVE_ARITH_P (operands[3])
15657 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15658 "* return output_387_binary_op (insn, operands);"
15659 [(set (attr "type")
15660 (if_then_else (eq_attr "alternative" "1")
15661 (if_then_else (match_operand:SF 3 "mult_operator" "")
15662 (const_string "ssemul")
15663 (const_string "sseadd"))
15664 (if_then_else (match_operand:SF 3 "mult_operator" "")
15665 (const_string "fmul")
15666 (const_string "fop"))))
15667 (set_attr "mode" "SF")])
15669 (define_insn "*fop_sf_comm_sse"
15670 [(set (match_operand:SF 0 "register_operand" "=x")
15671 (match_operator:SF 3 "binary_fp_operator"
15672 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15673 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15675 && COMMUTATIVE_ARITH_P (operands[3])
15676 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15677 "* return output_387_binary_op (insn, operands);"
15678 [(set (attr "type")
15679 (if_then_else (match_operand:SF 3 "mult_operator" "")
15680 (const_string "ssemul")
15681 (const_string "sseadd")))
15682 (set_attr "mode" "SF")])
15684 (define_insn "*fop_sf_comm_i387"
15685 [(set (match_operand:SF 0 "register_operand" "=f")
15686 (match_operator:SF 3 "binary_fp_operator"
15687 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15688 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15690 && COMMUTATIVE_ARITH_P (operands[3])
15691 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15692 "* return output_387_binary_op (insn, operands);"
15693 [(set (attr "type")
15694 (if_then_else (match_operand:SF 3 "mult_operator" "")
15695 (const_string "fmul")
15696 (const_string "fop")))
15697 (set_attr "mode" "SF")])
15699 (define_insn "*fop_sf_1_mixed"
15700 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15701 (match_operator:SF 3 "binary_fp_operator"
15702 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15703 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15704 "TARGET_MIX_SSE_I387
15705 && !COMMUTATIVE_ARITH_P (operands[3])
15706 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15707 "* return output_387_binary_op (insn, operands);"
15708 [(set (attr "type")
15709 (cond [(and (eq_attr "alternative" "2")
15710 (match_operand:SF 3 "mult_operator" ""))
15711 (const_string "ssemul")
15712 (and (eq_attr "alternative" "2")
15713 (match_operand:SF 3 "div_operator" ""))
15714 (const_string "ssediv")
15715 (eq_attr "alternative" "2")
15716 (const_string "sseadd")
15717 (match_operand:SF 3 "mult_operator" "")
15718 (const_string "fmul")
15719 (match_operand:SF 3 "div_operator" "")
15720 (const_string "fdiv")
15722 (const_string "fop")))
15723 (set_attr "mode" "SF")])
15725 (define_insn "*rcpsf2_sse"
15726 [(set (match_operand:SF 0 "register_operand" "=x")
15727 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15730 "rcpss\t{%1, %0|%0, %1}"
15731 [(set_attr "type" "sse")
15732 (set_attr "mode" "SF")])
15734 (define_insn "*fop_sf_1_sse"
15735 [(set (match_operand:SF 0 "register_operand" "=x")
15736 (match_operator:SF 3 "binary_fp_operator"
15737 [(match_operand:SF 1 "register_operand" "0")
15738 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15740 && !COMMUTATIVE_ARITH_P (operands[3])"
15741 "* return output_387_binary_op (insn, operands);"
15742 [(set (attr "type")
15743 (cond [(match_operand:SF 3 "mult_operator" "")
15744 (const_string "ssemul")
15745 (match_operand:SF 3 "div_operator" "")
15746 (const_string "ssediv")
15748 (const_string "sseadd")))
15749 (set_attr "mode" "SF")])
15751 ;; This pattern is not fully shadowed by the pattern above.
15752 (define_insn "*fop_sf_1_i387"
15753 [(set (match_operand:SF 0 "register_operand" "=f,f")
15754 (match_operator:SF 3 "binary_fp_operator"
15755 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15756 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15757 "TARGET_80387 && !TARGET_SSE_MATH
15758 && !COMMUTATIVE_ARITH_P (operands[3])
15759 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15760 "* return output_387_binary_op (insn, operands);"
15761 [(set (attr "type")
15762 (cond [(match_operand:SF 3 "mult_operator" "")
15763 (const_string "fmul")
15764 (match_operand:SF 3 "div_operator" "")
15765 (const_string "fdiv")
15767 (const_string "fop")))
15768 (set_attr "mode" "SF")])
15770 ;; ??? Add SSE splitters for these!
15771 (define_insn "*fop_sf_2<mode>_i387"
15772 [(set (match_operand:SF 0 "register_operand" "=f,f")
15773 (match_operator:SF 3 "binary_fp_operator"
15774 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15775 (match_operand:SF 2 "register_operand" "0,0")]))]
15776 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15777 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15778 [(set (attr "type")
15779 (cond [(match_operand:SF 3 "mult_operator" "")
15780 (const_string "fmul")
15781 (match_operand:SF 3 "div_operator" "")
15782 (const_string "fdiv")
15784 (const_string "fop")))
15785 (set_attr "fp_int_src" "true")
15786 (set_attr "mode" "<MODE>")])
15788 (define_insn "*fop_sf_3<mode>_i387"
15789 [(set (match_operand:SF 0 "register_operand" "=f,f")
15790 (match_operator:SF 3 "binary_fp_operator"
15791 [(match_operand:SF 1 "register_operand" "0,0")
15792 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15793 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15794 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15795 [(set (attr "type")
15796 (cond [(match_operand:SF 3 "mult_operator" "")
15797 (const_string "fmul")
15798 (match_operand:SF 3 "div_operator" "")
15799 (const_string "fdiv")
15801 (const_string "fop")))
15802 (set_attr "fp_int_src" "true")
15803 (set_attr "mode" "<MODE>")])
15805 (define_insn "*fop_df_comm_mixed"
15806 [(set (match_operand:DF 0 "register_operand" "=f,x")
15807 (match_operator:DF 3 "binary_fp_operator"
15808 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15809 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15810 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15811 && COMMUTATIVE_ARITH_P (operands[3])
15812 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15813 "* return output_387_binary_op (insn, operands);"
15814 [(set (attr "type")
15815 (if_then_else (eq_attr "alternative" "1")
15816 (if_then_else (match_operand:DF 3 "mult_operator" "")
15817 (const_string "ssemul")
15818 (const_string "sseadd"))
15819 (if_then_else (match_operand:DF 3 "mult_operator" "")
15820 (const_string "fmul")
15821 (const_string "fop"))))
15822 (set_attr "mode" "DF")])
15824 (define_insn "*fop_df_comm_sse"
15825 [(set (match_operand:DF 0 "register_operand" "=x")
15826 (match_operator:DF 3 "binary_fp_operator"
15827 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15828 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15829 "TARGET_SSE2 && TARGET_SSE_MATH
15830 && COMMUTATIVE_ARITH_P (operands[3])
15831 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15832 "* return output_387_binary_op (insn, operands);"
15833 [(set (attr "type")
15834 (if_then_else (match_operand:DF 3 "mult_operator" "")
15835 (const_string "ssemul")
15836 (const_string "sseadd")))
15837 (set_attr "mode" "DF")])
15839 (define_insn "*fop_df_comm_i387"
15840 [(set (match_operand:DF 0 "register_operand" "=f")
15841 (match_operator:DF 3 "binary_fp_operator"
15842 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15843 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15845 && COMMUTATIVE_ARITH_P (operands[3])
15846 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15847 "* return output_387_binary_op (insn, operands);"
15848 [(set (attr "type")
15849 (if_then_else (match_operand:DF 3 "mult_operator" "")
15850 (const_string "fmul")
15851 (const_string "fop")))
15852 (set_attr "mode" "DF")])
15854 (define_insn "*fop_df_1_mixed"
15855 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15856 (match_operator:DF 3 "binary_fp_operator"
15857 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15858 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15859 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15860 && !COMMUTATIVE_ARITH_P (operands[3])
15861 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15862 "* return output_387_binary_op (insn, operands);"
15863 [(set (attr "type")
15864 (cond [(and (eq_attr "alternative" "2")
15865 (match_operand:DF 3 "mult_operator" ""))
15866 (const_string "ssemul")
15867 (and (eq_attr "alternative" "2")
15868 (match_operand:DF 3 "div_operator" ""))
15869 (const_string "ssediv")
15870 (eq_attr "alternative" "2")
15871 (const_string "sseadd")
15872 (match_operand:DF 3 "mult_operator" "")
15873 (const_string "fmul")
15874 (match_operand:DF 3 "div_operator" "")
15875 (const_string "fdiv")
15877 (const_string "fop")))
15878 (set_attr "mode" "DF")])
15880 (define_insn "*fop_df_1_sse"
15881 [(set (match_operand:DF 0 "register_operand" "=x")
15882 (match_operator:DF 3 "binary_fp_operator"
15883 [(match_operand:DF 1 "register_operand" "0")
15884 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15885 "TARGET_SSE2 && TARGET_SSE_MATH
15886 && !COMMUTATIVE_ARITH_P (operands[3])"
15887 "* return output_387_binary_op (insn, operands);"
15888 [(set_attr "mode" "DF")
15890 (cond [(match_operand:DF 3 "mult_operator" "")
15891 (const_string "ssemul")
15892 (match_operand:DF 3 "div_operator" "")
15893 (const_string "ssediv")
15895 (const_string "sseadd")))])
15897 ;; This pattern is not fully shadowed by the pattern above.
15898 (define_insn "*fop_df_1_i387"
15899 [(set (match_operand:DF 0 "register_operand" "=f,f")
15900 (match_operator:DF 3 "binary_fp_operator"
15901 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15902 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15903 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15904 && !COMMUTATIVE_ARITH_P (operands[3])
15905 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15906 "* return output_387_binary_op (insn, operands);"
15907 [(set (attr "type")
15908 (cond [(match_operand:DF 3 "mult_operator" "")
15909 (const_string "fmul")
15910 (match_operand:DF 3 "div_operator" "")
15911 (const_string "fdiv")
15913 (const_string "fop")))
15914 (set_attr "mode" "DF")])
15916 ;; ??? Add SSE splitters for these!
15917 (define_insn "*fop_df_2<mode>_i387"
15918 [(set (match_operand:DF 0 "register_operand" "=f,f")
15919 (match_operator:DF 3 "binary_fp_operator"
15920 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15921 (match_operand:DF 2 "register_operand" "0,0")]))]
15922 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15923 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15924 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15925 [(set (attr "type")
15926 (cond [(match_operand:DF 3 "mult_operator" "")
15927 (const_string "fmul")
15928 (match_operand:DF 3 "div_operator" "")
15929 (const_string "fdiv")
15931 (const_string "fop")))
15932 (set_attr "fp_int_src" "true")
15933 (set_attr "mode" "<MODE>")])
15935 (define_insn "*fop_df_3<mode>_i387"
15936 [(set (match_operand:DF 0 "register_operand" "=f,f")
15937 (match_operator:DF 3 "binary_fp_operator"
15938 [(match_operand:DF 1 "register_operand" "0,0")
15939 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15940 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15941 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15942 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15943 [(set (attr "type")
15944 (cond [(match_operand:DF 3 "mult_operator" "")
15945 (const_string "fmul")
15946 (match_operand:DF 3 "div_operator" "")
15947 (const_string "fdiv")
15949 (const_string "fop")))
15950 (set_attr "fp_int_src" "true")
15951 (set_attr "mode" "<MODE>")])
15953 (define_insn "*fop_df_4_i387"
15954 [(set (match_operand:DF 0 "register_operand" "=f,f")
15955 (match_operator:DF 3 "binary_fp_operator"
15956 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15957 (match_operand:DF 2 "register_operand" "0,f")]))]
15958 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15959 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15960 "* return output_387_binary_op (insn, operands);"
15961 [(set (attr "type")
15962 (cond [(match_operand:DF 3 "mult_operator" "")
15963 (const_string "fmul")
15964 (match_operand:DF 3 "div_operator" "")
15965 (const_string "fdiv")
15967 (const_string "fop")))
15968 (set_attr "mode" "SF")])
15970 (define_insn "*fop_df_5_i387"
15971 [(set (match_operand:DF 0 "register_operand" "=f,f")
15972 (match_operator:DF 3 "binary_fp_operator"
15973 [(match_operand:DF 1 "register_operand" "0,f")
15975 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15976 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15977 "* return output_387_binary_op (insn, operands);"
15978 [(set (attr "type")
15979 (cond [(match_operand:DF 3 "mult_operator" "")
15980 (const_string "fmul")
15981 (match_operand:DF 3 "div_operator" "")
15982 (const_string "fdiv")
15984 (const_string "fop")))
15985 (set_attr "mode" "SF")])
15987 (define_insn "*fop_df_6_i387"
15988 [(set (match_operand:DF 0 "register_operand" "=f,f")
15989 (match_operator:DF 3 "binary_fp_operator"
15991 (match_operand:SF 1 "register_operand" "0,f"))
15993 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15994 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15995 "* return output_387_binary_op (insn, operands);"
15996 [(set (attr "type")
15997 (cond [(match_operand:DF 3 "mult_operator" "")
15998 (const_string "fmul")
15999 (match_operand:DF 3 "div_operator" "")
16000 (const_string "fdiv")
16002 (const_string "fop")))
16003 (set_attr "mode" "SF")])
16005 (define_insn "*fop_xf_comm_i387"
16006 [(set (match_operand:XF 0 "register_operand" "=f")
16007 (match_operator:XF 3 "binary_fp_operator"
16008 [(match_operand:XF 1 "register_operand" "%0")
16009 (match_operand:XF 2 "register_operand" "f")]))]
16011 && COMMUTATIVE_ARITH_P (operands[3])"
16012 "* return output_387_binary_op (insn, operands);"
16013 [(set (attr "type")
16014 (if_then_else (match_operand:XF 3 "mult_operator" "")
16015 (const_string "fmul")
16016 (const_string "fop")))
16017 (set_attr "mode" "XF")])
16019 (define_insn "*fop_xf_1_i387"
16020 [(set (match_operand:XF 0 "register_operand" "=f,f")
16021 (match_operator:XF 3 "binary_fp_operator"
16022 [(match_operand:XF 1 "register_operand" "0,f")
16023 (match_operand:XF 2 "register_operand" "f,0")]))]
16025 && !COMMUTATIVE_ARITH_P (operands[3])"
16026 "* return output_387_binary_op (insn, operands);"
16027 [(set (attr "type")
16028 (cond [(match_operand:XF 3 "mult_operator" "")
16029 (const_string "fmul")
16030 (match_operand:XF 3 "div_operator" "")
16031 (const_string "fdiv")
16033 (const_string "fop")))
16034 (set_attr "mode" "XF")])
16036 (define_insn "*fop_xf_2<mode>_i387"
16037 [(set (match_operand:XF 0 "register_operand" "=f,f")
16038 (match_operator:XF 3 "binary_fp_operator"
16039 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16040 (match_operand:XF 2 "register_operand" "0,0")]))]
16041 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16042 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16043 [(set (attr "type")
16044 (cond [(match_operand:XF 3 "mult_operator" "")
16045 (const_string "fmul")
16046 (match_operand:XF 3 "div_operator" "")
16047 (const_string "fdiv")
16049 (const_string "fop")))
16050 (set_attr "fp_int_src" "true")
16051 (set_attr "mode" "<MODE>")])
16053 (define_insn "*fop_xf_3<mode>_i387"
16054 [(set (match_operand:XF 0 "register_operand" "=f,f")
16055 (match_operator:XF 3 "binary_fp_operator"
16056 [(match_operand:XF 1 "register_operand" "0,0")
16057 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16058 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16059 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16060 [(set (attr "type")
16061 (cond [(match_operand:XF 3 "mult_operator" "")
16062 (const_string "fmul")
16063 (match_operand:XF 3 "div_operator" "")
16064 (const_string "fdiv")
16066 (const_string "fop")))
16067 (set_attr "fp_int_src" "true")
16068 (set_attr "mode" "<MODE>")])
16070 (define_insn "*fop_xf_4_i387"
16071 [(set (match_operand:XF 0 "register_operand" "=f,f")
16072 (match_operator:XF 3 "binary_fp_operator"
16074 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
16075 (match_operand:XF 2 "register_operand" "0,f")]))]
16077 "* return output_387_binary_op (insn, operands);"
16078 [(set (attr "type")
16079 (cond [(match_operand:XF 3 "mult_operator" "")
16080 (const_string "fmul")
16081 (match_operand:XF 3 "div_operator" "")
16082 (const_string "fdiv")
16084 (const_string "fop")))
16085 (set_attr "mode" "SF")])
16087 (define_insn "*fop_xf_5_i387"
16088 [(set (match_operand:XF 0 "register_operand" "=f,f")
16089 (match_operator:XF 3 "binary_fp_operator"
16090 [(match_operand:XF 1 "register_operand" "0,f")
16092 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16094 "* return output_387_binary_op (insn, operands);"
16095 [(set (attr "type")
16096 (cond [(match_operand:XF 3 "mult_operator" "")
16097 (const_string "fmul")
16098 (match_operand:XF 3 "div_operator" "")
16099 (const_string "fdiv")
16101 (const_string "fop")))
16102 (set_attr "mode" "SF")])
16104 (define_insn "*fop_xf_6_i387"
16105 [(set (match_operand:XF 0 "register_operand" "=f,f")
16106 (match_operator:XF 3 "binary_fp_operator"
16108 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
16110 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16112 "* return output_387_binary_op (insn, operands);"
16113 [(set (attr "type")
16114 (cond [(match_operand:XF 3 "mult_operator" "")
16115 (const_string "fmul")
16116 (match_operand:XF 3 "div_operator" "")
16117 (const_string "fdiv")
16119 (const_string "fop")))
16120 (set_attr "mode" "SF")])
16123 [(set (match_operand 0 "register_operand" "")
16124 (match_operator 3 "binary_fp_operator"
16125 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16126 (match_operand 2 "register_operand" "")]))]
16128 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16131 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16132 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16133 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16134 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16135 GET_MODE (operands[3]),
16138 ix86_free_from_memory (GET_MODE (operands[1]));
16143 [(set (match_operand 0 "register_operand" "")
16144 (match_operator 3 "binary_fp_operator"
16145 [(match_operand 1 "register_operand" "")
16146 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16148 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16151 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16152 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16153 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16154 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16155 GET_MODE (operands[3]),
16158 ix86_free_from_memory (GET_MODE (operands[2]));
16162 ;; FPU special functions.
16164 ;; This pattern implements a no-op XFmode truncation for
16165 ;; all fancy i386 XFmode math functions.
16167 (define_insn "truncxf<mode>2_i387_noop_unspec"
16168 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16169 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16170 UNSPEC_TRUNC_NOOP))]
16171 "TARGET_USE_FANCY_MATH_387"
16172 "* return output_387_reg_move (insn, operands);"
16173 [(set_attr "type" "fmov")
16174 (set_attr "mode" "<MODE>")])
16176 (define_insn "sqrtxf2"
16177 [(set (match_operand:XF 0 "register_operand" "=f")
16178 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16179 "TARGET_USE_FANCY_MATH_387"
16181 [(set_attr "type" "fpspc")
16182 (set_attr "mode" "XF")
16183 (set_attr "athlon_decode" "direct")
16184 (set_attr "amdfam10_decode" "direct")])
16186 (define_insn "sqrt_extend<mode>xf2_i387"
16187 [(set (match_operand:XF 0 "register_operand" "=f")
16190 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16191 "TARGET_USE_FANCY_MATH_387"
16193 [(set_attr "type" "fpspc")
16194 (set_attr "mode" "XF")
16195 (set_attr "athlon_decode" "direct")
16196 (set_attr "amdfam10_decode" "direct")])
16198 (define_insn "*rsqrtsf2_sse"
16199 [(set (match_operand:SF 0 "register_operand" "=x")
16200 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16203 "rsqrtss\t{%1, %0|%0, %1}"
16204 [(set_attr "type" "sse")
16205 (set_attr "mode" "SF")])
16207 (define_expand "rsqrtsf2"
16208 [(set (match_operand:SF 0 "register_operand" "=x")
16209 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16211 "TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16212 && flag_finite_math_only && !flag_trapping_math
16213 && flag_unsafe_math_optimizations"
16215 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16219 (define_insn "*sqrt<mode>2_sse"
16220 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16222 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16223 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16224 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16225 [(set_attr "type" "sse")
16226 (set_attr "mode" "<MODE>")
16227 (set_attr "athlon_decode" "*")
16228 (set_attr "amdfam10_decode" "*")])
16230 (define_expand "sqrt<mode>2"
16231 [(set (match_operand:X87MODEF12 0 "register_operand" "")
16233 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16234 "TARGET_USE_FANCY_MATH_387
16235 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16237 if (<MODE>mode == SFmode
16238 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16239 && flag_finite_math_only && !flag_trapping_math
16240 && flag_unsafe_math_optimizations)
16242 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16246 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16248 rtx op0 = gen_reg_rtx (XFmode);
16249 rtx op1 = force_reg (<MODE>mode, operands[1]);
16251 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16252 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16257 (define_insn "fpremxf4_i387"
16258 [(set (match_operand:XF 0 "register_operand" "=f")
16259 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16260 (match_operand:XF 3 "register_operand" "1")]
16262 (set (match_operand:XF 1 "register_operand" "=u")
16263 (unspec:XF [(match_dup 2) (match_dup 3)]
16265 (set (reg:CCFP FPSR_REG)
16266 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16268 "TARGET_USE_FANCY_MATH_387"
16270 [(set_attr "type" "fpspc")
16271 (set_attr "mode" "XF")])
16273 (define_expand "fmodxf3"
16274 [(use (match_operand:XF 0 "register_operand" ""))
16275 (use (match_operand:XF 1 "register_operand" ""))
16276 (use (match_operand:XF 2 "register_operand" ""))]
16277 "TARGET_USE_FANCY_MATH_387"
16279 rtx label = gen_label_rtx ();
16281 emit_label (label);
16283 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16284 operands[1], operands[2]));
16285 ix86_emit_fp_unordered_jump (label);
16286 LABEL_NUSES (label) = 1;
16288 emit_move_insn (operands[0], operands[1]);
16292 (define_expand "fmod<mode>3"
16293 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16294 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16295 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16296 "TARGET_USE_FANCY_MATH_387"
16298 rtx label = gen_label_rtx ();
16300 rtx op1 = gen_reg_rtx (XFmode);
16301 rtx op2 = gen_reg_rtx (XFmode);
16303 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16304 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16306 emit_label (label);
16307 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16308 ix86_emit_fp_unordered_jump (label);
16309 LABEL_NUSES (label) = 1;
16311 /* Truncate the result properly for strict SSE math. */
16312 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16313 && !TARGET_MIX_SSE_I387)
16314 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16316 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16321 (define_insn "fprem1xf4_i387"
16322 [(set (match_operand:XF 0 "register_operand" "=f")
16323 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16324 (match_operand:XF 3 "register_operand" "1")]
16326 (set (match_operand:XF 1 "register_operand" "=u")
16327 (unspec:XF [(match_dup 2) (match_dup 3)]
16329 (set (reg:CCFP FPSR_REG)
16330 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16332 "TARGET_USE_FANCY_MATH_387"
16334 [(set_attr "type" "fpspc")
16335 (set_attr "mode" "XF")])
16337 (define_expand "remainderxf3"
16338 [(use (match_operand:XF 0 "register_operand" ""))
16339 (use (match_operand:XF 1 "register_operand" ""))
16340 (use (match_operand:XF 2 "register_operand" ""))]
16341 "TARGET_USE_FANCY_MATH_387"
16343 rtx label = gen_label_rtx ();
16345 emit_label (label);
16347 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16348 operands[1], operands[2]));
16349 ix86_emit_fp_unordered_jump (label);
16350 LABEL_NUSES (label) = 1;
16352 emit_move_insn (operands[0], operands[1]);
16356 (define_expand "remainder<mode>3"
16357 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16358 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16359 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16360 "TARGET_USE_FANCY_MATH_387"
16362 rtx label = gen_label_rtx ();
16364 rtx op1 = gen_reg_rtx (XFmode);
16365 rtx op2 = gen_reg_rtx (XFmode);
16367 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16368 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16370 emit_label (label);
16372 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16373 ix86_emit_fp_unordered_jump (label);
16374 LABEL_NUSES (label) = 1;
16376 /* Truncate the result properly for strict SSE math. */
16377 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16378 && !TARGET_MIX_SSE_I387)
16379 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16381 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16386 (define_insn "*sinxf2_i387"
16387 [(set (match_operand:XF 0 "register_operand" "=f")
16388 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16389 "TARGET_USE_FANCY_MATH_387
16390 && flag_unsafe_math_optimizations"
16392 [(set_attr "type" "fpspc")
16393 (set_attr "mode" "XF")])
16395 (define_insn "*sin_extend<mode>xf2_i387"
16396 [(set (match_operand:XF 0 "register_operand" "=f")
16397 (unspec:XF [(float_extend:XF
16398 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16400 "TARGET_USE_FANCY_MATH_387
16401 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16402 || TARGET_MIX_SSE_I387)
16403 && flag_unsafe_math_optimizations"
16405 [(set_attr "type" "fpspc")
16406 (set_attr "mode" "XF")])
16408 (define_insn "*cosxf2_i387"
16409 [(set (match_operand:XF 0 "register_operand" "=f")
16410 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16411 "TARGET_USE_FANCY_MATH_387
16412 && flag_unsafe_math_optimizations"
16414 [(set_attr "type" "fpspc")
16415 (set_attr "mode" "XF")])
16417 (define_insn "*cos_extend<mode>xf2_i387"
16418 [(set (match_operand:XF 0 "register_operand" "=f")
16419 (unspec:XF [(float_extend:XF
16420 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16422 "TARGET_USE_FANCY_MATH_387
16423 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16424 || TARGET_MIX_SSE_I387)
16425 && flag_unsafe_math_optimizations"
16427 [(set_attr "type" "fpspc")
16428 (set_attr "mode" "XF")])
16430 ;; When sincos pattern is defined, sin and cos builtin functions will be
16431 ;; expanded to sincos pattern with one of its outputs left unused.
16432 ;; CSE pass will figure out if two sincos patterns can be combined,
16433 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16434 ;; depending on the unused output.
16436 (define_insn "sincosxf3"
16437 [(set (match_operand:XF 0 "register_operand" "=f")
16438 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16439 UNSPEC_SINCOS_COS))
16440 (set (match_operand:XF 1 "register_operand" "=u")
16441 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16442 "TARGET_USE_FANCY_MATH_387
16443 && flag_unsafe_math_optimizations"
16445 [(set_attr "type" "fpspc")
16446 (set_attr "mode" "XF")])
16449 [(set (match_operand:XF 0 "register_operand" "")
16450 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16451 UNSPEC_SINCOS_COS))
16452 (set (match_operand:XF 1 "register_operand" "")
16453 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16454 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16455 && !reload_completed && !reload_in_progress"
16456 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16460 [(set (match_operand:XF 0 "register_operand" "")
16461 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16462 UNSPEC_SINCOS_COS))
16463 (set (match_operand:XF 1 "register_operand" "")
16464 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16465 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16466 && !reload_completed && !reload_in_progress"
16467 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16470 (define_insn "sincos_extend<mode>xf3_i387"
16471 [(set (match_operand:XF 0 "register_operand" "=f")
16472 (unspec:XF [(float_extend:XF
16473 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16474 UNSPEC_SINCOS_COS))
16475 (set (match_operand:XF 1 "register_operand" "=u")
16476 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16477 "TARGET_USE_FANCY_MATH_387
16478 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16479 || TARGET_MIX_SSE_I387)
16480 && flag_unsafe_math_optimizations"
16482 [(set_attr "type" "fpspc")
16483 (set_attr "mode" "XF")])
16486 [(set (match_operand:XF 0 "register_operand" "")
16487 (unspec:XF [(float_extend:XF
16488 (match_operand:X87MODEF12 2 "register_operand" ""))]
16489 UNSPEC_SINCOS_COS))
16490 (set (match_operand:XF 1 "register_operand" "")
16491 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16492 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16493 && !reload_completed && !reload_in_progress"
16494 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16498 [(set (match_operand:XF 0 "register_operand" "")
16499 (unspec:XF [(float_extend:XF
16500 (match_operand:X87MODEF12 2 "register_operand" ""))]
16501 UNSPEC_SINCOS_COS))
16502 (set (match_operand:XF 1 "register_operand" "")
16503 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16504 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16505 && !reload_completed && !reload_in_progress"
16506 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16509 (define_expand "sincos<mode>3"
16510 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16511 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16512 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16513 "TARGET_USE_FANCY_MATH_387
16514 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16515 || TARGET_MIX_SSE_I387)
16516 && flag_unsafe_math_optimizations"
16518 rtx op0 = gen_reg_rtx (XFmode);
16519 rtx op1 = gen_reg_rtx (XFmode);
16521 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16522 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16523 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16527 (define_insn "fptanxf4_i387"
16528 [(set (match_operand:XF 0 "register_operand" "=f")
16529 (match_operand:XF 3 "const_double_operand" "F"))
16530 (set (match_operand:XF 1 "register_operand" "=u")
16531 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16533 "TARGET_USE_FANCY_MATH_387
16534 && flag_unsafe_math_optimizations
16535 && standard_80387_constant_p (operands[3]) == 2"
16537 [(set_attr "type" "fpspc")
16538 (set_attr "mode" "XF")])
16540 (define_insn "fptan_extend<mode>xf4_i387"
16541 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16542 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16543 (set (match_operand:XF 1 "register_operand" "=u")
16544 (unspec:XF [(float_extend:XF
16545 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16547 "TARGET_USE_FANCY_MATH_387
16548 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16549 || TARGET_MIX_SSE_I387)
16550 && flag_unsafe_math_optimizations
16551 && standard_80387_constant_p (operands[3]) == 2"
16553 [(set_attr "type" "fpspc")
16554 (set_attr "mode" "XF")])
16556 (define_expand "tanxf2"
16557 [(use (match_operand:XF 0 "register_operand" ""))
16558 (use (match_operand:XF 1 "register_operand" ""))]
16559 "TARGET_USE_FANCY_MATH_387
16560 && flag_unsafe_math_optimizations"
16562 rtx one = gen_reg_rtx (XFmode);
16563 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16565 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16569 (define_expand "tan<mode>2"
16570 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16571 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16572 "TARGET_USE_FANCY_MATH_387
16573 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16574 || TARGET_MIX_SSE_I387)
16575 && flag_unsafe_math_optimizations"
16577 rtx op0 = gen_reg_rtx (XFmode);
16579 rtx one = gen_reg_rtx (<MODE>mode);
16580 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16582 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16583 operands[1], op2));
16584 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16588 (define_insn "*fpatanxf3_i387"
16589 [(set (match_operand:XF 0 "register_operand" "=f")
16590 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16591 (match_operand:XF 2 "register_operand" "u")]
16593 (clobber (match_scratch:XF 3 "=2"))]
16594 "TARGET_USE_FANCY_MATH_387
16595 && flag_unsafe_math_optimizations"
16597 [(set_attr "type" "fpspc")
16598 (set_attr "mode" "XF")])
16600 (define_insn "fpatan_extend<mode>xf3_i387"
16601 [(set (match_operand:XF 0 "register_operand" "=f")
16602 (unspec:XF [(float_extend:XF
16603 (match_operand:X87MODEF12 1 "register_operand" "0"))
16605 (match_operand:X87MODEF12 2 "register_operand" "u"))]
16607 (clobber (match_scratch:XF 3 "=2"))]
16608 "TARGET_USE_FANCY_MATH_387
16609 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16610 || TARGET_MIX_SSE_I387)
16611 && flag_unsafe_math_optimizations"
16613 [(set_attr "type" "fpspc")
16614 (set_attr "mode" "XF")])
16616 (define_expand "atan2xf3"
16617 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16618 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16619 (match_operand:XF 1 "register_operand" "")]
16621 (clobber (match_scratch:XF 3 ""))])]
16622 "TARGET_USE_FANCY_MATH_387
16623 && flag_unsafe_math_optimizations"
16626 (define_expand "atan2<mode>3"
16627 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16628 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16629 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16630 "TARGET_USE_FANCY_MATH_387
16631 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16632 || TARGET_MIX_SSE_I387)
16633 && flag_unsafe_math_optimizations"
16635 rtx op0 = gen_reg_rtx (XFmode);
16637 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16638 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16642 (define_expand "atanxf2"
16643 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16644 (unspec:XF [(match_dup 2)
16645 (match_operand:XF 1 "register_operand" "")]
16647 (clobber (match_scratch:XF 3 ""))])]
16648 "TARGET_USE_FANCY_MATH_387
16649 && flag_unsafe_math_optimizations"
16651 operands[2] = gen_reg_rtx (XFmode);
16652 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16655 (define_expand "atan<mode>2"
16656 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16657 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16658 "TARGET_USE_FANCY_MATH_387
16659 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16660 || TARGET_MIX_SSE_I387)
16661 && flag_unsafe_math_optimizations"
16663 rtx op0 = gen_reg_rtx (XFmode);
16665 rtx op2 = gen_reg_rtx (<MODE>mode);
16666 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16668 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16669 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16673 (define_expand "asinxf2"
16674 [(set (match_dup 2)
16675 (mult:XF (match_operand:XF 1 "register_operand" "")
16677 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16678 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16679 (parallel [(set (match_operand:XF 0 "register_operand" "")
16680 (unspec:XF [(match_dup 5) (match_dup 1)]
16682 (clobber (match_scratch:XF 6 ""))])]
16683 "TARGET_USE_FANCY_MATH_387
16684 && flag_unsafe_math_optimizations && !optimize_size"
16688 for (i = 2; i < 6; i++)
16689 operands[i] = gen_reg_rtx (XFmode);
16691 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16694 (define_expand "asin<mode>2"
16695 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16696 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16697 "TARGET_USE_FANCY_MATH_387
16698 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16699 || TARGET_MIX_SSE_I387)
16700 && flag_unsafe_math_optimizations && !optimize_size"
16702 rtx op0 = gen_reg_rtx (XFmode);
16703 rtx op1 = gen_reg_rtx (XFmode);
16705 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16706 emit_insn (gen_asinxf2 (op0, op1));
16707 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16711 (define_expand "acosxf2"
16712 [(set (match_dup 2)
16713 (mult:XF (match_operand:XF 1 "register_operand" "")
16715 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16716 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16717 (parallel [(set (match_operand:XF 0 "register_operand" "")
16718 (unspec:XF [(match_dup 1) (match_dup 5)]
16720 (clobber (match_scratch:XF 6 ""))])]
16721 "TARGET_USE_FANCY_MATH_387
16722 && flag_unsafe_math_optimizations && !optimize_size"
16726 for (i = 2; i < 6; i++)
16727 operands[i] = gen_reg_rtx (XFmode);
16729 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16732 (define_expand "acos<mode>2"
16733 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16734 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16735 "TARGET_USE_FANCY_MATH_387
16736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16737 || TARGET_MIX_SSE_I387)
16738 && flag_unsafe_math_optimizations && !optimize_size"
16740 rtx op0 = gen_reg_rtx (XFmode);
16741 rtx op1 = gen_reg_rtx (XFmode);
16743 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16744 emit_insn (gen_acosxf2 (op0, op1));
16745 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16749 (define_insn "fyl2xxf3_i387"
16750 [(set (match_operand:XF 0 "register_operand" "=f")
16751 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16752 (match_operand:XF 2 "register_operand" "u")]
16754 (clobber (match_scratch:XF 3 "=2"))]
16755 "TARGET_USE_FANCY_MATH_387
16756 && flag_unsafe_math_optimizations"
16758 [(set_attr "type" "fpspc")
16759 (set_attr "mode" "XF")])
16761 (define_insn "fyl2x_extend<mode>xf3_i387"
16762 [(set (match_operand:XF 0 "register_operand" "=f")
16763 (unspec:XF [(float_extend:XF
16764 (match_operand:X87MODEF12 1 "register_operand" "0"))
16765 (match_operand:XF 2 "register_operand" "u")]
16767 (clobber (match_scratch:XF 3 "=2"))]
16768 "TARGET_USE_FANCY_MATH_387
16769 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16770 || TARGET_MIX_SSE_I387)
16771 && flag_unsafe_math_optimizations"
16773 [(set_attr "type" "fpspc")
16774 (set_attr "mode" "XF")])
16776 (define_expand "logxf2"
16777 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16778 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16779 (match_dup 2)] UNSPEC_FYL2X))
16780 (clobber (match_scratch:XF 3 ""))])]
16781 "TARGET_USE_FANCY_MATH_387
16782 && flag_unsafe_math_optimizations"
16784 operands[2] = gen_reg_rtx (XFmode);
16785 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16788 (define_expand "log<mode>2"
16789 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16790 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16791 "TARGET_USE_FANCY_MATH_387
16792 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16793 || TARGET_MIX_SSE_I387)
16794 && flag_unsafe_math_optimizations"
16796 rtx op0 = gen_reg_rtx (XFmode);
16798 rtx op2 = gen_reg_rtx (XFmode);
16799 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16801 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16802 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16806 (define_expand "log10xf2"
16807 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16808 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16809 (match_dup 2)] UNSPEC_FYL2X))
16810 (clobber (match_scratch:XF 3 ""))])]
16811 "TARGET_USE_FANCY_MATH_387
16812 && flag_unsafe_math_optimizations"
16814 operands[2] = gen_reg_rtx (XFmode);
16815 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16818 (define_expand "log10<mode>2"
16819 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16820 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16821 "TARGET_USE_FANCY_MATH_387
16822 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16823 || TARGET_MIX_SSE_I387)
16824 && flag_unsafe_math_optimizations"
16826 rtx op0 = gen_reg_rtx (XFmode);
16828 rtx op2 = gen_reg_rtx (XFmode);
16829 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16831 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16832 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16836 (define_expand "log2xf2"
16837 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16838 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16839 (match_dup 2)] UNSPEC_FYL2X))
16840 (clobber (match_scratch:XF 3 ""))])]
16841 "TARGET_USE_FANCY_MATH_387
16842 && flag_unsafe_math_optimizations"
16844 operands[2] = gen_reg_rtx (XFmode);
16845 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16848 (define_expand "log2<mode>2"
16849 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16850 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16851 "TARGET_USE_FANCY_MATH_387
16852 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16853 || TARGET_MIX_SSE_I387)
16854 && flag_unsafe_math_optimizations"
16856 rtx op0 = gen_reg_rtx (XFmode);
16858 rtx op2 = gen_reg_rtx (XFmode);
16859 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16861 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16862 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16866 (define_insn "fyl2xp1xf3_i387"
16867 [(set (match_operand:XF 0 "register_operand" "=f")
16868 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16869 (match_operand:XF 2 "register_operand" "u")]
16871 (clobber (match_scratch:XF 3 "=2"))]
16872 "TARGET_USE_FANCY_MATH_387
16873 && flag_unsafe_math_optimizations"
16875 [(set_attr "type" "fpspc")
16876 (set_attr "mode" "XF")])
16878 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16879 [(set (match_operand:XF 0 "register_operand" "=f")
16880 (unspec:XF [(float_extend:XF
16881 (match_operand:X87MODEF12 1 "register_operand" "0"))
16882 (match_operand:XF 2 "register_operand" "u")]
16884 (clobber (match_scratch:XF 3 "=2"))]
16885 "TARGET_USE_FANCY_MATH_387
16886 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16887 || TARGET_MIX_SSE_I387)
16888 && flag_unsafe_math_optimizations"
16890 [(set_attr "type" "fpspc")
16891 (set_attr "mode" "XF")])
16893 (define_expand "log1pxf2"
16894 [(use (match_operand:XF 0 "register_operand" ""))
16895 (use (match_operand:XF 1 "register_operand" ""))]
16896 "TARGET_USE_FANCY_MATH_387
16897 && flag_unsafe_math_optimizations && !optimize_size"
16899 ix86_emit_i387_log1p (operands[0], operands[1]);
16903 (define_expand "log1p<mode>2"
16904 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16905 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16906 "TARGET_USE_FANCY_MATH_387
16907 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16908 || TARGET_MIX_SSE_I387)
16909 && flag_unsafe_math_optimizations && !optimize_size"
16911 rtx op0 = gen_reg_rtx (XFmode);
16913 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16915 ix86_emit_i387_log1p (op0, operands[1]);
16916 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16920 (define_insn "fxtractxf3_i387"
16921 [(set (match_operand:XF 0 "register_operand" "=f")
16922 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16923 UNSPEC_XTRACT_FRACT))
16924 (set (match_operand:XF 1 "register_operand" "=u")
16925 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16926 "TARGET_USE_FANCY_MATH_387
16927 && flag_unsafe_math_optimizations"
16929 [(set_attr "type" "fpspc")
16930 (set_attr "mode" "XF")])
16932 (define_insn "fxtract_extend<mode>xf3_i387"
16933 [(set (match_operand:XF 0 "register_operand" "=f")
16934 (unspec:XF [(float_extend:XF
16935 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16936 UNSPEC_XTRACT_FRACT))
16937 (set (match_operand:XF 1 "register_operand" "=u")
16938 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16939 "TARGET_USE_FANCY_MATH_387
16940 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16941 || TARGET_MIX_SSE_I387)
16942 && flag_unsafe_math_optimizations"
16944 [(set_attr "type" "fpspc")
16945 (set_attr "mode" "XF")])
16947 (define_expand "logbxf2"
16948 [(parallel [(set (match_dup 2)
16949 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16950 UNSPEC_XTRACT_FRACT))
16951 (set (match_operand:XF 0 "register_operand" "")
16952 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16953 "TARGET_USE_FANCY_MATH_387
16954 && flag_unsafe_math_optimizations"
16956 operands[2] = gen_reg_rtx (XFmode);
16959 (define_expand "logb<mode>2"
16960 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16961 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16962 "TARGET_USE_FANCY_MATH_387
16963 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16964 || TARGET_MIX_SSE_I387)
16965 && flag_unsafe_math_optimizations"
16967 rtx op0 = gen_reg_rtx (XFmode);
16968 rtx op1 = gen_reg_rtx (XFmode);
16970 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16971 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16975 (define_expand "ilogbxf2"
16976 [(use (match_operand:SI 0 "register_operand" ""))
16977 (use (match_operand:XF 1 "register_operand" ""))]
16978 "TARGET_USE_FANCY_MATH_387
16979 && flag_unsafe_math_optimizations && !optimize_size"
16981 rtx op0 = gen_reg_rtx (XFmode);
16982 rtx op1 = gen_reg_rtx (XFmode);
16984 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16985 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16989 (define_expand "ilogb<mode>2"
16990 [(use (match_operand:SI 0 "register_operand" ""))
16991 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16992 "TARGET_USE_FANCY_MATH_387
16993 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16994 || TARGET_MIX_SSE_I387)
16995 && flag_unsafe_math_optimizations && !optimize_size"
16997 rtx op0 = gen_reg_rtx (XFmode);
16998 rtx op1 = gen_reg_rtx (XFmode);
17000 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17001 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17005 (define_insn "*f2xm1xf2_i387"
17006 [(set (match_operand:XF 0 "register_operand" "=f")
17007 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17009 "TARGET_USE_FANCY_MATH_387
17010 && flag_unsafe_math_optimizations"
17012 [(set_attr "type" "fpspc")
17013 (set_attr "mode" "XF")])
17015 (define_insn "*fscalexf4_i387"
17016 [(set (match_operand:XF 0 "register_operand" "=f")
17017 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17018 (match_operand:XF 3 "register_operand" "1")]
17019 UNSPEC_FSCALE_FRACT))
17020 (set (match_operand:XF 1 "register_operand" "=u")
17021 (unspec:XF [(match_dup 2) (match_dup 3)]
17022 UNSPEC_FSCALE_EXP))]
17023 "TARGET_USE_FANCY_MATH_387
17024 && flag_unsafe_math_optimizations"
17026 [(set_attr "type" "fpspc")
17027 (set_attr "mode" "XF")])
17029 (define_expand "expNcorexf3"
17030 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17031 (match_operand:XF 2 "register_operand" "")))
17032 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17033 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17034 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17035 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17036 (parallel [(set (match_operand:XF 0 "register_operand" "")
17037 (unspec:XF [(match_dup 8) (match_dup 4)]
17038 UNSPEC_FSCALE_FRACT))
17040 (unspec:XF [(match_dup 8) (match_dup 4)]
17041 UNSPEC_FSCALE_EXP))])]
17042 "TARGET_USE_FANCY_MATH_387
17043 && flag_unsafe_math_optimizations && !optimize_size"
17047 for (i = 3; i < 10; i++)
17048 operands[i] = gen_reg_rtx (XFmode);
17050 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17053 (define_expand "expxf2"
17054 [(use (match_operand:XF 0 "register_operand" ""))
17055 (use (match_operand:XF 1 "register_operand" ""))]
17056 "TARGET_USE_FANCY_MATH_387
17057 && flag_unsafe_math_optimizations && !optimize_size"
17059 rtx op2 = gen_reg_rtx (XFmode);
17060 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17062 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17066 (define_expand "exp<mode>2"
17067 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17068 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17069 "TARGET_USE_FANCY_MATH_387
17070 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17071 || TARGET_MIX_SSE_I387)
17072 && flag_unsafe_math_optimizations && !optimize_size"
17074 rtx op0 = gen_reg_rtx (XFmode);
17075 rtx op1 = gen_reg_rtx (XFmode);
17077 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17078 emit_insn (gen_expxf2 (op0, op1));
17079 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17083 (define_expand "exp10xf2"
17084 [(use (match_operand:XF 0 "register_operand" ""))
17085 (use (match_operand:XF 1 "register_operand" ""))]
17086 "TARGET_USE_FANCY_MATH_387
17087 && flag_unsafe_math_optimizations && !optimize_size"
17089 rtx op2 = gen_reg_rtx (XFmode);
17090 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17092 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17096 (define_expand "exp10<mode>2"
17097 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17098 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17099 "TARGET_USE_FANCY_MATH_387
17100 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17101 || TARGET_MIX_SSE_I387)
17102 && flag_unsafe_math_optimizations && !optimize_size"
17104 rtx op0 = gen_reg_rtx (XFmode);
17105 rtx op1 = gen_reg_rtx (XFmode);
17107 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17108 emit_insn (gen_exp10xf2 (op0, op1));
17109 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17113 (define_expand "exp2xf2"
17114 [(use (match_operand:XF 0 "register_operand" ""))
17115 (use (match_operand:XF 1 "register_operand" ""))]
17116 "TARGET_USE_FANCY_MATH_387
17117 && flag_unsafe_math_optimizations && !optimize_size"
17119 rtx op2 = gen_reg_rtx (XFmode);
17120 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17122 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17126 (define_expand "exp2<mode>2"
17127 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17128 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17129 "TARGET_USE_FANCY_MATH_387
17130 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17131 || TARGET_MIX_SSE_I387)
17132 && flag_unsafe_math_optimizations && !optimize_size"
17134 rtx op0 = gen_reg_rtx (XFmode);
17135 rtx op1 = gen_reg_rtx (XFmode);
17137 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17138 emit_insn (gen_exp2xf2 (op0, op1));
17139 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17143 (define_expand "expm1xf2"
17144 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17146 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17147 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17148 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17149 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17150 (parallel [(set (match_dup 7)
17151 (unspec:XF [(match_dup 6) (match_dup 4)]
17152 UNSPEC_FSCALE_FRACT))
17154 (unspec:XF [(match_dup 6) (match_dup 4)]
17155 UNSPEC_FSCALE_EXP))])
17156 (parallel [(set (match_dup 10)
17157 (unspec:XF [(match_dup 9) (match_dup 8)]
17158 UNSPEC_FSCALE_FRACT))
17159 (set (match_dup 11)
17160 (unspec:XF [(match_dup 9) (match_dup 8)]
17161 UNSPEC_FSCALE_EXP))])
17162 (set (match_dup 12) (minus:XF (match_dup 10)
17163 (float_extend:XF (match_dup 13))))
17164 (set (match_operand:XF 0 "register_operand" "")
17165 (plus:XF (match_dup 12) (match_dup 7)))]
17166 "TARGET_USE_FANCY_MATH_387
17167 && flag_unsafe_math_optimizations && !optimize_size"
17171 for (i = 2; i < 13; i++)
17172 operands[i] = gen_reg_rtx (XFmode);
17175 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17177 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17180 (define_expand "expm1<mode>2"
17181 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17182 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17183 "TARGET_USE_FANCY_MATH_387
17184 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17185 || TARGET_MIX_SSE_I387)
17186 && flag_unsafe_math_optimizations && !optimize_size"
17188 rtx op0 = gen_reg_rtx (XFmode);
17189 rtx op1 = gen_reg_rtx (XFmode);
17191 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17192 emit_insn (gen_expm1xf2 (op0, op1));
17193 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17197 (define_expand "ldexpxf3"
17198 [(set (match_dup 3)
17199 (float:XF (match_operand:SI 2 "register_operand" "")))
17200 (parallel [(set (match_operand:XF 0 " register_operand" "")
17201 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17203 UNSPEC_FSCALE_FRACT))
17205 (unspec:XF [(match_dup 1) (match_dup 3)]
17206 UNSPEC_FSCALE_EXP))])]
17207 "TARGET_USE_FANCY_MATH_387
17208 && flag_unsafe_math_optimizations && !optimize_size"
17210 operands[3] = gen_reg_rtx (XFmode);
17211 operands[4] = gen_reg_rtx (XFmode);
17214 (define_expand "ldexp<mode>3"
17215 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17216 (use (match_operand:X87MODEF12 1 "general_operand" ""))
17217 (use (match_operand:SI 2 "register_operand" ""))]
17218 "TARGET_USE_FANCY_MATH_387
17219 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17220 || TARGET_MIX_SSE_I387)
17221 && flag_unsafe_math_optimizations && !optimize_size"
17223 rtx op0 = gen_reg_rtx (XFmode);
17224 rtx op1 = gen_reg_rtx (XFmode);
17226 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17227 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17228 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17232 (define_expand "scalbxf3"
17233 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17234 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17235 (match_operand:XF 2 "register_operand" "")]
17236 UNSPEC_FSCALE_FRACT))
17238 (unspec:XF [(match_dup 1) (match_dup 2)]
17239 UNSPEC_FSCALE_EXP))])]
17240 "TARGET_USE_FANCY_MATH_387
17241 && flag_unsafe_math_optimizations && !optimize_size"
17243 operands[3] = gen_reg_rtx (XFmode);
17246 (define_expand "scalb<mode>3"
17247 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17248 (use (match_operand:X87MODEF12 1 "general_operand" ""))
17249 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
17250 "TARGET_USE_FANCY_MATH_387
17251 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17252 || TARGET_MIX_SSE_I387)
17253 && flag_unsafe_math_optimizations && !optimize_size"
17255 rtx op0 = gen_reg_rtx (XFmode);
17256 rtx op1 = gen_reg_rtx (XFmode);
17257 rtx op2 = gen_reg_rtx (XFmode);
17259 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17260 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17261 emit_insn (gen_scalbxf3 (op0, op1, op2));
17262 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17267 (define_insn "sse4_1_round<mode>2"
17268 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
17269 (unspec:SSEMODEF [(match_operand:SSEMODEF 1 "register_operand" "x")
17270 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17273 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17274 [(set_attr "type" "ssecvt")
17275 (set_attr "prefix_extra" "1")
17276 (set_attr "mode" "<MODE>")])
17278 (define_insn "rintxf2"
17279 [(set (match_operand:XF 0 "register_operand" "=f")
17280 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17282 "TARGET_USE_FANCY_MATH_387
17283 && flag_unsafe_math_optimizations"
17285 [(set_attr "type" "fpspc")
17286 (set_attr "mode" "XF")])
17288 (define_expand "rint<mode>2"
17289 [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17290 (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17291 "(TARGET_USE_FANCY_MATH_387
17292 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17293 || TARGET_MIX_SSE_I387)
17294 && flag_unsafe_math_optimizations)
17295 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17296 && !flag_trapping_math
17297 && (TARGET_SSE4_1 || !optimize_size))"
17299 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17300 && !flag_trapping_math
17301 && (TARGET_SSE4_1 || !optimize_size))
17304 emit_insn (gen_sse4_1_round<mode>2
17305 (operands[0], operands[1], GEN_INT (0x04)));
17307 ix86_expand_rint (operand0, operand1);
17311 rtx op0 = gen_reg_rtx (XFmode);
17312 rtx op1 = gen_reg_rtx (XFmode);
17314 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17315 emit_insn (gen_rintxf2 (op0, op1));
17317 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17322 (define_expand "round<mode>2"
17323 [(match_operand:SSEMODEF 0 "register_operand" "")
17324 (match_operand:SSEMODEF 1 "nonimmediate_operand" "")]
17325 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17326 && !flag_trapping_math && !flag_rounding_math
17329 if (TARGET_64BIT || (<MODE>mode != DFmode))
17330 ix86_expand_round (operand0, operand1);
17332 ix86_expand_rounddf_32 (operand0, operand1);
17336 (define_insn_and_split "*fistdi2_1"
17337 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17338 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17340 "TARGET_USE_FANCY_MATH_387
17341 && !(reload_completed || reload_in_progress)"
17346 if (memory_operand (operands[0], VOIDmode))
17347 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17350 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17351 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17356 [(set_attr "type" "fpspc")
17357 (set_attr "mode" "DI")])
17359 (define_insn "fistdi2"
17360 [(set (match_operand:DI 0 "memory_operand" "=m")
17361 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17363 (clobber (match_scratch:XF 2 "=&1f"))]
17364 "TARGET_USE_FANCY_MATH_387"
17365 "* return output_fix_trunc (insn, operands, 0);"
17366 [(set_attr "type" "fpspc")
17367 (set_attr "mode" "DI")])
17369 (define_insn "fistdi2_with_temp"
17370 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17371 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17373 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17374 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17375 "TARGET_USE_FANCY_MATH_387"
17377 [(set_attr "type" "fpspc")
17378 (set_attr "mode" "DI")])
17381 [(set (match_operand:DI 0 "register_operand" "")
17382 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17384 (clobber (match_operand:DI 2 "memory_operand" ""))
17385 (clobber (match_scratch 3 ""))]
17387 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17388 (clobber (match_dup 3))])
17389 (set (match_dup 0) (match_dup 2))]
17393 [(set (match_operand:DI 0 "memory_operand" "")
17394 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17396 (clobber (match_operand:DI 2 "memory_operand" ""))
17397 (clobber (match_scratch 3 ""))]
17399 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17400 (clobber (match_dup 3))])]
17403 (define_insn_and_split "*fist<mode>2_1"
17404 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17405 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17407 "TARGET_USE_FANCY_MATH_387
17408 && !(reload_completed || reload_in_progress)"
17413 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17414 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17418 [(set_attr "type" "fpspc")
17419 (set_attr "mode" "<MODE>")])
17421 (define_insn "fist<mode>2"
17422 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17423 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17425 "TARGET_USE_FANCY_MATH_387"
17426 "* return output_fix_trunc (insn, operands, 0);"
17427 [(set_attr "type" "fpspc")
17428 (set_attr "mode" "<MODE>")])
17430 (define_insn "fist<mode>2_with_temp"
17431 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17432 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17434 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17435 "TARGET_USE_FANCY_MATH_387"
17437 [(set_attr "type" "fpspc")
17438 (set_attr "mode" "<MODE>")])
17441 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17442 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17444 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17446 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17447 (set (match_dup 0) (match_dup 2))]
17451 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17452 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17454 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17456 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17459 (define_expand "lrintxf<mode>2"
17460 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17461 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17463 "TARGET_USE_FANCY_MATH_387"
17466 (define_expand "lrint<SSEMODEF:mode><SSEMODEI24:mode>2"
17467 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17468 (unspec:SSEMODEI24 [(match_operand:SSEMODEF 1 "register_operand" "")]
17469 UNSPEC_FIX_NOTRUNC))]
17470 "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17471 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17474 (define_expand "lround<SSEMODEF:mode><SSEMODEI24:mode>2"
17475 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17476 (match_operand:SSEMODEF 1 "register_operand" "")]
17477 "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17478 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17479 && !flag_trapping_math && !flag_rounding_math
17482 ix86_expand_lround (operand0, operand1);
17486 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17487 (define_insn_and_split "frndintxf2_floor"
17488 [(set (match_operand:XF 0 "register_operand" "=f")
17489 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17490 UNSPEC_FRNDINT_FLOOR))
17491 (clobber (reg:CC FLAGS_REG))]
17492 "TARGET_USE_FANCY_MATH_387
17493 && flag_unsafe_math_optimizations
17494 && !(reload_completed || reload_in_progress)"
17499 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17501 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17502 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17504 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17505 operands[2], operands[3]));
17508 [(set_attr "type" "frndint")
17509 (set_attr "i387_cw" "floor")
17510 (set_attr "mode" "XF")])
17512 (define_insn "frndintxf2_floor_i387"
17513 [(set (match_operand:XF 0 "register_operand" "=f")
17514 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17515 UNSPEC_FRNDINT_FLOOR))
17516 (use (match_operand:HI 2 "memory_operand" "m"))
17517 (use (match_operand:HI 3 "memory_operand" "m"))]
17518 "TARGET_USE_FANCY_MATH_387
17519 && flag_unsafe_math_optimizations"
17520 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17521 [(set_attr "type" "frndint")
17522 (set_attr "i387_cw" "floor")
17523 (set_attr "mode" "XF")])
17525 (define_expand "floorxf2"
17526 [(use (match_operand:XF 0 "register_operand" ""))
17527 (use (match_operand:XF 1 "register_operand" ""))]
17528 "TARGET_USE_FANCY_MATH_387
17529 && flag_unsafe_math_optimizations && !optimize_size"
17531 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17535 (define_expand "floor<mode>2"
17536 [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17537 (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17538 "(TARGET_USE_FANCY_MATH_387
17539 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17540 || TARGET_MIX_SSE_I387)
17541 && flag_unsafe_math_optimizations && !optimize_size)
17542 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17543 && !flag_trapping_math
17544 && (TARGET_SSE4_1 || !optimize_size))"
17546 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17547 && !flag_trapping_math
17548 && (TARGET_SSE4_1 || !optimize_size))
17551 emit_insn (gen_sse4_1_round<mode>2
17552 (operands[0], operands[1], GEN_INT (0x01)));
17553 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17554 ix86_expand_floorceil (operand0, operand1, true);
17556 ix86_expand_floorceildf_32 (operand0, operand1, true);
17560 rtx op0 = gen_reg_rtx (XFmode);
17561 rtx op1 = gen_reg_rtx (XFmode);
17563 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17564 emit_insn (gen_frndintxf2_floor (op0, op1));
17566 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17571 (define_insn_and_split "*fist<mode>2_floor_1"
17572 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17573 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17574 UNSPEC_FIST_FLOOR))
17575 (clobber (reg:CC FLAGS_REG))]
17576 "TARGET_USE_FANCY_MATH_387
17577 && flag_unsafe_math_optimizations
17578 && !(reload_completed || reload_in_progress)"
17583 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17585 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17586 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17587 if (memory_operand (operands[0], VOIDmode))
17588 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17589 operands[2], operands[3]));
17592 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17593 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17594 operands[2], operands[3],
17599 [(set_attr "type" "fistp")
17600 (set_attr "i387_cw" "floor")
17601 (set_attr "mode" "<MODE>")])
17603 (define_insn "fistdi2_floor"
17604 [(set (match_operand:DI 0 "memory_operand" "=m")
17605 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17606 UNSPEC_FIST_FLOOR))
17607 (use (match_operand:HI 2 "memory_operand" "m"))
17608 (use (match_operand:HI 3 "memory_operand" "m"))
17609 (clobber (match_scratch:XF 4 "=&1f"))]
17610 "TARGET_USE_FANCY_MATH_387
17611 && flag_unsafe_math_optimizations"
17612 "* return output_fix_trunc (insn, operands, 0);"
17613 [(set_attr "type" "fistp")
17614 (set_attr "i387_cw" "floor")
17615 (set_attr "mode" "DI")])
17617 (define_insn "fistdi2_floor_with_temp"
17618 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17619 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17620 UNSPEC_FIST_FLOOR))
17621 (use (match_operand:HI 2 "memory_operand" "m,m"))
17622 (use (match_operand:HI 3 "memory_operand" "m,m"))
17623 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17624 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17625 "TARGET_USE_FANCY_MATH_387
17626 && flag_unsafe_math_optimizations"
17628 [(set_attr "type" "fistp")
17629 (set_attr "i387_cw" "floor")
17630 (set_attr "mode" "DI")])
17633 [(set (match_operand:DI 0 "register_operand" "")
17634 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17635 UNSPEC_FIST_FLOOR))
17636 (use (match_operand:HI 2 "memory_operand" ""))
17637 (use (match_operand:HI 3 "memory_operand" ""))
17638 (clobber (match_operand:DI 4 "memory_operand" ""))
17639 (clobber (match_scratch 5 ""))]
17641 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17642 (use (match_dup 2))
17643 (use (match_dup 3))
17644 (clobber (match_dup 5))])
17645 (set (match_dup 0) (match_dup 4))]
17649 [(set (match_operand:DI 0 "memory_operand" "")
17650 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17651 UNSPEC_FIST_FLOOR))
17652 (use (match_operand:HI 2 "memory_operand" ""))
17653 (use (match_operand:HI 3 "memory_operand" ""))
17654 (clobber (match_operand:DI 4 "memory_operand" ""))
17655 (clobber (match_scratch 5 ""))]
17657 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17658 (use (match_dup 2))
17659 (use (match_dup 3))
17660 (clobber (match_dup 5))])]
17663 (define_insn "fist<mode>2_floor"
17664 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17665 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17666 UNSPEC_FIST_FLOOR))
17667 (use (match_operand:HI 2 "memory_operand" "m"))
17668 (use (match_operand:HI 3 "memory_operand" "m"))]
17669 "TARGET_USE_FANCY_MATH_387
17670 && flag_unsafe_math_optimizations"
17671 "* return output_fix_trunc (insn, operands, 0);"
17672 [(set_attr "type" "fistp")
17673 (set_attr "i387_cw" "floor")
17674 (set_attr "mode" "<MODE>")])
17676 (define_insn "fist<mode>2_floor_with_temp"
17677 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17678 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17679 UNSPEC_FIST_FLOOR))
17680 (use (match_operand:HI 2 "memory_operand" "m,m"))
17681 (use (match_operand:HI 3 "memory_operand" "m,m"))
17682 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17683 "TARGET_USE_FANCY_MATH_387
17684 && flag_unsafe_math_optimizations"
17686 [(set_attr "type" "fistp")
17687 (set_attr "i387_cw" "floor")
17688 (set_attr "mode" "<MODE>")])
17691 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17692 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17693 UNSPEC_FIST_FLOOR))
17694 (use (match_operand:HI 2 "memory_operand" ""))
17695 (use (match_operand:HI 3 "memory_operand" ""))
17696 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17698 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17699 UNSPEC_FIST_FLOOR))
17700 (use (match_dup 2))
17701 (use (match_dup 3))])
17702 (set (match_dup 0) (match_dup 4))]
17706 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17707 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17708 UNSPEC_FIST_FLOOR))
17709 (use (match_operand:HI 2 "memory_operand" ""))
17710 (use (match_operand:HI 3 "memory_operand" ""))
17711 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17713 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17714 UNSPEC_FIST_FLOOR))
17715 (use (match_dup 2))
17716 (use (match_dup 3))])]
17719 (define_expand "lfloorxf<mode>2"
17720 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17721 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17722 UNSPEC_FIST_FLOOR))
17723 (clobber (reg:CC FLAGS_REG))])]
17724 "TARGET_USE_FANCY_MATH_387
17725 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17726 && flag_unsafe_math_optimizations"
17729 (define_expand "lfloor<mode>di2"
17730 [(match_operand:DI 0 "nonimmediate_operand" "")
17731 (match_operand:SSEMODEF 1 "register_operand" "")]
17732 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17733 && !flag_trapping_math
17736 ix86_expand_lfloorceil (operand0, operand1, true);
17740 (define_expand "lfloor<mode>si2"
17741 [(match_operand:SI 0 "nonimmediate_operand" "")
17742 (match_operand:SSEMODEF 1 "register_operand" "")]
17743 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17744 && !flag_trapping_math
17745 && (!optimize_size || !TARGET_64BIT)"
17747 ix86_expand_lfloorceil (operand0, operand1, true);
17751 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17752 (define_insn_and_split "frndintxf2_ceil"
17753 [(set (match_operand:XF 0 "register_operand" "=f")
17754 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17755 UNSPEC_FRNDINT_CEIL))
17756 (clobber (reg:CC FLAGS_REG))]
17757 "TARGET_USE_FANCY_MATH_387
17758 && flag_unsafe_math_optimizations
17759 && !(reload_completed || reload_in_progress)"
17764 ix86_optimize_mode_switching[I387_CEIL] = 1;
17766 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17767 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17769 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17770 operands[2], operands[3]));
17773 [(set_attr "type" "frndint")
17774 (set_attr "i387_cw" "ceil")
17775 (set_attr "mode" "XF")])
17777 (define_insn "frndintxf2_ceil_i387"
17778 [(set (match_operand:XF 0 "register_operand" "=f")
17779 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17780 UNSPEC_FRNDINT_CEIL))
17781 (use (match_operand:HI 2 "memory_operand" "m"))
17782 (use (match_operand:HI 3 "memory_operand" "m"))]
17783 "TARGET_USE_FANCY_MATH_387
17784 && flag_unsafe_math_optimizations"
17785 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17786 [(set_attr "type" "frndint")
17787 (set_attr "i387_cw" "ceil")
17788 (set_attr "mode" "XF")])
17790 (define_expand "ceilxf2"
17791 [(use (match_operand:XF 0 "register_operand" ""))
17792 (use (match_operand:XF 1 "register_operand" ""))]
17793 "TARGET_USE_FANCY_MATH_387
17794 && flag_unsafe_math_optimizations && !optimize_size"
17796 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17800 (define_expand "ceil<mode>2"
17801 [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17802 (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17803 "(TARGET_USE_FANCY_MATH_387
17804 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17805 || TARGET_MIX_SSE_I387)
17806 && flag_unsafe_math_optimizations && !optimize_size)
17807 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17808 && !flag_trapping_math
17809 && (TARGET_SSE4_1 || !optimize_size))"
17811 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17812 && !flag_trapping_math
17813 && (TARGET_SSE4_1 || !optimize_size))
17816 emit_insn (gen_sse4_1_round<mode>2
17817 (operands[0], operands[1], GEN_INT (0x02)));
17818 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17819 ix86_expand_floorceil (operand0, operand1, false);
17821 ix86_expand_floorceildf_32 (operand0, operand1, false);
17825 rtx op0 = gen_reg_rtx (XFmode);
17826 rtx op1 = gen_reg_rtx (XFmode);
17828 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17829 emit_insn (gen_frndintxf2_ceil (op0, op1));
17831 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17836 (define_insn_and_split "*fist<mode>2_ceil_1"
17837 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17838 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17840 (clobber (reg:CC FLAGS_REG))]
17841 "TARGET_USE_FANCY_MATH_387
17842 && flag_unsafe_math_optimizations
17843 && !(reload_completed || reload_in_progress)"
17848 ix86_optimize_mode_switching[I387_CEIL] = 1;
17850 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17851 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17852 if (memory_operand (operands[0], VOIDmode))
17853 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17854 operands[2], operands[3]));
17857 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17858 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17859 operands[2], operands[3],
17864 [(set_attr "type" "fistp")
17865 (set_attr "i387_cw" "ceil")
17866 (set_attr "mode" "<MODE>")])
17868 (define_insn "fistdi2_ceil"
17869 [(set (match_operand:DI 0 "memory_operand" "=m")
17870 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17872 (use (match_operand:HI 2 "memory_operand" "m"))
17873 (use (match_operand:HI 3 "memory_operand" "m"))
17874 (clobber (match_scratch:XF 4 "=&1f"))]
17875 "TARGET_USE_FANCY_MATH_387
17876 && flag_unsafe_math_optimizations"
17877 "* return output_fix_trunc (insn, operands, 0);"
17878 [(set_attr "type" "fistp")
17879 (set_attr "i387_cw" "ceil")
17880 (set_attr "mode" "DI")])
17882 (define_insn "fistdi2_ceil_with_temp"
17883 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17884 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17886 (use (match_operand:HI 2 "memory_operand" "m,m"))
17887 (use (match_operand:HI 3 "memory_operand" "m,m"))
17888 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17889 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17890 "TARGET_USE_FANCY_MATH_387
17891 && flag_unsafe_math_optimizations"
17893 [(set_attr "type" "fistp")
17894 (set_attr "i387_cw" "ceil")
17895 (set_attr "mode" "DI")])
17898 [(set (match_operand:DI 0 "register_operand" "")
17899 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17901 (use (match_operand:HI 2 "memory_operand" ""))
17902 (use (match_operand:HI 3 "memory_operand" ""))
17903 (clobber (match_operand:DI 4 "memory_operand" ""))
17904 (clobber (match_scratch 5 ""))]
17906 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17907 (use (match_dup 2))
17908 (use (match_dup 3))
17909 (clobber (match_dup 5))])
17910 (set (match_dup 0) (match_dup 4))]
17914 [(set (match_operand:DI 0 "memory_operand" "")
17915 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17917 (use (match_operand:HI 2 "memory_operand" ""))
17918 (use (match_operand:HI 3 "memory_operand" ""))
17919 (clobber (match_operand:DI 4 "memory_operand" ""))
17920 (clobber (match_scratch 5 ""))]
17922 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17923 (use (match_dup 2))
17924 (use (match_dup 3))
17925 (clobber (match_dup 5))])]
17928 (define_insn "fist<mode>2_ceil"
17929 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17930 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17932 (use (match_operand:HI 2 "memory_operand" "m"))
17933 (use (match_operand:HI 3 "memory_operand" "m"))]
17934 "TARGET_USE_FANCY_MATH_387
17935 && flag_unsafe_math_optimizations"
17936 "* return output_fix_trunc (insn, operands, 0);"
17937 [(set_attr "type" "fistp")
17938 (set_attr "i387_cw" "ceil")
17939 (set_attr "mode" "<MODE>")])
17941 (define_insn "fist<mode>2_ceil_with_temp"
17942 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17943 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17945 (use (match_operand:HI 2 "memory_operand" "m,m"))
17946 (use (match_operand:HI 3 "memory_operand" "m,m"))
17947 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17948 "TARGET_USE_FANCY_MATH_387
17949 && flag_unsafe_math_optimizations"
17951 [(set_attr "type" "fistp")
17952 (set_attr "i387_cw" "ceil")
17953 (set_attr "mode" "<MODE>")])
17956 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17957 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17959 (use (match_operand:HI 2 "memory_operand" ""))
17960 (use (match_operand:HI 3 "memory_operand" ""))
17961 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17963 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17965 (use (match_dup 2))
17966 (use (match_dup 3))])
17967 (set (match_dup 0) (match_dup 4))]
17971 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17972 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17974 (use (match_operand:HI 2 "memory_operand" ""))
17975 (use (match_operand:HI 3 "memory_operand" ""))
17976 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17978 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17980 (use (match_dup 2))
17981 (use (match_dup 3))])]
17984 (define_expand "lceilxf<mode>2"
17985 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17986 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17988 (clobber (reg:CC FLAGS_REG))])]
17989 "TARGET_USE_FANCY_MATH_387
17990 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17991 && flag_unsafe_math_optimizations"
17994 (define_expand "lceil<mode>di2"
17995 [(match_operand:DI 0 "nonimmediate_operand" "")
17996 (match_operand:SSEMODEF 1 "register_operand" "")]
17997 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17998 && !flag_trapping_math"
18000 ix86_expand_lfloorceil (operand0, operand1, false);
18004 (define_expand "lceil<mode>si2"
18005 [(match_operand:SI 0 "nonimmediate_operand" "")
18006 (match_operand:SSEMODEF 1 "register_operand" "")]
18007 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18008 && !flag_trapping_math"
18010 ix86_expand_lfloorceil (operand0, operand1, false);
18014 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18015 (define_insn_and_split "frndintxf2_trunc"
18016 [(set (match_operand:XF 0 "register_operand" "=f")
18017 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18018 UNSPEC_FRNDINT_TRUNC))
18019 (clobber (reg:CC FLAGS_REG))]
18020 "TARGET_USE_FANCY_MATH_387
18021 && flag_unsafe_math_optimizations
18022 && !(reload_completed || reload_in_progress)"
18027 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18029 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18030 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18032 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18033 operands[2], operands[3]));
18036 [(set_attr "type" "frndint")
18037 (set_attr "i387_cw" "trunc")
18038 (set_attr "mode" "XF")])
18040 (define_insn "frndintxf2_trunc_i387"
18041 [(set (match_operand:XF 0 "register_operand" "=f")
18042 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18043 UNSPEC_FRNDINT_TRUNC))
18044 (use (match_operand:HI 2 "memory_operand" "m"))
18045 (use (match_operand:HI 3 "memory_operand" "m"))]
18046 "TARGET_USE_FANCY_MATH_387
18047 && flag_unsafe_math_optimizations"
18048 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18049 [(set_attr "type" "frndint")
18050 (set_attr "i387_cw" "trunc")
18051 (set_attr "mode" "XF")])
18053 (define_expand "btruncxf2"
18054 [(use (match_operand:XF 0 "register_operand" ""))
18055 (use (match_operand:XF 1 "register_operand" ""))]
18056 "TARGET_USE_FANCY_MATH_387
18057 && flag_unsafe_math_optimizations && !optimize_size"
18059 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18063 (define_expand "btrunc<mode>2"
18064 [(use (match_operand:SSEMODEF 0 "register_operand" ""))
18065 (use (match_operand:SSEMODEF 1 "register_operand" ""))]
18066 "(TARGET_USE_FANCY_MATH_387
18067 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18068 || TARGET_MIX_SSE_I387)
18069 && flag_unsafe_math_optimizations && !optimize_size)
18070 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18071 && !flag_trapping_math
18072 && (TARGET_SSE4_1 || !optimize_size))"
18074 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18075 && !flag_trapping_math
18076 && (TARGET_SSE4_1 || !optimize_size))
18079 emit_insn (gen_sse4_1_round<mode>2
18080 (operands[0], operands[1], GEN_INT (0x03)));
18081 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18082 ix86_expand_trunc (operand0, operand1);
18084 ix86_expand_truncdf_32 (operand0, operand1);
18088 rtx op0 = gen_reg_rtx (XFmode);
18089 rtx op1 = gen_reg_rtx (XFmode);
18091 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18092 emit_insn (gen_frndintxf2_trunc (op0, op1));
18094 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18099 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18100 (define_insn_and_split "frndintxf2_mask_pm"
18101 [(set (match_operand:XF 0 "register_operand" "=f")
18102 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18103 UNSPEC_FRNDINT_MASK_PM))
18104 (clobber (reg:CC FLAGS_REG))]
18105 "TARGET_USE_FANCY_MATH_387
18106 && flag_unsafe_math_optimizations
18107 && !(reload_completed || reload_in_progress)"
18112 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18114 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18115 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18117 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18118 operands[2], operands[3]));
18121 [(set_attr "type" "frndint")
18122 (set_attr "i387_cw" "mask_pm")
18123 (set_attr "mode" "XF")])
18125 (define_insn "frndintxf2_mask_pm_i387"
18126 [(set (match_operand:XF 0 "register_operand" "=f")
18127 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18128 UNSPEC_FRNDINT_MASK_PM))
18129 (use (match_operand:HI 2 "memory_operand" "m"))
18130 (use (match_operand:HI 3 "memory_operand" "m"))]
18131 "TARGET_USE_FANCY_MATH_387
18132 && flag_unsafe_math_optimizations"
18133 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18134 [(set_attr "type" "frndint")
18135 (set_attr "i387_cw" "mask_pm")
18136 (set_attr "mode" "XF")])
18138 (define_expand "nearbyintxf2"
18139 [(use (match_operand:XF 0 "register_operand" ""))
18140 (use (match_operand:XF 1 "register_operand" ""))]
18141 "TARGET_USE_FANCY_MATH_387
18142 && flag_unsafe_math_optimizations"
18144 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18149 (define_expand "nearbyintdf2"
18150 [(use (match_operand:DF 0 "register_operand" ""))
18151 (use (match_operand:DF 1 "register_operand" ""))]
18152 "TARGET_USE_FANCY_MATH_387
18153 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18154 && flag_unsafe_math_optimizations"
18156 rtx op0 = gen_reg_rtx (XFmode);
18157 rtx op1 = gen_reg_rtx (XFmode);
18159 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18160 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18162 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18166 (define_expand "nearbyintsf2"
18167 [(use (match_operand:SF 0 "register_operand" ""))
18168 (use (match_operand:SF 1 "register_operand" ""))]
18169 "TARGET_USE_FANCY_MATH_387
18170 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18171 && flag_unsafe_math_optimizations"
18173 rtx op0 = gen_reg_rtx (XFmode);
18174 rtx op1 = gen_reg_rtx (XFmode);
18176 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18177 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18179 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18183 (define_insn "fxam<mode>2_i387"
18184 [(set (match_operand:HI 0 "register_operand" "=a")
18186 [(match_operand:X87MODEF 1 "register_operand" "f")]
18188 "TARGET_USE_FANCY_MATH_387"
18189 "fxam\n\tfnstsw\t%0"
18190 [(set_attr "type" "multi")
18191 (set_attr "unit" "i387")
18192 (set_attr "mode" "<MODE>")])
18194 (define_expand "isinf<mode>2"
18195 [(use (match_operand:SI 0 "register_operand" ""))
18196 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18197 "TARGET_USE_FANCY_MATH_387
18198 && TARGET_C99_FUNCTIONS
18199 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18201 rtx mask = GEN_INT (0x45);
18202 rtx val = GEN_INT (0x05);
18206 rtx scratch = gen_reg_rtx (HImode);
18207 rtx res = gen_reg_rtx (QImode);
18209 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18210 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18211 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18212 cond = gen_rtx_fmt_ee (EQ, QImode,
18213 gen_rtx_REG (CCmode, FLAGS_REG),
18215 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18216 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18220 (define_expand "signbit<mode>2"
18221 [(use (match_operand:SI 0 "register_operand" ""))
18222 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18223 "TARGET_USE_FANCY_MATH_387
18224 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18226 rtx mask = GEN_INT (0x0200);
18228 rtx scratch = gen_reg_rtx (HImode);
18230 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18231 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18235 ;; Block operation instructions
18237 (define_expand "movmemsi"
18238 [(use (match_operand:BLK 0 "memory_operand" ""))
18239 (use (match_operand:BLK 1 "memory_operand" ""))
18240 (use (match_operand:SI 2 "nonmemory_operand" ""))
18241 (use (match_operand:SI 3 "const_int_operand" ""))
18242 (use (match_operand:SI 4 "const_int_operand" ""))
18243 (use (match_operand:SI 5 "const_int_operand" ""))]
18246 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18247 operands[4], operands[5]))
18253 (define_expand "movmemdi"
18254 [(use (match_operand:BLK 0 "memory_operand" ""))
18255 (use (match_operand:BLK 1 "memory_operand" ""))
18256 (use (match_operand:DI 2 "nonmemory_operand" ""))
18257 (use (match_operand:DI 3 "const_int_operand" ""))
18258 (use (match_operand:SI 4 "const_int_operand" ""))
18259 (use (match_operand:SI 5 "const_int_operand" ""))]
18262 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18263 operands[4], operands[5]))
18269 ;; Most CPUs don't like single string operations
18270 ;; Handle this case here to simplify previous expander.
18272 (define_expand "strmov"
18273 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18274 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18275 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18276 (clobber (reg:CC FLAGS_REG))])
18277 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18278 (clobber (reg:CC FLAGS_REG))])]
18281 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18283 /* If .md ever supports :P for Pmode, these can be directly
18284 in the pattern above. */
18285 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18286 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18288 if (TARGET_SINGLE_STRINGOP || optimize_size)
18290 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18291 operands[2], operands[3],
18292 operands[5], operands[6]));
18296 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18299 (define_expand "strmov_singleop"
18300 [(parallel [(set (match_operand 1 "memory_operand" "")
18301 (match_operand 3 "memory_operand" ""))
18302 (set (match_operand 0 "register_operand" "")
18303 (match_operand 4 "" ""))
18304 (set (match_operand 2 "register_operand" "")
18305 (match_operand 5 "" ""))])]
18306 "TARGET_SINGLE_STRINGOP || optimize_size"
18309 (define_insn "*strmovdi_rex_1"
18310 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18311 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18312 (set (match_operand:DI 0 "register_operand" "=D")
18313 (plus:DI (match_dup 2)
18315 (set (match_operand:DI 1 "register_operand" "=S")
18316 (plus:DI (match_dup 3)
18318 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18320 [(set_attr "type" "str")
18321 (set_attr "mode" "DI")
18322 (set_attr "memory" "both")])
18324 (define_insn "*strmovsi_1"
18325 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18326 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18327 (set (match_operand:SI 0 "register_operand" "=D")
18328 (plus:SI (match_dup 2)
18330 (set (match_operand:SI 1 "register_operand" "=S")
18331 (plus:SI (match_dup 3)
18333 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18335 [(set_attr "type" "str")
18336 (set_attr "mode" "SI")
18337 (set_attr "memory" "both")])
18339 (define_insn "*strmovsi_rex_1"
18340 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18341 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18342 (set (match_operand:DI 0 "register_operand" "=D")
18343 (plus:DI (match_dup 2)
18345 (set (match_operand:DI 1 "register_operand" "=S")
18346 (plus:DI (match_dup 3)
18348 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18350 [(set_attr "type" "str")
18351 (set_attr "mode" "SI")
18352 (set_attr "memory" "both")])
18354 (define_insn "*strmovhi_1"
18355 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18356 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18357 (set (match_operand:SI 0 "register_operand" "=D")
18358 (plus:SI (match_dup 2)
18360 (set (match_operand:SI 1 "register_operand" "=S")
18361 (plus:SI (match_dup 3)
18363 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18365 [(set_attr "type" "str")
18366 (set_attr "memory" "both")
18367 (set_attr "mode" "HI")])
18369 (define_insn "*strmovhi_rex_1"
18370 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18371 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18372 (set (match_operand:DI 0 "register_operand" "=D")
18373 (plus:DI (match_dup 2)
18375 (set (match_operand:DI 1 "register_operand" "=S")
18376 (plus:DI (match_dup 3)
18378 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18380 [(set_attr "type" "str")
18381 (set_attr "memory" "both")
18382 (set_attr "mode" "HI")])
18384 (define_insn "*strmovqi_1"
18385 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18386 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18387 (set (match_operand:SI 0 "register_operand" "=D")
18388 (plus:SI (match_dup 2)
18390 (set (match_operand:SI 1 "register_operand" "=S")
18391 (plus:SI (match_dup 3)
18393 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18395 [(set_attr "type" "str")
18396 (set_attr "memory" "both")
18397 (set_attr "mode" "QI")])
18399 (define_insn "*strmovqi_rex_1"
18400 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18401 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18402 (set (match_operand:DI 0 "register_operand" "=D")
18403 (plus:DI (match_dup 2)
18405 (set (match_operand:DI 1 "register_operand" "=S")
18406 (plus:DI (match_dup 3)
18408 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18410 [(set_attr "type" "str")
18411 (set_attr "memory" "both")
18412 (set_attr "mode" "QI")])
18414 (define_expand "rep_mov"
18415 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18416 (set (match_operand 0 "register_operand" "")
18417 (match_operand 5 "" ""))
18418 (set (match_operand 2 "register_operand" "")
18419 (match_operand 6 "" ""))
18420 (set (match_operand 1 "memory_operand" "")
18421 (match_operand 3 "memory_operand" ""))
18422 (use (match_dup 4))])]
18426 (define_insn "*rep_movdi_rex64"
18427 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18428 (set (match_operand:DI 0 "register_operand" "=D")
18429 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18431 (match_operand:DI 3 "register_operand" "0")))
18432 (set (match_operand:DI 1 "register_operand" "=S")
18433 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18434 (match_operand:DI 4 "register_operand" "1")))
18435 (set (mem:BLK (match_dup 3))
18436 (mem:BLK (match_dup 4)))
18437 (use (match_dup 5))]
18440 [(set_attr "type" "str")
18441 (set_attr "prefix_rep" "1")
18442 (set_attr "memory" "both")
18443 (set_attr "mode" "DI")])
18445 (define_insn "*rep_movsi"
18446 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18447 (set (match_operand:SI 0 "register_operand" "=D")
18448 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18450 (match_operand:SI 3 "register_operand" "0")))
18451 (set (match_operand:SI 1 "register_operand" "=S")
18452 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18453 (match_operand:SI 4 "register_operand" "1")))
18454 (set (mem:BLK (match_dup 3))
18455 (mem:BLK (match_dup 4)))
18456 (use (match_dup 5))]
18459 [(set_attr "type" "str")
18460 (set_attr "prefix_rep" "1")
18461 (set_attr "memory" "both")
18462 (set_attr "mode" "SI")])
18464 (define_insn "*rep_movsi_rex64"
18465 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18466 (set (match_operand:DI 0 "register_operand" "=D")
18467 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18469 (match_operand:DI 3 "register_operand" "0")))
18470 (set (match_operand:DI 1 "register_operand" "=S")
18471 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18472 (match_operand:DI 4 "register_operand" "1")))
18473 (set (mem:BLK (match_dup 3))
18474 (mem:BLK (match_dup 4)))
18475 (use (match_dup 5))]
18478 [(set_attr "type" "str")
18479 (set_attr "prefix_rep" "1")
18480 (set_attr "memory" "both")
18481 (set_attr "mode" "SI")])
18483 (define_insn "*rep_movqi"
18484 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18485 (set (match_operand:SI 0 "register_operand" "=D")
18486 (plus:SI (match_operand:SI 3 "register_operand" "0")
18487 (match_operand:SI 5 "register_operand" "2")))
18488 (set (match_operand:SI 1 "register_operand" "=S")
18489 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18490 (set (mem:BLK (match_dup 3))
18491 (mem:BLK (match_dup 4)))
18492 (use (match_dup 5))]
18495 [(set_attr "type" "str")
18496 (set_attr "prefix_rep" "1")
18497 (set_attr "memory" "both")
18498 (set_attr "mode" "SI")])
18500 (define_insn "*rep_movqi_rex64"
18501 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18502 (set (match_operand:DI 0 "register_operand" "=D")
18503 (plus:DI (match_operand:DI 3 "register_operand" "0")
18504 (match_operand:DI 5 "register_operand" "2")))
18505 (set (match_operand:DI 1 "register_operand" "=S")
18506 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18507 (set (mem:BLK (match_dup 3))
18508 (mem:BLK (match_dup 4)))
18509 (use (match_dup 5))]
18512 [(set_attr "type" "str")
18513 (set_attr "prefix_rep" "1")
18514 (set_attr "memory" "both")
18515 (set_attr "mode" "SI")])
18517 (define_expand "setmemsi"
18518 [(use (match_operand:BLK 0 "memory_operand" ""))
18519 (use (match_operand:SI 1 "nonmemory_operand" ""))
18520 (use (match_operand 2 "const_int_operand" ""))
18521 (use (match_operand 3 "const_int_operand" ""))
18522 (use (match_operand:SI 4 "const_int_operand" ""))
18523 (use (match_operand:SI 5 "const_int_operand" ""))]
18526 if (ix86_expand_setmem (operands[0], operands[1],
18527 operands[2], operands[3],
18528 operands[4], operands[5]))
18534 (define_expand "setmemdi"
18535 [(use (match_operand:BLK 0 "memory_operand" ""))
18536 (use (match_operand:DI 1 "nonmemory_operand" ""))
18537 (use (match_operand 2 "const_int_operand" ""))
18538 (use (match_operand 3 "const_int_operand" ""))
18539 (use (match_operand 4 "const_int_operand" ""))
18540 (use (match_operand 5 "const_int_operand" ""))]
18543 if (ix86_expand_setmem (operands[0], operands[1],
18544 operands[2], operands[3],
18545 operands[4], operands[5]))
18551 ;; Most CPUs don't like single string operations
18552 ;; Handle this case here to simplify previous expander.
18554 (define_expand "strset"
18555 [(set (match_operand 1 "memory_operand" "")
18556 (match_operand 2 "register_operand" ""))
18557 (parallel [(set (match_operand 0 "register_operand" "")
18559 (clobber (reg:CC FLAGS_REG))])]
18562 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18563 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18565 /* If .md ever supports :P for Pmode, this can be directly
18566 in the pattern above. */
18567 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18568 GEN_INT (GET_MODE_SIZE (GET_MODE
18570 if (TARGET_SINGLE_STRINGOP || optimize_size)
18572 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18578 (define_expand "strset_singleop"
18579 [(parallel [(set (match_operand 1 "memory_operand" "")
18580 (match_operand 2 "register_operand" ""))
18581 (set (match_operand 0 "register_operand" "")
18582 (match_operand 3 "" ""))])]
18583 "TARGET_SINGLE_STRINGOP || optimize_size"
18586 (define_insn "*strsetdi_rex_1"
18587 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18588 (match_operand:DI 2 "register_operand" "a"))
18589 (set (match_operand:DI 0 "register_operand" "=D")
18590 (plus:DI (match_dup 1)
18592 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18594 [(set_attr "type" "str")
18595 (set_attr "memory" "store")
18596 (set_attr "mode" "DI")])
18598 (define_insn "*strsetsi_1"
18599 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18600 (match_operand:SI 2 "register_operand" "a"))
18601 (set (match_operand:SI 0 "register_operand" "=D")
18602 (plus:SI (match_dup 1)
18604 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18606 [(set_attr "type" "str")
18607 (set_attr "memory" "store")
18608 (set_attr "mode" "SI")])
18610 (define_insn "*strsetsi_rex_1"
18611 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18612 (match_operand:SI 2 "register_operand" "a"))
18613 (set (match_operand:DI 0 "register_operand" "=D")
18614 (plus:DI (match_dup 1)
18616 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18618 [(set_attr "type" "str")
18619 (set_attr "memory" "store")
18620 (set_attr "mode" "SI")])
18622 (define_insn "*strsethi_1"
18623 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18624 (match_operand:HI 2 "register_operand" "a"))
18625 (set (match_operand:SI 0 "register_operand" "=D")
18626 (plus:SI (match_dup 1)
18628 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18630 [(set_attr "type" "str")
18631 (set_attr "memory" "store")
18632 (set_attr "mode" "HI")])
18634 (define_insn "*strsethi_rex_1"
18635 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18636 (match_operand:HI 2 "register_operand" "a"))
18637 (set (match_operand:DI 0 "register_operand" "=D")
18638 (plus:DI (match_dup 1)
18640 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18642 [(set_attr "type" "str")
18643 (set_attr "memory" "store")
18644 (set_attr "mode" "HI")])
18646 (define_insn "*strsetqi_1"
18647 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18648 (match_operand:QI 2 "register_operand" "a"))
18649 (set (match_operand:SI 0 "register_operand" "=D")
18650 (plus:SI (match_dup 1)
18652 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18654 [(set_attr "type" "str")
18655 (set_attr "memory" "store")
18656 (set_attr "mode" "QI")])
18658 (define_insn "*strsetqi_rex_1"
18659 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18660 (match_operand:QI 2 "register_operand" "a"))
18661 (set (match_operand:DI 0 "register_operand" "=D")
18662 (plus:DI (match_dup 1)
18664 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18666 [(set_attr "type" "str")
18667 (set_attr "memory" "store")
18668 (set_attr "mode" "QI")])
18670 (define_expand "rep_stos"
18671 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18672 (set (match_operand 0 "register_operand" "")
18673 (match_operand 4 "" ""))
18674 (set (match_operand 2 "memory_operand" "") (const_int 0))
18675 (use (match_operand 3 "register_operand" ""))
18676 (use (match_dup 1))])]
18680 (define_insn "*rep_stosdi_rex64"
18681 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18682 (set (match_operand:DI 0 "register_operand" "=D")
18683 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18685 (match_operand:DI 3 "register_operand" "0")))
18686 (set (mem:BLK (match_dup 3))
18688 (use (match_operand:DI 2 "register_operand" "a"))
18689 (use (match_dup 4))]
18692 [(set_attr "type" "str")
18693 (set_attr "prefix_rep" "1")
18694 (set_attr "memory" "store")
18695 (set_attr "mode" "DI")])
18697 (define_insn "*rep_stossi"
18698 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18699 (set (match_operand:SI 0 "register_operand" "=D")
18700 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18702 (match_operand:SI 3 "register_operand" "0")))
18703 (set (mem:BLK (match_dup 3))
18705 (use (match_operand:SI 2 "register_operand" "a"))
18706 (use (match_dup 4))]
18709 [(set_attr "type" "str")
18710 (set_attr "prefix_rep" "1")
18711 (set_attr "memory" "store")
18712 (set_attr "mode" "SI")])
18714 (define_insn "*rep_stossi_rex64"
18715 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18716 (set (match_operand:DI 0 "register_operand" "=D")
18717 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18719 (match_operand:DI 3 "register_operand" "0")))
18720 (set (mem:BLK (match_dup 3))
18722 (use (match_operand:SI 2 "register_operand" "a"))
18723 (use (match_dup 4))]
18726 [(set_attr "type" "str")
18727 (set_attr "prefix_rep" "1")
18728 (set_attr "memory" "store")
18729 (set_attr "mode" "SI")])
18731 (define_insn "*rep_stosqi"
18732 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18733 (set (match_operand:SI 0 "register_operand" "=D")
18734 (plus:SI (match_operand:SI 3 "register_operand" "0")
18735 (match_operand:SI 4 "register_operand" "1")))
18736 (set (mem:BLK (match_dup 3))
18738 (use (match_operand:QI 2 "register_operand" "a"))
18739 (use (match_dup 4))]
18742 [(set_attr "type" "str")
18743 (set_attr "prefix_rep" "1")
18744 (set_attr "memory" "store")
18745 (set_attr "mode" "QI")])
18747 (define_insn "*rep_stosqi_rex64"
18748 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18749 (set (match_operand:DI 0 "register_operand" "=D")
18750 (plus:DI (match_operand:DI 3 "register_operand" "0")
18751 (match_operand:DI 4 "register_operand" "1")))
18752 (set (mem:BLK (match_dup 3))
18754 (use (match_operand:QI 2 "register_operand" "a"))
18755 (use (match_dup 4))]
18758 [(set_attr "type" "str")
18759 (set_attr "prefix_rep" "1")
18760 (set_attr "memory" "store")
18761 (set_attr "mode" "QI")])
18763 (define_expand "cmpstrnsi"
18764 [(set (match_operand:SI 0 "register_operand" "")
18765 (compare:SI (match_operand:BLK 1 "general_operand" "")
18766 (match_operand:BLK 2 "general_operand" "")))
18767 (use (match_operand 3 "general_operand" ""))
18768 (use (match_operand 4 "immediate_operand" ""))]
18769 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18771 rtx addr1, addr2, out, outlow, count, countreg, align;
18773 /* Can't use this if the user has appropriated esi or edi. */
18774 if (global_regs[4] || global_regs[5])
18779 out = gen_reg_rtx (SImode);
18781 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18782 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18783 if (addr1 != XEXP (operands[1], 0))
18784 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18785 if (addr2 != XEXP (operands[2], 0))
18786 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18788 count = operands[3];
18789 countreg = ix86_zero_extend_to_Pmode (count);
18791 /* %%% Iff we are testing strict equality, we can use known alignment
18792 to good advantage. This may be possible with combine, particularly
18793 once cc0 is dead. */
18794 align = operands[4];
18796 if (CONST_INT_P (count))
18798 if (INTVAL (count) == 0)
18800 emit_move_insn (operands[0], const0_rtx);
18803 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18804 operands[1], operands[2]));
18809 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18811 emit_insn (gen_cmpsi_1 (countreg, countreg));
18812 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18813 operands[1], operands[2]));
18816 outlow = gen_lowpart (QImode, out);
18817 emit_insn (gen_cmpintqi (outlow));
18818 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18820 if (operands[0] != out)
18821 emit_move_insn (operands[0], out);
18826 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18828 (define_expand "cmpintqi"
18829 [(set (match_dup 1)
18830 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18832 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18833 (parallel [(set (match_operand:QI 0 "register_operand" "")
18834 (minus:QI (match_dup 1)
18836 (clobber (reg:CC FLAGS_REG))])]
18838 "operands[1] = gen_reg_rtx (QImode);
18839 operands[2] = gen_reg_rtx (QImode);")
18841 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18842 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18844 (define_expand "cmpstrnqi_nz_1"
18845 [(parallel [(set (reg:CC FLAGS_REG)
18846 (compare:CC (match_operand 4 "memory_operand" "")
18847 (match_operand 5 "memory_operand" "")))
18848 (use (match_operand 2 "register_operand" ""))
18849 (use (match_operand:SI 3 "immediate_operand" ""))
18850 (clobber (match_operand 0 "register_operand" ""))
18851 (clobber (match_operand 1 "register_operand" ""))
18852 (clobber (match_dup 2))])]
18856 (define_insn "*cmpstrnqi_nz_1"
18857 [(set (reg:CC FLAGS_REG)
18858 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18859 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18860 (use (match_operand:SI 6 "register_operand" "2"))
18861 (use (match_operand:SI 3 "immediate_operand" "i"))
18862 (clobber (match_operand:SI 0 "register_operand" "=S"))
18863 (clobber (match_operand:SI 1 "register_operand" "=D"))
18864 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18867 [(set_attr "type" "str")
18868 (set_attr "mode" "QI")
18869 (set_attr "prefix_rep" "1")])
18871 (define_insn "*cmpstrnqi_nz_rex_1"
18872 [(set (reg:CC FLAGS_REG)
18873 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18874 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18875 (use (match_operand:DI 6 "register_operand" "2"))
18876 (use (match_operand:SI 3 "immediate_operand" "i"))
18877 (clobber (match_operand:DI 0 "register_operand" "=S"))
18878 (clobber (match_operand:DI 1 "register_operand" "=D"))
18879 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18882 [(set_attr "type" "str")
18883 (set_attr "mode" "QI")
18884 (set_attr "prefix_rep" "1")])
18886 ;; The same, but the count is not known to not be zero.
18888 (define_expand "cmpstrnqi_1"
18889 [(parallel [(set (reg:CC FLAGS_REG)
18890 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18892 (compare:CC (match_operand 4 "memory_operand" "")
18893 (match_operand 5 "memory_operand" ""))
18895 (use (match_operand:SI 3 "immediate_operand" ""))
18896 (use (reg:CC FLAGS_REG))
18897 (clobber (match_operand 0 "register_operand" ""))
18898 (clobber (match_operand 1 "register_operand" ""))
18899 (clobber (match_dup 2))])]
18903 (define_insn "*cmpstrnqi_1"
18904 [(set (reg:CC FLAGS_REG)
18905 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18907 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18908 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18910 (use (match_operand:SI 3 "immediate_operand" "i"))
18911 (use (reg:CC FLAGS_REG))
18912 (clobber (match_operand:SI 0 "register_operand" "=S"))
18913 (clobber (match_operand:SI 1 "register_operand" "=D"))
18914 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18917 [(set_attr "type" "str")
18918 (set_attr "mode" "QI")
18919 (set_attr "prefix_rep" "1")])
18921 (define_insn "*cmpstrnqi_rex_1"
18922 [(set (reg:CC FLAGS_REG)
18923 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18925 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18926 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18928 (use (match_operand:SI 3 "immediate_operand" "i"))
18929 (use (reg:CC FLAGS_REG))
18930 (clobber (match_operand:DI 0 "register_operand" "=S"))
18931 (clobber (match_operand:DI 1 "register_operand" "=D"))
18932 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18935 [(set_attr "type" "str")
18936 (set_attr "mode" "QI")
18937 (set_attr "prefix_rep" "1")])
18939 (define_expand "strlensi"
18940 [(set (match_operand:SI 0 "register_operand" "")
18941 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18942 (match_operand:QI 2 "immediate_operand" "")
18943 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18946 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18952 (define_expand "strlendi"
18953 [(set (match_operand:DI 0 "register_operand" "")
18954 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18955 (match_operand:QI 2 "immediate_operand" "")
18956 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18959 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18965 (define_expand "strlenqi_1"
18966 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18967 (clobber (match_operand 1 "register_operand" ""))
18968 (clobber (reg:CC FLAGS_REG))])]
18972 (define_insn "*strlenqi_1"
18973 [(set (match_operand:SI 0 "register_operand" "=&c")
18974 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18975 (match_operand:QI 2 "register_operand" "a")
18976 (match_operand:SI 3 "immediate_operand" "i")
18977 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18978 (clobber (match_operand:SI 1 "register_operand" "=D"))
18979 (clobber (reg:CC FLAGS_REG))]
18982 [(set_attr "type" "str")
18983 (set_attr "mode" "QI")
18984 (set_attr "prefix_rep" "1")])
18986 (define_insn "*strlenqi_rex_1"
18987 [(set (match_operand:DI 0 "register_operand" "=&c")
18988 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18989 (match_operand:QI 2 "register_operand" "a")
18990 (match_operand:DI 3 "immediate_operand" "i")
18991 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18992 (clobber (match_operand:DI 1 "register_operand" "=D"))
18993 (clobber (reg:CC FLAGS_REG))]
18996 [(set_attr "type" "str")
18997 (set_attr "mode" "QI")
18998 (set_attr "prefix_rep" "1")])
19000 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19001 ;; handled in combine, but it is not currently up to the task.
19002 ;; When used for their truth value, the cmpstrn* expanders generate
19011 ;; The intermediate three instructions are unnecessary.
19013 ;; This one handles cmpstrn*_nz_1...
19016 (set (reg:CC FLAGS_REG)
19017 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19018 (mem:BLK (match_operand 5 "register_operand" ""))))
19019 (use (match_operand 6 "register_operand" ""))
19020 (use (match_operand:SI 3 "immediate_operand" ""))
19021 (clobber (match_operand 0 "register_operand" ""))
19022 (clobber (match_operand 1 "register_operand" ""))
19023 (clobber (match_operand 2 "register_operand" ""))])
19024 (set (match_operand:QI 7 "register_operand" "")
19025 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19026 (set (match_operand:QI 8 "register_operand" "")
19027 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19028 (set (reg FLAGS_REG)
19029 (compare (match_dup 7) (match_dup 8)))
19031 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19033 (set (reg:CC FLAGS_REG)
19034 (compare:CC (mem:BLK (match_dup 4))
19035 (mem:BLK (match_dup 5))))
19036 (use (match_dup 6))
19037 (use (match_dup 3))
19038 (clobber (match_dup 0))
19039 (clobber (match_dup 1))
19040 (clobber (match_dup 2))])]
19043 ;; ...and this one handles cmpstrn*_1.
19046 (set (reg:CC FLAGS_REG)
19047 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19049 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19050 (mem:BLK (match_operand 5 "register_operand" "")))
19052 (use (match_operand:SI 3 "immediate_operand" ""))
19053 (use (reg:CC FLAGS_REG))
19054 (clobber (match_operand 0 "register_operand" ""))
19055 (clobber (match_operand 1 "register_operand" ""))
19056 (clobber (match_operand 2 "register_operand" ""))])
19057 (set (match_operand:QI 7 "register_operand" "")
19058 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19059 (set (match_operand:QI 8 "register_operand" "")
19060 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19061 (set (reg FLAGS_REG)
19062 (compare (match_dup 7) (match_dup 8)))
19064 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19066 (set (reg:CC FLAGS_REG)
19067 (if_then_else:CC (ne (match_dup 6)
19069 (compare:CC (mem:BLK (match_dup 4))
19070 (mem:BLK (match_dup 5)))
19072 (use (match_dup 3))
19073 (use (reg:CC FLAGS_REG))
19074 (clobber (match_dup 0))
19075 (clobber (match_dup 1))
19076 (clobber (match_dup 2))])]
19081 ;; Conditional move instructions.
19083 (define_expand "movdicc"
19084 [(set (match_operand:DI 0 "register_operand" "")
19085 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19086 (match_operand:DI 2 "general_operand" "")
19087 (match_operand:DI 3 "general_operand" "")))]
19089 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19091 (define_insn "x86_movdicc_0_m1_rex64"
19092 [(set (match_operand:DI 0 "register_operand" "=r")
19093 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19096 (clobber (reg:CC FLAGS_REG))]
19099 ; Since we don't have the proper number of operands for an alu insn,
19100 ; fill in all the blanks.
19101 [(set_attr "type" "alu")
19102 (set_attr "pent_pair" "pu")
19103 (set_attr "memory" "none")
19104 (set_attr "imm_disp" "false")
19105 (set_attr "mode" "DI")
19106 (set_attr "length_immediate" "0")])
19108 (define_insn "*movdicc_c_rex64"
19109 [(set (match_operand:DI 0 "register_operand" "=r,r")
19110 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19111 [(reg FLAGS_REG) (const_int 0)])
19112 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19113 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19114 "TARGET_64BIT && TARGET_CMOVE
19115 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19117 cmov%O2%C1\t{%2, %0|%0, %2}
19118 cmov%O2%c1\t{%3, %0|%0, %3}"
19119 [(set_attr "type" "icmov")
19120 (set_attr "mode" "DI")])
19122 (define_expand "movsicc"
19123 [(set (match_operand:SI 0 "register_operand" "")
19124 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19125 (match_operand:SI 2 "general_operand" "")
19126 (match_operand:SI 3 "general_operand" "")))]
19128 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19130 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19131 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19132 ;; So just document what we're doing explicitly.
19134 (define_insn "x86_movsicc_0_m1"
19135 [(set (match_operand:SI 0 "register_operand" "=r")
19136 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19139 (clobber (reg:CC FLAGS_REG))]
19142 ; Since we don't have the proper number of operands for an alu insn,
19143 ; fill in all the blanks.
19144 [(set_attr "type" "alu")
19145 (set_attr "pent_pair" "pu")
19146 (set_attr "memory" "none")
19147 (set_attr "imm_disp" "false")
19148 (set_attr "mode" "SI")
19149 (set_attr "length_immediate" "0")])
19151 (define_insn "*movsicc_noc"
19152 [(set (match_operand:SI 0 "register_operand" "=r,r")
19153 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19154 [(reg FLAGS_REG) (const_int 0)])
19155 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19156 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19158 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19160 cmov%O2%C1\t{%2, %0|%0, %2}
19161 cmov%O2%c1\t{%3, %0|%0, %3}"
19162 [(set_attr "type" "icmov")
19163 (set_attr "mode" "SI")])
19165 (define_expand "movhicc"
19166 [(set (match_operand:HI 0 "register_operand" "")
19167 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19168 (match_operand:HI 2 "general_operand" "")
19169 (match_operand:HI 3 "general_operand" "")))]
19170 "TARGET_HIMODE_MATH"
19171 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19173 (define_insn "*movhicc_noc"
19174 [(set (match_operand:HI 0 "register_operand" "=r,r")
19175 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19176 [(reg FLAGS_REG) (const_int 0)])
19177 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19178 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19180 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19182 cmov%O2%C1\t{%2, %0|%0, %2}
19183 cmov%O2%c1\t{%3, %0|%0, %3}"
19184 [(set_attr "type" "icmov")
19185 (set_attr "mode" "HI")])
19187 (define_expand "movqicc"
19188 [(set (match_operand:QI 0 "register_operand" "")
19189 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19190 (match_operand:QI 2 "general_operand" "")
19191 (match_operand:QI 3 "general_operand" "")))]
19192 "TARGET_QIMODE_MATH"
19193 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19195 (define_insn_and_split "*movqicc_noc"
19196 [(set (match_operand:QI 0 "register_operand" "=r,r")
19197 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19198 [(match_operand 4 "flags_reg_operand" "")
19200 (match_operand:QI 2 "register_operand" "r,0")
19201 (match_operand:QI 3 "register_operand" "0,r")))]
19202 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19204 "&& reload_completed"
19205 [(set (match_dup 0)
19206 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19209 "operands[0] = gen_lowpart (SImode, operands[0]);
19210 operands[2] = gen_lowpart (SImode, operands[2]);
19211 operands[3] = gen_lowpart (SImode, operands[3]);"
19212 [(set_attr "type" "icmov")
19213 (set_attr "mode" "SI")])
19215 (define_expand "movsfcc"
19216 [(set (match_operand:SF 0 "register_operand" "")
19217 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19218 (match_operand:SF 2 "register_operand" "")
19219 (match_operand:SF 3 "register_operand" "")))]
19220 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19221 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19223 (define_insn "*movsfcc_1_387"
19224 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19225 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19226 [(reg FLAGS_REG) (const_int 0)])
19227 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19228 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19229 "TARGET_80387 && TARGET_CMOVE
19230 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19232 fcmov%F1\t{%2, %0|%0, %2}
19233 fcmov%f1\t{%3, %0|%0, %3}
19234 cmov%O2%C1\t{%2, %0|%0, %2}
19235 cmov%O2%c1\t{%3, %0|%0, %3}"
19236 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19237 (set_attr "mode" "SF,SF,SI,SI")])
19239 (define_expand "movdfcc"
19240 [(set (match_operand:DF 0 "register_operand" "")
19241 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19242 (match_operand:DF 2 "register_operand" "")
19243 (match_operand:DF 3 "register_operand" "")))]
19244 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19245 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19247 (define_insn "*movdfcc_1"
19248 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19249 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19250 [(reg FLAGS_REG) (const_int 0)])
19251 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19252 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19253 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19254 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19256 fcmov%F1\t{%2, %0|%0, %2}
19257 fcmov%f1\t{%3, %0|%0, %3}
19260 [(set_attr "type" "fcmov,fcmov,multi,multi")
19261 (set_attr "mode" "DF")])
19263 (define_insn "*movdfcc_1_rex64"
19264 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19265 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19266 [(reg FLAGS_REG) (const_int 0)])
19267 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19268 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19269 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19270 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19272 fcmov%F1\t{%2, %0|%0, %2}
19273 fcmov%f1\t{%3, %0|%0, %3}
19274 cmov%O2%C1\t{%2, %0|%0, %2}
19275 cmov%O2%c1\t{%3, %0|%0, %3}"
19276 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19277 (set_attr "mode" "DF")])
19280 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19281 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19282 [(match_operand 4 "flags_reg_operand" "")
19284 (match_operand:DF 2 "nonimmediate_operand" "")
19285 (match_operand:DF 3 "nonimmediate_operand" "")))]
19286 "!TARGET_64BIT && reload_completed"
19287 [(set (match_dup 2)
19288 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19292 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19295 "split_di (operands+2, 1, operands+5, operands+6);
19296 split_di (operands+3, 1, operands+7, operands+8);
19297 split_di (operands, 1, operands+2, operands+3);")
19299 (define_expand "movxfcc"
19300 [(set (match_operand:XF 0 "register_operand" "")
19301 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19302 (match_operand:XF 2 "register_operand" "")
19303 (match_operand:XF 3 "register_operand" "")))]
19304 "TARGET_80387 && TARGET_CMOVE"
19305 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19307 (define_insn "*movxfcc_1"
19308 [(set (match_operand:XF 0 "register_operand" "=f,f")
19309 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19310 [(reg FLAGS_REG) (const_int 0)])
19311 (match_operand:XF 2 "register_operand" "f,0")
19312 (match_operand:XF 3 "register_operand" "0,f")))]
19313 "TARGET_80387 && TARGET_CMOVE"
19315 fcmov%F1\t{%2, %0|%0, %2}
19316 fcmov%f1\t{%3, %0|%0, %3}"
19317 [(set_attr "type" "fcmov")
19318 (set_attr "mode" "XF")])
19320 ;; These versions of the min/max patterns are intentionally ignorant of
19321 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19322 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19323 ;; are undefined in this condition, we're certain this is correct.
19325 (define_insn "sminsf3"
19326 [(set (match_operand:SF 0 "register_operand" "=x")
19327 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19328 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19330 "minss\t{%2, %0|%0, %2}"
19331 [(set_attr "type" "sseadd")
19332 (set_attr "mode" "SF")])
19334 (define_insn "smaxsf3"
19335 [(set (match_operand:SF 0 "register_operand" "=x")
19336 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19337 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19339 "maxss\t{%2, %0|%0, %2}"
19340 [(set_attr "type" "sseadd")
19341 (set_attr "mode" "SF")])
19343 (define_insn "smindf3"
19344 [(set (match_operand:DF 0 "register_operand" "=x")
19345 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19346 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19347 "TARGET_SSE2 && TARGET_SSE_MATH"
19348 "minsd\t{%2, %0|%0, %2}"
19349 [(set_attr "type" "sseadd")
19350 (set_attr "mode" "DF")])
19352 (define_insn "smaxdf3"
19353 [(set (match_operand:DF 0 "register_operand" "=x")
19354 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19355 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19356 "TARGET_SSE2 && TARGET_SSE_MATH"
19357 "maxsd\t{%2, %0|%0, %2}"
19358 [(set_attr "type" "sseadd")
19359 (set_attr "mode" "DF")])
19361 ;; These versions of the min/max patterns implement exactly the operations
19362 ;; min = (op1 < op2 ? op1 : op2)
19363 ;; max = (!(op1 < op2) ? op1 : op2)
19364 ;; Their operands are not commutative, and thus they may be used in the
19365 ;; presence of -0.0 and NaN.
19367 (define_insn "*ieee_sminsf3"
19368 [(set (match_operand:SF 0 "register_operand" "=x")
19369 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19370 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19373 "minss\t{%2, %0|%0, %2}"
19374 [(set_attr "type" "sseadd")
19375 (set_attr "mode" "SF")])
19377 (define_insn "*ieee_smaxsf3"
19378 [(set (match_operand:SF 0 "register_operand" "=x")
19379 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19380 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19383 "maxss\t{%2, %0|%0, %2}"
19384 [(set_attr "type" "sseadd")
19385 (set_attr "mode" "SF")])
19387 (define_insn "*ieee_smindf3"
19388 [(set (match_operand:DF 0 "register_operand" "=x")
19389 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19390 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19392 "TARGET_SSE2 && TARGET_SSE_MATH"
19393 "minsd\t{%2, %0|%0, %2}"
19394 [(set_attr "type" "sseadd")
19395 (set_attr "mode" "DF")])
19397 (define_insn "*ieee_smaxdf3"
19398 [(set (match_operand:DF 0 "register_operand" "=x")
19399 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19400 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19402 "TARGET_SSE2 && TARGET_SSE_MATH"
19403 "maxsd\t{%2, %0|%0, %2}"
19404 [(set_attr "type" "sseadd")
19405 (set_attr "mode" "DF")])
19407 ;; Make two stack loads independent:
19409 ;; fld %st(0) -> fld bb
19410 ;; fmul bb fmul %st(1), %st
19412 ;; Actually we only match the last two instructions for simplicity.
19414 [(set (match_operand 0 "fp_register_operand" "")
19415 (match_operand 1 "fp_register_operand" ""))
19417 (match_operator 2 "binary_fp_operator"
19419 (match_operand 3 "memory_operand" "")]))]
19420 "REGNO (operands[0]) != REGNO (operands[1])"
19421 [(set (match_dup 0) (match_dup 3))
19422 (set (match_dup 0) (match_dup 4))]
19424 ;; The % modifier is not operational anymore in peephole2's, so we have to
19425 ;; swap the operands manually in the case of addition and multiplication.
19426 "if (COMMUTATIVE_ARITH_P (operands[2]))
19427 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19428 operands[0], operands[1]);
19430 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19431 operands[1], operands[0]);")
19433 ;; Conditional addition patterns
19434 (define_expand "addqicc"
19435 [(match_operand:QI 0 "register_operand" "")
19436 (match_operand 1 "comparison_operator" "")
19437 (match_operand:QI 2 "register_operand" "")
19438 (match_operand:QI 3 "const_int_operand" "")]
19440 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19442 (define_expand "addhicc"
19443 [(match_operand:HI 0 "register_operand" "")
19444 (match_operand 1 "comparison_operator" "")
19445 (match_operand:HI 2 "register_operand" "")
19446 (match_operand:HI 3 "const_int_operand" "")]
19448 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19450 (define_expand "addsicc"
19451 [(match_operand:SI 0 "register_operand" "")
19452 (match_operand 1 "comparison_operator" "")
19453 (match_operand:SI 2 "register_operand" "")
19454 (match_operand:SI 3 "const_int_operand" "")]
19456 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19458 (define_expand "adddicc"
19459 [(match_operand:DI 0 "register_operand" "")
19460 (match_operand 1 "comparison_operator" "")
19461 (match_operand:DI 2 "register_operand" "")
19462 (match_operand:DI 3 "const_int_operand" "")]
19464 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19467 ;; Misc patterns (?)
19469 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19470 ;; Otherwise there will be nothing to keep
19472 ;; [(set (reg ebp) (reg esp))]
19473 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19474 ;; (clobber (eflags)]
19475 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19477 ;; in proper program order.
19478 (define_insn "pro_epilogue_adjust_stack_1"
19479 [(set (match_operand:SI 0 "register_operand" "=r,r")
19480 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19481 (match_operand:SI 2 "immediate_operand" "i,i")))
19482 (clobber (reg:CC FLAGS_REG))
19483 (clobber (mem:BLK (scratch)))]
19486 switch (get_attr_type (insn))
19489 return "mov{l}\t{%1, %0|%0, %1}";
19492 if (CONST_INT_P (operands[2])
19493 && (INTVAL (operands[2]) == 128
19494 || (INTVAL (operands[2]) < 0
19495 && INTVAL (operands[2]) != -128)))
19497 operands[2] = GEN_INT (-INTVAL (operands[2]));
19498 return "sub{l}\t{%2, %0|%0, %2}";
19500 return "add{l}\t{%2, %0|%0, %2}";
19503 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19504 return "lea{l}\t{%a2, %0|%0, %a2}";
19507 gcc_unreachable ();
19510 [(set (attr "type")
19511 (cond [(eq_attr "alternative" "0")
19512 (const_string "alu")
19513 (match_operand:SI 2 "const0_operand" "")
19514 (const_string "imov")
19516 (const_string "lea")))
19517 (set_attr "mode" "SI")])
19519 (define_insn "pro_epilogue_adjust_stack_rex64"
19520 [(set (match_operand:DI 0 "register_operand" "=r,r")
19521 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19522 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19523 (clobber (reg:CC FLAGS_REG))
19524 (clobber (mem:BLK (scratch)))]
19527 switch (get_attr_type (insn))
19530 return "mov{q}\t{%1, %0|%0, %1}";
19533 if (CONST_INT_P (operands[2])
19534 /* Avoid overflows. */
19535 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19536 && (INTVAL (operands[2]) == 128
19537 || (INTVAL (operands[2]) < 0
19538 && INTVAL (operands[2]) != -128)))
19540 operands[2] = GEN_INT (-INTVAL (operands[2]));
19541 return "sub{q}\t{%2, %0|%0, %2}";
19543 return "add{q}\t{%2, %0|%0, %2}";
19546 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19547 return "lea{q}\t{%a2, %0|%0, %a2}";
19550 gcc_unreachable ();
19553 [(set (attr "type")
19554 (cond [(eq_attr "alternative" "0")
19555 (const_string "alu")
19556 (match_operand:DI 2 "const0_operand" "")
19557 (const_string "imov")
19559 (const_string "lea")))
19560 (set_attr "mode" "DI")])
19562 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19563 [(set (match_operand:DI 0 "register_operand" "=r,r")
19564 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19565 (match_operand:DI 3 "immediate_operand" "i,i")))
19566 (use (match_operand:DI 2 "register_operand" "r,r"))
19567 (clobber (reg:CC FLAGS_REG))
19568 (clobber (mem:BLK (scratch)))]
19571 switch (get_attr_type (insn))
19574 return "add{q}\t{%2, %0|%0, %2}";
19577 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19578 return "lea{q}\t{%a2, %0|%0, %a2}";
19581 gcc_unreachable ();
19584 [(set_attr "type" "alu,lea")
19585 (set_attr "mode" "DI")])
19587 (define_insn "allocate_stack_worker_32"
19588 [(set (match_operand:SI 0 "register_operand" "+a")
19589 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19590 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19591 (clobber (reg:CC FLAGS_REG))]
19592 "!TARGET_64BIT && TARGET_STACK_PROBE"
19594 [(set_attr "type" "multi")
19595 (set_attr "length" "5")])
19597 (define_insn "allocate_stack_worker_64"
19598 [(set (match_operand:DI 0 "register_operand" "=a")
19599 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19600 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19601 (clobber (reg:DI R10_REG))
19602 (clobber (reg:DI R11_REG))
19603 (clobber (reg:CC FLAGS_REG))]
19604 "TARGET_64BIT && TARGET_STACK_PROBE"
19606 [(set_attr "type" "multi")
19607 (set_attr "length" "5")])
19609 (define_expand "allocate_stack"
19610 [(match_operand 0 "register_operand" "")
19611 (match_operand 1 "general_operand" "")]
19612 "TARGET_STACK_PROBE"
19616 #ifndef CHECK_STACK_LIMIT
19617 #define CHECK_STACK_LIMIT 0
19620 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19621 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19623 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19624 stack_pointer_rtx, 0, OPTAB_DIRECT);
19625 if (x != stack_pointer_rtx)
19626 emit_move_insn (stack_pointer_rtx, x);
19630 x = copy_to_mode_reg (Pmode, operands[1]);
19632 x = gen_allocate_stack_worker_64 (x);
19634 x = gen_allocate_stack_worker_32 (x);
19638 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19642 (define_expand "builtin_setjmp_receiver"
19643 [(label_ref (match_operand 0 "" ""))]
19644 "!TARGET_64BIT && flag_pic"
19649 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19650 rtx label_rtx = gen_label_rtx ();
19651 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19652 xops[0] = xops[1] = picreg;
19653 xops[2] = gen_rtx_CONST (SImode,
19654 gen_rtx_MINUS (SImode,
19655 gen_rtx_LABEL_REF (SImode, label_rtx),
19656 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19657 ix86_expand_binary_operator (MINUS, SImode, xops);
19660 emit_insn (gen_set_got (pic_offset_table_rtx));
19664 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19667 [(set (match_operand 0 "register_operand" "")
19668 (match_operator 3 "promotable_binary_operator"
19669 [(match_operand 1 "register_operand" "")
19670 (match_operand 2 "aligned_operand" "")]))
19671 (clobber (reg:CC FLAGS_REG))]
19672 "! TARGET_PARTIAL_REG_STALL && reload_completed
19673 && ((GET_MODE (operands[0]) == HImode
19674 && ((!optimize_size && !TARGET_FAST_PREFIX)
19675 /* ??? next two lines just !satisfies_constraint_K (...) */
19676 || !CONST_INT_P (operands[2])
19677 || satisfies_constraint_K (operands[2])))
19678 || (GET_MODE (operands[0]) == QImode
19679 && (TARGET_PROMOTE_QImode || optimize_size)))"
19680 [(parallel [(set (match_dup 0)
19681 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19682 (clobber (reg:CC FLAGS_REG))])]
19683 "operands[0] = gen_lowpart (SImode, operands[0]);
19684 operands[1] = gen_lowpart (SImode, operands[1]);
19685 if (GET_CODE (operands[3]) != ASHIFT)
19686 operands[2] = gen_lowpart (SImode, operands[2]);
19687 PUT_MODE (operands[3], SImode);")
19689 ; Promote the QImode tests, as i386 has encoding of the AND
19690 ; instruction with 32-bit sign-extended immediate and thus the
19691 ; instruction size is unchanged, except in the %eax case for
19692 ; which it is increased by one byte, hence the ! optimize_size.
19694 [(set (match_operand 0 "flags_reg_operand" "")
19695 (match_operator 2 "compare_operator"
19696 [(and (match_operand 3 "aligned_operand" "")
19697 (match_operand 4 "const_int_operand" ""))
19699 (set (match_operand 1 "register_operand" "")
19700 (and (match_dup 3) (match_dup 4)))]
19701 "! TARGET_PARTIAL_REG_STALL && reload_completed
19703 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19704 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19705 /* Ensure that the operand will remain sign-extended immediate. */
19706 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19707 [(parallel [(set (match_dup 0)
19708 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19711 (and:SI (match_dup 3) (match_dup 4)))])]
19714 = gen_int_mode (INTVAL (operands[4])
19715 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19716 operands[1] = gen_lowpart (SImode, operands[1]);
19717 operands[3] = gen_lowpart (SImode, operands[3]);
19720 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19721 ; the TEST instruction with 32-bit sign-extended immediate and thus
19722 ; the instruction size would at least double, which is not what we
19723 ; want even with ! optimize_size.
19725 [(set (match_operand 0 "flags_reg_operand" "")
19726 (match_operator 1 "compare_operator"
19727 [(and (match_operand:HI 2 "aligned_operand" "")
19728 (match_operand:HI 3 "const_int_operand" ""))
19730 "! TARGET_PARTIAL_REG_STALL && reload_completed
19731 && ! TARGET_FAST_PREFIX
19733 /* Ensure that the operand will remain sign-extended immediate. */
19734 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19735 [(set (match_dup 0)
19736 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19740 = gen_int_mode (INTVAL (operands[3])
19741 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19742 operands[2] = gen_lowpart (SImode, operands[2]);
19746 [(set (match_operand 0 "register_operand" "")
19747 (neg (match_operand 1 "register_operand" "")))
19748 (clobber (reg:CC FLAGS_REG))]
19749 "! TARGET_PARTIAL_REG_STALL && reload_completed
19750 && (GET_MODE (operands[0]) == HImode
19751 || (GET_MODE (operands[0]) == QImode
19752 && (TARGET_PROMOTE_QImode || optimize_size)))"
19753 [(parallel [(set (match_dup 0)
19754 (neg:SI (match_dup 1)))
19755 (clobber (reg:CC FLAGS_REG))])]
19756 "operands[0] = gen_lowpart (SImode, operands[0]);
19757 operands[1] = gen_lowpart (SImode, operands[1]);")
19760 [(set (match_operand 0 "register_operand" "")
19761 (not (match_operand 1 "register_operand" "")))]
19762 "! TARGET_PARTIAL_REG_STALL && reload_completed
19763 && (GET_MODE (operands[0]) == HImode
19764 || (GET_MODE (operands[0]) == QImode
19765 && (TARGET_PROMOTE_QImode || optimize_size)))"
19766 [(set (match_dup 0)
19767 (not:SI (match_dup 1)))]
19768 "operands[0] = gen_lowpart (SImode, operands[0]);
19769 operands[1] = gen_lowpart (SImode, operands[1]);")
19772 [(set (match_operand 0 "register_operand" "")
19773 (if_then_else (match_operator 1 "comparison_operator"
19774 [(reg FLAGS_REG) (const_int 0)])
19775 (match_operand 2 "register_operand" "")
19776 (match_operand 3 "register_operand" "")))]
19777 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19778 && (GET_MODE (operands[0]) == HImode
19779 || (GET_MODE (operands[0]) == QImode
19780 && (TARGET_PROMOTE_QImode || optimize_size)))"
19781 [(set (match_dup 0)
19782 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19783 "operands[0] = gen_lowpart (SImode, operands[0]);
19784 operands[2] = gen_lowpart (SImode, operands[2]);
19785 operands[3] = gen_lowpart (SImode, operands[3]);")
19788 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19789 ;; transform a complex memory operation into two memory to register operations.
19791 ;; Don't push memory operands
19793 [(set (match_operand:SI 0 "push_operand" "")
19794 (match_operand:SI 1 "memory_operand" ""))
19795 (match_scratch:SI 2 "r")]
19796 "!optimize_size && !TARGET_PUSH_MEMORY
19797 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19798 [(set (match_dup 2) (match_dup 1))
19799 (set (match_dup 0) (match_dup 2))]
19803 [(set (match_operand:DI 0 "push_operand" "")
19804 (match_operand:DI 1 "memory_operand" ""))
19805 (match_scratch:DI 2 "r")]
19806 "!optimize_size && !TARGET_PUSH_MEMORY
19807 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19808 [(set (match_dup 2) (match_dup 1))
19809 (set (match_dup 0) (match_dup 2))]
19812 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19815 [(set (match_operand:SF 0 "push_operand" "")
19816 (match_operand:SF 1 "memory_operand" ""))
19817 (match_scratch:SF 2 "r")]
19818 "!optimize_size && !TARGET_PUSH_MEMORY
19819 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19820 [(set (match_dup 2) (match_dup 1))
19821 (set (match_dup 0) (match_dup 2))]
19825 [(set (match_operand:HI 0 "push_operand" "")
19826 (match_operand:HI 1 "memory_operand" ""))
19827 (match_scratch:HI 2 "r")]
19828 "!optimize_size && !TARGET_PUSH_MEMORY
19829 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19830 [(set (match_dup 2) (match_dup 1))
19831 (set (match_dup 0) (match_dup 2))]
19835 [(set (match_operand:QI 0 "push_operand" "")
19836 (match_operand:QI 1 "memory_operand" ""))
19837 (match_scratch:QI 2 "q")]
19838 "!optimize_size && !TARGET_PUSH_MEMORY
19839 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19840 [(set (match_dup 2) (match_dup 1))
19841 (set (match_dup 0) (match_dup 2))]
19844 ;; Don't move an immediate directly to memory when the instruction
19847 [(match_scratch:SI 1 "r")
19848 (set (match_operand:SI 0 "memory_operand" "")
19851 && ! TARGET_USE_MOV0
19852 && TARGET_SPLIT_LONG_MOVES
19853 && get_attr_length (insn) >= ix86_cost->large_insn
19854 && peep2_regno_dead_p (0, FLAGS_REG)"
19855 [(parallel [(set (match_dup 1) (const_int 0))
19856 (clobber (reg:CC FLAGS_REG))])
19857 (set (match_dup 0) (match_dup 1))]
19861 [(match_scratch:HI 1 "r")
19862 (set (match_operand:HI 0 "memory_operand" "")
19865 && ! TARGET_USE_MOV0
19866 && TARGET_SPLIT_LONG_MOVES
19867 && get_attr_length (insn) >= ix86_cost->large_insn
19868 && peep2_regno_dead_p (0, FLAGS_REG)"
19869 [(parallel [(set (match_dup 2) (const_int 0))
19870 (clobber (reg:CC FLAGS_REG))])
19871 (set (match_dup 0) (match_dup 1))]
19872 "operands[2] = gen_lowpart (SImode, operands[1]);")
19875 [(match_scratch:QI 1 "q")
19876 (set (match_operand:QI 0 "memory_operand" "")
19879 && ! TARGET_USE_MOV0
19880 && TARGET_SPLIT_LONG_MOVES
19881 && get_attr_length (insn) >= ix86_cost->large_insn
19882 && peep2_regno_dead_p (0, FLAGS_REG)"
19883 [(parallel [(set (match_dup 2) (const_int 0))
19884 (clobber (reg:CC FLAGS_REG))])
19885 (set (match_dup 0) (match_dup 1))]
19886 "operands[2] = gen_lowpart (SImode, operands[1]);")
19889 [(match_scratch:SI 2 "r")
19890 (set (match_operand:SI 0 "memory_operand" "")
19891 (match_operand:SI 1 "immediate_operand" ""))]
19893 && TARGET_SPLIT_LONG_MOVES
19894 && get_attr_length (insn) >= ix86_cost->large_insn"
19895 [(set (match_dup 2) (match_dup 1))
19896 (set (match_dup 0) (match_dup 2))]
19900 [(match_scratch:HI 2 "r")
19901 (set (match_operand:HI 0 "memory_operand" "")
19902 (match_operand:HI 1 "immediate_operand" ""))]
19904 && TARGET_SPLIT_LONG_MOVES
19905 && get_attr_length (insn) >= ix86_cost->large_insn"
19906 [(set (match_dup 2) (match_dup 1))
19907 (set (match_dup 0) (match_dup 2))]
19911 [(match_scratch:QI 2 "q")
19912 (set (match_operand:QI 0 "memory_operand" "")
19913 (match_operand:QI 1 "immediate_operand" ""))]
19915 && TARGET_SPLIT_LONG_MOVES
19916 && get_attr_length (insn) >= ix86_cost->large_insn"
19917 [(set (match_dup 2) (match_dup 1))
19918 (set (match_dup 0) (match_dup 2))]
19921 ;; Don't compare memory with zero, load and use a test instead.
19923 [(set (match_operand 0 "flags_reg_operand" "")
19924 (match_operator 1 "compare_operator"
19925 [(match_operand:SI 2 "memory_operand" "")
19927 (match_scratch:SI 3 "r")]
19928 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
19929 [(set (match_dup 3) (match_dup 2))
19930 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19933 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19934 ;; Don't split NOTs with a displacement operand, because resulting XOR
19935 ;; will not be pairable anyway.
19937 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19938 ;; represented using a modRM byte. The XOR replacement is long decoded,
19939 ;; so this split helps here as well.
19941 ;; Note: Can't do this as a regular split because we can't get proper
19942 ;; lifetime information then.
19945 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19946 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19948 && ((TARGET_NOT_UNPAIRABLE
19949 && (!MEM_P (operands[0])
19950 || !memory_displacement_operand (operands[0], SImode)))
19951 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19952 && peep2_regno_dead_p (0, FLAGS_REG)"
19953 [(parallel [(set (match_dup 0)
19954 (xor:SI (match_dup 1) (const_int -1)))
19955 (clobber (reg:CC FLAGS_REG))])]
19959 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19960 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19962 && ((TARGET_NOT_UNPAIRABLE
19963 && (!MEM_P (operands[0])
19964 || !memory_displacement_operand (operands[0], HImode)))
19965 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19966 && peep2_regno_dead_p (0, FLAGS_REG)"
19967 [(parallel [(set (match_dup 0)
19968 (xor:HI (match_dup 1) (const_int -1)))
19969 (clobber (reg:CC FLAGS_REG))])]
19973 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19974 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19976 && ((TARGET_NOT_UNPAIRABLE
19977 && (!MEM_P (operands[0])
19978 || !memory_displacement_operand (operands[0], QImode)))
19979 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19980 && peep2_regno_dead_p (0, FLAGS_REG)"
19981 [(parallel [(set (match_dup 0)
19982 (xor:QI (match_dup 1) (const_int -1)))
19983 (clobber (reg:CC FLAGS_REG))])]
19986 ;; Non pairable "test imm, reg" instructions can be translated to
19987 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19988 ;; byte opcode instead of two, have a short form for byte operands),
19989 ;; so do it for other CPUs as well. Given that the value was dead,
19990 ;; this should not create any new dependencies. Pass on the sub-word
19991 ;; versions if we're concerned about partial register stalls.
19994 [(set (match_operand 0 "flags_reg_operand" "")
19995 (match_operator 1 "compare_operator"
19996 [(and:SI (match_operand:SI 2 "register_operand" "")
19997 (match_operand:SI 3 "immediate_operand" ""))
19999 "ix86_match_ccmode (insn, CCNOmode)
20000 && (true_regnum (operands[2]) != 0
20001 || satisfies_constraint_K (operands[3]))
20002 && peep2_reg_dead_p (1, operands[2])"
20004 [(set (match_dup 0)
20005 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20008 (and:SI (match_dup 2) (match_dup 3)))])]
20011 ;; We don't need to handle HImode case, because it will be promoted to SImode
20012 ;; on ! TARGET_PARTIAL_REG_STALL
20015 [(set (match_operand 0 "flags_reg_operand" "")
20016 (match_operator 1 "compare_operator"
20017 [(and:QI (match_operand:QI 2 "register_operand" "")
20018 (match_operand:QI 3 "immediate_operand" ""))
20020 "! TARGET_PARTIAL_REG_STALL
20021 && ix86_match_ccmode (insn, CCNOmode)
20022 && true_regnum (operands[2]) != 0
20023 && peep2_reg_dead_p (1, operands[2])"
20025 [(set (match_dup 0)
20026 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20029 (and:QI (match_dup 2) (match_dup 3)))])]
20033 [(set (match_operand 0 "flags_reg_operand" "")
20034 (match_operator 1 "compare_operator"
20037 (match_operand 2 "ext_register_operand" "")
20040 (match_operand 3 "const_int_operand" ""))
20042 "! TARGET_PARTIAL_REG_STALL
20043 && ix86_match_ccmode (insn, CCNOmode)
20044 && true_regnum (operands[2]) != 0
20045 && peep2_reg_dead_p (1, operands[2])"
20046 [(parallel [(set (match_dup 0)
20055 (set (zero_extract:SI (match_dup 2)
20066 ;; Don't do logical operations with memory inputs.
20068 [(match_scratch:SI 2 "r")
20069 (parallel [(set (match_operand:SI 0 "register_operand" "")
20070 (match_operator:SI 3 "arith_or_logical_operator"
20072 (match_operand:SI 1 "memory_operand" "")]))
20073 (clobber (reg:CC FLAGS_REG))])]
20074 "! optimize_size && ! TARGET_READ_MODIFY"
20075 [(set (match_dup 2) (match_dup 1))
20076 (parallel [(set (match_dup 0)
20077 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20078 (clobber (reg:CC FLAGS_REG))])]
20082 [(match_scratch:SI 2 "r")
20083 (parallel [(set (match_operand:SI 0 "register_operand" "")
20084 (match_operator:SI 3 "arith_or_logical_operator"
20085 [(match_operand:SI 1 "memory_operand" "")
20087 (clobber (reg:CC FLAGS_REG))])]
20088 "! optimize_size && ! TARGET_READ_MODIFY"
20089 [(set (match_dup 2) (match_dup 1))
20090 (parallel [(set (match_dup 0)
20091 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20092 (clobber (reg:CC FLAGS_REG))])]
20095 ; Don't do logical operations with memory outputs
20097 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20098 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20099 ; the same decoder scheduling characteristics as the original.
20102 [(match_scratch:SI 2 "r")
20103 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20104 (match_operator:SI 3 "arith_or_logical_operator"
20106 (match_operand:SI 1 "nonmemory_operand" "")]))
20107 (clobber (reg:CC FLAGS_REG))])]
20108 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20109 [(set (match_dup 2) (match_dup 0))
20110 (parallel [(set (match_dup 2)
20111 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20112 (clobber (reg:CC FLAGS_REG))])
20113 (set (match_dup 0) (match_dup 2))]
20117 [(match_scratch:SI 2 "r")
20118 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20119 (match_operator:SI 3 "arith_or_logical_operator"
20120 [(match_operand:SI 1 "nonmemory_operand" "")
20122 (clobber (reg:CC FLAGS_REG))])]
20123 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20124 [(set (match_dup 2) (match_dup 0))
20125 (parallel [(set (match_dup 2)
20126 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20127 (clobber (reg:CC FLAGS_REG))])
20128 (set (match_dup 0) (match_dup 2))]
20131 ;; Attempt to always use XOR for zeroing registers.
20133 [(set (match_operand 0 "register_operand" "")
20134 (match_operand 1 "const0_operand" ""))]
20135 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20136 && (! TARGET_USE_MOV0 || optimize_size)
20137 && GENERAL_REG_P (operands[0])
20138 && peep2_regno_dead_p (0, FLAGS_REG)"
20139 [(parallel [(set (match_dup 0) (const_int 0))
20140 (clobber (reg:CC FLAGS_REG))])]
20142 operands[0] = gen_lowpart (word_mode, operands[0]);
20146 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20148 "(GET_MODE (operands[0]) == QImode
20149 || GET_MODE (operands[0]) == HImode)
20150 && (! TARGET_USE_MOV0 || optimize_size)
20151 && peep2_regno_dead_p (0, FLAGS_REG)"
20152 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20153 (clobber (reg:CC FLAGS_REG))])])
20155 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20157 [(set (match_operand 0 "register_operand" "")
20159 "(GET_MODE (operands[0]) == HImode
20160 || GET_MODE (operands[0]) == SImode
20161 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20162 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20163 && peep2_regno_dead_p (0, FLAGS_REG)"
20164 [(parallel [(set (match_dup 0) (const_int -1))
20165 (clobber (reg:CC FLAGS_REG))])]
20166 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20169 ;; Attempt to convert simple leas to adds. These can be created by
20172 [(set (match_operand:SI 0 "register_operand" "")
20173 (plus:SI (match_dup 0)
20174 (match_operand:SI 1 "nonmemory_operand" "")))]
20175 "peep2_regno_dead_p (0, FLAGS_REG)"
20176 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20177 (clobber (reg:CC FLAGS_REG))])]
20181 [(set (match_operand:SI 0 "register_operand" "")
20182 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20183 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20184 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20185 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20186 (clobber (reg:CC FLAGS_REG))])]
20187 "operands[2] = gen_lowpart (SImode, operands[2]);")
20190 [(set (match_operand:DI 0 "register_operand" "")
20191 (plus:DI (match_dup 0)
20192 (match_operand:DI 1 "x86_64_general_operand" "")))]
20193 "peep2_regno_dead_p (0, FLAGS_REG)"
20194 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20195 (clobber (reg:CC FLAGS_REG))])]
20199 [(set (match_operand:SI 0 "register_operand" "")
20200 (mult:SI (match_dup 0)
20201 (match_operand:SI 1 "const_int_operand" "")))]
20202 "exact_log2 (INTVAL (operands[1])) >= 0
20203 && peep2_regno_dead_p (0, FLAGS_REG)"
20204 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20205 (clobber (reg:CC FLAGS_REG))])]
20206 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20209 [(set (match_operand:DI 0 "register_operand" "")
20210 (mult:DI (match_dup 0)
20211 (match_operand:DI 1 "const_int_operand" "")))]
20212 "exact_log2 (INTVAL (operands[1])) >= 0
20213 && peep2_regno_dead_p (0, FLAGS_REG)"
20214 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20215 (clobber (reg:CC FLAGS_REG))])]
20216 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20219 [(set (match_operand:SI 0 "register_operand" "")
20220 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20221 (match_operand:DI 2 "const_int_operand" "")) 0))]
20222 "exact_log2 (INTVAL (operands[2])) >= 0
20223 && REGNO (operands[0]) == REGNO (operands[1])
20224 && peep2_regno_dead_p (0, FLAGS_REG)"
20225 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20226 (clobber (reg:CC FLAGS_REG))])]
20227 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20229 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20230 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20231 ;; many CPUs it is also faster, since special hardware to avoid esp
20232 ;; dependencies is present.
20234 ;; While some of these conversions may be done using splitters, we use peepholes
20235 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20237 ;; Convert prologue esp subtractions to push.
20238 ;; We need register to push. In order to keep verify_flow_info happy we have
20240 ;; - use scratch and clobber it in order to avoid dependencies
20241 ;; - use already live register
20242 ;; We can't use the second way right now, since there is no reliable way how to
20243 ;; verify that given register is live. First choice will also most likely in
20244 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20245 ;; call clobbered registers are dead. We may want to use base pointer as an
20246 ;; alternative when no register is available later.
20249 [(match_scratch:SI 0 "r")
20250 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20251 (clobber (reg:CC FLAGS_REG))
20252 (clobber (mem:BLK (scratch)))])]
20253 "optimize_size || !TARGET_SUB_ESP_4"
20254 [(clobber (match_dup 0))
20255 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20256 (clobber (mem:BLK (scratch)))])])
20259 [(match_scratch:SI 0 "r")
20260 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20261 (clobber (reg:CC FLAGS_REG))
20262 (clobber (mem:BLK (scratch)))])]
20263 "optimize_size || !TARGET_SUB_ESP_8"
20264 [(clobber (match_dup 0))
20265 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20266 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20267 (clobber (mem:BLK (scratch)))])])
20269 ;; Convert esp subtractions to push.
20271 [(match_scratch:SI 0 "r")
20272 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20273 (clobber (reg:CC FLAGS_REG))])]
20274 "optimize_size || !TARGET_SUB_ESP_4"
20275 [(clobber (match_dup 0))
20276 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20279 [(match_scratch:SI 0 "r")
20280 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20281 (clobber (reg:CC FLAGS_REG))])]
20282 "optimize_size || !TARGET_SUB_ESP_8"
20283 [(clobber (match_dup 0))
20284 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20285 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20287 ;; Convert epilogue deallocator to pop.
20289 [(match_scratch:SI 0 "r")
20290 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20291 (clobber (reg:CC FLAGS_REG))
20292 (clobber (mem:BLK (scratch)))])]
20293 "optimize_size || !TARGET_ADD_ESP_4"
20294 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20295 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20296 (clobber (mem:BLK (scratch)))])]
20299 ;; Two pops case is tricky, since pop causes dependency on destination register.
20300 ;; We use two registers if available.
20302 [(match_scratch:SI 0 "r")
20303 (match_scratch:SI 1 "r")
20304 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20305 (clobber (reg:CC FLAGS_REG))
20306 (clobber (mem:BLK (scratch)))])]
20307 "optimize_size || !TARGET_ADD_ESP_8"
20308 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20309 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20310 (clobber (mem:BLK (scratch)))])
20311 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20312 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20316 [(match_scratch:SI 0 "r")
20317 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20318 (clobber (reg:CC FLAGS_REG))
20319 (clobber (mem:BLK (scratch)))])]
20321 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20322 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20323 (clobber (mem:BLK (scratch)))])
20324 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20325 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20328 ;; Convert esp additions to pop.
20330 [(match_scratch:SI 0 "r")
20331 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20332 (clobber (reg:CC FLAGS_REG))])]
20334 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20335 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20338 ;; Two pops case is tricky, since pop causes dependency on destination register.
20339 ;; We use two registers if available.
20341 [(match_scratch:SI 0 "r")
20342 (match_scratch:SI 1 "r")
20343 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20344 (clobber (reg:CC FLAGS_REG))])]
20346 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20347 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20348 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20349 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20353 [(match_scratch:SI 0 "r")
20354 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20355 (clobber (reg:CC FLAGS_REG))])]
20357 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20358 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20359 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20360 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20363 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20364 ;; required and register dies. Similarly for 128 to plus -128.
20366 [(set (match_operand 0 "flags_reg_operand" "")
20367 (match_operator 1 "compare_operator"
20368 [(match_operand 2 "register_operand" "")
20369 (match_operand 3 "const_int_operand" "")]))]
20370 "(INTVAL (operands[3]) == -1
20371 || INTVAL (operands[3]) == 1
20372 || INTVAL (operands[3]) == 128)
20373 && ix86_match_ccmode (insn, CCGCmode)
20374 && peep2_reg_dead_p (1, operands[2])"
20375 [(parallel [(set (match_dup 0)
20376 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20377 (clobber (match_dup 2))])]
20381 [(match_scratch:DI 0 "r")
20382 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20383 (clobber (reg:CC FLAGS_REG))
20384 (clobber (mem:BLK (scratch)))])]
20385 "optimize_size || !TARGET_SUB_ESP_4"
20386 [(clobber (match_dup 0))
20387 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20388 (clobber (mem:BLK (scratch)))])])
20391 [(match_scratch:DI 0 "r")
20392 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20393 (clobber (reg:CC FLAGS_REG))
20394 (clobber (mem:BLK (scratch)))])]
20395 "optimize_size || !TARGET_SUB_ESP_8"
20396 [(clobber (match_dup 0))
20397 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20398 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20399 (clobber (mem:BLK (scratch)))])])
20401 ;; Convert esp subtractions to push.
20403 [(match_scratch:DI 0 "r")
20404 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20405 (clobber (reg:CC FLAGS_REG))])]
20406 "optimize_size || !TARGET_SUB_ESP_4"
20407 [(clobber (match_dup 0))
20408 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20411 [(match_scratch:DI 0 "r")
20412 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20413 (clobber (reg:CC FLAGS_REG))])]
20414 "optimize_size || !TARGET_SUB_ESP_8"
20415 [(clobber (match_dup 0))
20416 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20417 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20419 ;; Convert epilogue deallocator to pop.
20421 [(match_scratch:DI 0 "r")
20422 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20423 (clobber (reg:CC FLAGS_REG))
20424 (clobber (mem:BLK (scratch)))])]
20425 "optimize_size || !TARGET_ADD_ESP_4"
20426 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20427 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20428 (clobber (mem:BLK (scratch)))])]
20431 ;; Two pops case is tricky, since pop causes dependency on destination register.
20432 ;; We use two registers if available.
20434 [(match_scratch:DI 0 "r")
20435 (match_scratch:DI 1 "r")
20436 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20437 (clobber (reg:CC FLAGS_REG))
20438 (clobber (mem:BLK (scratch)))])]
20439 "optimize_size || !TARGET_ADD_ESP_8"
20440 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20441 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20442 (clobber (mem:BLK (scratch)))])
20443 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20444 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20448 [(match_scratch:DI 0 "r")
20449 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20450 (clobber (reg:CC FLAGS_REG))
20451 (clobber (mem:BLK (scratch)))])]
20453 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20454 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20455 (clobber (mem:BLK (scratch)))])
20456 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20457 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20460 ;; Convert esp additions to pop.
20462 [(match_scratch:DI 0 "r")
20463 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20464 (clobber (reg:CC FLAGS_REG))])]
20466 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20467 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20470 ;; Two pops case is tricky, since pop causes dependency on destination register.
20471 ;; We use two registers if available.
20473 [(match_scratch:DI 0 "r")
20474 (match_scratch:DI 1 "r")
20475 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20476 (clobber (reg:CC FLAGS_REG))])]
20478 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20479 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20480 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20481 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20485 [(match_scratch:DI 0 "r")
20486 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20487 (clobber (reg:CC FLAGS_REG))])]
20489 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20490 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20491 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20492 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20495 ;; Convert imul by three, five and nine into lea
20498 [(set (match_operand:SI 0 "register_operand" "")
20499 (mult:SI (match_operand:SI 1 "register_operand" "")
20500 (match_operand:SI 2 "const_int_operand" "")))
20501 (clobber (reg:CC FLAGS_REG))])]
20502 "INTVAL (operands[2]) == 3
20503 || INTVAL (operands[2]) == 5
20504 || INTVAL (operands[2]) == 9"
20505 [(set (match_dup 0)
20506 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20508 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20512 [(set (match_operand:SI 0 "register_operand" "")
20513 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20514 (match_operand:SI 2 "const_int_operand" "")))
20515 (clobber (reg:CC FLAGS_REG))])]
20517 && (INTVAL (operands[2]) == 3
20518 || INTVAL (operands[2]) == 5
20519 || INTVAL (operands[2]) == 9)"
20520 [(set (match_dup 0) (match_dup 1))
20522 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20524 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20528 [(set (match_operand:DI 0 "register_operand" "")
20529 (mult:DI (match_operand:DI 1 "register_operand" "")
20530 (match_operand:DI 2 "const_int_operand" "")))
20531 (clobber (reg:CC FLAGS_REG))])]
20533 && (INTVAL (operands[2]) == 3
20534 || INTVAL (operands[2]) == 5
20535 || INTVAL (operands[2]) == 9)"
20536 [(set (match_dup 0)
20537 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20539 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20543 [(set (match_operand:DI 0 "register_operand" "")
20544 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20545 (match_operand:DI 2 "const_int_operand" "")))
20546 (clobber (reg:CC FLAGS_REG))])]
20549 && (INTVAL (operands[2]) == 3
20550 || INTVAL (operands[2]) == 5
20551 || INTVAL (operands[2]) == 9)"
20552 [(set (match_dup 0) (match_dup 1))
20554 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20556 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20558 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20559 ;; imul $32bit_imm, reg, reg is direct decoded.
20561 [(match_scratch:DI 3 "r")
20562 (parallel [(set (match_operand:DI 0 "register_operand" "")
20563 (mult:DI (match_operand:DI 1 "memory_operand" "")
20564 (match_operand:DI 2 "immediate_operand" "")))
20565 (clobber (reg:CC FLAGS_REG))])]
20566 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20567 && !satisfies_constraint_K (operands[2])"
20568 [(set (match_dup 3) (match_dup 1))
20569 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20570 (clobber (reg:CC FLAGS_REG))])]
20574 [(match_scratch:SI 3 "r")
20575 (parallel [(set (match_operand:SI 0 "register_operand" "")
20576 (mult:SI (match_operand:SI 1 "memory_operand" "")
20577 (match_operand:SI 2 "immediate_operand" "")))
20578 (clobber (reg:CC FLAGS_REG))])]
20579 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20580 && !satisfies_constraint_K (operands[2])"
20581 [(set (match_dup 3) (match_dup 1))
20582 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20583 (clobber (reg:CC FLAGS_REG))])]
20587 [(match_scratch:SI 3 "r")
20588 (parallel [(set (match_operand:DI 0 "register_operand" "")
20590 (mult:SI (match_operand:SI 1 "memory_operand" "")
20591 (match_operand:SI 2 "immediate_operand" ""))))
20592 (clobber (reg:CC FLAGS_REG))])]
20593 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20594 && !satisfies_constraint_K (operands[2])"
20595 [(set (match_dup 3) (match_dup 1))
20596 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20597 (clobber (reg:CC FLAGS_REG))])]
20600 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20601 ;; Convert it into imul reg, reg
20602 ;; It would be better to force assembler to encode instruction using long
20603 ;; immediate, but there is apparently no way to do so.
20605 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20606 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20607 (match_operand:DI 2 "const_int_operand" "")))
20608 (clobber (reg:CC FLAGS_REG))])
20609 (match_scratch:DI 3 "r")]
20610 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20611 && satisfies_constraint_K (operands[2])"
20612 [(set (match_dup 3) (match_dup 2))
20613 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20614 (clobber (reg:CC FLAGS_REG))])]
20616 if (!rtx_equal_p (operands[0], operands[1]))
20617 emit_move_insn (operands[0], operands[1]);
20621 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20622 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20623 (match_operand:SI 2 "const_int_operand" "")))
20624 (clobber (reg:CC FLAGS_REG))])
20625 (match_scratch:SI 3 "r")]
20626 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20627 && satisfies_constraint_K (operands[2])"
20628 [(set (match_dup 3) (match_dup 2))
20629 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20630 (clobber (reg:CC FLAGS_REG))])]
20632 if (!rtx_equal_p (operands[0], operands[1]))
20633 emit_move_insn (operands[0], operands[1]);
20637 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20638 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20639 (match_operand:HI 2 "immediate_operand" "")))
20640 (clobber (reg:CC FLAGS_REG))])
20641 (match_scratch:HI 3 "r")]
20642 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20643 [(set (match_dup 3) (match_dup 2))
20644 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20645 (clobber (reg:CC FLAGS_REG))])]
20647 if (!rtx_equal_p (operands[0], operands[1]))
20648 emit_move_insn (operands[0], operands[1]);
20651 ;; After splitting up read-modify operations, array accesses with memory
20652 ;; operands might end up in form:
20654 ;; movl 4(%esp), %edx
20656 ;; instead of pre-splitting:
20658 ;; addl 4(%esp), %eax
20660 ;; movl 4(%esp), %edx
20661 ;; leal (%edx,%eax,4), %eax
20664 [(parallel [(set (match_operand 0 "register_operand" "")
20665 (ashift (match_operand 1 "register_operand" "")
20666 (match_operand 2 "const_int_operand" "")))
20667 (clobber (reg:CC FLAGS_REG))])
20668 (set (match_operand 3 "register_operand")
20669 (match_operand 4 "x86_64_general_operand" ""))
20670 (parallel [(set (match_operand 5 "register_operand" "")
20671 (plus (match_operand 6 "register_operand" "")
20672 (match_operand 7 "register_operand" "")))
20673 (clobber (reg:CC FLAGS_REG))])]
20674 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20675 /* Validate MODE for lea. */
20676 && ((!TARGET_PARTIAL_REG_STALL
20677 && (GET_MODE (operands[0]) == QImode
20678 || GET_MODE (operands[0]) == HImode))
20679 || GET_MODE (operands[0]) == SImode
20680 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20681 /* We reorder load and the shift. */
20682 && !rtx_equal_p (operands[1], operands[3])
20683 && !reg_overlap_mentioned_p (operands[0], operands[4])
20684 /* Last PLUS must consist of operand 0 and 3. */
20685 && !rtx_equal_p (operands[0], operands[3])
20686 && (rtx_equal_p (operands[3], operands[6])
20687 || rtx_equal_p (operands[3], operands[7]))
20688 && (rtx_equal_p (operands[0], operands[6])
20689 || rtx_equal_p (operands[0], operands[7]))
20690 /* The intermediate operand 0 must die or be same as output. */
20691 && (rtx_equal_p (operands[0], operands[5])
20692 || peep2_reg_dead_p (3, operands[0]))"
20693 [(set (match_dup 3) (match_dup 4))
20694 (set (match_dup 0) (match_dup 1))]
20696 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20697 int scale = 1 << INTVAL (operands[2]);
20698 rtx index = gen_lowpart (Pmode, operands[1]);
20699 rtx base = gen_lowpart (Pmode, operands[3]);
20700 rtx dest = gen_lowpart (mode, operands[5]);
20702 operands[1] = gen_rtx_PLUS (Pmode, base,
20703 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20705 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20706 operands[0] = dest;
20709 ;; Call-value patterns last so that the wildcard operand does not
20710 ;; disrupt insn-recog's switch tables.
20712 (define_insn "*call_value_pop_0"
20713 [(set (match_operand 0 "" "")
20714 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20715 (match_operand:SI 2 "" "")))
20716 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20717 (match_operand:SI 3 "immediate_operand" "")))]
20720 if (SIBLING_CALL_P (insn))
20723 return "call\t%P1";
20725 [(set_attr "type" "callv")])
20727 (define_insn "*call_value_pop_1"
20728 [(set (match_operand 0 "" "")
20729 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20730 (match_operand:SI 2 "" "")))
20731 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20732 (match_operand:SI 3 "immediate_operand" "i")))]
20735 if (constant_call_address_operand (operands[1], Pmode))
20737 if (SIBLING_CALL_P (insn))
20740 return "call\t%P1";
20742 if (SIBLING_CALL_P (insn))
20745 return "call\t%A1";
20747 [(set_attr "type" "callv")])
20749 (define_insn "*call_value_0"
20750 [(set (match_operand 0 "" "")
20751 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20752 (match_operand:SI 2 "" "")))]
20755 if (SIBLING_CALL_P (insn))
20758 return "call\t%P1";
20760 [(set_attr "type" "callv")])
20762 (define_insn "*call_value_0_rex64"
20763 [(set (match_operand 0 "" "")
20764 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20765 (match_operand:DI 2 "const_int_operand" "")))]
20768 if (SIBLING_CALL_P (insn))
20771 return "call\t%P1";
20773 [(set_attr "type" "callv")])
20775 (define_insn "*call_value_1"
20776 [(set (match_operand 0 "" "")
20777 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20778 (match_operand:SI 2 "" "")))]
20779 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20781 if (constant_call_address_operand (operands[1], Pmode))
20782 return "call\t%P1";
20783 return "call\t%A1";
20785 [(set_attr "type" "callv")])
20787 (define_insn "*sibcall_value_1"
20788 [(set (match_operand 0 "" "")
20789 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20790 (match_operand:SI 2 "" "")))]
20791 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20793 if (constant_call_address_operand (operands[1], Pmode))
20797 [(set_attr "type" "callv")])
20799 (define_insn "*call_value_1_rex64"
20800 [(set (match_operand 0 "" "")
20801 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20802 (match_operand:DI 2 "" "")))]
20803 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20804 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20806 if (constant_call_address_operand (operands[1], Pmode))
20807 return "call\t%P1";
20808 return "call\t%A1";
20810 [(set_attr "type" "callv")])
20812 (define_insn "*call_value_1_rex64_large"
20813 [(set (match_operand 0 "" "")
20814 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20815 (match_operand:DI 2 "" "")))]
20816 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20818 [(set_attr "type" "callv")])
20820 (define_insn "*sibcall_value_1_rex64"
20821 [(set (match_operand 0 "" "")
20822 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20823 (match_operand:DI 2 "" "")))]
20824 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20826 [(set_attr "type" "callv")])
20828 (define_insn "*sibcall_value_1_rex64_v"
20829 [(set (match_operand 0 "" "")
20830 (call (mem:QI (reg:DI R11_REG))
20831 (match_operand:DI 1 "" "")))]
20832 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20834 [(set_attr "type" "callv")])
20836 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20837 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20838 ;; caught for use by garbage collectors and the like. Using an insn that
20839 ;; maps to SIGILL makes it more likely the program will rightfully die.
20840 ;; Keeping with tradition, "6" is in honor of #UD.
20841 (define_insn "trap"
20842 [(trap_if (const_int 1) (const_int 6))]
20844 { return ASM_SHORT "0x0b0f"; }
20845 [(set_attr "length" "2")])
20847 (define_expand "sse_prologue_save"
20848 [(parallel [(set (match_operand:BLK 0 "" "")
20849 (unspec:BLK [(reg:DI 21)
20856 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20857 (use (match_operand:DI 1 "register_operand" ""))
20858 (use (match_operand:DI 2 "immediate_operand" ""))
20859 (use (label_ref:DI (match_operand 3 "" "")))])]
20863 (define_insn "*sse_prologue_save_insn"
20864 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20865 (match_operand:DI 4 "const_int_operand" "n")))
20866 (unspec:BLK [(reg:DI 21)
20873 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20874 (use (match_operand:DI 1 "register_operand" "r"))
20875 (use (match_operand:DI 2 "const_int_operand" "i"))
20876 (use (label_ref:DI (match_operand 3 "" "X")))]
20878 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20879 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20883 operands[0] = gen_rtx_MEM (Pmode,
20884 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20885 output_asm_insn (\"jmp\\t%A1\", operands);
20886 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20888 operands[4] = adjust_address (operands[0], DImode, i*16);
20889 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20890 PUT_MODE (operands[4], TImode);
20891 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20892 output_asm_insn (\"rex\", operands);
20893 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20895 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20896 CODE_LABEL_NUMBER (operands[3]));
20900 [(set_attr "type" "other")
20901 (set_attr "length_immediate" "0")
20902 (set_attr "length_address" "0")
20903 (set_attr "length" "135")
20904 (set_attr "memory" "store")
20905 (set_attr "modrm" "0")
20906 (set_attr "mode" "DI")])
20908 (define_expand "prefetch"
20909 [(prefetch (match_operand 0 "address_operand" "")
20910 (match_operand:SI 1 "const_int_operand" "")
20911 (match_operand:SI 2 "const_int_operand" ""))]
20912 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20914 int rw = INTVAL (operands[1]);
20915 int locality = INTVAL (operands[2]);
20917 gcc_assert (rw == 0 || rw == 1);
20918 gcc_assert (locality >= 0 && locality <= 3);
20919 gcc_assert (GET_MODE (operands[0]) == Pmode
20920 || GET_MODE (operands[0]) == VOIDmode);
20922 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20923 supported by SSE counterpart or the SSE prefetch is not available
20924 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20926 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20927 operands[2] = GEN_INT (3);
20929 operands[1] = const0_rtx;
20932 (define_insn "*prefetch_sse"
20933 [(prefetch (match_operand:SI 0 "address_operand" "p")
20935 (match_operand:SI 1 "const_int_operand" ""))]
20936 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20938 static const char * const patterns[4] = {
20939 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20942 int locality = INTVAL (operands[1]);
20943 gcc_assert (locality >= 0 && locality <= 3);
20945 return patterns[locality];
20947 [(set_attr "type" "sse")
20948 (set_attr "memory" "none")])
20950 (define_insn "*prefetch_sse_rex"
20951 [(prefetch (match_operand:DI 0 "address_operand" "p")
20953 (match_operand:SI 1 "const_int_operand" ""))]
20954 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20956 static const char * const patterns[4] = {
20957 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20960 int locality = INTVAL (operands[1]);
20961 gcc_assert (locality >= 0 && locality <= 3);
20963 return patterns[locality];
20965 [(set_attr "type" "sse")
20966 (set_attr "memory" "none")])
20968 (define_insn "*prefetch_3dnow"
20969 [(prefetch (match_operand:SI 0 "address_operand" "p")
20970 (match_operand:SI 1 "const_int_operand" "n")
20972 "TARGET_3DNOW && !TARGET_64BIT"
20974 if (INTVAL (operands[1]) == 0)
20975 return "prefetch\t%a0";
20977 return "prefetchw\t%a0";
20979 [(set_attr "type" "mmx")
20980 (set_attr "memory" "none")])
20982 (define_insn "*prefetch_3dnow_rex"
20983 [(prefetch (match_operand:DI 0 "address_operand" "p")
20984 (match_operand:SI 1 "const_int_operand" "n")
20986 "TARGET_3DNOW && TARGET_64BIT"
20988 if (INTVAL (operands[1]) == 0)
20989 return "prefetch\t%a0";
20991 return "prefetchw\t%a0";
20993 [(set_attr "type" "mmx")
20994 (set_attr "memory" "none")])
20996 (define_expand "stack_protect_set"
20997 [(match_operand 0 "memory_operand" "")
20998 (match_operand 1 "memory_operand" "")]
21001 #ifdef TARGET_THREAD_SSP_OFFSET
21003 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21004 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21006 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21007 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21010 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21012 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21017 (define_insn "stack_protect_set_si"
21018 [(set (match_operand:SI 0 "memory_operand" "=m")
21019 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21020 (set (match_scratch:SI 2 "=&r") (const_int 0))
21021 (clobber (reg:CC FLAGS_REG))]
21023 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21024 [(set_attr "type" "multi")])
21026 (define_insn "stack_protect_set_di"
21027 [(set (match_operand:DI 0 "memory_operand" "=m")
21028 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21029 (set (match_scratch:DI 2 "=&r") (const_int 0))
21030 (clobber (reg:CC FLAGS_REG))]
21032 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21033 [(set_attr "type" "multi")])
21035 (define_insn "stack_tls_protect_set_si"
21036 [(set (match_operand:SI 0 "memory_operand" "=m")
21037 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21038 (set (match_scratch:SI 2 "=&r") (const_int 0))
21039 (clobber (reg:CC FLAGS_REG))]
21041 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21042 [(set_attr "type" "multi")])
21044 (define_insn "stack_tls_protect_set_di"
21045 [(set (match_operand:DI 0 "memory_operand" "=m")
21046 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21047 (set (match_scratch:DI 2 "=&r") (const_int 0))
21048 (clobber (reg:CC FLAGS_REG))]
21051 /* The kernel uses a different segment register for performance reasons; a
21052 system call would not have to trash the userspace segment register,
21053 which would be expensive */
21054 if (ix86_cmodel != CM_KERNEL)
21055 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21057 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21059 [(set_attr "type" "multi")])
21061 (define_expand "stack_protect_test"
21062 [(match_operand 0 "memory_operand" "")
21063 (match_operand 1 "memory_operand" "")
21064 (match_operand 2 "" "")]
21067 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21068 ix86_compare_op0 = operands[0];
21069 ix86_compare_op1 = operands[1];
21070 ix86_compare_emitted = flags;
21072 #ifdef TARGET_THREAD_SSP_OFFSET
21074 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21075 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21077 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21078 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21081 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21083 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21085 emit_jump_insn (gen_beq (operands[2]));
21089 (define_insn "stack_protect_test_si"
21090 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21091 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21092 (match_operand:SI 2 "memory_operand" "m")]
21094 (clobber (match_scratch:SI 3 "=&r"))]
21096 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21097 [(set_attr "type" "multi")])
21099 (define_insn "stack_protect_test_di"
21100 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21101 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21102 (match_operand:DI 2 "memory_operand" "m")]
21104 (clobber (match_scratch:DI 3 "=&r"))]
21106 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21107 [(set_attr "type" "multi")])
21109 (define_insn "stack_tls_protect_test_si"
21110 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21111 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21112 (match_operand:SI 2 "const_int_operand" "i")]
21113 UNSPEC_SP_TLS_TEST))
21114 (clobber (match_scratch:SI 3 "=r"))]
21116 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21117 [(set_attr "type" "multi")])
21119 (define_insn "stack_tls_protect_test_di"
21120 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21121 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21122 (match_operand:DI 2 "const_int_operand" "i")]
21123 UNSPEC_SP_TLS_TEST))
21124 (clobber (match_scratch:DI 3 "=r"))]
21127 /* The kernel uses a different segment register for performance reasons; a
21128 system call would not have to trash the userspace segment register,
21129 which would be expensive */
21130 if (ix86_cmodel != CM_KERNEL)
21131 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21133 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21135 [(set_attr "type" "multi")])
21137 (define_mode_iterator CRC32MODE [QI HI SI])
21138 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21139 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21141 (define_insn "sse4_2_crc32<mode>"
21142 [(set (match_operand:SI 0 "register_operand" "=r")
21144 [(match_operand:SI 1 "register_operand" "0")
21145 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21148 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21149 [(set_attr "type" "sselog1")
21150 (set_attr "prefix_rep" "1")
21151 (set_attr "prefix_extra" "1")
21152 (set_attr "mode" "SI")])
21154 (define_insn "sse4_2_crc32di"
21155 [(set (match_operand:DI 0 "register_operand" "=r")
21157 [(match_operand:DI 1 "register_operand" "0")
21158 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21160 "TARGET_SSE4_2 && TARGET_64BIT"
21161 "crc32q\t{%2, %0|%0, %2}"
21162 [(set_attr "type" "sselog1")
21163 (set_attr "prefix_rep" "1")
21164 (set_attr "prefix_extra" "1")
21165 (set_attr "mode" "DI")])
21169 (include "sync.md")