1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; The special asm out single letter directives following a '%' are:
31 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
33 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
34 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
35 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
36 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
37 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
38 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
39 ;; 'J' Print the appropriate jump operand.
41 ;; 'b' Print the QImode name of the register for the indicated operand.
42 ;; %b0 would print %al if operands[0] is reg 0.
43 ;; 'w' Likewise, print the HImode name of the register.
44 ;; 'k' Likewise, print the SImode name of the register.
45 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
46 ;; 'y' Print "st(0)" instead of "st" as a register.
51 [; Relocation specifiers
64 (UNSPEC_STACK_ALLOC 11)
66 (UNSPEC_SSE_PROLOGUE_SAVE 13)
70 (UNSPEC_SET_GOT_OFFSET 17)
75 (UNSPEC_TLS_LD_BASE 20)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
88 (UNSPEC_TRUNC_NOOP 39)
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 40)
99 (UNSPEC_NOP 48) ; prevents combiner cleverness
110 ; Generic math support
112 (UNSPEC_IEEE_MIN 51) ; not commutative
113 (UNSPEC_IEEE_MAX 52) ; not commutative
128 (UNSPEC_FRNDINT_FLOOR 70)
129 (UNSPEC_FRNDINT_CEIL 71)
130 (UNSPEC_FRNDINT_TRUNC 72)
131 (UNSPEC_FRNDINT_MASK_PM 73)
132 (UNSPEC_FIST_FLOOR 74)
133 (UNSPEC_FIST_CEIL 75)
135 ; x87 Double output FP
136 (UNSPEC_SINCOS_COS 80)
137 (UNSPEC_SINCOS_SIN 81)
138 (UNSPEC_XTRACT_FRACT 84)
139 (UNSPEC_XTRACT_EXP 85)
140 (UNSPEC_FSCALE_FRACT 86)
141 (UNSPEC_FSCALE_EXP 87)
152 (UNSPEC_SP_TLS_SET 102)
153 (UNSPEC_SP_TLS_TEST 103)
163 (UNSPEC_INSERTQI 132)
168 [(UNSPECV_BLOCKAGE 0)
169 (UNSPECV_STACK_PROBE 1)
178 (UNSPECV_CMPXCHG_1 10)
179 (UNSPECV_CMPXCHG_2 11)
184 ;; Registers by name.
195 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
198 ;; In C guard expressions, put expressions which may be compile-time
199 ;; constants first. This allows for better optimization. For
200 ;; example, write "TARGET_64BIT && reload_completed", not
201 ;; "reload_completed && TARGET_64BIT".
204 ;; Processor type. This attribute must exactly match the processor_type
205 ;; enumeration in i386.h.
206 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
207 nocona,core2,generic32,generic64,amdfam10"
208 (const (symbol_ref "ix86_tune")))
210 ;; A basic instruction type. Refinements due to arguments to be
211 ;; provided in other attributes.
214 alu,alu1,negnot,imov,imovx,lea,
215 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
216 icmp,test,ibr,setcc,icmov,
217 push,pop,call,callv,leave,
219 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
220 sselog,sselog1,sseiadd,sseishft,sseimul,
221 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
222 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
223 (const_string "other"))
225 ;; Main data type used by the insn
227 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
228 (const_string "unknown"))
230 ;; The CPU unit operations uses.
231 (define_attr "unit" "integer,i387,sse,mmx,unknown"
232 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
233 (const_string "i387")
234 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
235 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
237 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
239 (eq_attr "type" "other")
240 (const_string "unknown")]
241 (const_string "integer")))
243 ;; The (bounding maximum) length of an instruction immediate.
244 (define_attr "length_immediate" ""
245 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
248 (eq_attr "unit" "i387,sse,mmx")
250 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
252 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
253 (eq_attr "type" "imov,test")
254 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
255 (eq_attr "type" "call")
256 (if_then_else (match_operand 0 "constant_call_address_operand" "")
259 (eq_attr "type" "callv")
260 (if_then_else (match_operand 1 "constant_call_address_operand" "")
263 ;; We don't know the size before shorten_branches. Expect
264 ;; the instruction to fit for better scheduling.
265 (eq_attr "type" "ibr")
268 (symbol_ref "/* Update immediate_length and other attributes! */
269 gcc_unreachable (),1")))
271 ;; The (bounding maximum) length of an instruction address.
272 (define_attr "length_address" ""
273 (cond [(eq_attr "type" "str,other,multi,fxch")
275 (and (eq_attr "type" "call")
276 (match_operand 0 "constant_call_address_operand" ""))
278 (and (eq_attr "type" "callv")
279 (match_operand 1 "constant_call_address_operand" ""))
282 (symbol_ref "ix86_attr_length_address_default (insn)")))
284 ;; Set when length prefix is used.
285 (define_attr "prefix_data16" ""
286 (if_then_else (ior (eq_attr "mode" "HI")
287 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
291 ;; Set when string REP prefix is used.
292 (define_attr "prefix_rep" ""
293 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
297 ;; Set when 0f opcode prefix is used.
298 (define_attr "prefix_0f" ""
300 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
301 (eq_attr "unit" "sse,mmx"))
305 ;; Set when REX opcode prefix is used.
306 (define_attr "prefix_rex" ""
307 (cond [(and (eq_attr "mode" "DI")
308 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
310 (and (eq_attr "mode" "QI")
311 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
314 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
320 ;; Set when modrm byte is used.
321 (define_attr "modrm" ""
322 (cond [(eq_attr "type" "str,leave")
324 (eq_attr "unit" "i387")
326 (and (eq_attr "type" "incdec")
327 (ior (match_operand:SI 1 "register_operand" "")
328 (match_operand:HI 1 "register_operand" "")))
330 (and (eq_attr "type" "push")
331 (not (match_operand 1 "memory_operand" "")))
333 (and (eq_attr "type" "pop")
334 (not (match_operand 0 "memory_operand" "")))
336 (and (eq_attr "type" "imov")
337 (ior (and (match_operand 0 "register_operand" "")
338 (match_operand 1 "immediate_operand" ""))
339 (ior (and (match_operand 0 "ax_reg_operand" "")
340 (match_operand 1 "memory_displacement_only_operand" ""))
341 (and (match_operand 0 "memory_displacement_only_operand" "")
342 (match_operand 1 "ax_reg_operand" "")))))
344 (and (eq_attr "type" "call")
345 (match_operand 0 "constant_call_address_operand" ""))
347 (and (eq_attr "type" "callv")
348 (match_operand 1 "constant_call_address_operand" ""))
353 ;; The (bounding maximum) length of an instruction in bytes.
354 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
355 ;; Later we may want to split them and compute proper length as for
357 (define_attr "length" ""
358 (cond [(eq_attr "type" "other,multi,fistp,frndint")
360 (eq_attr "type" "fcmp")
362 (eq_attr "unit" "i387")
364 (plus (attr "prefix_data16")
365 (attr "length_address")))]
366 (plus (plus (attr "modrm")
367 (plus (attr "prefix_0f")
368 (plus (attr "prefix_rex")
370 (plus (attr "prefix_rep")
371 (plus (attr "prefix_data16")
372 (plus (attr "length_immediate")
373 (attr "length_address")))))))
375 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
376 ;; `store' if there is a simple memory reference therein, or `unknown'
377 ;; if the instruction is complex.
379 (define_attr "memory" "none,load,store,both,unknown"
380 (cond [(eq_attr "type" "other,multi,str")
381 (const_string "unknown")
382 (eq_attr "type" "lea,fcmov,fpspc")
383 (const_string "none")
384 (eq_attr "type" "fistp,leave")
385 (const_string "both")
386 (eq_attr "type" "frndint")
387 (const_string "load")
388 (eq_attr "type" "push")
389 (if_then_else (match_operand 1 "memory_operand" "")
390 (const_string "both")
391 (const_string "store"))
392 (eq_attr "type" "pop")
393 (if_then_else (match_operand 0 "memory_operand" "")
394 (const_string "both")
395 (const_string "load"))
396 (eq_attr "type" "setcc")
397 (if_then_else (match_operand 0 "memory_operand" "")
398 (const_string "store")
399 (const_string "none"))
400 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
401 (if_then_else (ior (match_operand 0 "memory_operand" "")
402 (match_operand 1 "memory_operand" ""))
403 (const_string "load")
404 (const_string "none"))
405 (eq_attr "type" "ibr")
406 (if_then_else (match_operand 0 "memory_operand" "")
407 (const_string "load")
408 (const_string "none"))
409 (eq_attr "type" "call")
410 (if_then_else (match_operand 0 "constant_call_address_operand" "")
411 (const_string "none")
412 (const_string "load"))
413 (eq_attr "type" "callv")
414 (if_then_else (match_operand 1 "constant_call_address_operand" "")
415 (const_string "none")
416 (const_string "load"))
417 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
418 (match_operand 1 "memory_operand" ""))
419 (const_string "both")
420 (and (match_operand 0 "memory_operand" "")
421 (match_operand 1 "memory_operand" ""))
422 (const_string "both")
423 (match_operand 0 "memory_operand" "")
424 (const_string "store")
425 (match_operand 1 "memory_operand" "")
426 (const_string "load")
428 "!alu1,negnot,ishift1,
429 imov,imovx,icmp,test,bitmanip,
431 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
432 mmx,mmxmov,mmxcmp,mmxcvt")
433 (match_operand 2 "memory_operand" ""))
434 (const_string "load")
435 (and (eq_attr "type" "icmov")
436 (match_operand 3 "memory_operand" ""))
437 (const_string "load")
439 (const_string "none")))
441 ;; Indicates if an instruction has both an immediate and a displacement.
443 (define_attr "imm_disp" "false,true,unknown"
444 (cond [(eq_attr "type" "other,multi")
445 (const_string "unknown")
446 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
447 (and (match_operand 0 "memory_displacement_operand" "")
448 (match_operand 1 "immediate_operand" "")))
449 (const_string "true")
450 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
451 (and (match_operand 0 "memory_displacement_operand" "")
452 (match_operand 2 "immediate_operand" "")))
453 (const_string "true")
455 (const_string "false")))
457 ;; Indicates if an FP operation has an integer source.
459 (define_attr "fp_int_src" "false,true"
460 (const_string "false"))
462 ;; Defines rounding mode of an FP operation.
464 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
465 (const_string "any"))
467 ;; Describe a user's asm statement.
468 (define_asm_attributes
469 [(set_attr "length" "128")
470 (set_attr "type" "multi")])
472 ;; All x87 floating point modes
473 (define_mode_macro X87MODEF [SF DF XF])
475 ;; x87 SFmode and DFMode floating point modes
476 (define_mode_macro X87MODEF12 [SF DF])
478 ;; All integer modes handled by x87 fisttp operator.
479 (define_mode_macro X87MODEI [HI SI DI])
481 ;; All integer modes handled by integer x87 operators.
482 (define_mode_macro X87MODEI12 [HI SI])
484 ;; All SSE floating point modes
485 (define_mode_macro SSEMODEF [SF DF])
487 ;; All integer modes handled by SSE cvtts?2si* operators.
488 (define_mode_macro SSEMODEI24 [SI DI])
490 ;; SSE asm suffix for floating point modes
491 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
493 ;; SSE vector mode corresponding to a scalar mode
494 (define_mode_attr ssevecmode
495 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
497 ;; Scheduling descriptions
499 (include "pentium.md")
502 (include "athlon.md")
506 ;; Operand and operator predicates and constraints
508 (include "predicates.md")
509 (include "constraints.md")
512 ;; Compare instructions.
514 ;; All compare insns have expanders that save the operands away without
515 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
516 ;; after the cmp) will actually emit the cmpM.
518 (define_expand "cmpti"
519 [(set (reg:CC FLAGS_REG)
520 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
521 (match_operand:TI 1 "x86_64_general_operand" "")))]
524 if (MEM_P (operands[0]) && MEM_P (operands[1]))
525 operands[0] = force_reg (TImode, operands[0]);
526 ix86_compare_op0 = operands[0];
527 ix86_compare_op1 = operands[1];
531 (define_expand "cmpdi"
532 [(set (reg:CC FLAGS_REG)
533 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
534 (match_operand:DI 1 "x86_64_general_operand" "")))]
537 if (MEM_P (operands[0]) && MEM_P (operands[1]))
538 operands[0] = force_reg (DImode, operands[0]);
539 ix86_compare_op0 = operands[0];
540 ix86_compare_op1 = operands[1];
544 (define_expand "cmpsi"
545 [(set (reg:CC FLAGS_REG)
546 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
547 (match_operand:SI 1 "general_operand" "")))]
550 if (MEM_P (operands[0]) && MEM_P (operands[1]))
551 operands[0] = force_reg (SImode, operands[0]);
552 ix86_compare_op0 = operands[0];
553 ix86_compare_op1 = operands[1];
557 (define_expand "cmphi"
558 [(set (reg:CC FLAGS_REG)
559 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
560 (match_operand:HI 1 "general_operand" "")))]
563 if (MEM_P (operands[0]) && MEM_P (operands[1]))
564 operands[0] = force_reg (HImode, operands[0]);
565 ix86_compare_op0 = operands[0];
566 ix86_compare_op1 = operands[1];
570 (define_expand "cmpqi"
571 [(set (reg:CC FLAGS_REG)
572 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
573 (match_operand:QI 1 "general_operand" "")))]
576 if (MEM_P (operands[0]) && MEM_P (operands[1]))
577 operands[0] = force_reg (QImode, operands[0]);
578 ix86_compare_op0 = operands[0];
579 ix86_compare_op1 = operands[1];
583 (define_insn "cmpdi_ccno_1_rex64"
584 [(set (reg FLAGS_REG)
585 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
586 (match_operand:DI 1 "const0_operand" "n,n")))]
587 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
590 cmp{q}\t{%1, %0|%0, %1}"
591 [(set_attr "type" "test,icmp")
592 (set_attr "length_immediate" "0,1")
593 (set_attr "mode" "DI")])
595 (define_insn "*cmpdi_minus_1_rex64"
596 [(set (reg FLAGS_REG)
597 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
598 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
600 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
601 "cmp{q}\t{%1, %0|%0, %1}"
602 [(set_attr "type" "icmp")
603 (set_attr "mode" "DI")])
605 (define_expand "cmpdi_1_rex64"
606 [(set (reg:CC FLAGS_REG)
607 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
608 (match_operand:DI 1 "general_operand" "")))]
612 (define_insn "cmpdi_1_insn_rex64"
613 [(set (reg FLAGS_REG)
614 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
615 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
616 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
617 "cmp{q}\t{%1, %0|%0, %1}"
618 [(set_attr "type" "icmp")
619 (set_attr "mode" "DI")])
622 (define_insn "*cmpsi_ccno_1"
623 [(set (reg FLAGS_REG)
624 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
625 (match_operand:SI 1 "const0_operand" "n,n")))]
626 "ix86_match_ccmode (insn, CCNOmode)"
629 cmp{l}\t{%1, %0|%0, %1}"
630 [(set_attr "type" "test,icmp")
631 (set_attr "length_immediate" "0,1")
632 (set_attr "mode" "SI")])
634 (define_insn "*cmpsi_minus_1"
635 [(set (reg FLAGS_REG)
636 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
637 (match_operand:SI 1 "general_operand" "ri,mr"))
639 "ix86_match_ccmode (insn, CCGOCmode)"
640 "cmp{l}\t{%1, %0|%0, %1}"
641 [(set_attr "type" "icmp")
642 (set_attr "mode" "SI")])
644 (define_expand "cmpsi_1"
645 [(set (reg:CC FLAGS_REG)
646 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
647 (match_operand:SI 1 "general_operand" "ri,mr")))]
651 (define_insn "*cmpsi_1_insn"
652 [(set (reg FLAGS_REG)
653 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
654 (match_operand:SI 1 "general_operand" "ri,mr")))]
655 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
656 && ix86_match_ccmode (insn, CCmode)"
657 "cmp{l}\t{%1, %0|%0, %1}"
658 [(set_attr "type" "icmp")
659 (set_attr "mode" "SI")])
661 (define_insn "*cmphi_ccno_1"
662 [(set (reg FLAGS_REG)
663 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
664 (match_operand:HI 1 "const0_operand" "n,n")))]
665 "ix86_match_ccmode (insn, CCNOmode)"
668 cmp{w}\t{%1, %0|%0, %1}"
669 [(set_attr "type" "test,icmp")
670 (set_attr "length_immediate" "0,1")
671 (set_attr "mode" "HI")])
673 (define_insn "*cmphi_minus_1"
674 [(set (reg FLAGS_REG)
675 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
676 (match_operand:HI 1 "general_operand" "ri,mr"))
678 "ix86_match_ccmode (insn, CCGOCmode)"
679 "cmp{w}\t{%1, %0|%0, %1}"
680 [(set_attr "type" "icmp")
681 (set_attr "mode" "HI")])
683 (define_insn "*cmphi_1"
684 [(set (reg FLAGS_REG)
685 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
686 (match_operand:HI 1 "general_operand" "ri,mr")))]
687 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
688 && ix86_match_ccmode (insn, CCmode)"
689 "cmp{w}\t{%1, %0|%0, %1}"
690 [(set_attr "type" "icmp")
691 (set_attr "mode" "HI")])
693 (define_insn "*cmpqi_ccno_1"
694 [(set (reg FLAGS_REG)
695 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
696 (match_operand:QI 1 "const0_operand" "n,n")))]
697 "ix86_match_ccmode (insn, CCNOmode)"
700 cmp{b}\t{$0, %0|%0, 0}"
701 [(set_attr "type" "test,icmp")
702 (set_attr "length_immediate" "0,1")
703 (set_attr "mode" "QI")])
705 (define_insn "*cmpqi_1"
706 [(set (reg FLAGS_REG)
707 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
708 (match_operand:QI 1 "general_operand" "qi,mq")))]
709 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
710 && ix86_match_ccmode (insn, CCmode)"
711 "cmp{b}\t{%1, %0|%0, %1}"
712 [(set_attr "type" "icmp")
713 (set_attr "mode" "QI")])
715 (define_insn "*cmpqi_minus_1"
716 [(set (reg FLAGS_REG)
717 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
718 (match_operand:QI 1 "general_operand" "qi,mq"))
720 "ix86_match_ccmode (insn, CCGOCmode)"
721 "cmp{b}\t{%1, %0|%0, %1}"
722 [(set_attr "type" "icmp")
723 (set_attr "mode" "QI")])
725 (define_insn "*cmpqi_ext_1"
726 [(set (reg FLAGS_REG)
728 (match_operand:QI 0 "general_operand" "Qm")
731 (match_operand 1 "ext_register_operand" "Q")
734 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
735 "cmp{b}\t{%h1, %0|%0, %h1}"
736 [(set_attr "type" "icmp")
737 (set_attr "mode" "QI")])
739 (define_insn "*cmpqi_ext_1_rex64"
740 [(set (reg FLAGS_REG)
742 (match_operand:QI 0 "register_operand" "Q")
745 (match_operand 1 "ext_register_operand" "Q")
748 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
749 "cmp{b}\t{%h1, %0|%0, %h1}"
750 [(set_attr "type" "icmp")
751 (set_attr "mode" "QI")])
753 (define_insn "*cmpqi_ext_2"
754 [(set (reg FLAGS_REG)
758 (match_operand 0 "ext_register_operand" "Q")
761 (match_operand:QI 1 "const0_operand" "n")))]
762 "ix86_match_ccmode (insn, CCNOmode)"
764 [(set_attr "type" "test")
765 (set_attr "length_immediate" "0")
766 (set_attr "mode" "QI")])
768 (define_expand "cmpqi_ext_3"
769 [(set (reg:CC FLAGS_REG)
773 (match_operand 0 "ext_register_operand" "")
776 (match_operand:QI 1 "general_operand" "")))]
780 (define_insn "cmpqi_ext_3_insn"
781 [(set (reg FLAGS_REG)
785 (match_operand 0 "ext_register_operand" "Q")
788 (match_operand:QI 1 "general_operand" "Qmn")))]
789 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
790 "cmp{b}\t{%1, %h0|%h0, %1}"
791 [(set_attr "type" "icmp")
792 (set_attr "mode" "QI")])
794 (define_insn "cmpqi_ext_3_insn_rex64"
795 [(set (reg FLAGS_REG)
799 (match_operand 0 "ext_register_operand" "Q")
802 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
803 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
804 "cmp{b}\t{%1, %h0|%h0, %1}"
805 [(set_attr "type" "icmp")
806 (set_attr "mode" "QI")])
808 (define_insn "*cmpqi_ext_4"
809 [(set (reg FLAGS_REG)
813 (match_operand 0 "ext_register_operand" "Q")
818 (match_operand 1 "ext_register_operand" "Q")
821 "ix86_match_ccmode (insn, CCmode)"
822 "cmp{b}\t{%h1, %h0|%h0, %h1}"
823 [(set_attr "type" "icmp")
824 (set_attr "mode" "QI")])
826 ;; These implement float point compares.
827 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
828 ;; which would allow mix and match FP modes on the compares. Which is what
829 ;; the old patterns did, but with many more of them.
831 (define_expand "cmpxf"
832 [(set (reg:CC FLAGS_REG)
833 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
834 (match_operand:XF 1 "nonmemory_operand" "")))]
837 ix86_compare_op0 = operands[0];
838 ix86_compare_op1 = operands[1];
842 (define_expand "cmpdf"
843 [(set (reg:CC FLAGS_REG)
844 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
845 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
846 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
848 ix86_compare_op0 = operands[0];
849 ix86_compare_op1 = operands[1];
853 (define_expand "cmpsf"
854 [(set (reg:CC FLAGS_REG)
855 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
856 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
857 "TARGET_80387 || TARGET_SSE_MATH"
859 ix86_compare_op0 = operands[0];
860 ix86_compare_op1 = operands[1];
864 ;; FP compares, step 1:
865 ;; Set the FP condition codes.
867 ;; CCFPmode compare with exceptions
868 ;; CCFPUmode compare with no exceptions
870 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
871 ;; used to manage the reg stack popping would not be preserved.
873 (define_insn "*cmpfp_0"
874 [(set (match_operand:HI 0 "register_operand" "=a")
877 (match_operand 1 "register_operand" "f")
878 (match_operand 2 "const0_operand" "X"))]
881 && FLOAT_MODE_P (GET_MODE (operands[1]))
882 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
883 "* return output_fp_compare (insn, operands, 0, 0);"
884 [(set_attr "type" "multi")
885 (set_attr "unit" "i387")
887 (cond [(match_operand:SF 1 "" "")
889 (match_operand:DF 1 "" "")
892 (const_string "XF")))])
894 (define_insn "*cmpfp_sf"
895 [(set (match_operand:HI 0 "register_operand" "=a")
898 (match_operand:SF 1 "register_operand" "f")
899 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
902 "* return output_fp_compare (insn, operands, 0, 0);"
903 [(set_attr "type" "multi")
904 (set_attr "unit" "i387")
905 (set_attr "mode" "SF")])
907 (define_insn "*cmpfp_df"
908 [(set (match_operand:HI 0 "register_operand" "=a")
911 (match_operand:DF 1 "register_operand" "f")
912 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
915 "* return output_fp_compare (insn, operands, 0, 0);"
916 [(set_attr "type" "multi")
917 (set_attr "unit" "i387")
918 (set_attr "mode" "DF")])
920 (define_insn "*cmpfp_xf"
921 [(set (match_operand:HI 0 "register_operand" "=a")
924 (match_operand:XF 1 "register_operand" "f")
925 (match_operand:XF 2 "register_operand" "f"))]
928 "* return output_fp_compare (insn, operands, 0, 0);"
929 [(set_attr "type" "multi")
930 (set_attr "unit" "i387")
931 (set_attr "mode" "XF")])
933 (define_insn "*cmpfp_u"
934 [(set (match_operand:HI 0 "register_operand" "=a")
937 (match_operand 1 "register_operand" "f")
938 (match_operand 2 "register_operand" "f"))]
941 && FLOAT_MODE_P (GET_MODE (operands[1]))
942 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
943 "* return output_fp_compare (insn, operands, 0, 1);"
944 [(set_attr "type" "multi")
945 (set_attr "unit" "i387")
947 (cond [(match_operand:SF 1 "" "")
949 (match_operand:DF 1 "" "")
952 (const_string "XF")))])
954 (define_insn "*cmpfp_<mode>"
955 [(set (match_operand:HI 0 "register_operand" "=a")
958 (match_operand 1 "register_operand" "f")
959 (match_operator 3 "float_operator"
960 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
962 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
963 && FLOAT_MODE_P (GET_MODE (operands[1]))
964 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
965 "* return output_fp_compare (insn, operands, 0, 0);"
966 [(set_attr "type" "multi")
967 (set_attr "unit" "i387")
968 (set_attr "fp_int_src" "true")
969 (set_attr "mode" "<MODE>")])
971 ;; FP compares, step 2
972 ;; Move the fpsw to ax.
974 (define_insn "x86_fnstsw_1"
975 [(set (match_operand:HI 0 "register_operand" "=a")
976 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
979 [(set_attr "length" "2")
980 (set_attr "mode" "SI")
981 (set_attr "unit" "i387")])
983 ;; FP compares, step 3
984 ;; Get ax into flags, general case.
986 (define_insn "x86_sahf_1"
987 [(set (reg:CC FLAGS_REG)
988 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
992 [(set_attr "length" "1")
993 (set_attr "athlon_decode" "vector")
994 (set_attr "amdfam10_decode" "direct")
995 (set_attr "mode" "SI")])
997 ;; Pentium Pro can do steps 1 through 3 in one go.
998 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
999 (define_insn "*cmpfp_i_mixed"
1000 [(set (reg:CCFP FLAGS_REG)
1001 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1002 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1003 "TARGET_MIX_SSE_I387
1004 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1005 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006 "* return output_fp_compare (insn, operands, 1, 0);"
1007 [(set_attr "type" "fcmp,ssecomi")
1009 (if_then_else (match_operand:SF 1 "" "")
1011 (const_string "DF")))
1012 (set_attr "athlon_decode" "vector")
1013 (set_attr "amdfam10_decode" "direct")])
1015 (define_insn "*cmpfp_i_sse"
1016 [(set (reg:CCFP FLAGS_REG)
1017 (compare:CCFP (match_operand 0 "register_operand" "x")
1018 (match_operand 1 "nonimmediate_operand" "xm")))]
1020 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022 "* return output_fp_compare (insn, operands, 1, 0);"
1023 [(set_attr "type" "ssecomi")
1025 (if_then_else (match_operand:SF 1 "" "")
1027 (const_string "DF")))
1028 (set_attr "athlon_decode" "vector")
1029 (set_attr "amdfam10_decode" "direct")])
1031 (define_insn "*cmpfp_i_i387"
1032 [(set (reg:CCFP FLAGS_REG)
1033 (compare:CCFP (match_operand 0 "register_operand" "f")
1034 (match_operand 1 "register_operand" "f")))]
1035 "TARGET_80387 && TARGET_CMOVE
1036 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1037 && FLOAT_MODE_P (GET_MODE (operands[0]))
1038 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039 "* return output_fp_compare (insn, operands, 1, 0);"
1040 [(set_attr "type" "fcmp")
1042 (cond [(match_operand:SF 1 "" "")
1044 (match_operand:DF 1 "" "")
1047 (const_string "XF")))
1048 (set_attr "athlon_decode" "vector")
1049 (set_attr "amdfam10_decode" "direct")])
1051 (define_insn "*cmpfp_iu_mixed"
1052 [(set (reg:CCFPU FLAGS_REG)
1053 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1054 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1055 "TARGET_MIX_SSE_I387
1056 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1057 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1058 "* return output_fp_compare (insn, operands, 1, 1);"
1059 [(set_attr "type" "fcmp,ssecomi")
1061 (if_then_else (match_operand:SF 1 "" "")
1063 (const_string "DF")))
1064 (set_attr "athlon_decode" "vector")
1065 (set_attr "amdfam10_decode" "direct")])
1067 (define_insn "*cmpfp_iu_sse"
1068 [(set (reg:CCFPU FLAGS_REG)
1069 (compare:CCFPU (match_operand 0 "register_operand" "x")
1070 (match_operand 1 "nonimmediate_operand" "xm")))]
1072 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1073 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1074 "* return output_fp_compare (insn, operands, 1, 1);"
1075 [(set_attr "type" "ssecomi")
1077 (if_then_else (match_operand:SF 1 "" "")
1079 (const_string "DF")))
1080 (set_attr "athlon_decode" "vector")
1081 (set_attr "amdfam10_decode" "direct")])
1083 (define_insn "*cmpfp_iu_387"
1084 [(set (reg:CCFPU FLAGS_REG)
1085 (compare:CCFPU (match_operand 0 "register_operand" "f")
1086 (match_operand 1 "register_operand" "f")))]
1087 "TARGET_80387 && TARGET_CMOVE
1088 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1089 && FLOAT_MODE_P (GET_MODE (operands[0]))
1090 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1091 "* return output_fp_compare (insn, operands, 1, 1);"
1092 [(set_attr "type" "fcmp")
1094 (cond [(match_operand:SF 1 "" "")
1096 (match_operand:DF 1 "" "")
1099 (const_string "XF")))
1100 (set_attr "athlon_decode" "vector")
1101 (set_attr "amdfam10_decode" "direct")])
1103 ;; Move instructions.
1105 ;; General case of fullword move.
1107 (define_expand "movsi"
1108 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1109 (match_operand:SI 1 "general_operand" ""))]
1111 "ix86_expand_move (SImode, operands); DONE;")
1113 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1116 ;; %%% We don't use a post-inc memory reference because x86 is not a
1117 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1118 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1119 ;; targets without our curiosities, and it is just as easy to represent
1120 ;; this differently.
1122 (define_insn "*pushsi2"
1123 [(set (match_operand:SI 0 "push_operand" "=<")
1124 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1127 [(set_attr "type" "push")
1128 (set_attr "mode" "SI")])
1130 ;; For 64BIT abi we always round up to 8 bytes.
1131 (define_insn "*pushsi2_rex64"
1132 [(set (match_operand:SI 0 "push_operand" "=X")
1133 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1136 [(set_attr "type" "push")
1137 (set_attr "mode" "SI")])
1139 (define_insn "*pushsi2_prologue"
1140 [(set (match_operand:SI 0 "push_operand" "=<")
1141 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1142 (clobber (mem:BLK (scratch)))]
1145 [(set_attr "type" "push")
1146 (set_attr "mode" "SI")])
1148 (define_insn "*popsi1_epilogue"
1149 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1150 (mem:SI (reg:SI SP_REG)))
1151 (set (reg:SI SP_REG)
1152 (plus:SI (reg:SI SP_REG) (const_int 4)))
1153 (clobber (mem:BLK (scratch)))]
1156 [(set_attr "type" "pop")
1157 (set_attr "mode" "SI")])
1159 (define_insn "popsi1"
1160 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1161 (mem:SI (reg:SI SP_REG)))
1162 (set (reg:SI SP_REG)
1163 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1166 [(set_attr "type" "pop")
1167 (set_attr "mode" "SI")])
1169 (define_insn "*movsi_xor"
1170 [(set (match_operand:SI 0 "register_operand" "=r")
1171 (match_operand:SI 1 "const0_operand" "i"))
1172 (clobber (reg:CC FLAGS_REG))]
1173 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1175 [(set_attr "type" "alu1")
1176 (set_attr "mode" "SI")
1177 (set_attr "length_immediate" "0")])
1179 (define_insn "*movsi_or"
1180 [(set (match_operand:SI 0 "register_operand" "=r")
1181 (match_operand:SI 1 "immediate_operand" "i"))
1182 (clobber (reg:CC FLAGS_REG))]
1184 && operands[1] == constm1_rtx
1185 && (TARGET_PENTIUM || optimize_size)"
1187 operands[1] = constm1_rtx;
1188 return "or{l}\t{%1, %0|%0, %1}";
1190 [(set_attr "type" "alu1")
1191 (set_attr "mode" "SI")
1192 (set_attr "length_immediate" "1")])
1194 (define_insn "*movsi_1"
1195 [(set (match_operand:SI 0 "nonimmediate_operand"
1196 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1197 (match_operand:SI 1 "general_operand"
1198 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1199 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1201 switch (get_attr_type (insn))
1204 if (get_attr_mode (insn) == MODE_TI)
1205 return "pxor\t%0, %0";
1206 return "xorps\t%0, %0";
1209 switch (get_attr_mode (insn))
1212 return "movdqa\t{%1, %0|%0, %1}";
1214 return "movaps\t{%1, %0|%0, %1}";
1216 return "movd\t{%1, %0|%0, %1}";
1218 return "movss\t{%1, %0|%0, %1}";
1224 return "pxor\t%0, %0";
1227 if (get_attr_mode (insn) == MODE_DI)
1228 return "movq\t{%1, %0|%0, %1}";
1229 return "movd\t{%1, %0|%0, %1}";
1232 return "lea{l}\t{%1, %0|%0, %1}";
1235 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1236 return "mov{l}\t{%1, %0|%0, %1}";
1240 (cond [(eq_attr "alternative" "2")
1241 (const_string "mmxadd")
1242 (eq_attr "alternative" "3,4,5")
1243 (const_string "mmxmov")
1244 (eq_attr "alternative" "6")
1245 (const_string "sselog1")
1246 (eq_attr "alternative" "7,8,9,10,11")
1247 (const_string "ssemov")
1248 (match_operand:DI 1 "pic_32bit_operand" "")
1249 (const_string "lea")
1251 (const_string "imov")))
1253 (cond [(eq_attr "alternative" "2,3")
1255 (eq_attr "alternative" "6,7")
1257 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1258 (const_string "V4SF")
1259 (const_string "TI"))
1260 (and (eq_attr "alternative" "8,9,10,11")
1261 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1264 (const_string "SI")))])
1266 ;; Stores and loads of ax to arbitrary constant address.
1267 ;; We fake an second form of instruction to force reload to load address
1268 ;; into register when rax is not available
1269 (define_insn "*movabssi_1_rex64"
1270 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1271 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1272 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1274 movabs{l}\t{%1, %P0|%P0, %1}
1275 mov{l}\t{%1, %a0|%a0, %1}"
1276 [(set_attr "type" "imov")
1277 (set_attr "modrm" "0,*")
1278 (set_attr "length_address" "8,0")
1279 (set_attr "length_immediate" "0,*")
1280 (set_attr "memory" "store")
1281 (set_attr "mode" "SI")])
1283 (define_insn "*movabssi_2_rex64"
1284 [(set (match_operand:SI 0 "register_operand" "=a,r")
1285 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1286 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1288 movabs{l}\t{%P1, %0|%0, %P1}
1289 mov{l}\t{%a1, %0|%0, %a1}"
1290 [(set_attr "type" "imov")
1291 (set_attr "modrm" "0,*")
1292 (set_attr "length_address" "8,0")
1293 (set_attr "length_immediate" "0")
1294 (set_attr "memory" "load")
1295 (set_attr "mode" "SI")])
1297 (define_insn "*swapsi"
1298 [(set (match_operand:SI 0 "register_operand" "+r")
1299 (match_operand:SI 1 "register_operand" "+r"))
1304 [(set_attr "type" "imov")
1305 (set_attr "mode" "SI")
1306 (set_attr "pent_pair" "np")
1307 (set_attr "athlon_decode" "vector")
1308 (set_attr "amdfam10_decode" "double")])
1310 (define_expand "movhi"
1311 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1312 (match_operand:HI 1 "general_operand" ""))]
1314 "ix86_expand_move (HImode, operands); DONE;")
1316 (define_insn "*pushhi2"
1317 [(set (match_operand:HI 0 "push_operand" "=X")
1318 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1321 [(set_attr "type" "push")
1322 (set_attr "mode" "SI")])
1324 ;; For 64BIT abi we always round up to 8 bytes.
1325 (define_insn "*pushhi2_rex64"
1326 [(set (match_operand:HI 0 "push_operand" "=X")
1327 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1330 [(set_attr "type" "push")
1331 (set_attr "mode" "DI")])
1333 (define_insn "*movhi_1"
1334 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1335 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1336 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1338 switch (get_attr_type (insn))
1341 /* movzwl is faster than movw on p2 due to partial word stalls,
1342 though not as fast as an aligned movl. */
1343 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1345 if (get_attr_mode (insn) == MODE_SI)
1346 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1348 return "mov{w}\t{%1, %0|%0, %1}";
1352 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1353 (const_string "imov")
1354 (and (eq_attr "alternative" "0")
1355 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1357 (eq (symbol_ref "TARGET_HIMODE_MATH")
1359 (const_string "imov")
1360 (and (eq_attr "alternative" "1,2")
1361 (match_operand:HI 1 "aligned_operand" ""))
1362 (const_string "imov")
1363 (and (ne (symbol_ref "TARGET_MOVX")
1365 (eq_attr "alternative" "0,2"))
1366 (const_string "imovx")
1368 (const_string "imov")))
1370 (cond [(eq_attr "type" "imovx")
1372 (and (eq_attr "alternative" "1,2")
1373 (match_operand:HI 1 "aligned_operand" ""))
1375 (and (eq_attr "alternative" "0")
1376 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1378 (eq (symbol_ref "TARGET_HIMODE_MATH")
1382 (const_string "HI")))])
1384 ;; Stores and loads of ax to arbitrary constant address.
1385 ;; We fake an second form of instruction to force reload to load address
1386 ;; into register when rax is not available
1387 (define_insn "*movabshi_1_rex64"
1388 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1389 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1390 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1392 movabs{w}\t{%1, %P0|%P0, %1}
1393 mov{w}\t{%1, %a0|%a0, %1}"
1394 [(set_attr "type" "imov")
1395 (set_attr "modrm" "0,*")
1396 (set_attr "length_address" "8,0")
1397 (set_attr "length_immediate" "0,*")
1398 (set_attr "memory" "store")
1399 (set_attr "mode" "HI")])
1401 (define_insn "*movabshi_2_rex64"
1402 [(set (match_operand:HI 0 "register_operand" "=a,r")
1403 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1404 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1406 movabs{w}\t{%P1, %0|%0, %P1}
1407 mov{w}\t{%a1, %0|%0, %a1}"
1408 [(set_attr "type" "imov")
1409 (set_attr "modrm" "0,*")
1410 (set_attr "length_address" "8,0")
1411 (set_attr "length_immediate" "0")
1412 (set_attr "memory" "load")
1413 (set_attr "mode" "HI")])
1415 (define_insn "*swaphi_1"
1416 [(set (match_operand:HI 0 "register_operand" "+r")
1417 (match_operand:HI 1 "register_operand" "+r"))
1420 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1422 [(set_attr "type" "imov")
1423 (set_attr "mode" "SI")
1424 (set_attr "pent_pair" "np")
1425 (set_attr "athlon_decode" "vector")
1426 (set_attr "amdfam10_decode" "double")])
1428 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1429 (define_insn "*swaphi_2"
1430 [(set (match_operand:HI 0 "register_operand" "+r")
1431 (match_operand:HI 1 "register_operand" "+r"))
1434 "TARGET_PARTIAL_REG_STALL"
1436 [(set_attr "type" "imov")
1437 (set_attr "mode" "HI")
1438 (set_attr "pent_pair" "np")
1439 (set_attr "athlon_decode" "vector")])
1441 (define_expand "movstricthi"
1442 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1443 (match_operand:HI 1 "general_operand" ""))]
1444 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1446 /* Don't generate memory->memory moves, go through a register */
1447 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1448 operands[1] = force_reg (HImode, operands[1]);
1451 (define_insn "*movstricthi_1"
1452 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1453 (match_operand:HI 1 "general_operand" "rn,m"))]
1454 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1455 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1456 "mov{w}\t{%1, %0|%0, %1}"
1457 [(set_attr "type" "imov")
1458 (set_attr "mode" "HI")])
1460 (define_insn "*movstricthi_xor"
1461 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1462 (match_operand:HI 1 "const0_operand" "i"))
1463 (clobber (reg:CC FLAGS_REG))]
1465 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1467 [(set_attr "type" "alu1")
1468 (set_attr "mode" "HI")
1469 (set_attr "length_immediate" "0")])
1471 (define_expand "movqi"
1472 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1473 (match_operand:QI 1 "general_operand" ""))]
1475 "ix86_expand_move (QImode, operands); DONE;")
1477 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1478 ;; "push a byte". But actually we use pushl, which has the effect
1479 ;; of rounding the amount pushed up to a word.
1481 (define_insn "*pushqi2"
1482 [(set (match_operand:QI 0 "push_operand" "=X")
1483 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1486 [(set_attr "type" "push")
1487 (set_attr "mode" "SI")])
1489 ;; For 64BIT abi we always round up to 8 bytes.
1490 (define_insn "*pushqi2_rex64"
1491 [(set (match_operand:QI 0 "push_operand" "=X")
1492 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1495 [(set_attr "type" "push")
1496 (set_attr "mode" "DI")])
1498 ;; Situation is quite tricky about when to choose full sized (SImode) move
1499 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1500 ;; partial register dependency machines (such as AMD Athlon), where QImode
1501 ;; moves issue extra dependency and for partial register stalls machines
1502 ;; that don't use QImode patterns (and QImode move cause stall on the next
1505 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1506 ;; register stall machines with, where we use QImode instructions, since
1507 ;; partial register stall can be caused there. Then we use movzx.
1508 (define_insn "*movqi_1"
1509 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1510 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1511 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1513 switch (get_attr_type (insn))
1516 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1517 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1519 if (get_attr_mode (insn) == MODE_SI)
1520 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1522 return "mov{b}\t{%1, %0|%0, %1}";
1526 (cond [(and (eq_attr "alternative" "5")
1527 (not (match_operand:QI 1 "aligned_operand" "")))
1528 (const_string "imovx")
1529 (ne (symbol_ref "optimize_size") (const_int 0))
1530 (const_string "imov")
1531 (and (eq_attr "alternative" "3")
1532 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1534 (eq (symbol_ref "TARGET_QIMODE_MATH")
1536 (const_string "imov")
1537 (eq_attr "alternative" "3,5")
1538 (const_string "imovx")
1539 (and (ne (symbol_ref "TARGET_MOVX")
1541 (eq_attr "alternative" "2"))
1542 (const_string "imovx")
1544 (const_string "imov")))
1546 (cond [(eq_attr "alternative" "3,4,5")
1548 (eq_attr "alternative" "6")
1550 (eq_attr "type" "imovx")
1552 (and (eq_attr "type" "imov")
1553 (and (eq_attr "alternative" "0,1")
1554 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1556 (and (eq (symbol_ref "optimize_size")
1558 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1561 ;; Avoid partial register stalls when not using QImode arithmetic
1562 (and (eq_attr "type" "imov")
1563 (and (eq_attr "alternative" "0,1")
1564 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1566 (eq (symbol_ref "TARGET_QIMODE_MATH")
1570 (const_string "QI")))])
1572 (define_expand "reload_outqi"
1573 [(parallel [(match_operand:QI 0 "" "=m")
1574 (match_operand:QI 1 "register_operand" "r")
1575 (match_operand:QI 2 "register_operand" "=&q")])]
1579 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1581 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1582 if (! q_regs_operand (op1, QImode))
1584 emit_insn (gen_movqi (op2, op1));
1587 emit_insn (gen_movqi (op0, op1));
1591 (define_insn "*swapqi_1"
1592 [(set (match_operand:QI 0 "register_operand" "+r")
1593 (match_operand:QI 1 "register_operand" "+r"))
1596 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1598 [(set_attr "type" "imov")
1599 (set_attr "mode" "SI")
1600 (set_attr "pent_pair" "np")
1601 (set_attr "athlon_decode" "vector")
1602 (set_attr "amdfam10_decode" "vector")])
1604 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1605 (define_insn "*swapqi_2"
1606 [(set (match_operand:QI 0 "register_operand" "+q")
1607 (match_operand:QI 1 "register_operand" "+q"))
1610 "TARGET_PARTIAL_REG_STALL"
1612 [(set_attr "type" "imov")
1613 (set_attr "mode" "QI")
1614 (set_attr "pent_pair" "np")
1615 (set_attr "athlon_decode" "vector")])
1617 (define_expand "movstrictqi"
1618 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1619 (match_operand:QI 1 "general_operand" ""))]
1620 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1622 /* Don't generate memory->memory moves, go through a register. */
1623 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1624 operands[1] = force_reg (QImode, operands[1]);
1627 (define_insn "*movstrictqi_1"
1628 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1629 (match_operand:QI 1 "general_operand" "*qn,m"))]
1630 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1631 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1632 "mov{b}\t{%1, %0|%0, %1}"
1633 [(set_attr "type" "imov")
1634 (set_attr "mode" "QI")])
1636 (define_insn "*movstrictqi_xor"
1637 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1638 (match_operand:QI 1 "const0_operand" "i"))
1639 (clobber (reg:CC FLAGS_REG))]
1640 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1642 [(set_attr "type" "alu1")
1643 (set_attr "mode" "QI")
1644 (set_attr "length_immediate" "0")])
1646 (define_insn "*movsi_extv_1"
1647 [(set (match_operand:SI 0 "register_operand" "=R")
1648 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1652 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1653 [(set_attr "type" "imovx")
1654 (set_attr "mode" "SI")])
1656 (define_insn "*movhi_extv_1"
1657 [(set (match_operand:HI 0 "register_operand" "=R")
1658 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1662 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1663 [(set_attr "type" "imovx")
1664 (set_attr "mode" "SI")])
1666 (define_insn "*movqi_extv_1"
1667 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1668 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1673 switch (get_attr_type (insn))
1676 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1678 return "mov{b}\t{%h1, %0|%0, %h1}";
1682 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1683 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1684 (ne (symbol_ref "TARGET_MOVX")
1686 (const_string "imovx")
1687 (const_string "imov")))
1689 (if_then_else (eq_attr "type" "imovx")
1691 (const_string "QI")))])
1693 (define_insn "*movqi_extv_1_rex64"
1694 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1695 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1700 switch (get_attr_type (insn))
1703 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1705 return "mov{b}\t{%h1, %0|%0, %h1}";
1709 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1710 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1711 (ne (symbol_ref "TARGET_MOVX")
1713 (const_string "imovx")
1714 (const_string "imov")))
1716 (if_then_else (eq_attr "type" "imovx")
1718 (const_string "QI")))])
1720 ;; Stores and loads of ax to arbitrary constant address.
1721 ;; We fake an second form of instruction to force reload to load address
1722 ;; into register when rax is not available
1723 (define_insn "*movabsqi_1_rex64"
1724 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1725 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1726 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1728 movabs{b}\t{%1, %P0|%P0, %1}
1729 mov{b}\t{%1, %a0|%a0, %1}"
1730 [(set_attr "type" "imov")
1731 (set_attr "modrm" "0,*")
1732 (set_attr "length_address" "8,0")
1733 (set_attr "length_immediate" "0,*")
1734 (set_attr "memory" "store")
1735 (set_attr "mode" "QI")])
1737 (define_insn "*movabsqi_2_rex64"
1738 [(set (match_operand:QI 0 "register_operand" "=a,r")
1739 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1740 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1742 movabs{b}\t{%P1, %0|%0, %P1}
1743 mov{b}\t{%a1, %0|%0, %a1}"
1744 [(set_attr "type" "imov")
1745 (set_attr "modrm" "0,*")
1746 (set_attr "length_address" "8,0")
1747 (set_attr "length_immediate" "0")
1748 (set_attr "memory" "load")
1749 (set_attr "mode" "QI")])
1751 (define_insn "*movdi_extzv_1"
1752 [(set (match_operand:DI 0 "register_operand" "=R")
1753 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1757 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1758 [(set_attr "type" "imovx")
1759 (set_attr "mode" "DI")])
1761 (define_insn "*movsi_extzv_1"
1762 [(set (match_operand:SI 0 "register_operand" "=R")
1763 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1767 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1768 [(set_attr "type" "imovx")
1769 (set_attr "mode" "SI")])
1771 (define_insn "*movqi_extzv_2"
1772 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1773 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1778 switch (get_attr_type (insn))
1781 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1783 return "mov{b}\t{%h1, %0|%0, %h1}";
1787 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1788 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1789 (ne (symbol_ref "TARGET_MOVX")
1791 (const_string "imovx")
1792 (const_string "imov")))
1794 (if_then_else (eq_attr "type" "imovx")
1796 (const_string "QI")))])
1798 (define_insn "*movqi_extzv_2_rex64"
1799 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1800 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1805 switch (get_attr_type (insn))
1808 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1810 return "mov{b}\t{%h1, %0|%0, %h1}";
1814 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1815 (ne (symbol_ref "TARGET_MOVX")
1817 (const_string "imovx")
1818 (const_string "imov")))
1820 (if_then_else (eq_attr "type" "imovx")
1822 (const_string "QI")))])
1824 (define_insn "movsi_insv_1"
1825 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1828 (match_operand:SI 1 "general_operand" "Qmn"))]
1830 "mov{b}\t{%b1, %h0|%h0, %b1}"
1831 [(set_attr "type" "imov")
1832 (set_attr "mode" "QI")])
1834 (define_insn "*movsi_insv_1_rex64"
1835 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1838 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1840 "mov{b}\t{%b1, %h0|%h0, %b1}"
1841 [(set_attr "type" "imov")
1842 (set_attr "mode" "QI")])
1844 (define_insn "movdi_insv_1_rex64"
1845 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1848 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1850 "mov{b}\t{%b1, %h0|%h0, %b1}"
1851 [(set_attr "type" "imov")
1852 (set_attr "mode" "QI")])
1854 (define_insn "*movqi_insv_2"
1855 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1858 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1861 "mov{b}\t{%h1, %h0|%h0, %h1}"
1862 [(set_attr "type" "imov")
1863 (set_attr "mode" "QI")])
1865 (define_expand "movdi"
1866 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1867 (match_operand:DI 1 "general_operand" ""))]
1869 "ix86_expand_move (DImode, operands); DONE;")
1871 (define_insn "*pushdi"
1872 [(set (match_operand:DI 0 "push_operand" "=<")
1873 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1877 (define_insn "*pushdi2_rex64"
1878 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1879 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1884 [(set_attr "type" "push,multi")
1885 (set_attr "mode" "DI")])
1887 ;; Convert impossible pushes of immediate to existing instructions.
1888 ;; First try to get scratch register and go through it. In case this
1889 ;; fails, push sign extended lower part first and then overwrite
1890 ;; upper part by 32bit move.
1892 [(match_scratch:DI 2 "r")
1893 (set (match_operand:DI 0 "push_operand" "")
1894 (match_operand:DI 1 "immediate_operand" ""))]
1895 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1896 && !x86_64_immediate_operand (operands[1], DImode)"
1897 [(set (match_dup 2) (match_dup 1))
1898 (set (match_dup 0) (match_dup 2))]
1901 ;; We need to define this as both peepholer and splitter for case
1902 ;; peephole2 pass is not run.
1903 ;; "&& 1" is needed to keep it from matching the previous pattern.
1905 [(set (match_operand:DI 0 "push_operand" "")
1906 (match_operand:DI 1 "immediate_operand" ""))]
1907 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1908 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1909 [(set (match_dup 0) (match_dup 1))
1910 (set (match_dup 2) (match_dup 3))]
1911 "split_di (operands + 1, 1, operands + 2, operands + 3);
1912 operands[1] = gen_lowpart (DImode, operands[2]);
1913 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1918 [(set (match_operand:DI 0 "push_operand" "")
1919 (match_operand:DI 1 "immediate_operand" ""))]
1920 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1921 ? flow2_completed : reload_completed)
1922 && !symbolic_operand (operands[1], DImode)
1923 && !x86_64_immediate_operand (operands[1], DImode)"
1924 [(set (match_dup 0) (match_dup 1))
1925 (set (match_dup 2) (match_dup 3))]
1926 "split_di (operands + 1, 1, operands + 2, operands + 3);
1927 operands[1] = gen_lowpart (DImode, operands[2]);
1928 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1932 (define_insn "*pushdi2_prologue_rex64"
1933 [(set (match_operand:DI 0 "push_operand" "=<")
1934 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1935 (clobber (mem:BLK (scratch)))]
1938 [(set_attr "type" "push")
1939 (set_attr "mode" "DI")])
1941 (define_insn "*popdi1_epilogue_rex64"
1942 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1943 (mem:DI (reg:DI SP_REG)))
1944 (set (reg:DI SP_REG)
1945 (plus:DI (reg:DI SP_REG) (const_int 8)))
1946 (clobber (mem:BLK (scratch)))]
1949 [(set_attr "type" "pop")
1950 (set_attr "mode" "DI")])
1952 (define_insn "popdi1"
1953 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1954 (mem:DI (reg:DI SP_REG)))
1955 (set (reg:DI SP_REG)
1956 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1959 [(set_attr "type" "pop")
1960 (set_attr "mode" "DI")])
1962 (define_insn "*movdi_xor_rex64"
1963 [(set (match_operand:DI 0 "register_operand" "=r")
1964 (match_operand:DI 1 "const0_operand" "i"))
1965 (clobber (reg:CC FLAGS_REG))]
1966 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1967 && reload_completed"
1969 [(set_attr "type" "alu1")
1970 (set_attr "mode" "SI")
1971 (set_attr "length_immediate" "0")])
1973 (define_insn "*movdi_or_rex64"
1974 [(set (match_operand:DI 0 "register_operand" "=r")
1975 (match_operand:DI 1 "const_int_operand" "i"))
1976 (clobber (reg:CC FLAGS_REG))]
1977 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1979 && operands[1] == constm1_rtx"
1981 operands[1] = constm1_rtx;
1982 return "or{q}\t{%1, %0|%0, %1}";
1984 [(set_attr "type" "alu1")
1985 (set_attr "mode" "DI")
1986 (set_attr "length_immediate" "1")])
1988 (define_insn "*movdi_2"
1989 [(set (match_operand:DI 0 "nonimmediate_operand"
1990 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
1991 (match_operand:DI 1 "general_operand"
1992 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
1993 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1998 movq\t{%1, %0|%0, %1}
1999 movq\t{%1, %0|%0, %1}
2001 movq\t{%1, %0|%0, %1}
2002 movdqa\t{%1, %0|%0, %1}
2003 movq\t{%1, %0|%0, %1}
2005 movlps\t{%1, %0|%0, %1}
2006 movaps\t{%1, %0|%0, %1}
2007 movlps\t{%1, %0|%0, %1}"
2008 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2009 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2012 [(set (match_operand:DI 0 "push_operand" "")
2013 (match_operand:DI 1 "general_operand" ""))]
2014 "!TARGET_64BIT && reload_completed
2015 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2017 "ix86_split_long_move (operands); DONE;")
2019 ;; %%% This multiword shite has got to go.
2021 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2022 (match_operand:DI 1 "general_operand" ""))]
2023 "!TARGET_64BIT && reload_completed
2024 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2025 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2027 "ix86_split_long_move (operands); DONE;")
2029 (define_insn "*movdi_1_rex64"
2030 [(set (match_operand:DI 0 "nonimmediate_operand"
2031 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2032 (match_operand:DI 1 "general_operand"
2033 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2034 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2036 switch (get_attr_type (insn))
2039 if (SSE_REG_P (operands[0]))
2040 return "movq2dq\t{%1, %0|%0, %1}";
2042 return "movdq2q\t{%1, %0|%0, %1}";
2045 if (get_attr_mode (insn) == MODE_TI)
2046 return "movdqa\t{%1, %0|%0, %1}";
2050 /* Moves from and into integer register is done using movd
2051 opcode with REX prefix. */
2052 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2053 return "movd\t{%1, %0|%0, %1}";
2054 return "movq\t{%1, %0|%0, %1}";
2058 return "pxor\t%0, %0";
2064 return "lea{q}\t{%a1, %0|%0, %a1}";
2067 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2068 if (get_attr_mode (insn) == MODE_SI)
2069 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2070 else if (which_alternative == 2)
2071 return "movabs{q}\t{%1, %0|%0, %1}";
2073 return "mov{q}\t{%1, %0|%0, %1}";
2077 (cond [(eq_attr "alternative" "5")
2078 (const_string "mmxadd")
2079 (eq_attr "alternative" "6,7,8,9,10")
2080 (const_string "mmxmov")
2081 (eq_attr "alternative" "11")
2082 (const_string "sselog1")
2083 (eq_attr "alternative" "12,13,14,15,16")
2084 (const_string "ssemov")
2085 (eq_attr "alternative" "17,18")
2086 (const_string "ssecvt")
2087 (eq_attr "alternative" "4")
2088 (const_string "multi")
2089 (match_operand:DI 1 "pic_32bit_operand" "")
2090 (const_string "lea")
2092 (const_string "imov")))
2093 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2094 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2095 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2097 ;; Stores and loads of ax to arbitrary constant address.
2098 ;; We fake an second form of instruction to force reload to load address
2099 ;; into register when rax is not available
2100 (define_insn "*movabsdi_1_rex64"
2101 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2102 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2103 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2105 movabs{q}\t{%1, %P0|%P0, %1}
2106 mov{q}\t{%1, %a0|%a0, %1}"
2107 [(set_attr "type" "imov")
2108 (set_attr "modrm" "0,*")
2109 (set_attr "length_address" "8,0")
2110 (set_attr "length_immediate" "0,*")
2111 (set_attr "memory" "store")
2112 (set_attr "mode" "DI")])
2114 (define_insn "*movabsdi_2_rex64"
2115 [(set (match_operand:DI 0 "register_operand" "=a,r")
2116 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2117 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2119 movabs{q}\t{%P1, %0|%0, %P1}
2120 mov{q}\t{%a1, %0|%0, %a1}"
2121 [(set_attr "type" "imov")
2122 (set_attr "modrm" "0,*")
2123 (set_attr "length_address" "8,0")
2124 (set_attr "length_immediate" "0")
2125 (set_attr "memory" "load")
2126 (set_attr "mode" "DI")])
2128 ;; Convert impossible stores of immediate to existing instructions.
2129 ;; First try to get scratch register and go through it. In case this
2130 ;; fails, move by 32bit parts.
2132 [(match_scratch:DI 2 "r")
2133 (set (match_operand:DI 0 "memory_operand" "")
2134 (match_operand:DI 1 "immediate_operand" ""))]
2135 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2136 && !x86_64_immediate_operand (operands[1], DImode)"
2137 [(set (match_dup 2) (match_dup 1))
2138 (set (match_dup 0) (match_dup 2))]
2141 ;; We need to define this as both peepholer and splitter for case
2142 ;; peephole2 pass is not run.
2143 ;; "&& 1" is needed to keep it from matching the previous pattern.
2145 [(set (match_operand:DI 0 "memory_operand" "")
2146 (match_operand:DI 1 "immediate_operand" ""))]
2147 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2148 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2149 [(set (match_dup 2) (match_dup 3))
2150 (set (match_dup 4) (match_dup 5))]
2151 "split_di (operands, 2, operands + 2, operands + 4);")
2154 [(set (match_operand:DI 0 "memory_operand" "")
2155 (match_operand:DI 1 "immediate_operand" ""))]
2156 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2157 ? flow2_completed : reload_completed)
2158 && !symbolic_operand (operands[1], DImode)
2159 && !x86_64_immediate_operand (operands[1], DImode)"
2160 [(set (match_dup 2) (match_dup 3))
2161 (set (match_dup 4) (match_dup 5))]
2162 "split_di (operands, 2, operands + 2, operands + 4);")
2164 (define_insn "*swapdi_rex64"
2165 [(set (match_operand:DI 0 "register_operand" "+r")
2166 (match_operand:DI 1 "register_operand" "+r"))
2171 [(set_attr "type" "imov")
2172 (set_attr "mode" "DI")
2173 (set_attr "pent_pair" "np")
2174 (set_attr "athlon_decode" "vector")
2175 (set_attr "amdfam10_decode" "double")])
2177 (define_expand "movti"
2178 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2179 (match_operand:TI 1 "nonimmediate_operand" ""))]
2180 "TARGET_SSE || TARGET_64BIT"
2183 ix86_expand_move (TImode, operands);
2185 ix86_expand_vector_move (TImode, operands);
2189 (define_insn "*movti_internal"
2190 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2191 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2192 "TARGET_SSE && !TARGET_64BIT
2193 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2195 switch (which_alternative)
2198 if (get_attr_mode (insn) == MODE_V4SF)
2199 return "xorps\t%0, %0";
2201 return "pxor\t%0, %0";
2204 if (get_attr_mode (insn) == MODE_V4SF)
2205 return "movaps\t{%1, %0|%0, %1}";
2207 return "movdqa\t{%1, %0|%0, %1}";
2212 [(set_attr "type" "sselog1,ssemov,ssemov")
2214 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2215 (ne (symbol_ref "optimize_size") (const_int 0)))
2216 (const_string "V4SF")
2217 (and (eq_attr "alternative" "2")
2218 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2220 (const_string "V4SF")]
2221 (const_string "TI")))])
2223 (define_insn "*movti_rex64"
2224 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2225 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2227 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2229 switch (which_alternative)
2235 if (get_attr_mode (insn) == MODE_V4SF)
2236 return "xorps\t%0, %0";
2238 return "pxor\t%0, %0";
2241 if (get_attr_mode (insn) == MODE_V4SF)
2242 return "movaps\t{%1, %0|%0, %1}";
2244 return "movdqa\t{%1, %0|%0, %1}";
2249 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2251 (cond [(eq_attr "alternative" "2,3")
2253 (ne (symbol_ref "optimize_size")
2255 (const_string "V4SF")
2256 (const_string "TI"))
2257 (eq_attr "alternative" "4")
2259 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2261 (ne (symbol_ref "optimize_size")
2263 (const_string "V4SF")
2264 (const_string "TI"))]
2265 (const_string "DI")))])
2268 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2269 (match_operand:TI 1 "general_operand" ""))]
2270 "reload_completed && !SSE_REG_P (operands[0])
2271 && !SSE_REG_P (operands[1])"
2273 "ix86_split_long_move (operands); DONE;")
2275 ;; This expands to what emit_move_complex would generate if we didn't
2276 ;; have a movti pattern. Having this avoids problems with reload on
2277 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2278 ;; to have around all the time.
2279 (define_expand "movcdi"
2280 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2281 (match_operand:CDI 1 "general_operand" ""))]
2284 if (push_operand (operands[0], CDImode))
2285 emit_move_complex_push (CDImode, operands[0], operands[1]);
2287 emit_move_complex_parts (operands[0], operands[1]);
2291 (define_expand "movsf"
2292 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2293 (match_operand:SF 1 "general_operand" ""))]
2295 "ix86_expand_move (SFmode, operands); DONE;")
2297 (define_insn "*pushsf"
2298 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2299 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2302 /* Anything else should be already split before reg-stack. */
2303 gcc_assert (which_alternative == 1);
2304 return "push{l}\t%1";
2306 [(set_attr "type" "multi,push,multi")
2307 (set_attr "unit" "i387,*,*")
2308 (set_attr "mode" "SF,SI,SF")])
2310 (define_insn "*pushsf_rex64"
2311 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2312 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2315 /* Anything else should be already split before reg-stack. */
2316 gcc_assert (which_alternative == 1);
2317 return "push{q}\t%q1";
2319 [(set_attr "type" "multi,push,multi")
2320 (set_attr "unit" "i387,*,*")
2321 (set_attr "mode" "SF,DI,SF")])
2324 [(set (match_operand:SF 0 "push_operand" "")
2325 (match_operand:SF 1 "memory_operand" ""))]
2327 && MEM_P (operands[1])
2328 && constant_pool_reference_p (operands[1])"
2331 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2334 ;; %%% Kill this when call knows how to work this out.
2336 [(set (match_operand:SF 0 "push_operand" "")
2337 (match_operand:SF 1 "any_fp_register_operand" ""))]
2339 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2340 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2343 [(set (match_operand:SF 0 "push_operand" "")
2344 (match_operand:SF 1 "any_fp_register_operand" ""))]
2346 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2347 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2349 (define_insn "*movsf_1"
2350 [(set (match_operand:SF 0 "nonimmediate_operand"
2351 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2352 (match_operand:SF 1 "general_operand"
2353 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2354 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2355 && (reload_in_progress || reload_completed
2356 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2357 || (!TARGET_SSE_MATH && optimize_size
2358 && standard_80387_constant_p (operands[1]))
2359 || GET_CODE (operands[1]) != CONST_DOUBLE
2360 || memory_operand (operands[0], SFmode))"
2362 switch (which_alternative)
2365 return output_387_reg_move (insn, operands);
2368 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2369 return "fstp%z0\t%y0";
2371 return "fst%z0\t%y0";
2374 return standard_80387_constant_opcode (operands[1]);
2378 return "mov{l}\t{%1, %0|%0, %1}";
2380 if (get_attr_mode (insn) == MODE_TI)
2381 return "pxor\t%0, %0";
2383 return "xorps\t%0, %0";
2385 if (get_attr_mode (insn) == MODE_V4SF)
2386 return "movaps\t{%1, %0|%0, %1}";
2388 return "movss\t{%1, %0|%0, %1}";
2390 return "movss\t{%1, %0|%0, %1}";
2393 case 12: case 13: case 14: case 15:
2394 return "movd\t{%1, %0|%0, %1}";
2397 return "movq\t{%1, %0|%0, %1}";
2403 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2405 (cond [(eq_attr "alternative" "3,4,9,10")
2407 (eq_attr "alternative" "5")
2409 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2411 (ne (symbol_ref "TARGET_SSE2")
2413 (eq (symbol_ref "optimize_size")
2416 (const_string "V4SF"))
2417 /* For architectures resolving dependencies on
2418 whole SSE registers use APS move to break dependency
2419 chains, otherwise use short move to avoid extra work.
2421 Do the same for architectures resolving dependencies on
2422 the parts. While in DF mode it is better to always handle
2423 just register parts, the SF mode is different due to lack
2424 of instructions to load just part of the register. It is
2425 better to maintain the whole registers in single format
2426 to avoid problems on using packed logical operations. */
2427 (eq_attr "alternative" "6")
2429 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2431 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2433 (const_string "V4SF")
2434 (const_string "SF"))
2435 (eq_attr "alternative" "11")
2436 (const_string "DI")]
2437 (const_string "SF")))])
2439 (define_insn "*swapsf"
2440 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2441 (match_operand:SF 1 "fp_register_operand" "+f"))
2444 "reload_completed || TARGET_80387"
2446 if (STACK_TOP_P (operands[0]))
2451 [(set_attr "type" "fxch")
2452 (set_attr "mode" "SF")])
2454 (define_expand "movdf"
2455 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2456 (match_operand:DF 1 "general_operand" ""))]
2458 "ix86_expand_move (DFmode, operands); DONE;")
2460 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2461 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2462 ;; On the average, pushdf using integers can be still shorter. Allow this
2463 ;; pattern for optimize_size too.
2465 (define_insn "*pushdf_nointeger"
2466 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2467 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2468 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2470 /* This insn should be already split before reg-stack. */
2473 [(set_attr "type" "multi")
2474 (set_attr "unit" "i387,*,*,*")
2475 (set_attr "mode" "DF,SI,SI,DF")])
2477 (define_insn "*pushdf_integer"
2478 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2479 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2480 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2482 /* This insn should be already split before reg-stack. */
2485 [(set_attr "type" "multi")
2486 (set_attr "unit" "i387,*,*")
2487 (set_attr "mode" "DF,SI,DF")])
2489 ;; %%% Kill this when call knows how to work this out.
2491 [(set (match_operand:DF 0 "push_operand" "")
2492 (match_operand:DF 1 "any_fp_register_operand" ""))]
2493 "!TARGET_64BIT && reload_completed"
2494 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2495 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2499 [(set (match_operand:DF 0 "push_operand" "")
2500 (match_operand:DF 1 "any_fp_register_operand" ""))]
2501 "TARGET_64BIT && reload_completed"
2502 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2503 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2507 [(set (match_operand:DF 0 "push_operand" "")
2508 (match_operand:DF 1 "general_operand" ""))]
2511 "ix86_split_long_move (operands); DONE;")
2513 ;; Moving is usually shorter when only FP registers are used. This separate
2514 ;; movdf pattern avoids the use of integer registers for FP operations
2515 ;; when optimizing for size.
2517 (define_insn "*movdf_nointeger"
2518 [(set (match_operand:DF 0 "nonimmediate_operand"
2519 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2520 (match_operand:DF 1 "general_operand"
2521 "fm,f,G,*roF,F*r,C ,Y2*x,mY2*x,Y2*x"))]
2522 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2523 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2524 && (reload_in_progress || reload_completed
2525 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2526 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2527 && standard_80387_constant_p (operands[1]))
2528 || GET_CODE (operands[1]) != CONST_DOUBLE
2529 || memory_operand (operands[0], DFmode))"
2531 switch (which_alternative)
2534 return output_387_reg_move (insn, operands);
2537 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2538 return "fstp%z0\t%y0";
2540 return "fst%z0\t%y0";
2543 return standard_80387_constant_opcode (operands[1]);
2549 switch (get_attr_mode (insn))
2552 return "xorps\t%0, %0";
2554 return "xorpd\t%0, %0";
2556 return "pxor\t%0, %0";
2563 switch (get_attr_mode (insn))
2566 return "movaps\t{%1, %0|%0, %1}";
2568 return "movapd\t{%1, %0|%0, %1}";
2570 return "movdqa\t{%1, %0|%0, %1}";
2572 return "movq\t{%1, %0|%0, %1}";
2574 return "movsd\t{%1, %0|%0, %1}";
2576 return "movlpd\t{%1, %0|%0, %1}";
2578 return "movlps\t{%1, %0|%0, %1}";
2587 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2589 (cond [(eq_attr "alternative" "0,1,2")
2591 (eq_attr "alternative" "3,4")
2594 /* For SSE1, we have many fewer alternatives. */
2595 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2596 (cond [(eq_attr "alternative" "5,6")
2597 (const_string "V4SF")
2599 (const_string "V2SF"))
2601 /* xorps is one byte shorter. */
2602 (eq_attr "alternative" "5")
2603 (cond [(ne (symbol_ref "optimize_size")
2605 (const_string "V4SF")
2606 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2610 (const_string "V2DF"))
2612 /* For architectures resolving dependencies on
2613 whole SSE registers use APD move to break dependency
2614 chains, otherwise use short move to avoid extra work.
2616 movaps encodes one byte shorter. */
2617 (eq_attr "alternative" "6")
2619 [(ne (symbol_ref "optimize_size")
2621 (const_string "V4SF")
2622 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2624 (const_string "V2DF")
2626 (const_string "DF"))
2627 /* For architectures resolving dependencies on register
2628 parts we may avoid extra work to zero out upper part
2630 (eq_attr "alternative" "7")
2632 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2634 (const_string "V1DF")
2635 (const_string "DF"))
2637 (const_string "DF")))])
2639 (define_insn "*movdf_integer_rex64"
2640 [(set (match_operand:DF 0 "nonimmediate_operand"
2641 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2642 (match_operand:DF 1 "general_operand"
2643 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2644 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2645 && (reload_in_progress || reload_completed
2646 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2647 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2648 && standard_80387_constant_p (operands[1]))
2649 || GET_CODE (operands[1]) != CONST_DOUBLE
2650 || memory_operand (operands[0], DFmode))"
2652 switch (which_alternative)
2655 return output_387_reg_move (insn, operands);
2658 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2659 return "fstp%z0\t%y0";
2661 return "fst%z0\t%y0";
2664 return standard_80387_constant_opcode (operands[1]);
2671 switch (get_attr_mode (insn))
2674 return "xorps\t%0, %0";
2676 return "xorpd\t%0, %0";
2678 return "pxor\t%0, %0";
2685 switch (get_attr_mode (insn))
2688 return "movaps\t{%1, %0|%0, %1}";
2690 return "movapd\t{%1, %0|%0, %1}";
2692 return "movdqa\t{%1, %0|%0, %1}";
2694 return "movq\t{%1, %0|%0, %1}";
2696 return "movsd\t{%1, %0|%0, %1}";
2698 return "movlpd\t{%1, %0|%0, %1}";
2700 return "movlps\t{%1, %0|%0, %1}";
2707 return "movd\t{%1, %0|%0, %1}";
2713 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2715 (cond [(eq_attr "alternative" "0,1,2")
2717 (eq_attr "alternative" "3,4,9,10")
2720 /* For SSE1, we have many fewer alternatives. */
2721 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2722 (cond [(eq_attr "alternative" "5,6")
2723 (const_string "V4SF")
2725 (const_string "V2SF"))
2727 /* xorps is one byte shorter. */
2728 (eq_attr "alternative" "5")
2729 (cond [(ne (symbol_ref "optimize_size")
2731 (const_string "V4SF")
2732 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2736 (const_string "V2DF"))
2738 /* For architectures resolving dependencies on
2739 whole SSE registers use APD move to break dependency
2740 chains, otherwise use short move to avoid extra work.
2742 movaps encodes one byte shorter. */
2743 (eq_attr "alternative" "6")
2745 [(ne (symbol_ref "optimize_size")
2747 (const_string "V4SF")
2748 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2750 (const_string "V2DF")
2752 (const_string "DF"))
2753 /* For architectures resolving dependencies on register
2754 parts we may avoid extra work to zero out upper part
2756 (eq_attr "alternative" "7")
2758 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2760 (const_string "V1DF")
2761 (const_string "DF"))
2763 (const_string "DF")))])
2765 (define_insn "*movdf_integer"
2766 [(set (match_operand:DF 0 "nonimmediate_operand"
2767 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2768 (match_operand:DF 1 "general_operand"
2769 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2770 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2771 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2772 && (reload_in_progress || reload_completed
2773 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2774 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2775 && standard_80387_constant_p (operands[1]))
2776 || GET_CODE (operands[1]) != CONST_DOUBLE
2777 || memory_operand (operands[0], DFmode))"
2779 switch (which_alternative)
2782 return output_387_reg_move (insn, operands);
2785 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2786 return "fstp%z0\t%y0";
2788 return "fst%z0\t%y0";
2791 return standard_80387_constant_opcode (operands[1]);
2798 switch (get_attr_mode (insn))
2801 return "xorps\t%0, %0";
2803 return "xorpd\t%0, %0";
2805 return "pxor\t%0, %0";
2812 switch (get_attr_mode (insn))
2815 return "movaps\t{%1, %0|%0, %1}";
2817 return "movapd\t{%1, %0|%0, %1}";
2819 return "movdqa\t{%1, %0|%0, %1}";
2821 return "movq\t{%1, %0|%0, %1}";
2823 return "movsd\t{%1, %0|%0, %1}";
2825 return "movlpd\t{%1, %0|%0, %1}";
2827 return "movlps\t{%1, %0|%0, %1}";
2836 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2838 (cond [(eq_attr "alternative" "0,1,2")
2840 (eq_attr "alternative" "3,4")
2843 /* For SSE1, we have many fewer alternatives. */
2844 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2845 (cond [(eq_attr "alternative" "5,6")
2846 (const_string "V4SF")
2848 (const_string "V2SF"))
2850 /* xorps is one byte shorter. */
2851 (eq_attr "alternative" "5")
2852 (cond [(ne (symbol_ref "optimize_size")
2854 (const_string "V4SF")
2855 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2859 (const_string "V2DF"))
2861 /* For architectures resolving dependencies on
2862 whole SSE registers use APD move to break dependency
2863 chains, otherwise use short move to avoid extra work.
2865 movaps encodes one byte shorter. */
2866 (eq_attr "alternative" "6")
2868 [(ne (symbol_ref "optimize_size")
2870 (const_string "V4SF")
2871 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2873 (const_string "V2DF")
2875 (const_string "DF"))
2876 /* For architectures resolving dependencies on register
2877 parts we may avoid extra work to zero out upper part
2879 (eq_attr "alternative" "7")
2881 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2883 (const_string "V1DF")
2884 (const_string "DF"))
2886 (const_string "DF")))])
2889 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2890 (match_operand:DF 1 "general_operand" ""))]
2892 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2893 && ! (ANY_FP_REG_P (operands[0]) ||
2894 (GET_CODE (operands[0]) == SUBREG
2895 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2896 && ! (ANY_FP_REG_P (operands[1]) ||
2897 (GET_CODE (operands[1]) == SUBREG
2898 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2900 "ix86_split_long_move (operands); DONE;")
2902 (define_insn "*swapdf"
2903 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2904 (match_operand:DF 1 "fp_register_operand" "+f"))
2907 "reload_completed || TARGET_80387"
2909 if (STACK_TOP_P (operands[0]))
2914 [(set_attr "type" "fxch")
2915 (set_attr "mode" "DF")])
2917 (define_expand "movxf"
2918 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2919 (match_operand:XF 1 "general_operand" ""))]
2921 "ix86_expand_move (XFmode, operands); DONE;")
2923 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2924 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2925 ;; Pushing using integer instructions is longer except for constants
2926 ;; and direct memory references.
2927 ;; (assuming that any given constant is pushed only once, but this ought to be
2928 ;; handled elsewhere).
2930 (define_insn "*pushxf_nointeger"
2931 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2932 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2935 /* This insn should be already split before reg-stack. */
2938 [(set_attr "type" "multi")
2939 (set_attr "unit" "i387,*,*")
2940 (set_attr "mode" "XF,SI,SI")])
2942 (define_insn "*pushxf_integer"
2943 [(set (match_operand:XF 0 "push_operand" "=<,<")
2944 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2947 /* This insn should be already split before reg-stack. */
2950 [(set_attr "type" "multi")
2951 (set_attr "unit" "i387,*")
2952 (set_attr "mode" "XF,SI")])
2955 [(set (match_operand 0 "push_operand" "")
2956 (match_operand 1 "general_operand" ""))]
2958 && (GET_MODE (operands[0]) == XFmode
2959 || GET_MODE (operands[0]) == DFmode)
2960 && !ANY_FP_REG_P (operands[1])"
2962 "ix86_split_long_move (operands); DONE;")
2965 [(set (match_operand:XF 0 "push_operand" "")
2966 (match_operand:XF 1 "any_fp_register_operand" ""))]
2968 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2969 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2970 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2973 [(set (match_operand:XF 0 "push_operand" "")
2974 (match_operand:XF 1 "any_fp_register_operand" ""))]
2976 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2977 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2978 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2980 ;; Do not use integer registers when optimizing for size
2981 (define_insn "*movxf_nointeger"
2982 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2983 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2985 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2986 && (reload_in_progress || reload_completed
2987 || (optimize_size && standard_80387_constant_p (operands[1]))
2988 || GET_CODE (operands[1]) != CONST_DOUBLE
2989 || memory_operand (operands[0], XFmode))"
2991 switch (which_alternative)
2994 return output_387_reg_move (insn, operands);
2997 /* There is no non-popping store to memory for XFmode. So if
2998 we need one, follow the store with a load. */
2999 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3000 return "fstp%z0\t%y0\;fld%z0\t%y0";
3002 return "fstp%z0\t%y0";
3005 return standard_80387_constant_opcode (operands[1]);
3013 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3014 (set_attr "mode" "XF,XF,XF,SI,SI")])
3016 (define_insn "*movxf_integer"
3017 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3018 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3020 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3021 && (reload_in_progress || reload_completed
3022 || (optimize_size && standard_80387_constant_p (operands[1]))
3023 || GET_CODE (operands[1]) != CONST_DOUBLE
3024 || memory_operand (operands[0], XFmode))"
3026 switch (which_alternative)
3029 return output_387_reg_move (insn, operands);
3032 /* There is no non-popping store to memory for XFmode. So if
3033 we need one, follow the store with a load. */
3034 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3035 return "fstp%z0\t%y0\;fld%z0\t%y0";
3037 return "fstp%z0\t%y0";
3040 return standard_80387_constant_opcode (operands[1]);
3049 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3050 (set_attr "mode" "XF,XF,XF,SI,SI")])
3053 [(set (match_operand 0 "nonimmediate_operand" "")
3054 (match_operand 1 "general_operand" ""))]
3056 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3057 && GET_MODE (operands[0]) == XFmode
3058 && ! (ANY_FP_REG_P (operands[0]) ||
3059 (GET_CODE (operands[0]) == SUBREG
3060 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3061 && ! (ANY_FP_REG_P (operands[1]) ||
3062 (GET_CODE (operands[1]) == SUBREG
3063 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3065 "ix86_split_long_move (operands); DONE;")
3068 [(set (match_operand 0 "register_operand" "")
3069 (match_operand 1 "memory_operand" ""))]
3071 && MEM_P (operands[1])
3072 && (GET_MODE (operands[0]) == XFmode
3073 || GET_MODE (operands[0]) == SFmode
3074 || GET_MODE (operands[0]) == DFmode)
3075 && constant_pool_reference_p (operands[1])"
3076 [(set (match_dup 0) (match_dup 1))]
3078 rtx c = avoid_constant_pool_reference (operands[1]);
3079 rtx r = operands[0];
3081 if (GET_CODE (r) == SUBREG)
3086 if (!standard_sse_constant_p (c))
3089 else if (FP_REG_P (r))
3091 if (!standard_80387_constant_p (c))
3094 else if (MMX_REG_P (r))
3101 [(set (match_operand 0 "register_operand" "")
3102 (float_extend (match_operand 1 "memory_operand" "")))]
3104 && MEM_P (operands[1])
3105 && (GET_MODE (operands[0]) == XFmode
3106 || GET_MODE (operands[0]) == SFmode
3107 || GET_MODE (operands[0]) == DFmode)
3108 && constant_pool_reference_p (operands[1])"
3109 [(set (match_dup 0) (match_dup 1))]
3111 rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
3112 rtx r = operands[0];
3114 if (GET_CODE (r) == SUBREG)
3119 if (!standard_sse_constant_p (c))
3122 else if (FP_REG_P (r))
3124 if (!standard_80387_constant_p (c))
3127 else if (MMX_REG_P (r))
3133 (define_insn "swapxf"
3134 [(set (match_operand:XF 0 "register_operand" "+f")
3135 (match_operand:XF 1 "register_operand" "+f"))
3140 if (STACK_TOP_P (operands[0]))
3145 [(set_attr "type" "fxch")
3146 (set_attr "mode" "XF")])
3148 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3150 [(set (match_operand:X87MODEF 0 "register_operand" "")
3151 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3152 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3153 && (standard_80387_constant_p (operands[1]) == 8
3154 || standard_80387_constant_p (operands[1]) == 9)"
3155 [(set (match_dup 0)(match_dup 1))
3157 (neg:X87MODEF (match_dup 0)))]
3161 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3162 if (real_isnegzero (&r))
3163 operands[1] = CONST0_RTX (<MODE>mode);
3165 operands[1] = CONST1_RTX (<MODE>mode);
3168 (define_expand "movtf"
3169 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3170 (match_operand:TF 1 "nonimmediate_operand" ""))]
3173 ix86_expand_move (TFmode, operands);
3177 (define_insn "*movtf_internal"
3178 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3179 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3181 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3183 switch (which_alternative)
3189 if (get_attr_mode (insn) == MODE_V4SF)
3190 return "xorps\t%0, %0";
3192 return "pxor\t%0, %0";
3195 if (get_attr_mode (insn) == MODE_V4SF)
3196 return "movaps\t{%1, %0|%0, %1}";
3198 return "movdqa\t{%1, %0|%0, %1}";
3203 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3205 (cond [(eq_attr "alternative" "2,3")
3207 (ne (symbol_ref "optimize_size")
3209 (const_string "V4SF")
3210 (const_string "TI"))
3211 (eq_attr "alternative" "4")
3213 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3215 (ne (symbol_ref "optimize_size")
3217 (const_string "V4SF")
3218 (const_string "TI"))]
3219 (const_string "DI")))])
3222 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3223 (match_operand:TF 1 "general_operand" ""))]
3224 "reload_completed && !SSE_REG_P (operands[0])
3225 && !SSE_REG_P (operands[1])"
3227 "ix86_split_long_move (operands); DONE;")
3229 ;; Zero extension instructions
3231 (define_expand "zero_extendhisi2"
3232 [(set (match_operand:SI 0 "register_operand" "")
3233 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3236 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3238 operands[1] = force_reg (HImode, operands[1]);
3239 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3244 (define_insn "zero_extendhisi2_and"
3245 [(set (match_operand:SI 0 "register_operand" "=r")
3246 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3247 (clobber (reg:CC FLAGS_REG))]
3248 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3250 [(set_attr "type" "alu1")
3251 (set_attr "mode" "SI")])
3254 [(set (match_operand:SI 0 "register_operand" "")
3255 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3256 (clobber (reg:CC FLAGS_REG))]
3257 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3258 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3259 (clobber (reg:CC FLAGS_REG))])]
3262 (define_insn "*zero_extendhisi2_movzwl"
3263 [(set (match_operand:SI 0 "register_operand" "=r")
3264 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3265 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3266 "movz{wl|x}\t{%1, %0|%0, %1}"
3267 [(set_attr "type" "imovx")
3268 (set_attr "mode" "SI")])
3270 (define_expand "zero_extendqihi2"
3272 [(set (match_operand:HI 0 "register_operand" "")
3273 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3274 (clobber (reg:CC FLAGS_REG))])]
3278 (define_insn "*zero_extendqihi2_and"
3279 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3280 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3281 (clobber (reg:CC FLAGS_REG))]
3282 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3284 [(set_attr "type" "alu1")
3285 (set_attr "mode" "HI")])
3287 (define_insn "*zero_extendqihi2_movzbw_and"
3288 [(set (match_operand:HI 0 "register_operand" "=r,r")
3289 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3290 (clobber (reg:CC FLAGS_REG))]
3291 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3293 [(set_attr "type" "imovx,alu1")
3294 (set_attr "mode" "HI")])
3296 ; zero extend to SImode here to avoid partial register stalls
3297 (define_insn "*zero_extendqihi2_movzbl"
3298 [(set (match_operand:HI 0 "register_operand" "=r")
3299 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3300 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3301 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3302 [(set_attr "type" "imovx")
3303 (set_attr "mode" "SI")])
3305 ;; For the movzbw case strip only the clobber
3307 [(set (match_operand:HI 0 "register_operand" "")
3308 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3309 (clobber (reg:CC FLAGS_REG))]
3311 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3312 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3313 [(set (match_operand:HI 0 "register_operand" "")
3314 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3316 ;; When source and destination does not overlap, clear destination
3317 ;; first and then do the movb
3319 [(set (match_operand:HI 0 "register_operand" "")
3320 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3321 (clobber (reg:CC FLAGS_REG))]
3323 && ANY_QI_REG_P (operands[0])
3324 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3325 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3326 [(set (match_dup 0) (const_int 0))
3327 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3328 "operands[2] = gen_lowpart (QImode, operands[0]);")
3330 ;; Rest is handled by single and.
3332 [(set (match_operand:HI 0 "register_operand" "")
3333 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3334 (clobber (reg:CC FLAGS_REG))]
3336 && true_regnum (operands[0]) == true_regnum (operands[1])"
3337 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3338 (clobber (reg:CC FLAGS_REG))])]
3341 (define_expand "zero_extendqisi2"
3343 [(set (match_operand:SI 0 "register_operand" "")
3344 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3345 (clobber (reg:CC FLAGS_REG))])]
3349 (define_insn "*zero_extendqisi2_and"
3350 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3351 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3352 (clobber (reg:CC FLAGS_REG))]
3353 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3355 [(set_attr "type" "alu1")
3356 (set_attr "mode" "SI")])
3358 (define_insn "*zero_extendqisi2_movzbw_and"
3359 [(set (match_operand:SI 0 "register_operand" "=r,r")
3360 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3361 (clobber (reg:CC FLAGS_REG))]
3362 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3364 [(set_attr "type" "imovx,alu1")
3365 (set_attr "mode" "SI")])
3367 (define_insn "*zero_extendqisi2_movzbw"
3368 [(set (match_operand:SI 0 "register_operand" "=r")
3369 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3370 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3371 "movz{bl|x}\t{%1, %0|%0, %1}"
3372 [(set_attr "type" "imovx")
3373 (set_attr "mode" "SI")])
3375 ;; For the movzbl case strip only the clobber
3377 [(set (match_operand:SI 0 "register_operand" "")
3378 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3379 (clobber (reg:CC FLAGS_REG))]
3381 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3382 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3384 (zero_extend:SI (match_dup 1)))])
3386 ;; When source and destination does not overlap, clear destination
3387 ;; first and then do the movb
3389 [(set (match_operand:SI 0 "register_operand" "")
3390 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3391 (clobber (reg:CC FLAGS_REG))]
3393 && ANY_QI_REG_P (operands[0])
3394 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3395 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3396 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3397 [(set (match_dup 0) (const_int 0))
3398 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3399 "operands[2] = gen_lowpart (QImode, operands[0]);")
3401 ;; Rest is handled by single and.
3403 [(set (match_operand:SI 0 "register_operand" "")
3404 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3405 (clobber (reg:CC FLAGS_REG))]
3407 && true_regnum (operands[0]) == true_regnum (operands[1])"
3408 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3409 (clobber (reg:CC FLAGS_REG))])]
3412 ;; %%% Kill me once multi-word ops are sane.
3413 (define_expand "zero_extendsidi2"
3414 [(set (match_operand:DI 0 "register_operand" "=r")
3415 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3420 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3425 (define_insn "zero_extendsidi2_32"
3426 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3428 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3429 (clobber (reg:CC FLAGS_REG))]
3435 movd\t{%1, %0|%0, %1}
3436 movd\t{%1, %0|%0, %1}
3437 movd\t{%1, %0|%0, %1}
3438 movd\t{%1, %0|%0, %1}"
3439 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3440 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3442 (define_insn "zero_extendsidi2_rex64"
3443 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3445 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3448 mov\t{%k1, %k0|%k0, %k1}
3450 movd\t{%1, %0|%0, %1}
3451 movd\t{%1, %0|%0, %1}
3452 movd\t{%1, %0|%0, %1}
3453 movd\t{%1, %0|%0, %1}"
3454 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3455 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3458 [(set (match_operand:DI 0 "memory_operand" "")
3459 (zero_extend:DI (match_dup 0)))]
3461 [(set (match_dup 4) (const_int 0))]
3462 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3465 [(set (match_operand:DI 0 "register_operand" "")
3466 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3467 (clobber (reg:CC FLAGS_REG))]
3468 "!TARGET_64BIT && reload_completed
3469 && true_regnum (operands[0]) == true_regnum (operands[1])"
3470 [(set (match_dup 4) (const_int 0))]
3471 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3474 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3475 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3476 (clobber (reg:CC FLAGS_REG))]
3477 "!TARGET_64BIT && reload_completed
3478 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3479 [(set (match_dup 3) (match_dup 1))
3480 (set (match_dup 4) (const_int 0))]
3481 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3483 (define_insn "zero_extendhidi2"
3484 [(set (match_operand:DI 0 "register_operand" "=r")
3485 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3487 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3488 [(set_attr "type" "imovx")
3489 (set_attr "mode" "DI")])
3491 (define_insn "zero_extendqidi2"
3492 [(set (match_operand:DI 0 "register_operand" "=r")
3493 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3495 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3496 [(set_attr "type" "imovx")
3497 (set_attr "mode" "DI")])
3499 ;; Sign extension instructions
3501 (define_expand "extendsidi2"
3502 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3503 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3504 (clobber (reg:CC FLAGS_REG))
3505 (clobber (match_scratch:SI 2 ""))])]
3510 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3515 (define_insn "*extendsidi2_1"
3516 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3517 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3518 (clobber (reg:CC FLAGS_REG))
3519 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3523 (define_insn "extendsidi2_rex64"
3524 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3525 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3529 movs{lq|x}\t{%1,%0|%0, %1}"
3530 [(set_attr "type" "imovx")
3531 (set_attr "mode" "DI")
3532 (set_attr "prefix_0f" "0")
3533 (set_attr "modrm" "0,1")])
3535 (define_insn "extendhidi2"
3536 [(set (match_operand:DI 0 "register_operand" "=r")
3537 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3539 "movs{wq|x}\t{%1,%0|%0, %1}"
3540 [(set_attr "type" "imovx")
3541 (set_attr "mode" "DI")])
3543 (define_insn "extendqidi2"
3544 [(set (match_operand:DI 0 "register_operand" "=r")
3545 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3547 "movs{bq|x}\t{%1,%0|%0, %1}"
3548 [(set_attr "type" "imovx")
3549 (set_attr "mode" "DI")])
3551 ;; Extend to memory case when source register does die.
3553 [(set (match_operand:DI 0 "memory_operand" "")
3554 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3555 (clobber (reg:CC FLAGS_REG))
3556 (clobber (match_operand:SI 2 "register_operand" ""))]
3558 && dead_or_set_p (insn, operands[1])
3559 && !reg_mentioned_p (operands[1], operands[0]))"
3560 [(set (match_dup 3) (match_dup 1))
3561 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3562 (clobber (reg:CC FLAGS_REG))])
3563 (set (match_dup 4) (match_dup 1))]
3564 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3566 ;; Extend to memory case when source register does not die.
3568 [(set (match_operand:DI 0 "memory_operand" "")
3569 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3570 (clobber (reg:CC FLAGS_REG))
3571 (clobber (match_operand:SI 2 "register_operand" ""))]
3575 split_di (&operands[0], 1, &operands[3], &operands[4]);
3577 emit_move_insn (operands[3], operands[1]);
3579 /* Generate a cltd if possible and doing so it profitable. */
3580 if (true_regnum (operands[1]) == 0
3581 && true_regnum (operands[2]) == 1
3582 && (optimize_size || TARGET_USE_CLTD))
3584 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3588 emit_move_insn (operands[2], operands[1]);
3589 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3591 emit_move_insn (operands[4], operands[2]);
3595 ;; Extend to register case. Optimize case where source and destination
3596 ;; registers match and cases where we can use cltd.
3598 [(set (match_operand:DI 0 "register_operand" "")
3599 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3600 (clobber (reg:CC FLAGS_REG))
3601 (clobber (match_scratch:SI 2 ""))]
3605 split_di (&operands[0], 1, &operands[3], &operands[4]);
3607 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3608 emit_move_insn (operands[3], operands[1]);
3610 /* Generate a cltd if possible and doing so it profitable. */
3611 if (true_regnum (operands[3]) == 0
3612 && (optimize_size || TARGET_USE_CLTD))
3614 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3618 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3619 emit_move_insn (operands[4], operands[1]);
3621 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3625 (define_insn "extendhisi2"
3626 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3627 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3630 switch (get_attr_prefix_0f (insn))
3633 return "{cwtl|cwde}";
3635 return "movs{wl|x}\t{%1,%0|%0, %1}";
3638 [(set_attr "type" "imovx")
3639 (set_attr "mode" "SI")
3640 (set (attr "prefix_0f")
3641 ;; movsx is short decodable while cwtl is vector decoded.
3642 (if_then_else (and (eq_attr "cpu" "!k6")
3643 (eq_attr "alternative" "0"))
3645 (const_string "1")))
3647 (if_then_else (eq_attr "prefix_0f" "0")
3649 (const_string "1")))])
3651 (define_insn "*extendhisi2_zext"
3652 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3654 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3657 switch (get_attr_prefix_0f (insn))
3660 return "{cwtl|cwde}";
3662 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3665 [(set_attr "type" "imovx")
3666 (set_attr "mode" "SI")
3667 (set (attr "prefix_0f")
3668 ;; movsx is short decodable while cwtl is vector decoded.
3669 (if_then_else (and (eq_attr "cpu" "!k6")
3670 (eq_attr "alternative" "0"))
3672 (const_string "1")))
3674 (if_then_else (eq_attr "prefix_0f" "0")
3676 (const_string "1")))])
3678 (define_insn "extendqihi2"
3679 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3680 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3683 switch (get_attr_prefix_0f (insn))
3686 return "{cbtw|cbw}";
3688 return "movs{bw|x}\t{%1,%0|%0, %1}";
3691 [(set_attr "type" "imovx")
3692 (set_attr "mode" "HI")
3693 (set (attr "prefix_0f")
3694 ;; movsx is short decodable while cwtl is vector decoded.
3695 (if_then_else (and (eq_attr "cpu" "!k6")
3696 (eq_attr "alternative" "0"))
3698 (const_string "1")))
3700 (if_then_else (eq_attr "prefix_0f" "0")
3702 (const_string "1")))])
3704 (define_insn "extendqisi2"
3705 [(set (match_operand:SI 0 "register_operand" "=r")
3706 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3708 "movs{bl|x}\t{%1,%0|%0, %1}"
3709 [(set_attr "type" "imovx")
3710 (set_attr "mode" "SI")])
3712 (define_insn "*extendqisi2_zext"
3713 [(set (match_operand:DI 0 "register_operand" "=r")
3715 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3717 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3718 [(set_attr "type" "imovx")
3719 (set_attr "mode" "SI")])
3721 ;; Conversions between float and double.
3723 ;; These are all no-ops in the model used for the 80387. So just
3726 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3727 (define_insn "*dummy_extendsfdf2"
3728 [(set (match_operand:DF 0 "push_operand" "=<")
3729 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3734 [(set (match_operand:DF 0 "push_operand" "")
3735 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3737 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3738 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3741 [(set (match_operand:DF 0 "push_operand" "")
3742 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3744 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3745 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3747 (define_insn "*dummy_extendsfxf2"
3748 [(set (match_operand:XF 0 "push_operand" "=<")
3749 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3754 [(set (match_operand:XF 0 "push_operand" "")
3755 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3757 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3758 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3759 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3762 [(set (match_operand:XF 0 "push_operand" "")
3763 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3765 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3766 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3767 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3770 [(set (match_operand:XF 0 "push_operand" "")
3771 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3773 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3774 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3775 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3778 [(set (match_operand:XF 0 "push_operand" "")
3779 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3781 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3782 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3783 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3785 (define_expand "extendsfdf2"
3786 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3787 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3788 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3790 /* ??? Needed for compress_float_constant since all fp constants
3791 are LEGITIMATE_CONSTANT_P. */
3792 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3794 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3795 && standard_80387_constant_p (operands[1]) > 0)
3797 operands[1] = simplify_const_unary_operation
3798 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3799 emit_move_insn_1 (operands[0], operands[1]);
3802 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3806 (define_insn "*extendsfdf2_mixed"
3807 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3809 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3810 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3812 switch (which_alternative)
3815 return output_387_reg_move (insn, operands);
3818 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3819 return "fstp%z0\t%y0";
3821 return "fst%z0\t%y0";
3824 return "cvtss2sd\t{%1, %0|%0, %1}";
3830 [(set_attr "type" "fmov,fmov,ssecvt")
3831 (set_attr "mode" "SF,XF,DF")])
3833 (define_insn "*extendsfdf2_sse"
3834 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3835 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3836 "TARGET_SSE2 && TARGET_SSE_MATH"
3837 "cvtss2sd\t{%1, %0|%0, %1}"
3838 [(set_attr "type" "ssecvt")
3839 (set_attr "mode" "DF")])
3841 (define_insn "*extendsfdf2_i387"
3842 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3843 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3846 switch (which_alternative)
3849 return output_387_reg_move (insn, operands);
3852 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3853 return "fstp%z0\t%y0";
3855 return "fst%z0\t%y0";
3861 [(set_attr "type" "fmov")
3862 (set_attr "mode" "SF,XF")])
3864 (define_expand "extendsfxf2"
3865 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3866 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3869 /* ??? Needed for compress_float_constant since all fp constants
3870 are LEGITIMATE_CONSTANT_P. */
3871 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3873 if (standard_80387_constant_p (operands[1]) > 0)
3875 operands[1] = simplify_const_unary_operation
3876 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3877 emit_move_insn_1 (operands[0], operands[1]);
3880 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3884 (define_insn "*extendsfxf2_i387"
3885 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3886 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3889 switch (which_alternative)
3892 return output_387_reg_move (insn, operands);
3895 /* There is no non-popping store to memory for XFmode. So if
3896 we need one, follow the store with a load. */
3897 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3898 return "fstp%z0\t%y0";
3900 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3906 [(set_attr "type" "fmov")
3907 (set_attr "mode" "SF,XF")])
3909 (define_expand "extenddfxf2"
3910 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3911 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3914 /* ??? Needed for compress_float_constant since all fp constants
3915 are LEGITIMATE_CONSTANT_P. */
3916 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3918 if (standard_80387_constant_p (operands[1]) > 0)
3920 operands[1] = simplify_const_unary_operation
3921 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3922 emit_move_insn_1 (operands[0], operands[1]);
3925 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3929 (define_insn "*extenddfxf2_i387"
3930 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3931 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3934 switch (which_alternative)
3937 return output_387_reg_move (insn, operands);
3940 /* There is no non-popping store to memory for XFmode. So if
3941 we need one, follow the store with a load. */
3942 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3943 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3945 return "fstp%z0\t%y0";
3951 [(set_attr "type" "fmov")
3952 (set_attr "mode" "DF,XF")])
3954 ;; %%% This seems bad bad news.
3955 ;; This cannot output into an f-reg because there is no way to be sure
3956 ;; of truncating in that case. Otherwise this is just like a simple move
3957 ;; insn. So we pretend we can output to a reg in order to get better
3958 ;; register preferencing, but we really use a stack slot.
3960 ;; Conversion from DFmode to SFmode.
3962 (define_expand "truncdfsf2"
3963 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3965 (match_operand:DF 1 "nonimmediate_operand" "")))]
3966 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3968 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3970 else if (flag_unsafe_math_optimizations)
3974 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3975 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3980 (define_expand "truncdfsf2_with_temp"
3981 [(parallel [(set (match_operand:SF 0 "" "")
3982 (float_truncate:SF (match_operand:DF 1 "" "")))
3983 (clobber (match_operand:SF 2 "" ""))])]
3986 (define_insn "*truncdfsf_fast_mixed"
3987 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
3989 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3990 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3992 switch (which_alternative)
3995 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3996 return "fstp%z0\t%y0";
3998 return "fst%z0\t%y0";
4000 return output_387_reg_move (insn, operands);
4002 return "cvtsd2ss\t{%1, %0|%0, %1}";
4007 [(set_attr "type" "fmov,fmov,ssecvt")
4008 (set_attr "mode" "SF")])
4010 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4011 ;; because nothing we do here is unsafe.
4012 (define_insn "*truncdfsf_fast_sse"
4013 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4015 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4016 "TARGET_SSE2 && TARGET_SSE_MATH"
4017 "cvtsd2ss\t{%1, %0|%0, %1}"
4018 [(set_attr "type" "ssecvt")
4019 (set_attr "mode" "SF")])
4021 (define_insn "*truncdfsf_fast_i387"
4022 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4024 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4025 "TARGET_80387 && flag_unsafe_math_optimizations"
4026 "* return output_387_reg_move (insn, operands);"
4027 [(set_attr "type" "fmov")
4028 (set_attr "mode" "SF")])
4030 (define_insn "*truncdfsf_mixed"
4031 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4033 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4034 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4035 "TARGET_MIX_SSE_I387"
4037 switch (which_alternative)
4040 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4041 return "fstp%z0\t%y0";
4043 return "fst%z0\t%y0";
4047 return "cvtsd2ss\t{%1, %0|%0, %1}";
4052 [(set_attr "type" "fmov,multi,ssecvt")
4053 (set_attr "unit" "*,i387,*")
4054 (set_attr "mode" "SF")])
4056 (define_insn "*truncdfsf_i387"
4057 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4059 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4060 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4063 switch (which_alternative)
4066 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4067 return "fstp%z0\t%y0";
4069 return "fst%z0\t%y0";
4076 [(set_attr "type" "fmov,multi")
4077 (set_attr "unit" "*,i387")
4078 (set_attr "mode" "SF")])
4080 (define_insn "*truncdfsf2_i387_1"
4081 [(set (match_operand:SF 0 "memory_operand" "=m")
4083 (match_operand:DF 1 "register_operand" "f")))]
4085 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4086 && !TARGET_MIX_SSE_I387"
4088 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4089 return "fstp%z0\t%y0";
4091 return "fst%z0\t%y0";
4093 [(set_attr "type" "fmov")
4094 (set_attr "mode" "SF")])
4097 [(set (match_operand:SF 0 "register_operand" "")
4099 (match_operand:DF 1 "fp_register_operand" "")))
4100 (clobber (match_operand 2 "" ""))]
4102 [(set (match_dup 2) (match_dup 1))
4103 (set (match_dup 0) (match_dup 2))]
4105 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4108 ;; Conversion from XFmode to SFmode.
4110 (define_expand "truncxfsf2"
4111 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4113 (match_operand:XF 1 "register_operand" "")))
4114 (clobber (match_dup 2))])]
4117 if (flag_unsafe_math_optimizations)
4119 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
4120 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
4121 if (reg != operands[0])
4122 emit_move_insn (operands[0], reg);
4126 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
4129 (define_insn "*truncxfsf2_mixed"
4130 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
4132 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4133 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4136 gcc_assert (!which_alternative);
4137 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4138 return "fstp%z0\t%y0";
4140 return "fst%z0\t%y0";
4142 [(set_attr "type" "fmov,multi,multi,multi")
4143 (set_attr "unit" "*,i387,i387,i387")
4144 (set_attr "mode" "SF")])
4146 (define_insn "truncxfsf2_i387_noop"
4147 [(set (match_operand:SF 0 "register_operand" "=f")
4148 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
4149 "TARGET_80387 && flag_unsafe_math_optimizations"
4150 "* return output_387_reg_move (insn, operands);"
4151 [(set_attr "type" "fmov")
4152 (set_attr "mode" "SF")])
4154 (define_insn "*truncxfsf2_i387"
4155 [(set (match_operand:SF 0 "memory_operand" "=m")
4157 (match_operand:XF 1 "register_operand" "f")))]
4160 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4161 return "fstp%z0\t%y0";
4163 return "fst%z0\t%y0";
4165 [(set_attr "type" "fmov")
4166 (set_attr "mode" "SF")])
4169 [(set (match_operand:SF 0 "register_operand" "")
4171 (match_operand:XF 1 "register_operand" "")))
4172 (clobber (match_operand:SF 2 "memory_operand" ""))]
4173 "TARGET_80387 && reload_completed"
4174 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4175 (set (match_dup 0) (match_dup 2))]
4179 [(set (match_operand:SF 0 "memory_operand" "")
4181 (match_operand:XF 1 "register_operand" "")))
4182 (clobber (match_operand:SF 2 "memory_operand" ""))]
4184 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4187 ;; Conversion from XFmode to DFmode.
4189 (define_expand "truncxfdf2"
4190 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4192 (match_operand:XF 1 "register_operand" "")))
4193 (clobber (match_dup 2))])]
4196 if (flag_unsafe_math_optimizations)
4198 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4199 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4200 if (reg != operands[0])
4201 emit_move_insn (operands[0], reg);
4205 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4208 (define_insn "*truncxfdf2_mixed"
4209 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y2*x")
4211 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4212 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4215 gcc_assert (!which_alternative);
4216 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4217 return "fstp%z0\t%y0";
4219 return "fst%z0\t%y0";
4221 [(set_attr "type" "fmov,multi,multi,multi")
4222 (set_attr "unit" "*,i387,i387,i387")
4223 (set_attr "mode" "DF")])
4225 (define_insn "truncxfdf2_i387_noop"
4226 [(set (match_operand:DF 0 "register_operand" "=f")
4227 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4228 "TARGET_80387 && flag_unsafe_math_optimizations"
4229 "* return output_387_reg_move (insn, operands);"
4230 [(set_attr "type" "fmov")
4231 (set_attr "mode" "DF")])
4233 (define_insn "*truncxfdf2_i387"
4234 [(set (match_operand:DF 0 "memory_operand" "=m")
4236 (match_operand:XF 1 "register_operand" "f")))]
4239 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4240 return "fstp%z0\t%y0";
4242 return "fst%z0\t%y0";
4244 [(set_attr "type" "fmov")
4245 (set_attr "mode" "DF")])
4248 [(set (match_operand:DF 0 "register_operand" "")
4250 (match_operand:XF 1 "register_operand" "")))
4251 (clobber (match_operand:DF 2 "memory_operand" ""))]
4252 "TARGET_80387 && reload_completed"
4253 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4254 (set (match_dup 0) (match_dup 2))]
4258 [(set (match_operand:DF 0 "memory_operand" "")
4260 (match_operand:XF 1 "register_operand" "")))
4261 (clobber (match_operand:DF 2 "memory_operand" ""))]
4263 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4266 ;; Signed conversion to DImode.
4268 (define_expand "fix_truncxfdi2"
4269 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4270 (fix:DI (match_operand:XF 1 "register_operand" "")))
4271 (clobber (reg:CC FLAGS_REG))])]
4276 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4281 (define_expand "fix_trunc<mode>di2"
4282 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4283 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4284 (clobber (reg:CC FLAGS_REG))])]
4285 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4288 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4290 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4293 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4295 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4296 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4297 if (out != operands[0])
4298 emit_move_insn (operands[0], out);
4303 ;; Signed conversion to SImode.
4305 (define_expand "fix_truncxfsi2"
4306 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4307 (fix:SI (match_operand:XF 1 "register_operand" "")))
4308 (clobber (reg:CC FLAGS_REG))])]
4313 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4318 (define_expand "fix_trunc<mode>si2"
4319 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4320 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4321 (clobber (reg:CC FLAGS_REG))])]
4322 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4325 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4327 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4330 if (SSE_FLOAT_MODE_P (<MODE>mode))
4332 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4333 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4334 if (out != operands[0])
4335 emit_move_insn (operands[0], out);
4340 ;; Signed conversion to HImode.
4342 (define_expand "fix_trunc<mode>hi2"
4343 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4344 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4345 (clobber (reg:CC FLAGS_REG))])]
4347 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4351 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4356 ;; Unsigned conversion to SImode.
4358 (define_expand "fixuns_trunc<mode>si2"
4360 [(set (match_operand:SI 0 "register_operand" "")
4362 (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4364 (clobber (match_scratch:<ssevecmode> 3 ""))
4365 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4366 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4368 enum machine_mode mode = <MODE>mode;
4369 enum machine_mode vecmode = <ssevecmode>mode;
4370 REAL_VALUE_TYPE TWO31r;
4373 real_ldexp (&TWO31r, &dconst1, 31);
4374 two31 = const_double_from_real_value (TWO31r, mode);
4375 two31 = ix86_build_const_vector (mode, true, two31);
4376 operands[2] = force_reg (vecmode, two31);
4379 (define_insn_and_split "*fixuns_trunc<mode>_1"
4380 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4382 (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4383 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4384 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4385 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4386 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4388 "&& reload_completed"
4391 ix86_split_convert_uns_si_sse (operands);
4395 ;; Unsigned conversion to HImode.
4396 ;; Without these patterns, we'll try the unsigned SI conversion which
4397 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4399 (define_expand "fixuns_trunc<mode>hi2"
4401 (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4402 (set (match_operand:HI 0 "nonimmediate_operand" "")
4403 (subreg:HI (match_dup 2) 0))]
4404 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4405 "operands[2] = gen_reg_rtx (SImode);")
4407 ;; When SSE is available, it is always faster to use it!
4408 (define_insn "fix_trunc<mode>di_sse"
4409 [(set (match_operand:DI 0 "register_operand" "=r,r")
4410 (fix:DI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,xm")))]
4411 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4412 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4413 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4414 [(set_attr "type" "sseicvt")
4415 (set_attr "mode" "<MODE>")
4416 (set_attr "athlon_decode" "double,vector")
4417 (set_attr "amdfam10_decode" "double,double")])
4419 (define_insn "fix_trunc<mode>si_sse"
4420 [(set (match_operand:SI 0 "register_operand" "=r,r")
4421 (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,xm")))]
4422 "SSE_FLOAT_MODE_P (<MODE>mode)
4423 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4424 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4425 [(set_attr "type" "sseicvt")
4426 (set_attr "mode" "<MODE>")
4427 (set_attr "athlon_decode" "double,vector")
4428 (set_attr "amdfam10_decode" "double,double")])
4430 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4432 [(set (match_operand:SSEMODEF 0 "register_operand" "")
4433 (match_operand:SSEMODEF 1 "memory_operand" ""))
4434 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4435 (fix:SSEMODEI24 (match_dup 0)))]
4437 && peep2_reg_dead_p (2, operands[0])"
4438 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4441 ;; Avoid vector decoded forms of the instruction.
4443 [(match_scratch:DF 2 "Y2")
4444 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4445 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4446 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4447 [(set (match_dup 2) (match_dup 1))
4448 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4452 [(match_scratch:SF 2 "x")
4453 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4454 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4455 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4456 [(set (match_dup 2) (match_dup 1))
4457 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4460 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4461 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4462 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4464 && FLOAT_MODE_P (GET_MODE (operands[1]))
4465 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4466 && (TARGET_64BIT || <MODE>mode != DImode))
4468 && !(reload_completed || reload_in_progress)"
4473 if (memory_operand (operands[0], VOIDmode))
4474 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4477 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4478 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4484 [(set_attr "type" "fisttp")
4485 (set_attr "mode" "<MODE>")])
4487 (define_insn "fix_trunc<mode>_i387_fisttp"
4488 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4489 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4490 (clobber (match_scratch:XF 2 "=&1f"))]
4492 && FLOAT_MODE_P (GET_MODE (operands[1]))
4493 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4494 && (TARGET_64BIT || <MODE>mode != DImode))
4495 && TARGET_SSE_MATH)"
4496 "* return output_fix_trunc (insn, operands, 1);"
4497 [(set_attr "type" "fisttp")
4498 (set_attr "mode" "<MODE>")])
4500 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4501 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4502 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4503 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4504 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4506 && FLOAT_MODE_P (GET_MODE (operands[1]))
4507 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4508 && (TARGET_64BIT || <MODE>mode != DImode))
4509 && TARGET_SSE_MATH)"
4511 [(set_attr "type" "fisttp")
4512 (set_attr "mode" "<MODE>")])
4515 [(set (match_operand:X87MODEI 0 "register_operand" "")
4516 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4517 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4518 (clobber (match_scratch 3 ""))]
4520 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4521 (clobber (match_dup 3))])
4522 (set (match_dup 0) (match_dup 2))]
4526 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4527 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4528 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4529 (clobber (match_scratch 3 ""))]
4531 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4532 (clobber (match_dup 3))])]
4535 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4536 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4537 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4538 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4539 ;; function in i386.c.
4540 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4541 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4542 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4543 (clobber (reg:CC FLAGS_REG))]
4544 "TARGET_80387 && !TARGET_FISTTP
4545 && FLOAT_MODE_P (GET_MODE (operands[1]))
4546 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4547 && (TARGET_64BIT || <MODE>mode != DImode))
4548 && !(reload_completed || reload_in_progress)"
4553 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4555 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4556 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4557 if (memory_operand (operands[0], VOIDmode))
4558 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4559 operands[2], operands[3]));
4562 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4563 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4564 operands[2], operands[3],
4569 [(set_attr "type" "fistp")
4570 (set_attr "i387_cw" "trunc")
4571 (set_attr "mode" "<MODE>")])
4573 (define_insn "fix_truncdi_i387"
4574 [(set (match_operand:DI 0 "memory_operand" "=m")
4575 (fix:DI (match_operand 1 "register_operand" "f")))
4576 (use (match_operand:HI 2 "memory_operand" "m"))
4577 (use (match_operand:HI 3 "memory_operand" "m"))
4578 (clobber (match_scratch:XF 4 "=&1f"))]
4579 "TARGET_80387 && !TARGET_FISTTP
4580 && FLOAT_MODE_P (GET_MODE (operands[1]))
4581 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4582 "* return output_fix_trunc (insn, operands, 0);"
4583 [(set_attr "type" "fistp")
4584 (set_attr "i387_cw" "trunc")
4585 (set_attr "mode" "DI")])
4587 (define_insn "fix_truncdi_i387_with_temp"
4588 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4589 (fix:DI (match_operand 1 "register_operand" "f,f")))
4590 (use (match_operand:HI 2 "memory_operand" "m,m"))
4591 (use (match_operand:HI 3 "memory_operand" "m,m"))
4592 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4593 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4594 "TARGET_80387 && !TARGET_FISTTP
4595 && FLOAT_MODE_P (GET_MODE (operands[1]))
4596 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4598 [(set_attr "type" "fistp")
4599 (set_attr "i387_cw" "trunc")
4600 (set_attr "mode" "DI")])
4603 [(set (match_operand:DI 0 "register_operand" "")
4604 (fix:DI (match_operand 1 "register_operand" "")))
4605 (use (match_operand:HI 2 "memory_operand" ""))
4606 (use (match_operand:HI 3 "memory_operand" ""))
4607 (clobber (match_operand:DI 4 "memory_operand" ""))
4608 (clobber (match_scratch 5 ""))]
4610 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4613 (clobber (match_dup 5))])
4614 (set (match_dup 0) (match_dup 4))]
4618 [(set (match_operand:DI 0 "memory_operand" "")
4619 (fix:DI (match_operand 1 "register_operand" "")))
4620 (use (match_operand:HI 2 "memory_operand" ""))
4621 (use (match_operand:HI 3 "memory_operand" ""))
4622 (clobber (match_operand:DI 4 "memory_operand" ""))
4623 (clobber (match_scratch 5 ""))]
4625 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4628 (clobber (match_dup 5))])]
4631 (define_insn "fix_trunc<mode>_i387"
4632 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4633 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4634 (use (match_operand:HI 2 "memory_operand" "m"))
4635 (use (match_operand:HI 3 "memory_operand" "m"))]
4636 "TARGET_80387 && !TARGET_FISTTP
4637 && FLOAT_MODE_P (GET_MODE (operands[1]))
4638 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4639 "* return output_fix_trunc (insn, operands, 0);"
4640 [(set_attr "type" "fistp")
4641 (set_attr "i387_cw" "trunc")
4642 (set_attr "mode" "<MODE>")])
4644 (define_insn "fix_trunc<mode>_i387_with_temp"
4645 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4646 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4647 (use (match_operand:HI 2 "memory_operand" "m,m"))
4648 (use (match_operand:HI 3 "memory_operand" "m,m"))
4649 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4650 "TARGET_80387 && !TARGET_FISTTP
4651 && FLOAT_MODE_P (GET_MODE (operands[1]))
4652 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4654 [(set_attr "type" "fistp")
4655 (set_attr "i387_cw" "trunc")
4656 (set_attr "mode" "<MODE>")])
4659 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4660 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4661 (use (match_operand:HI 2 "memory_operand" ""))
4662 (use (match_operand:HI 3 "memory_operand" ""))
4663 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4665 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4667 (use (match_dup 3))])
4668 (set (match_dup 0) (match_dup 4))]
4672 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4673 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4674 (use (match_operand:HI 2 "memory_operand" ""))
4675 (use (match_operand:HI 3 "memory_operand" ""))
4676 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4678 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4680 (use (match_dup 3))])]
4683 (define_insn "x86_fnstcw_1"
4684 [(set (match_operand:HI 0 "memory_operand" "=m")
4685 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4688 [(set_attr "length" "2")
4689 (set_attr "mode" "HI")
4690 (set_attr "unit" "i387")])
4692 (define_insn "x86_fldcw_1"
4693 [(set (reg:HI FPCR_REG)
4694 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4697 [(set_attr "length" "2")
4698 (set_attr "mode" "HI")
4699 (set_attr "unit" "i387")
4700 (set_attr "athlon_decode" "vector")
4701 (set_attr "amdfam10_decode" "vector")])
4703 ;; Conversion between fixed point and floating point.
4705 ;; Even though we only accept memory inputs, the backend _really_
4706 ;; wants to be able to do this between registers.
4708 (define_expand "floathisf2"
4709 [(set (match_operand:SF 0 "register_operand" "")
4710 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4711 "TARGET_80387 || TARGET_SSE_MATH"
4713 if (TARGET_SSE_MATH)
4715 emit_insn (gen_floatsisf2 (operands[0],
4716 convert_to_mode (SImode, operands[1], 0)));
4721 (define_insn "*floathisf2_i387"
4722 [(set (match_operand:SF 0 "register_operand" "=f,f")
4723 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4724 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4728 [(set_attr "type" "fmov,multi")
4729 (set_attr "mode" "SF")
4730 (set_attr "unit" "*,i387")
4731 (set_attr "fp_int_src" "true")])
4733 (define_expand "floatsisf2"
4734 [(set (match_operand:SF 0 "register_operand" "")
4735 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4736 "TARGET_80387 || TARGET_SSE_MATH"
4739 (define_insn "*floatsisf2_mixed"
4740 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4741 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4742 "TARGET_MIX_SSE_I387"
4746 cvtsi2ss\t{%1, %0|%0, %1}
4747 cvtsi2ss\t{%1, %0|%0, %1}"
4748 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4749 (set_attr "mode" "SF")
4750 (set_attr "unit" "*,i387,*,*")
4751 (set_attr "athlon_decode" "*,*,vector,double")
4752 (set_attr "amdfam10_decode" "*,*,vector,double")
4753 (set_attr "fp_int_src" "true")])
4755 (define_insn "*floatsisf2_sse"
4756 [(set (match_operand:SF 0 "register_operand" "=x,x")
4757 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4759 "cvtsi2ss\t{%1, %0|%0, %1}"
4760 [(set_attr "type" "sseicvt")
4761 (set_attr "mode" "SF")
4762 (set_attr "athlon_decode" "vector,double")
4763 (set_attr "amdfam10_decode" "vector,double")
4764 (set_attr "fp_int_src" "true")])
4766 (define_insn "*floatsisf2_i387"
4767 [(set (match_operand:SF 0 "register_operand" "=f,f")
4768 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4773 [(set_attr "type" "fmov,multi")
4774 (set_attr "mode" "SF")
4775 (set_attr "unit" "*,i387")
4776 (set_attr "fp_int_src" "true")])
4778 (define_expand "floatdisf2"
4779 [(set (match_operand:SF 0 "register_operand" "")
4780 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4781 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4784 (define_insn "*floatdisf2_mixed"
4785 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4786 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4787 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4791 cvtsi2ss{q}\t{%1, %0|%0, %1}
4792 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4793 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4794 (set_attr "mode" "SF")
4795 (set_attr "unit" "*,i387,*,*")
4796 (set_attr "athlon_decode" "*,*,vector,double")
4797 (set_attr "amdfam10_decode" "*,*,vector,double")
4798 (set_attr "fp_int_src" "true")])
4800 (define_insn "*floatdisf2_sse"
4801 [(set (match_operand:SF 0 "register_operand" "=x,x")
4802 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4803 "TARGET_64BIT && TARGET_SSE_MATH"
4804 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4805 [(set_attr "type" "sseicvt")
4806 (set_attr "mode" "SF")
4807 (set_attr "athlon_decode" "vector,double")
4808 (set_attr "amdfam10_decode" "vector,double")
4809 (set_attr "fp_int_src" "true")])
4811 (define_insn "*floatdisf2_i387"
4812 [(set (match_operand:SF 0 "register_operand" "=f,f")
4813 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4818 [(set_attr "type" "fmov,multi")
4819 (set_attr "mode" "SF")
4820 (set_attr "unit" "*,i387")
4821 (set_attr "fp_int_src" "true")])
4823 (define_expand "floathidf2"
4824 [(set (match_operand:DF 0 "register_operand" "")
4825 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4826 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4828 if (TARGET_SSE2 && TARGET_SSE_MATH)
4830 emit_insn (gen_floatsidf2 (operands[0],
4831 convert_to_mode (SImode, operands[1], 0)));
4836 (define_insn "*floathidf2_i387"
4837 [(set (match_operand:DF 0 "register_operand" "=f,f")
4838 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4839 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4843 [(set_attr "type" "fmov,multi")
4844 (set_attr "mode" "DF")
4845 (set_attr "unit" "*,i387")
4846 (set_attr "fp_int_src" "true")])
4848 (define_expand "floatsidf2"
4849 [(set (match_operand:DF 0 "register_operand" "")
4850 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4851 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4854 (define_insn "*floatsidf2_mixed"
4855 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4856 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4857 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4861 cvtsi2sd\t{%1, %0|%0, %1}
4862 cvtsi2sd\t{%1, %0|%0, %1}"
4863 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4864 (set_attr "mode" "DF")
4865 (set_attr "unit" "*,i387,*,*")
4866 (set_attr "athlon_decode" "*,*,double,direct")
4867 (set_attr "amdfam10_decode" "*,*,vector,double")
4868 (set_attr "fp_int_src" "true")])
4870 (define_insn "*floatsidf2_sse"
4871 [(set (match_operand:DF 0 "register_operand" "=x,x")
4872 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4873 "TARGET_SSE2 && TARGET_SSE_MATH"
4874 "cvtsi2sd\t{%1, %0|%0, %1}"
4875 [(set_attr "type" "sseicvt")
4876 (set_attr "mode" "DF")
4877 (set_attr "athlon_decode" "double,direct")
4878 (set_attr "amdfam10_decode" "vector,double")
4879 (set_attr "fp_int_src" "true")])
4881 (define_insn "*floatsidf2_i387"
4882 [(set (match_operand:DF 0 "register_operand" "=f,f")
4883 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4888 [(set_attr "type" "fmov,multi")
4889 (set_attr "mode" "DF")
4890 (set_attr "unit" "*,i387")
4891 (set_attr "fp_int_src" "true")])
4893 (define_expand "floatdidf2"
4894 [(set (match_operand:DF 0 "register_operand" "")
4895 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4896 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4898 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4900 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4905 (define_insn "*floatdidf2_mixed"
4906 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4907 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4908 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4912 cvtsi2sd{q}\t{%1, %0|%0, %1}
4913 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4914 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4915 (set_attr "mode" "DF")
4916 (set_attr "unit" "*,i387,*,*")
4917 (set_attr "athlon_decode" "*,*,double,direct")
4918 (set_attr "amdfam10_decode" "*,*,vector,double")
4919 (set_attr "fp_int_src" "true")])
4921 (define_insn "*floatdidf2_sse"
4922 [(set (match_operand:DF 0 "register_operand" "=x,x")
4923 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4924 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4925 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4926 [(set_attr "type" "sseicvt")
4927 (set_attr "mode" "DF")
4928 (set_attr "athlon_decode" "double,direct")
4929 (set_attr "amdfam10_decode" "vector,double")
4930 (set_attr "fp_int_src" "true")])
4932 (define_insn "*floatdidf2_i387"
4933 [(set (match_operand:DF 0 "register_operand" "=f,f")
4934 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4939 [(set_attr "type" "fmov,multi")
4940 (set_attr "mode" "DF")
4941 (set_attr "unit" "*,i387")
4942 (set_attr "fp_int_src" "true")])
4944 (define_insn "floathixf2"
4945 [(set (match_operand:XF 0 "register_operand" "=f,f")
4946 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4951 [(set_attr "type" "fmov,multi")
4952 (set_attr "mode" "XF")
4953 (set_attr "unit" "*,i387")
4954 (set_attr "fp_int_src" "true")])
4956 (define_insn "floatsixf2"
4957 [(set (match_operand:XF 0 "register_operand" "=f,f")
4958 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4963 [(set_attr "type" "fmov,multi")
4964 (set_attr "mode" "XF")
4965 (set_attr "unit" "*,i387")
4966 (set_attr "fp_int_src" "true")])
4968 (define_insn "floatdixf2"
4969 [(set (match_operand:XF 0 "register_operand" "=f,f")
4970 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4975 [(set_attr "type" "fmov,multi")
4976 (set_attr "mode" "XF")
4977 (set_attr "unit" "*,i387")
4978 (set_attr "fp_int_src" "true")])
4980 ;; %%% Kill these when reload knows how to do it.
4982 [(set (match_operand 0 "fp_register_operand" "")
4983 (float (match_operand 1 "register_operand" "")))]
4986 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4989 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4990 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4991 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4992 ix86_free_from_memory (GET_MODE (operands[1]));
4996 (define_expand "floatunssisf2"
4997 [(use (match_operand:SF 0 "register_operand" ""))
4998 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5001 if (TARGET_SSE_MATH && TARGET_SSE2)
5002 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5004 x86_emit_floatuns (operands);
5008 (define_expand "floatunssidf2"
5009 [(use (match_operand:DF 0 "register_operand" ""))
5010 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5011 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5012 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5014 (define_expand "floatunsdisf2"
5015 [(use (match_operand:SF 0 "register_operand" ""))
5016 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5017 "TARGET_64BIT && TARGET_SSE_MATH"
5018 "x86_emit_floatuns (operands); DONE;")
5020 (define_expand "floatunsdidf2"
5021 [(use (match_operand:DF 0 "register_operand" ""))
5022 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5023 "TARGET_SSE_MATH && TARGET_SSE2
5024 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5027 x86_emit_floatuns (operands);
5029 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5033 ;; SSE extract/set expanders
5038 ;; %%% splits for addditi3
5040 (define_expand "addti3"
5041 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5042 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5043 (match_operand:TI 2 "x86_64_general_operand" "")))
5044 (clobber (reg:CC FLAGS_REG))]
5046 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5048 (define_insn "*addti3_1"
5049 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5050 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5051 (match_operand:TI 2 "general_operand" "roiF,riF")))
5052 (clobber (reg:CC FLAGS_REG))]
5053 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5057 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5058 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5059 (match_operand:TI 2 "general_operand" "")))
5060 (clobber (reg:CC FLAGS_REG))]
5061 "TARGET_64BIT && reload_completed"
5062 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5064 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5065 (parallel [(set (match_dup 3)
5066 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5069 (clobber (reg:CC FLAGS_REG))])]
5070 "split_ti (operands+0, 1, operands+0, operands+3);
5071 split_ti (operands+1, 1, operands+1, operands+4);
5072 split_ti (operands+2, 1, operands+2, operands+5);")
5074 ;; %%% splits for addsidi3
5075 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5076 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5077 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5079 (define_expand "adddi3"
5080 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5081 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5082 (match_operand:DI 2 "x86_64_general_operand" "")))
5083 (clobber (reg:CC FLAGS_REG))]
5085 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5087 (define_insn "*adddi3_1"
5088 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5089 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5090 (match_operand:DI 2 "general_operand" "roiF,riF")))
5091 (clobber (reg:CC FLAGS_REG))]
5092 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5096 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5097 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5098 (match_operand:DI 2 "general_operand" "")))
5099 (clobber (reg:CC FLAGS_REG))]
5100 "!TARGET_64BIT && reload_completed"
5101 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5103 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5104 (parallel [(set (match_dup 3)
5105 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5108 (clobber (reg:CC FLAGS_REG))])]
5109 "split_di (operands+0, 1, operands+0, operands+3);
5110 split_di (operands+1, 1, operands+1, operands+4);
5111 split_di (operands+2, 1, operands+2, operands+5);")
5113 (define_insn "adddi3_carry_rex64"
5114 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5115 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5116 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5117 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5118 (clobber (reg:CC FLAGS_REG))]
5119 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5120 "adc{q}\t{%2, %0|%0, %2}"
5121 [(set_attr "type" "alu")
5122 (set_attr "pent_pair" "pu")
5123 (set_attr "mode" "DI")])
5125 (define_insn "*adddi3_cc_rex64"
5126 [(set (reg:CC FLAGS_REG)
5127 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5128 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5130 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5131 (plus:DI (match_dup 1) (match_dup 2)))]
5132 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5133 "add{q}\t{%2, %0|%0, %2}"
5134 [(set_attr "type" "alu")
5135 (set_attr "mode" "DI")])
5137 (define_insn "addqi3_carry"
5138 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5139 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5140 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5141 (match_operand:QI 2 "general_operand" "qi,qm")))
5142 (clobber (reg:CC FLAGS_REG))]
5143 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5144 "adc{b}\t{%2, %0|%0, %2}"
5145 [(set_attr "type" "alu")
5146 (set_attr "pent_pair" "pu")
5147 (set_attr "mode" "QI")])
5149 (define_insn "addhi3_carry"
5150 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5151 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5152 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5153 (match_operand:HI 2 "general_operand" "ri,rm")))
5154 (clobber (reg:CC FLAGS_REG))]
5155 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5156 "adc{w}\t{%2, %0|%0, %2}"
5157 [(set_attr "type" "alu")
5158 (set_attr "pent_pair" "pu")
5159 (set_attr "mode" "HI")])
5161 (define_insn "addsi3_carry"
5162 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5163 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5164 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5165 (match_operand:SI 2 "general_operand" "ri,rm")))
5166 (clobber (reg:CC FLAGS_REG))]
5167 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5168 "adc{l}\t{%2, %0|%0, %2}"
5169 [(set_attr "type" "alu")
5170 (set_attr "pent_pair" "pu")
5171 (set_attr "mode" "SI")])
5173 (define_insn "*addsi3_carry_zext"
5174 [(set (match_operand:DI 0 "register_operand" "=r")
5176 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5177 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5178 (match_operand:SI 2 "general_operand" "rim"))))
5179 (clobber (reg:CC FLAGS_REG))]
5180 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5181 "adc{l}\t{%2, %k0|%k0, %2}"
5182 [(set_attr "type" "alu")
5183 (set_attr "pent_pair" "pu")
5184 (set_attr "mode" "SI")])
5186 (define_insn "*addsi3_cc"
5187 [(set (reg:CC FLAGS_REG)
5188 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5189 (match_operand:SI 2 "general_operand" "ri,rm")]
5191 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5192 (plus:SI (match_dup 1) (match_dup 2)))]
5193 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5194 "add{l}\t{%2, %0|%0, %2}"
5195 [(set_attr "type" "alu")
5196 (set_attr "mode" "SI")])
5198 (define_insn "addqi3_cc"
5199 [(set (reg:CC FLAGS_REG)
5200 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5201 (match_operand:QI 2 "general_operand" "qi,qm")]
5203 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5204 (plus:QI (match_dup 1) (match_dup 2)))]
5205 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5206 "add{b}\t{%2, %0|%0, %2}"
5207 [(set_attr "type" "alu")
5208 (set_attr "mode" "QI")])
5210 (define_expand "addsi3"
5211 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5212 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5213 (match_operand:SI 2 "general_operand" "")))
5214 (clobber (reg:CC FLAGS_REG))])]
5216 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5218 (define_insn "*lea_1"
5219 [(set (match_operand:SI 0 "register_operand" "=r")
5220 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5222 "lea{l}\t{%a1, %0|%0, %a1}"
5223 [(set_attr "type" "lea")
5224 (set_attr "mode" "SI")])
5226 (define_insn "*lea_1_rex64"
5227 [(set (match_operand:SI 0 "register_operand" "=r")
5228 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5230 "lea{l}\t{%a1, %0|%0, %a1}"
5231 [(set_attr "type" "lea")
5232 (set_attr "mode" "SI")])
5234 (define_insn "*lea_1_zext"
5235 [(set (match_operand:DI 0 "register_operand" "=r")
5237 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5239 "lea{l}\t{%a1, %k0|%k0, %a1}"
5240 [(set_attr "type" "lea")
5241 (set_attr "mode" "SI")])
5243 (define_insn "*lea_2_rex64"
5244 [(set (match_operand:DI 0 "register_operand" "=r")
5245 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5247 "lea{q}\t{%a1, %0|%0, %a1}"
5248 [(set_attr "type" "lea")
5249 (set_attr "mode" "DI")])
5251 ;; The lea patterns for non-Pmodes needs to be matched by several
5252 ;; insns converted to real lea by splitters.
5254 (define_insn_and_split "*lea_general_1"
5255 [(set (match_operand 0 "register_operand" "=r")
5256 (plus (plus (match_operand 1 "index_register_operand" "l")
5257 (match_operand 2 "register_operand" "r"))
5258 (match_operand 3 "immediate_operand" "i")))]
5259 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5260 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5261 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5262 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5263 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5264 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5265 || GET_MODE (operands[3]) == VOIDmode)"
5267 "&& reload_completed"
5271 operands[0] = gen_lowpart (SImode, operands[0]);
5272 operands[1] = gen_lowpart (Pmode, operands[1]);
5273 operands[2] = gen_lowpart (Pmode, operands[2]);
5274 operands[3] = gen_lowpart (Pmode, operands[3]);
5275 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5277 if (Pmode != SImode)
5278 pat = gen_rtx_SUBREG (SImode, pat, 0);
5279 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5282 [(set_attr "type" "lea")
5283 (set_attr "mode" "SI")])
5285 (define_insn_and_split "*lea_general_1_zext"
5286 [(set (match_operand:DI 0 "register_operand" "=r")
5288 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5289 (match_operand:SI 2 "register_operand" "r"))
5290 (match_operand:SI 3 "immediate_operand" "i"))))]
5293 "&& reload_completed"
5295 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5297 (match_dup 3)) 0)))]
5299 operands[1] = gen_lowpart (Pmode, operands[1]);
5300 operands[2] = gen_lowpart (Pmode, operands[2]);
5301 operands[3] = gen_lowpart (Pmode, operands[3]);
5303 [(set_attr "type" "lea")
5304 (set_attr "mode" "SI")])
5306 (define_insn_and_split "*lea_general_2"
5307 [(set (match_operand 0 "register_operand" "=r")
5308 (plus (mult (match_operand 1 "index_register_operand" "l")
5309 (match_operand 2 "const248_operand" "i"))
5310 (match_operand 3 "nonmemory_operand" "ri")))]
5311 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5312 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5313 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5314 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5315 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5316 || GET_MODE (operands[3]) == VOIDmode)"
5318 "&& reload_completed"
5322 operands[0] = gen_lowpart (SImode, operands[0]);
5323 operands[1] = gen_lowpart (Pmode, operands[1]);
5324 operands[3] = gen_lowpart (Pmode, operands[3]);
5325 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5327 if (Pmode != SImode)
5328 pat = gen_rtx_SUBREG (SImode, pat, 0);
5329 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5332 [(set_attr "type" "lea")
5333 (set_attr "mode" "SI")])
5335 (define_insn_and_split "*lea_general_2_zext"
5336 [(set (match_operand:DI 0 "register_operand" "=r")
5338 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5339 (match_operand:SI 2 "const248_operand" "n"))
5340 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5343 "&& reload_completed"
5345 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5347 (match_dup 3)) 0)))]
5349 operands[1] = gen_lowpart (Pmode, operands[1]);
5350 operands[3] = gen_lowpart (Pmode, operands[3]);
5352 [(set_attr "type" "lea")
5353 (set_attr "mode" "SI")])
5355 (define_insn_and_split "*lea_general_3"
5356 [(set (match_operand 0 "register_operand" "=r")
5357 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5358 (match_operand 2 "const248_operand" "i"))
5359 (match_operand 3 "register_operand" "r"))
5360 (match_operand 4 "immediate_operand" "i")))]
5361 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5362 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5363 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5364 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5365 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5367 "&& reload_completed"
5371 operands[0] = gen_lowpart (SImode, operands[0]);
5372 operands[1] = gen_lowpart (Pmode, operands[1]);
5373 operands[3] = gen_lowpart (Pmode, operands[3]);
5374 operands[4] = gen_lowpart (Pmode, operands[4]);
5375 pat = gen_rtx_PLUS (Pmode,
5376 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5380 if (Pmode != SImode)
5381 pat = gen_rtx_SUBREG (SImode, pat, 0);
5382 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5385 [(set_attr "type" "lea")
5386 (set_attr "mode" "SI")])
5388 (define_insn_and_split "*lea_general_3_zext"
5389 [(set (match_operand:DI 0 "register_operand" "=r")
5391 (plus:SI (plus:SI (mult:SI
5392 (match_operand:SI 1 "index_register_operand" "l")
5393 (match_operand:SI 2 "const248_operand" "n"))
5394 (match_operand:SI 3 "register_operand" "r"))
5395 (match_operand:SI 4 "immediate_operand" "i"))))]
5398 "&& reload_completed"
5400 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5403 (match_dup 4)) 0)))]
5405 operands[1] = gen_lowpart (Pmode, operands[1]);
5406 operands[3] = gen_lowpart (Pmode, operands[3]);
5407 operands[4] = gen_lowpart (Pmode, operands[4]);
5409 [(set_attr "type" "lea")
5410 (set_attr "mode" "SI")])
5412 (define_insn "*adddi_1_rex64"
5413 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5414 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5415 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5416 (clobber (reg:CC FLAGS_REG))]
5417 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5419 switch (get_attr_type (insn))
5422 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5423 return "lea{q}\t{%a2, %0|%0, %a2}";
5426 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5427 if (operands[2] == const1_rtx)
5428 return "inc{q}\t%0";
5431 gcc_assert (operands[2] == constm1_rtx);
5432 return "dec{q}\t%0";
5436 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5438 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5439 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5440 if (CONST_INT_P (operands[2])
5441 /* Avoid overflows. */
5442 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5443 && (INTVAL (operands[2]) == 128
5444 || (INTVAL (operands[2]) < 0
5445 && INTVAL (operands[2]) != -128)))
5447 operands[2] = GEN_INT (-INTVAL (operands[2]));
5448 return "sub{q}\t{%2, %0|%0, %2}";
5450 return "add{q}\t{%2, %0|%0, %2}";
5454 (cond [(eq_attr "alternative" "2")
5455 (const_string "lea")
5456 ; Current assemblers are broken and do not allow @GOTOFF in
5457 ; ought but a memory context.
5458 (match_operand:DI 2 "pic_symbolic_operand" "")
5459 (const_string "lea")
5460 (match_operand:DI 2 "incdec_operand" "")
5461 (const_string "incdec")
5463 (const_string "alu")))
5464 (set_attr "mode" "DI")])
5466 ;; Convert lea to the lea pattern to avoid flags dependency.
5468 [(set (match_operand:DI 0 "register_operand" "")
5469 (plus:DI (match_operand:DI 1 "register_operand" "")
5470 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5471 (clobber (reg:CC FLAGS_REG))]
5472 "TARGET_64BIT && reload_completed
5473 && true_regnum (operands[0]) != true_regnum (operands[1])"
5475 (plus:DI (match_dup 1)
5479 (define_insn "*adddi_2_rex64"
5480 [(set (reg FLAGS_REG)
5482 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5483 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5485 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5486 (plus:DI (match_dup 1) (match_dup 2)))]
5487 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5488 && ix86_binary_operator_ok (PLUS, DImode, operands)
5489 /* Current assemblers are broken and do not allow @GOTOFF in
5490 ought but a memory context. */
5491 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5493 switch (get_attr_type (insn))
5496 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5497 if (operands[2] == const1_rtx)
5498 return "inc{q}\t%0";
5501 gcc_assert (operands[2] == constm1_rtx);
5502 return "dec{q}\t%0";
5506 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5507 /* ???? We ought to handle there the 32bit case too
5508 - do we need new constraint? */
5509 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5510 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5511 if (CONST_INT_P (operands[2])
5512 /* Avoid overflows. */
5513 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5514 && (INTVAL (operands[2]) == 128
5515 || (INTVAL (operands[2]) < 0
5516 && INTVAL (operands[2]) != -128)))
5518 operands[2] = GEN_INT (-INTVAL (operands[2]));
5519 return "sub{q}\t{%2, %0|%0, %2}";
5521 return "add{q}\t{%2, %0|%0, %2}";
5525 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5526 (const_string "incdec")
5527 (const_string "alu")))
5528 (set_attr "mode" "DI")])
5530 (define_insn "*adddi_3_rex64"
5531 [(set (reg FLAGS_REG)
5532 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5533 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5534 (clobber (match_scratch:DI 0 "=r"))]
5536 && ix86_match_ccmode (insn, CCZmode)
5537 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5538 /* Current assemblers are broken and do not allow @GOTOFF in
5539 ought but a memory context. */
5540 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5542 switch (get_attr_type (insn))
5545 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5546 if (operands[2] == const1_rtx)
5547 return "inc{q}\t%0";
5550 gcc_assert (operands[2] == constm1_rtx);
5551 return "dec{q}\t%0";
5555 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5556 /* ???? We ought to handle there the 32bit case too
5557 - do we need new constraint? */
5558 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5559 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5560 if (CONST_INT_P (operands[2])
5561 /* Avoid overflows. */
5562 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5563 && (INTVAL (operands[2]) == 128
5564 || (INTVAL (operands[2]) < 0
5565 && INTVAL (operands[2]) != -128)))
5567 operands[2] = GEN_INT (-INTVAL (operands[2]));
5568 return "sub{q}\t{%2, %0|%0, %2}";
5570 return "add{q}\t{%2, %0|%0, %2}";
5574 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5575 (const_string "incdec")
5576 (const_string "alu")))
5577 (set_attr "mode" "DI")])
5579 ; For comparisons against 1, -1 and 128, we may generate better code
5580 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5581 ; is matched then. We can't accept general immediate, because for
5582 ; case of overflows, the result is messed up.
5583 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5585 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5586 ; only for comparisons not depending on it.
5587 (define_insn "*adddi_4_rex64"
5588 [(set (reg FLAGS_REG)
5589 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5590 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5591 (clobber (match_scratch:DI 0 "=rm"))]
5593 && ix86_match_ccmode (insn, CCGCmode)"
5595 switch (get_attr_type (insn))
5598 if (operands[2] == constm1_rtx)
5599 return "inc{q}\t%0";
5602 gcc_assert (operands[2] == const1_rtx);
5603 return "dec{q}\t%0";
5607 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5608 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5609 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5610 if ((INTVAL (operands[2]) == -128
5611 || (INTVAL (operands[2]) > 0
5612 && INTVAL (operands[2]) != 128))
5613 /* Avoid overflows. */
5614 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5615 return "sub{q}\t{%2, %0|%0, %2}";
5616 operands[2] = GEN_INT (-INTVAL (operands[2]));
5617 return "add{q}\t{%2, %0|%0, %2}";
5621 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5622 (const_string "incdec")
5623 (const_string "alu")))
5624 (set_attr "mode" "DI")])
5626 (define_insn "*adddi_5_rex64"
5627 [(set (reg FLAGS_REG)
5629 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5630 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5632 (clobber (match_scratch:DI 0 "=r"))]
5634 && ix86_match_ccmode (insn, CCGOCmode)
5635 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5636 /* Current assemblers are broken and do not allow @GOTOFF in
5637 ought but a memory context. */
5638 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5640 switch (get_attr_type (insn))
5643 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644 if (operands[2] == const1_rtx)
5645 return "inc{q}\t%0";
5648 gcc_assert (operands[2] == constm1_rtx);
5649 return "dec{q}\t%0";
5653 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5654 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5655 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5656 if (CONST_INT_P (operands[2])
5657 /* Avoid overflows. */
5658 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5659 && (INTVAL (operands[2]) == 128
5660 || (INTVAL (operands[2]) < 0
5661 && INTVAL (operands[2]) != -128)))
5663 operands[2] = GEN_INT (-INTVAL (operands[2]));
5664 return "sub{q}\t{%2, %0|%0, %2}";
5666 return "add{q}\t{%2, %0|%0, %2}";
5670 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5671 (const_string "incdec")
5672 (const_string "alu")))
5673 (set_attr "mode" "DI")])
5676 (define_insn "*addsi_1"
5677 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5678 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5679 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5680 (clobber (reg:CC FLAGS_REG))]
5681 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5683 switch (get_attr_type (insn))
5686 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5687 return "lea{l}\t{%a2, %0|%0, %a2}";
5690 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5691 if (operands[2] == const1_rtx)
5692 return "inc{l}\t%0";
5695 gcc_assert (operands[2] == constm1_rtx);
5696 return "dec{l}\t%0";
5700 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5702 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5703 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5704 if (CONST_INT_P (operands[2])
5705 && (INTVAL (operands[2]) == 128
5706 || (INTVAL (operands[2]) < 0
5707 && INTVAL (operands[2]) != -128)))
5709 operands[2] = GEN_INT (-INTVAL (operands[2]));
5710 return "sub{l}\t{%2, %0|%0, %2}";
5712 return "add{l}\t{%2, %0|%0, %2}";
5716 (cond [(eq_attr "alternative" "2")
5717 (const_string "lea")
5718 ; Current assemblers are broken and do not allow @GOTOFF in
5719 ; ought but a memory context.
5720 (match_operand:SI 2 "pic_symbolic_operand" "")
5721 (const_string "lea")
5722 (match_operand:SI 2 "incdec_operand" "")
5723 (const_string "incdec")
5725 (const_string "alu")))
5726 (set_attr "mode" "SI")])
5728 ;; Convert lea to the lea pattern to avoid flags dependency.
5730 [(set (match_operand 0 "register_operand" "")
5731 (plus (match_operand 1 "register_operand" "")
5732 (match_operand 2 "nonmemory_operand" "")))
5733 (clobber (reg:CC FLAGS_REG))]
5735 && true_regnum (operands[0]) != true_regnum (operands[1])"
5739 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5740 may confuse gen_lowpart. */
5741 if (GET_MODE (operands[0]) != Pmode)
5743 operands[1] = gen_lowpart (Pmode, operands[1]);
5744 operands[2] = gen_lowpart (Pmode, operands[2]);
5746 operands[0] = gen_lowpart (SImode, operands[0]);
5747 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5748 if (Pmode != SImode)
5749 pat = gen_rtx_SUBREG (SImode, pat, 0);
5750 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5754 ;; It may seem that nonimmediate operand is proper one for operand 1.
5755 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5756 ;; we take care in ix86_binary_operator_ok to not allow two memory
5757 ;; operands so proper swapping will be done in reload. This allow
5758 ;; patterns constructed from addsi_1 to match.
5759 (define_insn "addsi_1_zext"
5760 [(set (match_operand:DI 0 "register_operand" "=r,r")
5762 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5763 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5764 (clobber (reg:CC FLAGS_REG))]
5765 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5767 switch (get_attr_type (insn))
5770 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5771 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5774 if (operands[2] == const1_rtx)
5775 return "inc{l}\t%k0";
5778 gcc_assert (operands[2] == constm1_rtx);
5779 return "dec{l}\t%k0";
5783 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5784 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5785 if (CONST_INT_P (operands[2])
5786 && (INTVAL (operands[2]) == 128
5787 || (INTVAL (operands[2]) < 0
5788 && INTVAL (operands[2]) != -128)))
5790 operands[2] = GEN_INT (-INTVAL (operands[2]));
5791 return "sub{l}\t{%2, %k0|%k0, %2}";
5793 return "add{l}\t{%2, %k0|%k0, %2}";
5797 (cond [(eq_attr "alternative" "1")
5798 (const_string "lea")
5799 ; Current assemblers are broken and do not allow @GOTOFF in
5800 ; ought but a memory context.
5801 (match_operand:SI 2 "pic_symbolic_operand" "")
5802 (const_string "lea")
5803 (match_operand:SI 2 "incdec_operand" "")
5804 (const_string "incdec")
5806 (const_string "alu")))
5807 (set_attr "mode" "SI")])
5809 ;; Convert lea to the lea pattern to avoid flags dependency.
5811 [(set (match_operand:DI 0 "register_operand" "")
5813 (plus:SI (match_operand:SI 1 "register_operand" "")
5814 (match_operand:SI 2 "nonmemory_operand" ""))))
5815 (clobber (reg:CC FLAGS_REG))]
5816 "TARGET_64BIT && reload_completed
5817 && true_regnum (operands[0]) != true_regnum (operands[1])"
5819 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5821 operands[1] = gen_lowpart (Pmode, operands[1]);
5822 operands[2] = gen_lowpart (Pmode, operands[2]);
5825 (define_insn "*addsi_2"
5826 [(set (reg FLAGS_REG)
5828 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5829 (match_operand:SI 2 "general_operand" "rmni,rni"))
5831 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5832 (plus:SI (match_dup 1) (match_dup 2)))]
5833 "ix86_match_ccmode (insn, CCGOCmode)
5834 && ix86_binary_operator_ok (PLUS, SImode, operands)
5835 /* Current assemblers are broken and do not allow @GOTOFF in
5836 ought but a memory context. */
5837 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5839 switch (get_attr_type (insn))
5842 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5843 if (operands[2] == const1_rtx)
5844 return "inc{l}\t%0";
5847 gcc_assert (operands[2] == constm1_rtx);
5848 return "dec{l}\t%0";
5852 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5853 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5854 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5855 if (CONST_INT_P (operands[2])
5856 && (INTVAL (operands[2]) == 128
5857 || (INTVAL (operands[2]) < 0
5858 && INTVAL (operands[2]) != -128)))
5860 operands[2] = GEN_INT (-INTVAL (operands[2]));
5861 return "sub{l}\t{%2, %0|%0, %2}";
5863 return "add{l}\t{%2, %0|%0, %2}";
5867 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5868 (const_string "incdec")
5869 (const_string "alu")))
5870 (set_attr "mode" "SI")])
5872 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5873 (define_insn "*addsi_2_zext"
5874 [(set (reg FLAGS_REG)
5876 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5877 (match_operand:SI 2 "general_operand" "rmni"))
5879 (set (match_operand:DI 0 "register_operand" "=r")
5880 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5881 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5882 && ix86_binary_operator_ok (PLUS, SImode, operands)
5883 /* Current assemblers are broken and do not allow @GOTOFF in
5884 ought but a memory context. */
5885 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5887 switch (get_attr_type (insn))
5890 if (operands[2] == const1_rtx)
5891 return "inc{l}\t%k0";
5894 gcc_assert (operands[2] == constm1_rtx);
5895 return "dec{l}\t%k0";
5899 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5900 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5901 if (CONST_INT_P (operands[2])
5902 && (INTVAL (operands[2]) == 128
5903 || (INTVAL (operands[2]) < 0
5904 && INTVAL (operands[2]) != -128)))
5906 operands[2] = GEN_INT (-INTVAL (operands[2]));
5907 return "sub{l}\t{%2, %k0|%k0, %2}";
5909 return "add{l}\t{%2, %k0|%k0, %2}";
5913 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5914 (const_string "incdec")
5915 (const_string "alu")))
5916 (set_attr "mode" "SI")])
5918 (define_insn "*addsi_3"
5919 [(set (reg FLAGS_REG)
5920 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5921 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5922 (clobber (match_scratch:SI 0 "=r"))]
5923 "ix86_match_ccmode (insn, CCZmode)
5924 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5925 /* Current assemblers are broken and do not allow @GOTOFF in
5926 ought but a memory context. */
5927 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5929 switch (get_attr_type (insn))
5932 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5933 if (operands[2] == const1_rtx)
5934 return "inc{l}\t%0";
5937 gcc_assert (operands[2] == constm1_rtx);
5938 return "dec{l}\t%0";
5942 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5943 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5944 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5945 if (CONST_INT_P (operands[2])
5946 && (INTVAL (operands[2]) == 128
5947 || (INTVAL (operands[2]) < 0
5948 && INTVAL (operands[2]) != -128)))
5950 operands[2] = GEN_INT (-INTVAL (operands[2]));
5951 return "sub{l}\t{%2, %0|%0, %2}";
5953 return "add{l}\t{%2, %0|%0, %2}";
5957 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5958 (const_string "incdec")
5959 (const_string "alu")))
5960 (set_attr "mode" "SI")])
5962 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5963 (define_insn "*addsi_3_zext"
5964 [(set (reg FLAGS_REG)
5965 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5966 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5967 (set (match_operand:DI 0 "register_operand" "=r")
5968 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5969 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5970 && ix86_binary_operator_ok (PLUS, SImode, operands)
5971 /* Current assemblers are broken and do not allow @GOTOFF in
5972 ought but a memory context. */
5973 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5975 switch (get_attr_type (insn))
5978 if (operands[2] == const1_rtx)
5979 return "inc{l}\t%k0";
5982 gcc_assert (operands[2] == constm1_rtx);
5983 return "dec{l}\t%k0";
5987 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5988 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5989 if (CONST_INT_P (operands[2])
5990 && (INTVAL (operands[2]) == 128
5991 || (INTVAL (operands[2]) < 0
5992 && INTVAL (operands[2]) != -128)))
5994 operands[2] = GEN_INT (-INTVAL (operands[2]));
5995 return "sub{l}\t{%2, %k0|%k0, %2}";
5997 return "add{l}\t{%2, %k0|%k0, %2}";
6001 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6002 (const_string "incdec")
6003 (const_string "alu")))
6004 (set_attr "mode" "SI")])
6006 ; For comparisons against 1, -1 and 128, we may generate better code
6007 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6008 ; is matched then. We can't accept general immediate, because for
6009 ; case of overflows, the result is messed up.
6010 ; This pattern also don't hold of 0x80000000, since the value overflows
6012 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6013 ; only for comparisons not depending on it.
6014 (define_insn "*addsi_4"
6015 [(set (reg FLAGS_REG)
6016 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6017 (match_operand:SI 2 "const_int_operand" "n")))
6018 (clobber (match_scratch:SI 0 "=rm"))]
6019 "ix86_match_ccmode (insn, CCGCmode)
6020 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6022 switch (get_attr_type (insn))
6025 if (operands[2] == constm1_rtx)
6026 return "inc{l}\t%0";
6029 gcc_assert (operands[2] == const1_rtx);
6030 return "dec{l}\t%0";
6034 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6035 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6036 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6037 if ((INTVAL (operands[2]) == -128
6038 || (INTVAL (operands[2]) > 0
6039 && INTVAL (operands[2]) != 128)))
6040 return "sub{l}\t{%2, %0|%0, %2}";
6041 operands[2] = GEN_INT (-INTVAL (operands[2]));
6042 return "add{l}\t{%2, %0|%0, %2}";
6046 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6047 (const_string "incdec")
6048 (const_string "alu")))
6049 (set_attr "mode" "SI")])
6051 (define_insn "*addsi_5"
6052 [(set (reg FLAGS_REG)
6054 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6055 (match_operand:SI 2 "general_operand" "rmni"))
6057 (clobber (match_scratch:SI 0 "=r"))]
6058 "ix86_match_ccmode (insn, CCGOCmode)
6059 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6060 /* Current assemblers are broken and do not allow @GOTOFF in
6061 ought but a memory context. */
6062 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6064 switch (get_attr_type (insn))
6067 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6068 if (operands[2] == const1_rtx)
6069 return "inc{l}\t%0";
6072 gcc_assert (operands[2] == constm1_rtx);
6073 return "dec{l}\t%0";
6077 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6078 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6079 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6080 if (CONST_INT_P (operands[2])
6081 && (INTVAL (operands[2]) == 128
6082 || (INTVAL (operands[2]) < 0
6083 && INTVAL (operands[2]) != -128)))
6085 operands[2] = GEN_INT (-INTVAL (operands[2]));
6086 return "sub{l}\t{%2, %0|%0, %2}";
6088 return "add{l}\t{%2, %0|%0, %2}";
6092 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6093 (const_string "incdec")
6094 (const_string "alu")))
6095 (set_attr "mode" "SI")])
6097 (define_expand "addhi3"
6098 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6099 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6100 (match_operand:HI 2 "general_operand" "")))
6101 (clobber (reg:CC FLAGS_REG))])]
6102 "TARGET_HIMODE_MATH"
6103 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6105 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6106 ;; type optimizations enabled by define-splits. This is not important
6107 ;; for PII, and in fact harmful because of partial register stalls.
6109 (define_insn "*addhi_1_lea"
6110 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6111 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6112 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6113 (clobber (reg:CC FLAGS_REG))]
6114 "!TARGET_PARTIAL_REG_STALL
6115 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6117 switch (get_attr_type (insn))
6122 if (operands[2] == const1_rtx)
6123 return "inc{w}\t%0";
6126 gcc_assert (operands[2] == constm1_rtx);
6127 return "dec{w}\t%0";
6131 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6132 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6133 if (CONST_INT_P (operands[2])
6134 && (INTVAL (operands[2]) == 128
6135 || (INTVAL (operands[2]) < 0
6136 && INTVAL (operands[2]) != -128)))
6138 operands[2] = GEN_INT (-INTVAL (operands[2]));
6139 return "sub{w}\t{%2, %0|%0, %2}";
6141 return "add{w}\t{%2, %0|%0, %2}";
6145 (if_then_else (eq_attr "alternative" "2")
6146 (const_string "lea")
6147 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6148 (const_string "incdec")
6149 (const_string "alu"))))
6150 (set_attr "mode" "HI,HI,SI")])
6152 (define_insn "*addhi_1"
6153 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6154 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6155 (match_operand:HI 2 "general_operand" "ri,rm")))
6156 (clobber (reg:CC FLAGS_REG))]
6157 "TARGET_PARTIAL_REG_STALL
6158 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6160 switch (get_attr_type (insn))
6163 if (operands[2] == const1_rtx)
6164 return "inc{w}\t%0";
6167 gcc_assert (operands[2] == constm1_rtx);
6168 return "dec{w}\t%0";
6172 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6173 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6174 if (CONST_INT_P (operands[2])
6175 && (INTVAL (operands[2]) == 128
6176 || (INTVAL (operands[2]) < 0
6177 && INTVAL (operands[2]) != -128)))
6179 operands[2] = GEN_INT (-INTVAL (operands[2]));
6180 return "sub{w}\t{%2, %0|%0, %2}";
6182 return "add{w}\t{%2, %0|%0, %2}";
6186 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6187 (const_string "incdec")
6188 (const_string "alu")))
6189 (set_attr "mode" "HI")])
6191 (define_insn "*addhi_2"
6192 [(set (reg FLAGS_REG)
6194 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6195 (match_operand:HI 2 "general_operand" "rmni,rni"))
6197 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6198 (plus:HI (match_dup 1) (match_dup 2)))]
6199 "ix86_match_ccmode (insn, CCGOCmode)
6200 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6202 switch (get_attr_type (insn))
6205 if (operands[2] == const1_rtx)
6206 return "inc{w}\t%0";
6209 gcc_assert (operands[2] == constm1_rtx);
6210 return "dec{w}\t%0";
6214 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6215 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6216 if (CONST_INT_P (operands[2])
6217 && (INTVAL (operands[2]) == 128
6218 || (INTVAL (operands[2]) < 0
6219 && INTVAL (operands[2]) != -128)))
6221 operands[2] = GEN_INT (-INTVAL (operands[2]));
6222 return "sub{w}\t{%2, %0|%0, %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" "HI")])
6233 (define_insn "*addhi_3"
6234 [(set (reg FLAGS_REG)
6235 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6236 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6237 (clobber (match_scratch:HI 0 "=r"))]
6238 "ix86_match_ccmode (insn, CCZmode)
6239 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6241 switch (get_attr_type (insn))
6244 if (operands[2] == const1_rtx)
6245 return "inc{w}\t%0";
6248 gcc_assert (operands[2] == constm1_rtx);
6249 return "dec{w}\t%0";
6253 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6254 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6255 if (CONST_INT_P (operands[2])
6256 && (INTVAL (operands[2]) == 128
6257 || (INTVAL (operands[2]) < 0
6258 && INTVAL (operands[2]) != -128)))
6260 operands[2] = GEN_INT (-INTVAL (operands[2]));
6261 return "sub{w}\t{%2, %0|%0, %2}";
6263 return "add{w}\t{%2, %0|%0, %2}";
6267 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6268 (const_string "incdec")
6269 (const_string "alu")))
6270 (set_attr "mode" "HI")])
6272 ; See comments above addsi_4 for details.
6273 (define_insn "*addhi_4"
6274 [(set (reg FLAGS_REG)
6275 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6276 (match_operand:HI 2 "const_int_operand" "n")))
6277 (clobber (match_scratch:HI 0 "=rm"))]
6278 "ix86_match_ccmode (insn, CCGCmode)
6279 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6281 switch (get_attr_type (insn))
6284 if (operands[2] == constm1_rtx)
6285 return "inc{w}\t%0";
6288 gcc_assert (operands[2] == const1_rtx);
6289 return "dec{w}\t%0";
6293 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6294 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6295 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6296 if ((INTVAL (operands[2]) == -128
6297 || (INTVAL (operands[2]) > 0
6298 && INTVAL (operands[2]) != 128)))
6299 return "sub{w}\t{%2, %0|%0, %2}";
6300 operands[2] = GEN_INT (-INTVAL (operands[2]));
6301 return "add{w}\t{%2, %0|%0, %2}";
6305 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6306 (const_string "incdec")
6307 (const_string "alu")))
6308 (set_attr "mode" "SI")])
6311 (define_insn "*addhi_5"
6312 [(set (reg FLAGS_REG)
6314 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6315 (match_operand:HI 2 "general_operand" "rmni"))
6317 (clobber (match_scratch:HI 0 "=r"))]
6318 "ix86_match_ccmode (insn, CCGOCmode)
6319 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6321 switch (get_attr_type (insn))
6324 if (operands[2] == const1_rtx)
6325 return "inc{w}\t%0";
6328 gcc_assert (operands[2] == constm1_rtx);
6329 return "dec{w}\t%0";
6333 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6334 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6335 if (CONST_INT_P (operands[2])
6336 && (INTVAL (operands[2]) == 128
6337 || (INTVAL (operands[2]) < 0
6338 && INTVAL (operands[2]) != -128)))
6340 operands[2] = GEN_INT (-INTVAL (operands[2]));
6341 return "sub{w}\t{%2, %0|%0, %2}";
6343 return "add{w}\t{%2, %0|%0, %2}";
6347 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6348 (const_string "incdec")
6349 (const_string "alu")))
6350 (set_attr "mode" "HI")])
6352 (define_expand "addqi3"
6353 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6354 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6355 (match_operand:QI 2 "general_operand" "")))
6356 (clobber (reg:CC FLAGS_REG))])]
6357 "TARGET_QIMODE_MATH"
6358 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6360 ;; %%% Potential partial reg stall on alternative 2. What to do?
6361 (define_insn "*addqi_1_lea"
6362 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6363 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6364 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6365 (clobber (reg:CC FLAGS_REG))]
6366 "!TARGET_PARTIAL_REG_STALL
6367 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6369 int widen = (which_alternative == 2);
6370 switch (get_attr_type (insn))
6375 if (operands[2] == const1_rtx)
6376 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6379 gcc_assert (operands[2] == constm1_rtx);
6380 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6384 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6385 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6386 if (CONST_INT_P (operands[2])
6387 && (INTVAL (operands[2]) == 128
6388 || (INTVAL (operands[2]) < 0
6389 && INTVAL (operands[2]) != -128)))
6391 operands[2] = GEN_INT (-INTVAL (operands[2]));
6393 return "sub{l}\t{%2, %k0|%k0, %2}";
6395 return "sub{b}\t{%2, %0|%0, %2}";
6398 return "add{l}\t{%k2, %k0|%k0, %k2}";
6400 return "add{b}\t{%2, %0|%0, %2}";
6404 (if_then_else (eq_attr "alternative" "3")
6405 (const_string "lea")
6406 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6407 (const_string "incdec")
6408 (const_string "alu"))))
6409 (set_attr "mode" "QI,QI,SI,SI")])
6411 (define_insn "*addqi_1"
6412 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6413 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6414 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6415 (clobber (reg:CC FLAGS_REG))]
6416 "TARGET_PARTIAL_REG_STALL
6417 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6419 int widen = (which_alternative == 2);
6420 switch (get_attr_type (insn))
6423 if (operands[2] == const1_rtx)
6424 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6427 gcc_assert (operands[2] == constm1_rtx);
6428 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6432 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6433 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6434 if (CONST_INT_P (operands[2])
6435 && (INTVAL (operands[2]) == 128
6436 || (INTVAL (operands[2]) < 0
6437 && INTVAL (operands[2]) != -128)))
6439 operands[2] = GEN_INT (-INTVAL (operands[2]));
6441 return "sub{l}\t{%2, %k0|%k0, %2}";
6443 return "sub{b}\t{%2, %0|%0, %2}";
6446 return "add{l}\t{%k2, %k0|%k0, %k2}";
6448 return "add{b}\t{%2, %0|%0, %2}";
6452 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6453 (const_string "incdec")
6454 (const_string "alu")))
6455 (set_attr "mode" "QI,QI,SI")])
6457 (define_insn "*addqi_1_slp"
6458 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6459 (plus:QI (match_dup 0)
6460 (match_operand:QI 1 "general_operand" "qn,qnm")))
6461 (clobber (reg:CC FLAGS_REG))]
6462 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6463 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6465 switch (get_attr_type (insn))
6468 if (operands[1] == const1_rtx)
6469 return "inc{b}\t%0";
6472 gcc_assert (operands[1] == constm1_rtx);
6473 return "dec{b}\t%0";
6477 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6478 if (CONST_INT_P (operands[1])
6479 && INTVAL (operands[1]) < 0)
6481 operands[1] = GEN_INT (-INTVAL (operands[1]));
6482 return "sub{b}\t{%1, %0|%0, %1}";
6484 return "add{b}\t{%1, %0|%0, %1}";
6488 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6489 (const_string "incdec")
6490 (const_string "alu1")))
6491 (set (attr "memory")
6492 (if_then_else (match_operand 1 "memory_operand" "")
6493 (const_string "load")
6494 (const_string "none")))
6495 (set_attr "mode" "QI")])
6497 (define_insn "*addqi_2"
6498 [(set (reg FLAGS_REG)
6500 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6501 (match_operand:QI 2 "general_operand" "qmni,qni"))
6503 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6504 (plus:QI (match_dup 1) (match_dup 2)))]
6505 "ix86_match_ccmode (insn, CCGOCmode)
6506 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6508 switch (get_attr_type (insn))
6511 if (operands[2] == const1_rtx)
6512 return "inc{b}\t%0";
6515 gcc_assert (operands[2] == constm1_rtx
6516 || (CONST_INT_P (operands[2])
6517 && INTVAL (operands[2]) == 255));
6518 return "dec{b}\t%0";
6522 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6523 if (CONST_INT_P (operands[2])
6524 && INTVAL (operands[2]) < 0)
6526 operands[2] = GEN_INT (-INTVAL (operands[2]));
6527 return "sub{b}\t{%2, %0|%0, %2}";
6529 return "add{b}\t{%2, %0|%0, %2}";
6533 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6534 (const_string "incdec")
6535 (const_string "alu")))
6536 (set_attr "mode" "QI")])
6538 (define_insn "*addqi_3"
6539 [(set (reg FLAGS_REG)
6540 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6541 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6542 (clobber (match_scratch:QI 0 "=q"))]
6543 "ix86_match_ccmode (insn, CCZmode)
6544 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6546 switch (get_attr_type (insn))
6549 if (operands[2] == const1_rtx)
6550 return "inc{b}\t%0";
6553 gcc_assert (operands[2] == constm1_rtx
6554 || (CONST_INT_P (operands[2])
6555 && INTVAL (operands[2]) == 255));
6556 return "dec{b}\t%0";
6560 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6561 if (CONST_INT_P (operands[2])
6562 && INTVAL (operands[2]) < 0)
6564 operands[2] = GEN_INT (-INTVAL (operands[2]));
6565 return "sub{b}\t{%2, %0|%0, %2}";
6567 return "add{b}\t{%2, %0|%0, %2}";
6571 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6572 (const_string "incdec")
6573 (const_string "alu")))
6574 (set_attr "mode" "QI")])
6576 ; See comments above addsi_4 for details.
6577 (define_insn "*addqi_4"
6578 [(set (reg FLAGS_REG)
6579 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6580 (match_operand:QI 2 "const_int_operand" "n")))
6581 (clobber (match_scratch:QI 0 "=qm"))]
6582 "ix86_match_ccmode (insn, CCGCmode)
6583 && (INTVAL (operands[2]) & 0xff) != 0x80"
6585 switch (get_attr_type (insn))
6588 if (operands[2] == constm1_rtx
6589 || (CONST_INT_P (operands[2])
6590 && INTVAL (operands[2]) == 255))
6591 return "inc{b}\t%0";
6594 gcc_assert (operands[2] == const1_rtx);
6595 return "dec{b}\t%0";
6599 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6600 if (INTVAL (operands[2]) < 0)
6602 operands[2] = GEN_INT (-INTVAL (operands[2]));
6603 return "add{b}\t{%2, %0|%0, %2}";
6605 return "sub{b}\t{%2, %0|%0, %2}";
6609 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6610 (const_string "incdec")
6611 (const_string "alu")))
6612 (set_attr "mode" "QI")])
6615 (define_insn "*addqi_5"
6616 [(set (reg FLAGS_REG)
6618 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6619 (match_operand:QI 2 "general_operand" "qmni"))
6621 (clobber (match_scratch:QI 0 "=q"))]
6622 "ix86_match_ccmode (insn, CCGOCmode)
6623 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6625 switch (get_attr_type (insn))
6628 if (operands[2] == const1_rtx)
6629 return "inc{b}\t%0";
6632 gcc_assert (operands[2] == constm1_rtx
6633 || (CONST_INT_P (operands[2])
6634 && INTVAL (operands[2]) == 255));
6635 return "dec{b}\t%0";
6639 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6640 if (CONST_INT_P (operands[2])
6641 && INTVAL (operands[2]) < 0)
6643 operands[2] = GEN_INT (-INTVAL (operands[2]));
6644 return "sub{b}\t{%2, %0|%0, %2}";
6646 return "add{b}\t{%2, %0|%0, %2}";
6650 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6651 (const_string "incdec")
6652 (const_string "alu")))
6653 (set_attr "mode" "QI")])
6656 (define_insn "addqi_ext_1"
6657 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6662 (match_operand 1 "ext_register_operand" "0")
6665 (match_operand:QI 2 "general_operand" "Qmn")))
6666 (clobber (reg:CC FLAGS_REG))]
6669 switch (get_attr_type (insn))
6672 if (operands[2] == const1_rtx)
6673 return "inc{b}\t%h0";
6676 gcc_assert (operands[2] == constm1_rtx
6677 || (CONST_INT_P (operands[2])
6678 && INTVAL (operands[2]) == 255));
6679 return "dec{b}\t%h0";
6683 return "add{b}\t{%2, %h0|%h0, %2}";
6687 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6688 (const_string "incdec")
6689 (const_string "alu")))
6690 (set_attr "mode" "QI")])
6692 (define_insn "*addqi_ext_1_rex64"
6693 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6698 (match_operand 1 "ext_register_operand" "0")
6701 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6702 (clobber (reg:CC FLAGS_REG))]
6705 switch (get_attr_type (insn))
6708 if (operands[2] == const1_rtx)
6709 return "inc{b}\t%h0";
6712 gcc_assert (operands[2] == constm1_rtx
6713 || (CONST_INT_P (operands[2])
6714 && INTVAL (operands[2]) == 255));
6715 return "dec{b}\t%h0";
6719 return "add{b}\t{%2, %h0|%h0, %2}";
6723 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6724 (const_string "incdec")
6725 (const_string "alu")))
6726 (set_attr "mode" "QI")])
6728 (define_insn "*addqi_ext_2"
6729 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6734 (match_operand 1 "ext_register_operand" "%0")
6738 (match_operand 2 "ext_register_operand" "Q")
6741 (clobber (reg:CC FLAGS_REG))]
6743 "add{b}\t{%h2, %h0|%h0, %h2}"
6744 [(set_attr "type" "alu")
6745 (set_attr "mode" "QI")])
6747 ;; The patterns that match these are at the end of this file.
6749 (define_expand "addxf3"
6750 [(set (match_operand:XF 0 "register_operand" "")
6751 (plus:XF (match_operand:XF 1 "register_operand" "")
6752 (match_operand:XF 2 "register_operand" "")))]
6756 (define_expand "adddf3"
6757 [(set (match_operand:DF 0 "register_operand" "")
6758 (plus:DF (match_operand:DF 1 "register_operand" "")
6759 (match_operand:DF 2 "nonimmediate_operand" "")))]
6760 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6763 (define_expand "addsf3"
6764 [(set (match_operand:SF 0 "register_operand" "")
6765 (plus:SF (match_operand:SF 1 "register_operand" "")
6766 (match_operand:SF 2 "nonimmediate_operand" "")))]
6767 "TARGET_80387 || TARGET_SSE_MATH"
6770 ;; Subtract instructions
6772 ;; %%% splits for subditi3
6774 (define_expand "subti3"
6775 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6776 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6777 (match_operand:TI 2 "x86_64_general_operand" "")))
6778 (clobber (reg:CC FLAGS_REG))])]
6780 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6782 (define_insn "*subti3_1"
6783 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6784 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6785 (match_operand:TI 2 "general_operand" "roiF,riF")))
6786 (clobber (reg:CC FLAGS_REG))]
6787 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6791 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6792 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6793 (match_operand:TI 2 "general_operand" "")))
6794 (clobber (reg:CC FLAGS_REG))]
6795 "TARGET_64BIT && reload_completed"
6796 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6797 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6798 (parallel [(set (match_dup 3)
6799 (minus:DI (match_dup 4)
6800 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6802 (clobber (reg:CC FLAGS_REG))])]
6803 "split_ti (operands+0, 1, operands+0, operands+3);
6804 split_ti (operands+1, 1, operands+1, operands+4);
6805 split_ti (operands+2, 1, operands+2, operands+5);")
6807 ;; %%% splits for subsidi3
6809 (define_expand "subdi3"
6810 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6811 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6812 (match_operand:DI 2 "x86_64_general_operand" "")))
6813 (clobber (reg:CC FLAGS_REG))])]
6815 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6817 (define_insn "*subdi3_1"
6818 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6819 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6820 (match_operand:DI 2 "general_operand" "roiF,riF")))
6821 (clobber (reg:CC FLAGS_REG))]
6822 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6826 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6827 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6828 (match_operand:DI 2 "general_operand" "")))
6829 (clobber (reg:CC FLAGS_REG))]
6830 "!TARGET_64BIT && reload_completed"
6831 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6832 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6833 (parallel [(set (match_dup 3)
6834 (minus:SI (match_dup 4)
6835 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6837 (clobber (reg:CC FLAGS_REG))])]
6838 "split_di (operands+0, 1, operands+0, operands+3);
6839 split_di (operands+1, 1, operands+1, operands+4);
6840 split_di (operands+2, 1, operands+2, operands+5);")
6842 (define_insn "subdi3_carry_rex64"
6843 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6844 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6845 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6846 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6847 (clobber (reg:CC FLAGS_REG))]
6848 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6849 "sbb{q}\t{%2, %0|%0, %2}"
6850 [(set_attr "type" "alu")
6851 (set_attr "pent_pair" "pu")
6852 (set_attr "mode" "DI")])
6854 (define_insn "*subdi_1_rex64"
6855 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6856 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6857 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6858 (clobber (reg:CC FLAGS_REG))]
6859 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6860 "sub{q}\t{%2, %0|%0, %2}"
6861 [(set_attr "type" "alu")
6862 (set_attr "mode" "DI")])
6864 (define_insn "*subdi_2_rex64"
6865 [(set (reg FLAGS_REG)
6867 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6868 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6870 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6871 (minus:DI (match_dup 1) (match_dup 2)))]
6872 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6873 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6874 "sub{q}\t{%2, %0|%0, %2}"
6875 [(set_attr "type" "alu")
6876 (set_attr "mode" "DI")])
6878 (define_insn "*subdi_3_rex63"
6879 [(set (reg FLAGS_REG)
6880 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6881 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6882 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6883 (minus:DI (match_dup 1) (match_dup 2)))]
6884 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6885 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6886 "sub{q}\t{%2, %0|%0, %2}"
6887 [(set_attr "type" "alu")
6888 (set_attr "mode" "DI")])
6890 (define_insn "subqi3_carry"
6891 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6892 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6893 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6894 (match_operand:QI 2 "general_operand" "qi,qm"))))
6895 (clobber (reg:CC FLAGS_REG))]
6896 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6897 "sbb{b}\t{%2, %0|%0, %2}"
6898 [(set_attr "type" "alu")
6899 (set_attr "pent_pair" "pu")
6900 (set_attr "mode" "QI")])
6902 (define_insn "subhi3_carry"
6903 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6904 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6905 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6906 (match_operand:HI 2 "general_operand" "ri,rm"))))
6907 (clobber (reg:CC FLAGS_REG))]
6908 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6909 "sbb{w}\t{%2, %0|%0, %2}"
6910 [(set_attr "type" "alu")
6911 (set_attr "pent_pair" "pu")
6912 (set_attr "mode" "HI")])
6914 (define_insn "subsi3_carry"
6915 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6916 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6917 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6918 (match_operand:SI 2 "general_operand" "ri,rm"))))
6919 (clobber (reg:CC FLAGS_REG))]
6920 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6921 "sbb{l}\t{%2, %0|%0, %2}"
6922 [(set_attr "type" "alu")
6923 (set_attr "pent_pair" "pu")
6924 (set_attr "mode" "SI")])
6926 (define_insn "subsi3_carry_zext"
6927 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6929 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6930 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6931 (match_operand:SI 2 "general_operand" "ri,rm")))))
6932 (clobber (reg:CC FLAGS_REG))]
6933 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6934 "sbb{l}\t{%2, %k0|%k0, %2}"
6935 [(set_attr "type" "alu")
6936 (set_attr "pent_pair" "pu")
6937 (set_attr "mode" "SI")])
6939 (define_expand "subsi3"
6940 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6941 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6942 (match_operand:SI 2 "general_operand" "")))
6943 (clobber (reg:CC FLAGS_REG))])]
6945 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6947 (define_insn "*subsi_1"
6948 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6949 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6950 (match_operand:SI 2 "general_operand" "ri,rm")))
6951 (clobber (reg:CC FLAGS_REG))]
6952 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6953 "sub{l}\t{%2, %0|%0, %2}"
6954 [(set_attr "type" "alu")
6955 (set_attr "mode" "SI")])
6957 (define_insn "*subsi_1_zext"
6958 [(set (match_operand:DI 0 "register_operand" "=r")
6960 (minus:SI (match_operand:SI 1 "register_operand" "0")
6961 (match_operand:SI 2 "general_operand" "rim"))))
6962 (clobber (reg:CC FLAGS_REG))]
6963 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6964 "sub{l}\t{%2, %k0|%k0, %2}"
6965 [(set_attr "type" "alu")
6966 (set_attr "mode" "SI")])
6968 (define_insn "*subsi_2"
6969 [(set (reg FLAGS_REG)
6971 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6972 (match_operand:SI 2 "general_operand" "ri,rm"))
6974 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6975 (minus:SI (match_dup 1) (match_dup 2)))]
6976 "ix86_match_ccmode (insn, CCGOCmode)
6977 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6978 "sub{l}\t{%2, %0|%0, %2}"
6979 [(set_attr "type" "alu")
6980 (set_attr "mode" "SI")])
6982 (define_insn "*subsi_2_zext"
6983 [(set (reg FLAGS_REG)
6985 (minus:SI (match_operand:SI 1 "register_operand" "0")
6986 (match_operand:SI 2 "general_operand" "rim"))
6988 (set (match_operand:DI 0 "register_operand" "=r")
6990 (minus:SI (match_dup 1)
6992 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6993 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6994 "sub{l}\t{%2, %k0|%k0, %2}"
6995 [(set_attr "type" "alu")
6996 (set_attr "mode" "SI")])
6998 (define_insn "*subsi_3"
6999 [(set (reg FLAGS_REG)
7000 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7001 (match_operand:SI 2 "general_operand" "ri,rm")))
7002 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7003 (minus:SI (match_dup 1) (match_dup 2)))]
7004 "ix86_match_ccmode (insn, CCmode)
7005 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7006 "sub{l}\t{%2, %0|%0, %2}"
7007 [(set_attr "type" "alu")
7008 (set_attr "mode" "SI")])
7010 (define_insn "*subsi_3_zext"
7011 [(set (reg FLAGS_REG)
7012 (compare (match_operand:SI 1 "register_operand" "0")
7013 (match_operand:SI 2 "general_operand" "rim")))
7014 (set (match_operand:DI 0 "register_operand" "=r")
7016 (minus:SI (match_dup 1)
7018 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7019 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7020 "sub{l}\t{%2, %1|%1, %2}"
7021 [(set_attr "type" "alu")
7022 (set_attr "mode" "DI")])
7024 (define_expand "subhi3"
7025 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7026 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7027 (match_operand:HI 2 "general_operand" "")))
7028 (clobber (reg:CC FLAGS_REG))])]
7029 "TARGET_HIMODE_MATH"
7030 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7032 (define_insn "*subhi_1"
7033 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7034 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7035 (match_operand:HI 2 "general_operand" "ri,rm")))
7036 (clobber (reg:CC FLAGS_REG))]
7037 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7038 "sub{w}\t{%2, %0|%0, %2}"
7039 [(set_attr "type" "alu")
7040 (set_attr "mode" "HI")])
7042 (define_insn "*subhi_2"
7043 [(set (reg FLAGS_REG)
7045 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7046 (match_operand:HI 2 "general_operand" "ri,rm"))
7048 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7049 (minus:HI (match_dup 1) (match_dup 2)))]
7050 "ix86_match_ccmode (insn, CCGOCmode)
7051 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7052 "sub{w}\t{%2, %0|%0, %2}"
7053 [(set_attr "type" "alu")
7054 (set_attr "mode" "HI")])
7056 (define_insn "*subhi_3"
7057 [(set (reg FLAGS_REG)
7058 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7059 (match_operand:HI 2 "general_operand" "ri,rm")))
7060 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7061 (minus:HI (match_dup 1) (match_dup 2)))]
7062 "ix86_match_ccmode (insn, CCmode)
7063 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7064 "sub{w}\t{%2, %0|%0, %2}"
7065 [(set_attr "type" "alu")
7066 (set_attr "mode" "HI")])
7068 (define_expand "subqi3"
7069 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7070 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7071 (match_operand:QI 2 "general_operand" "")))
7072 (clobber (reg:CC FLAGS_REG))])]
7073 "TARGET_QIMODE_MATH"
7074 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7076 (define_insn "*subqi_1"
7077 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7078 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7079 (match_operand:QI 2 "general_operand" "qn,qmn")))
7080 (clobber (reg:CC FLAGS_REG))]
7081 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7082 "sub{b}\t{%2, %0|%0, %2}"
7083 [(set_attr "type" "alu")
7084 (set_attr "mode" "QI")])
7086 (define_insn "*subqi_1_slp"
7087 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7088 (minus:QI (match_dup 0)
7089 (match_operand:QI 1 "general_operand" "qn,qmn")))
7090 (clobber (reg:CC FLAGS_REG))]
7091 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7092 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7093 "sub{b}\t{%1, %0|%0, %1}"
7094 [(set_attr "type" "alu1")
7095 (set_attr "mode" "QI")])
7097 (define_insn "*subqi_2"
7098 [(set (reg FLAGS_REG)
7100 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7101 (match_operand:QI 2 "general_operand" "qi,qm"))
7103 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7104 (minus:HI (match_dup 1) (match_dup 2)))]
7105 "ix86_match_ccmode (insn, CCGOCmode)
7106 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7107 "sub{b}\t{%2, %0|%0, %2}"
7108 [(set_attr "type" "alu")
7109 (set_attr "mode" "QI")])
7111 (define_insn "*subqi_3"
7112 [(set (reg FLAGS_REG)
7113 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7114 (match_operand:QI 2 "general_operand" "qi,qm")))
7115 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7116 (minus:HI (match_dup 1) (match_dup 2)))]
7117 "ix86_match_ccmode (insn, CCmode)
7118 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7119 "sub{b}\t{%2, %0|%0, %2}"
7120 [(set_attr "type" "alu")
7121 (set_attr "mode" "QI")])
7123 ;; The patterns that match these are at the end of this file.
7125 (define_expand "subxf3"
7126 [(set (match_operand:XF 0 "register_operand" "")
7127 (minus:XF (match_operand:XF 1 "register_operand" "")
7128 (match_operand:XF 2 "register_operand" "")))]
7132 (define_expand "subdf3"
7133 [(set (match_operand:DF 0 "register_operand" "")
7134 (minus:DF (match_operand:DF 1 "register_operand" "")
7135 (match_operand:DF 2 "nonimmediate_operand" "")))]
7136 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7139 (define_expand "subsf3"
7140 [(set (match_operand:SF 0 "register_operand" "")
7141 (minus:SF (match_operand:SF 1 "register_operand" "")
7142 (match_operand:SF 2 "nonimmediate_operand" "")))]
7143 "TARGET_80387 || TARGET_SSE_MATH"
7146 ;; Multiply instructions
7148 (define_expand "muldi3"
7149 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7150 (mult:DI (match_operand:DI 1 "register_operand" "")
7151 (match_operand:DI 2 "x86_64_general_operand" "")))
7152 (clobber (reg:CC FLAGS_REG))])]
7157 ;; IMUL reg64, reg64, imm8 Direct
7158 ;; IMUL reg64, mem64, imm8 VectorPath
7159 ;; IMUL reg64, reg64, imm32 Direct
7160 ;; IMUL reg64, mem64, imm32 VectorPath
7161 ;; IMUL reg64, reg64 Direct
7162 ;; IMUL reg64, mem64 Direct
7164 (define_insn "*muldi3_1_rex64"
7165 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7166 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7167 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7168 (clobber (reg:CC FLAGS_REG))]
7170 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7172 imul{q}\t{%2, %1, %0|%0, %1, %2}
7173 imul{q}\t{%2, %1, %0|%0, %1, %2}
7174 imul{q}\t{%2, %0|%0, %2}"
7175 [(set_attr "type" "imul")
7176 (set_attr "prefix_0f" "0,0,1")
7177 (set (attr "athlon_decode")
7178 (cond [(eq_attr "cpu" "athlon")
7179 (const_string "vector")
7180 (eq_attr "alternative" "1")
7181 (const_string "vector")
7182 (and (eq_attr "alternative" "2")
7183 (match_operand 1 "memory_operand" ""))
7184 (const_string "vector")]
7185 (const_string "direct")))
7186 (set (attr "amdfam10_decode")
7187 (cond [(and (eq_attr "alternative" "0,1")
7188 (match_operand 1 "memory_operand" ""))
7189 (const_string "vector")]
7190 (const_string "direct")))
7191 (set_attr "mode" "DI")])
7193 (define_expand "mulsi3"
7194 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7195 (mult:SI (match_operand:SI 1 "register_operand" "")
7196 (match_operand:SI 2 "general_operand" "")))
7197 (clobber (reg:CC FLAGS_REG))])]
7202 ;; IMUL reg32, reg32, imm8 Direct
7203 ;; IMUL reg32, mem32, imm8 VectorPath
7204 ;; IMUL reg32, reg32, imm32 Direct
7205 ;; IMUL reg32, mem32, imm32 VectorPath
7206 ;; IMUL reg32, reg32 Direct
7207 ;; IMUL reg32, mem32 Direct
7209 (define_insn "*mulsi3_1"
7210 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7211 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7212 (match_operand:SI 2 "general_operand" "K,i,mr")))
7213 (clobber (reg:CC FLAGS_REG))]
7214 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7216 imul{l}\t{%2, %1, %0|%0, %1, %2}
7217 imul{l}\t{%2, %1, %0|%0, %1, %2}
7218 imul{l}\t{%2, %0|%0, %2}"
7219 [(set_attr "type" "imul")
7220 (set_attr "prefix_0f" "0,0,1")
7221 (set (attr "athlon_decode")
7222 (cond [(eq_attr "cpu" "athlon")
7223 (const_string "vector")
7224 (eq_attr "alternative" "1")
7225 (const_string "vector")
7226 (and (eq_attr "alternative" "2")
7227 (match_operand 1 "memory_operand" ""))
7228 (const_string "vector")]
7229 (const_string "direct")))
7230 (set (attr "amdfam10_decode")
7231 (cond [(and (eq_attr "alternative" "0,1")
7232 (match_operand 1 "memory_operand" ""))
7233 (const_string "vector")]
7234 (const_string "direct")))
7235 (set_attr "mode" "SI")])
7237 (define_insn "*mulsi3_1_zext"
7238 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7240 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7241 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7242 (clobber (reg:CC FLAGS_REG))]
7244 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7246 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7247 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7248 imul{l}\t{%2, %k0|%k0, %2}"
7249 [(set_attr "type" "imul")
7250 (set_attr "prefix_0f" "0,0,1")
7251 (set (attr "athlon_decode")
7252 (cond [(eq_attr "cpu" "athlon")
7253 (const_string "vector")
7254 (eq_attr "alternative" "1")
7255 (const_string "vector")
7256 (and (eq_attr "alternative" "2")
7257 (match_operand 1 "memory_operand" ""))
7258 (const_string "vector")]
7259 (const_string "direct")))
7260 (set (attr "amdfam10_decode")
7261 (cond [(and (eq_attr "alternative" "0,1")
7262 (match_operand 1 "memory_operand" ""))
7263 (const_string "vector")]
7264 (const_string "direct")))
7265 (set_attr "mode" "SI")])
7267 (define_expand "mulhi3"
7268 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7269 (mult:HI (match_operand:HI 1 "register_operand" "")
7270 (match_operand:HI 2 "general_operand" "")))
7271 (clobber (reg:CC FLAGS_REG))])]
7272 "TARGET_HIMODE_MATH"
7276 ;; IMUL reg16, reg16, imm8 VectorPath
7277 ;; IMUL reg16, mem16, imm8 VectorPath
7278 ;; IMUL reg16, reg16, imm16 VectorPath
7279 ;; IMUL reg16, mem16, imm16 VectorPath
7280 ;; IMUL reg16, reg16 Direct
7281 ;; IMUL reg16, mem16 Direct
7282 (define_insn "*mulhi3_1"
7283 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7284 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7285 (match_operand:HI 2 "general_operand" "K,i,mr")))
7286 (clobber (reg:CC FLAGS_REG))]
7287 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7289 imul{w}\t{%2, %1, %0|%0, %1, %2}
7290 imul{w}\t{%2, %1, %0|%0, %1, %2}
7291 imul{w}\t{%2, %0|%0, %2}"
7292 [(set_attr "type" "imul")
7293 (set_attr "prefix_0f" "0,0,1")
7294 (set (attr "athlon_decode")
7295 (cond [(eq_attr "cpu" "athlon")
7296 (const_string "vector")
7297 (eq_attr "alternative" "1,2")
7298 (const_string "vector")]
7299 (const_string "direct")))
7300 (set (attr "amdfam10_decode")
7301 (cond [(eq_attr "alternative" "0,1")
7302 (const_string "vector")]
7303 (const_string "direct")))
7304 (set_attr "mode" "HI")])
7306 (define_expand "mulqi3"
7307 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7308 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7309 (match_operand:QI 2 "register_operand" "")))
7310 (clobber (reg:CC FLAGS_REG))])]
7311 "TARGET_QIMODE_MATH"
7318 (define_insn "*mulqi3_1"
7319 [(set (match_operand:QI 0 "register_operand" "=a")
7320 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7321 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7322 (clobber (reg:CC FLAGS_REG))]
7324 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7326 [(set_attr "type" "imul")
7327 (set_attr "length_immediate" "0")
7328 (set (attr "athlon_decode")
7329 (if_then_else (eq_attr "cpu" "athlon")
7330 (const_string "vector")
7331 (const_string "direct")))
7332 (set_attr "amdfam10_decode" "direct")
7333 (set_attr "mode" "QI")])
7335 (define_expand "umulqihi3"
7336 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7337 (mult:HI (zero_extend:HI
7338 (match_operand:QI 1 "nonimmediate_operand" ""))
7340 (match_operand:QI 2 "register_operand" ""))))
7341 (clobber (reg:CC FLAGS_REG))])]
7342 "TARGET_QIMODE_MATH"
7345 (define_insn "*umulqihi3_1"
7346 [(set (match_operand:HI 0 "register_operand" "=a")
7347 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7348 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7349 (clobber (reg:CC FLAGS_REG))]
7351 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7353 [(set_attr "type" "imul")
7354 (set_attr "length_immediate" "0")
7355 (set (attr "athlon_decode")
7356 (if_then_else (eq_attr "cpu" "athlon")
7357 (const_string "vector")
7358 (const_string "direct")))
7359 (set_attr "amdfam10_decode" "direct")
7360 (set_attr "mode" "QI")])
7362 (define_expand "mulqihi3"
7363 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7364 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7365 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7366 (clobber (reg:CC FLAGS_REG))])]
7367 "TARGET_QIMODE_MATH"
7370 (define_insn "*mulqihi3_insn"
7371 [(set (match_operand:HI 0 "register_operand" "=a")
7372 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7373 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7374 (clobber (reg:CC FLAGS_REG))]
7376 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7378 [(set_attr "type" "imul")
7379 (set_attr "length_immediate" "0")
7380 (set (attr "athlon_decode")
7381 (if_then_else (eq_attr "cpu" "athlon")
7382 (const_string "vector")
7383 (const_string "direct")))
7384 (set_attr "amdfam10_decode" "direct")
7385 (set_attr "mode" "QI")])
7387 (define_expand "umulditi3"
7388 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7389 (mult:TI (zero_extend:TI
7390 (match_operand:DI 1 "nonimmediate_operand" ""))
7392 (match_operand:DI 2 "register_operand" ""))))
7393 (clobber (reg:CC FLAGS_REG))])]
7397 (define_insn "*umulditi3_insn"
7398 [(set (match_operand:TI 0 "register_operand" "=A")
7399 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7400 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7401 (clobber (reg:CC FLAGS_REG))]
7403 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7405 [(set_attr "type" "imul")
7406 (set_attr "length_immediate" "0")
7407 (set (attr "athlon_decode")
7408 (if_then_else (eq_attr "cpu" "athlon")
7409 (const_string "vector")
7410 (const_string "double")))
7411 (set_attr "amdfam10_decode" "double")
7412 (set_attr "mode" "DI")])
7414 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7415 (define_expand "umulsidi3"
7416 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7417 (mult:DI (zero_extend:DI
7418 (match_operand:SI 1 "nonimmediate_operand" ""))
7420 (match_operand:SI 2 "register_operand" ""))))
7421 (clobber (reg:CC FLAGS_REG))])]
7425 (define_insn "*umulsidi3_insn"
7426 [(set (match_operand:DI 0 "register_operand" "=A")
7427 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7428 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7429 (clobber (reg:CC FLAGS_REG))]
7431 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7433 [(set_attr "type" "imul")
7434 (set_attr "length_immediate" "0")
7435 (set (attr "athlon_decode")
7436 (if_then_else (eq_attr "cpu" "athlon")
7437 (const_string "vector")
7438 (const_string "double")))
7439 (set_attr "amdfam10_decode" "double")
7440 (set_attr "mode" "SI")])
7442 (define_expand "mulditi3"
7443 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7444 (mult:TI (sign_extend:TI
7445 (match_operand:DI 1 "nonimmediate_operand" ""))
7447 (match_operand:DI 2 "register_operand" ""))))
7448 (clobber (reg:CC FLAGS_REG))])]
7452 (define_insn "*mulditi3_insn"
7453 [(set (match_operand:TI 0 "register_operand" "=A")
7454 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7455 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7456 (clobber (reg:CC FLAGS_REG))]
7458 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7460 [(set_attr "type" "imul")
7461 (set_attr "length_immediate" "0")
7462 (set (attr "athlon_decode")
7463 (if_then_else (eq_attr "cpu" "athlon")
7464 (const_string "vector")
7465 (const_string "double")))
7466 (set_attr "amdfam10_decode" "double")
7467 (set_attr "mode" "DI")])
7469 (define_expand "mulsidi3"
7470 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7471 (mult:DI (sign_extend:DI
7472 (match_operand:SI 1 "nonimmediate_operand" ""))
7474 (match_operand:SI 2 "register_operand" ""))))
7475 (clobber (reg:CC FLAGS_REG))])]
7479 (define_insn "*mulsidi3_insn"
7480 [(set (match_operand:DI 0 "register_operand" "=A")
7481 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7482 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7483 (clobber (reg:CC FLAGS_REG))]
7485 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7487 [(set_attr "type" "imul")
7488 (set_attr "length_immediate" "0")
7489 (set (attr "athlon_decode")
7490 (if_then_else (eq_attr "cpu" "athlon")
7491 (const_string "vector")
7492 (const_string "double")))
7493 (set_attr "amdfam10_decode" "double")
7494 (set_attr "mode" "SI")])
7496 (define_expand "umuldi3_highpart"
7497 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7500 (mult:TI (zero_extend:TI
7501 (match_operand:DI 1 "nonimmediate_operand" ""))
7503 (match_operand:DI 2 "register_operand" "")))
7505 (clobber (match_scratch:DI 3 ""))
7506 (clobber (reg:CC FLAGS_REG))])]
7510 (define_insn "*umuldi3_highpart_rex64"
7511 [(set (match_operand:DI 0 "register_operand" "=d")
7514 (mult:TI (zero_extend:TI
7515 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7517 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7519 (clobber (match_scratch:DI 3 "=1"))
7520 (clobber (reg:CC FLAGS_REG))]
7522 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7524 [(set_attr "type" "imul")
7525 (set_attr "length_immediate" "0")
7526 (set (attr "athlon_decode")
7527 (if_then_else (eq_attr "cpu" "athlon")
7528 (const_string "vector")
7529 (const_string "double")))
7530 (set_attr "amdfam10_decode" "double")
7531 (set_attr "mode" "DI")])
7533 (define_expand "umulsi3_highpart"
7534 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7537 (mult:DI (zero_extend:DI
7538 (match_operand:SI 1 "nonimmediate_operand" ""))
7540 (match_operand:SI 2 "register_operand" "")))
7542 (clobber (match_scratch:SI 3 ""))
7543 (clobber (reg:CC FLAGS_REG))])]
7547 (define_insn "*umulsi3_highpart_insn"
7548 [(set (match_operand:SI 0 "register_operand" "=d")
7551 (mult:DI (zero_extend:DI
7552 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7554 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7556 (clobber (match_scratch:SI 3 "=1"))
7557 (clobber (reg:CC FLAGS_REG))]
7558 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7560 [(set_attr "type" "imul")
7561 (set_attr "length_immediate" "0")
7562 (set (attr "athlon_decode")
7563 (if_then_else (eq_attr "cpu" "athlon")
7564 (const_string "vector")
7565 (const_string "double")))
7566 (set_attr "amdfam10_decode" "double")
7567 (set_attr "mode" "SI")])
7569 (define_insn "*umulsi3_highpart_zext"
7570 [(set (match_operand:DI 0 "register_operand" "=d")
7571 (zero_extend:DI (truncate:SI
7573 (mult:DI (zero_extend:DI
7574 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7576 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7578 (clobber (match_scratch:SI 3 "=1"))
7579 (clobber (reg:CC FLAGS_REG))]
7581 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7583 [(set_attr "type" "imul")
7584 (set_attr "length_immediate" "0")
7585 (set (attr "athlon_decode")
7586 (if_then_else (eq_attr "cpu" "athlon")
7587 (const_string "vector")
7588 (const_string "double")))
7589 (set_attr "amdfam10_decode" "double")
7590 (set_attr "mode" "SI")])
7592 (define_expand "smuldi3_highpart"
7593 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7596 (mult:TI (sign_extend:TI
7597 (match_operand:DI 1 "nonimmediate_operand" ""))
7599 (match_operand:DI 2 "register_operand" "")))
7601 (clobber (match_scratch:DI 3 ""))
7602 (clobber (reg:CC FLAGS_REG))])]
7606 (define_insn "*smuldi3_highpart_rex64"
7607 [(set (match_operand:DI 0 "register_operand" "=d")
7610 (mult:TI (sign_extend:TI
7611 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7613 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7615 (clobber (match_scratch:DI 3 "=1"))
7616 (clobber (reg:CC FLAGS_REG))]
7618 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7620 [(set_attr "type" "imul")
7621 (set (attr "athlon_decode")
7622 (if_then_else (eq_attr "cpu" "athlon")
7623 (const_string "vector")
7624 (const_string "double")))
7625 (set_attr "amdfam10_decode" "double")
7626 (set_attr "mode" "DI")])
7628 (define_expand "smulsi3_highpart"
7629 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7632 (mult:DI (sign_extend:DI
7633 (match_operand:SI 1 "nonimmediate_operand" ""))
7635 (match_operand:SI 2 "register_operand" "")))
7637 (clobber (match_scratch:SI 3 ""))
7638 (clobber (reg:CC FLAGS_REG))])]
7642 (define_insn "*smulsi3_highpart_insn"
7643 [(set (match_operand:SI 0 "register_operand" "=d")
7646 (mult:DI (sign_extend:DI
7647 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7649 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7651 (clobber (match_scratch:SI 3 "=1"))
7652 (clobber (reg:CC FLAGS_REG))]
7653 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7655 [(set_attr "type" "imul")
7656 (set (attr "athlon_decode")
7657 (if_then_else (eq_attr "cpu" "athlon")
7658 (const_string "vector")
7659 (const_string "double")))
7660 (set_attr "amdfam10_decode" "double")
7661 (set_attr "mode" "SI")])
7663 (define_insn "*smulsi3_highpart_zext"
7664 [(set (match_operand:DI 0 "register_operand" "=d")
7665 (zero_extend:DI (truncate:SI
7667 (mult:DI (sign_extend:DI
7668 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7670 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7672 (clobber (match_scratch:SI 3 "=1"))
7673 (clobber (reg:CC FLAGS_REG))]
7675 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7677 [(set_attr "type" "imul")
7678 (set (attr "athlon_decode")
7679 (if_then_else (eq_attr "cpu" "athlon")
7680 (const_string "vector")
7681 (const_string "double")))
7682 (set_attr "amdfam10_decode" "double")
7683 (set_attr "mode" "SI")])
7685 ;; The patterns that match these are at the end of this file.
7687 (define_expand "mulxf3"
7688 [(set (match_operand:XF 0 "register_operand" "")
7689 (mult:XF (match_operand:XF 1 "register_operand" "")
7690 (match_operand:XF 2 "register_operand" "")))]
7694 (define_expand "muldf3"
7695 [(set (match_operand:DF 0 "register_operand" "")
7696 (mult:DF (match_operand:DF 1 "register_operand" "")
7697 (match_operand:DF 2 "nonimmediate_operand" "")))]
7698 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7701 (define_expand "mulsf3"
7702 [(set (match_operand:SF 0 "register_operand" "")
7703 (mult:SF (match_operand:SF 1 "register_operand" "")
7704 (match_operand:SF 2 "nonimmediate_operand" "")))]
7705 "TARGET_80387 || TARGET_SSE_MATH"
7708 ;; Divide instructions
7710 (define_insn "divqi3"
7711 [(set (match_operand:QI 0 "register_operand" "=a")
7712 (div:QI (match_operand:HI 1 "register_operand" "0")
7713 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7714 (clobber (reg:CC FLAGS_REG))]
7715 "TARGET_QIMODE_MATH"
7717 [(set_attr "type" "idiv")
7718 (set_attr "mode" "QI")])
7720 (define_insn "udivqi3"
7721 [(set (match_operand:QI 0 "register_operand" "=a")
7722 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7723 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7724 (clobber (reg:CC FLAGS_REG))]
7725 "TARGET_QIMODE_MATH"
7727 [(set_attr "type" "idiv")
7728 (set_attr "mode" "QI")])
7730 ;; The patterns that match these are at the end of this file.
7732 (define_expand "divxf3"
7733 [(set (match_operand:XF 0 "register_operand" "")
7734 (div:XF (match_operand:XF 1 "register_operand" "")
7735 (match_operand:XF 2 "register_operand" "")))]
7739 (define_expand "divdf3"
7740 [(set (match_operand:DF 0 "register_operand" "")
7741 (div:DF (match_operand:DF 1 "register_operand" "")
7742 (match_operand:DF 2 "nonimmediate_operand" "")))]
7743 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7746 (define_expand "divsf3"
7747 [(set (match_operand:SF 0 "register_operand" "")
7748 (div:SF (match_operand:SF 1 "register_operand" "")
7749 (match_operand:SF 2 "nonimmediate_operand" "")))]
7750 "TARGET_80387 || TARGET_SSE_MATH"
7753 ;; Remainder instructions.
7755 (define_expand "divmoddi4"
7756 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7757 (div:DI (match_operand:DI 1 "register_operand" "")
7758 (match_operand:DI 2 "nonimmediate_operand" "")))
7759 (set (match_operand:DI 3 "register_operand" "")
7760 (mod:DI (match_dup 1) (match_dup 2)))
7761 (clobber (reg:CC FLAGS_REG))])]
7765 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7766 ;; Penalize eax case slightly because it results in worse scheduling
7768 (define_insn "*divmoddi4_nocltd_rex64"
7769 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7770 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7771 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7772 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7773 (mod:DI (match_dup 2) (match_dup 3)))
7774 (clobber (reg:CC FLAGS_REG))]
7775 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7777 [(set_attr "type" "multi")])
7779 (define_insn "*divmoddi4_cltd_rex64"
7780 [(set (match_operand:DI 0 "register_operand" "=a")
7781 (div:DI (match_operand:DI 2 "register_operand" "a")
7782 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7783 (set (match_operand:DI 1 "register_operand" "=&d")
7784 (mod:DI (match_dup 2) (match_dup 3)))
7785 (clobber (reg:CC FLAGS_REG))]
7786 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7788 [(set_attr "type" "multi")])
7790 (define_insn "*divmoddi_noext_rex64"
7791 [(set (match_operand:DI 0 "register_operand" "=a")
7792 (div:DI (match_operand:DI 1 "register_operand" "0")
7793 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7794 (set (match_operand:DI 3 "register_operand" "=d")
7795 (mod:DI (match_dup 1) (match_dup 2)))
7796 (use (match_operand:DI 4 "register_operand" "3"))
7797 (clobber (reg:CC FLAGS_REG))]
7800 [(set_attr "type" "idiv")
7801 (set_attr "mode" "DI")])
7804 [(set (match_operand:DI 0 "register_operand" "")
7805 (div:DI (match_operand:DI 1 "register_operand" "")
7806 (match_operand:DI 2 "nonimmediate_operand" "")))
7807 (set (match_operand:DI 3 "register_operand" "")
7808 (mod:DI (match_dup 1) (match_dup 2)))
7809 (clobber (reg:CC FLAGS_REG))]
7810 "TARGET_64BIT && reload_completed"
7811 [(parallel [(set (match_dup 3)
7812 (ashiftrt:DI (match_dup 4) (const_int 63)))
7813 (clobber (reg:CC FLAGS_REG))])
7814 (parallel [(set (match_dup 0)
7815 (div:DI (reg:DI 0) (match_dup 2)))
7817 (mod:DI (reg:DI 0) (match_dup 2)))
7819 (clobber (reg:CC FLAGS_REG))])]
7821 /* Avoid use of cltd in favor of a mov+shift. */
7822 if (!TARGET_USE_CLTD && !optimize_size)
7824 if (true_regnum (operands[1]))
7825 emit_move_insn (operands[0], operands[1]);
7827 emit_move_insn (operands[3], operands[1]);
7828 operands[4] = operands[3];
7832 gcc_assert (!true_regnum (operands[1]));
7833 operands[4] = operands[1];
7838 (define_expand "divmodsi4"
7839 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7840 (div:SI (match_operand:SI 1 "register_operand" "")
7841 (match_operand:SI 2 "nonimmediate_operand" "")))
7842 (set (match_operand:SI 3 "register_operand" "")
7843 (mod:SI (match_dup 1) (match_dup 2)))
7844 (clobber (reg:CC FLAGS_REG))])]
7848 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7849 ;; Penalize eax case slightly because it results in worse scheduling
7851 (define_insn "*divmodsi4_nocltd"
7852 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7853 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7854 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7855 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7856 (mod:SI (match_dup 2) (match_dup 3)))
7857 (clobber (reg:CC FLAGS_REG))]
7858 "!optimize_size && !TARGET_USE_CLTD"
7860 [(set_attr "type" "multi")])
7862 (define_insn "*divmodsi4_cltd"
7863 [(set (match_operand:SI 0 "register_operand" "=a")
7864 (div:SI (match_operand:SI 2 "register_operand" "a")
7865 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7866 (set (match_operand:SI 1 "register_operand" "=&d")
7867 (mod:SI (match_dup 2) (match_dup 3)))
7868 (clobber (reg:CC FLAGS_REG))]
7869 "optimize_size || TARGET_USE_CLTD"
7871 [(set_attr "type" "multi")])
7873 (define_insn "*divmodsi_noext"
7874 [(set (match_operand:SI 0 "register_operand" "=a")
7875 (div:SI (match_operand:SI 1 "register_operand" "0")
7876 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7877 (set (match_operand:SI 3 "register_operand" "=d")
7878 (mod:SI (match_dup 1) (match_dup 2)))
7879 (use (match_operand:SI 4 "register_operand" "3"))
7880 (clobber (reg:CC FLAGS_REG))]
7883 [(set_attr "type" "idiv")
7884 (set_attr "mode" "SI")])
7887 [(set (match_operand:SI 0 "register_operand" "")
7888 (div:SI (match_operand:SI 1 "register_operand" "")
7889 (match_operand:SI 2 "nonimmediate_operand" "")))
7890 (set (match_operand:SI 3 "register_operand" "")
7891 (mod:SI (match_dup 1) (match_dup 2)))
7892 (clobber (reg:CC FLAGS_REG))]
7894 [(parallel [(set (match_dup 3)
7895 (ashiftrt:SI (match_dup 4) (const_int 31)))
7896 (clobber (reg:CC FLAGS_REG))])
7897 (parallel [(set (match_dup 0)
7898 (div:SI (reg:SI 0) (match_dup 2)))
7900 (mod:SI (reg:SI 0) (match_dup 2)))
7902 (clobber (reg:CC FLAGS_REG))])]
7904 /* Avoid use of cltd in favor of a mov+shift. */
7905 if (!TARGET_USE_CLTD && !optimize_size)
7907 if (true_regnum (operands[1]))
7908 emit_move_insn (operands[0], operands[1]);
7910 emit_move_insn (operands[3], operands[1]);
7911 operands[4] = operands[3];
7915 gcc_assert (!true_regnum (operands[1]));
7916 operands[4] = operands[1];
7920 (define_insn "divmodhi4"
7921 [(set (match_operand:HI 0 "register_operand" "=a")
7922 (div:HI (match_operand:HI 1 "register_operand" "0")
7923 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7924 (set (match_operand:HI 3 "register_operand" "=&d")
7925 (mod:HI (match_dup 1) (match_dup 2)))
7926 (clobber (reg:CC FLAGS_REG))]
7927 "TARGET_HIMODE_MATH"
7929 [(set_attr "type" "multi")
7930 (set_attr "length_immediate" "0")
7931 (set_attr "mode" "SI")])
7933 (define_insn "udivmoddi4"
7934 [(set (match_operand:DI 0 "register_operand" "=a")
7935 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7936 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7937 (set (match_operand:DI 3 "register_operand" "=&d")
7938 (umod:DI (match_dup 1) (match_dup 2)))
7939 (clobber (reg:CC FLAGS_REG))]
7941 "xor{q}\t%3, %3\;div{q}\t%2"
7942 [(set_attr "type" "multi")
7943 (set_attr "length_immediate" "0")
7944 (set_attr "mode" "DI")])
7946 (define_insn "*udivmoddi4_noext"
7947 [(set (match_operand:DI 0 "register_operand" "=a")
7948 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7949 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7950 (set (match_operand:DI 3 "register_operand" "=d")
7951 (umod:DI (match_dup 1) (match_dup 2)))
7953 (clobber (reg:CC FLAGS_REG))]
7956 [(set_attr "type" "idiv")
7957 (set_attr "mode" "DI")])
7960 [(set (match_operand:DI 0 "register_operand" "")
7961 (udiv:DI (match_operand:DI 1 "register_operand" "")
7962 (match_operand:DI 2 "nonimmediate_operand" "")))
7963 (set (match_operand:DI 3 "register_operand" "")
7964 (umod:DI (match_dup 1) (match_dup 2)))
7965 (clobber (reg:CC FLAGS_REG))]
7966 "TARGET_64BIT && reload_completed"
7967 [(set (match_dup 3) (const_int 0))
7968 (parallel [(set (match_dup 0)
7969 (udiv:DI (match_dup 1) (match_dup 2)))
7971 (umod:DI (match_dup 1) (match_dup 2)))
7973 (clobber (reg:CC FLAGS_REG))])]
7976 (define_insn "udivmodsi4"
7977 [(set (match_operand:SI 0 "register_operand" "=a")
7978 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7979 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7980 (set (match_operand:SI 3 "register_operand" "=&d")
7981 (umod:SI (match_dup 1) (match_dup 2)))
7982 (clobber (reg:CC FLAGS_REG))]
7984 "xor{l}\t%3, %3\;div{l}\t%2"
7985 [(set_attr "type" "multi")
7986 (set_attr "length_immediate" "0")
7987 (set_attr "mode" "SI")])
7989 (define_insn "*udivmodsi4_noext"
7990 [(set (match_operand:SI 0 "register_operand" "=a")
7991 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7992 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7993 (set (match_operand:SI 3 "register_operand" "=d")
7994 (umod:SI (match_dup 1) (match_dup 2)))
7996 (clobber (reg:CC FLAGS_REG))]
7999 [(set_attr "type" "idiv")
8000 (set_attr "mode" "SI")])
8003 [(set (match_operand:SI 0 "register_operand" "")
8004 (udiv:SI (match_operand:SI 1 "register_operand" "")
8005 (match_operand:SI 2 "nonimmediate_operand" "")))
8006 (set (match_operand:SI 3 "register_operand" "")
8007 (umod:SI (match_dup 1) (match_dup 2)))
8008 (clobber (reg:CC FLAGS_REG))]
8010 [(set (match_dup 3) (const_int 0))
8011 (parallel [(set (match_dup 0)
8012 (udiv:SI (match_dup 1) (match_dup 2)))
8014 (umod:SI (match_dup 1) (match_dup 2)))
8016 (clobber (reg:CC FLAGS_REG))])]
8019 (define_expand "udivmodhi4"
8020 [(set (match_dup 4) (const_int 0))
8021 (parallel [(set (match_operand:HI 0 "register_operand" "")
8022 (udiv:HI (match_operand:HI 1 "register_operand" "")
8023 (match_operand:HI 2 "nonimmediate_operand" "")))
8024 (set (match_operand:HI 3 "register_operand" "")
8025 (umod:HI (match_dup 1) (match_dup 2)))
8027 (clobber (reg:CC FLAGS_REG))])]
8028 "TARGET_HIMODE_MATH"
8029 "operands[4] = gen_reg_rtx (HImode);")
8031 (define_insn "*udivmodhi_noext"
8032 [(set (match_operand:HI 0 "register_operand" "=a")
8033 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8034 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8035 (set (match_operand:HI 3 "register_operand" "=d")
8036 (umod:HI (match_dup 1) (match_dup 2)))
8037 (use (match_operand:HI 4 "register_operand" "3"))
8038 (clobber (reg:CC FLAGS_REG))]
8041 [(set_attr "type" "idiv")
8042 (set_attr "mode" "HI")])
8044 ;; We cannot use div/idiv for double division, because it causes
8045 ;; "division by zero" on the overflow and that's not what we expect
8046 ;; from truncate. Because true (non truncating) double division is
8047 ;; never generated, we can't create this insn anyway.
8050 ; [(set (match_operand:SI 0 "register_operand" "=a")
8052 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8054 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8055 ; (set (match_operand:SI 3 "register_operand" "=d")
8057 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8058 ; (clobber (reg:CC FLAGS_REG))]
8060 ; "div{l}\t{%2, %0|%0, %2}"
8061 ; [(set_attr "type" "idiv")])
8063 ;;- Logical AND instructions
8065 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8066 ;; Note that this excludes ah.
8068 (define_insn "*testdi_1_rex64"
8069 [(set (reg FLAGS_REG)
8071 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8072 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8074 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8075 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8077 test{l}\t{%k1, %k0|%k0, %k1}
8078 test{l}\t{%k1, %k0|%k0, %k1}
8079 test{q}\t{%1, %0|%0, %1}
8080 test{q}\t{%1, %0|%0, %1}
8081 test{q}\t{%1, %0|%0, %1}"
8082 [(set_attr "type" "test")
8083 (set_attr "modrm" "0,1,0,1,1")
8084 (set_attr "mode" "SI,SI,DI,DI,DI")
8085 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8087 (define_insn "testsi_1"
8088 [(set (reg FLAGS_REG)
8090 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8091 (match_operand:SI 1 "general_operand" "in,in,rin"))
8093 "ix86_match_ccmode (insn, CCNOmode)
8094 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8095 "test{l}\t{%1, %0|%0, %1}"
8096 [(set_attr "type" "test")
8097 (set_attr "modrm" "0,1,1")
8098 (set_attr "mode" "SI")
8099 (set_attr "pent_pair" "uv,np,uv")])
8101 (define_expand "testsi_ccno_1"
8102 [(set (reg:CCNO FLAGS_REG)
8104 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8105 (match_operand:SI 1 "nonmemory_operand" ""))
8110 (define_insn "*testhi_1"
8111 [(set (reg FLAGS_REG)
8112 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8113 (match_operand:HI 1 "general_operand" "n,n,rn"))
8115 "ix86_match_ccmode (insn, CCNOmode)
8116 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8117 "test{w}\t{%1, %0|%0, %1}"
8118 [(set_attr "type" "test")
8119 (set_attr "modrm" "0,1,1")
8120 (set_attr "mode" "HI")
8121 (set_attr "pent_pair" "uv,np,uv")])
8123 (define_expand "testqi_ccz_1"
8124 [(set (reg:CCZ FLAGS_REG)
8125 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8126 (match_operand:QI 1 "nonmemory_operand" ""))
8131 (define_insn "*testqi_1_maybe_si"
8132 [(set (reg FLAGS_REG)
8135 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8136 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8138 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8139 && ix86_match_ccmode (insn,
8140 CONST_INT_P (operands[1])
8141 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8143 if (which_alternative == 3)
8145 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8146 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8147 return "test{l}\t{%1, %k0|%k0, %1}";
8149 return "test{b}\t{%1, %0|%0, %1}";
8151 [(set_attr "type" "test")
8152 (set_attr "modrm" "0,1,1,1")
8153 (set_attr "mode" "QI,QI,QI,SI")
8154 (set_attr "pent_pair" "uv,np,uv,np")])
8156 (define_insn "*testqi_1"
8157 [(set (reg FLAGS_REG)
8160 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8161 (match_operand:QI 1 "general_operand" "n,n,qn"))
8163 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8164 && ix86_match_ccmode (insn, CCNOmode)"
8165 "test{b}\t{%1, %0|%0, %1}"
8166 [(set_attr "type" "test")
8167 (set_attr "modrm" "0,1,1")
8168 (set_attr "mode" "QI")
8169 (set_attr "pent_pair" "uv,np,uv")])
8171 (define_expand "testqi_ext_ccno_0"
8172 [(set (reg:CCNO FLAGS_REG)
8176 (match_operand 0 "ext_register_operand" "")
8179 (match_operand 1 "const_int_operand" ""))
8184 (define_insn "*testqi_ext_0"
8185 [(set (reg FLAGS_REG)
8189 (match_operand 0 "ext_register_operand" "Q")
8192 (match_operand 1 "const_int_operand" "n"))
8194 "ix86_match_ccmode (insn, CCNOmode)"
8195 "test{b}\t{%1, %h0|%h0, %1}"
8196 [(set_attr "type" "test")
8197 (set_attr "mode" "QI")
8198 (set_attr "length_immediate" "1")
8199 (set_attr "pent_pair" "np")])
8201 (define_insn "*testqi_ext_1"
8202 [(set (reg FLAGS_REG)
8206 (match_operand 0 "ext_register_operand" "Q")
8210 (match_operand:QI 1 "general_operand" "Qm")))
8212 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8213 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8214 "test{b}\t{%1, %h0|%h0, %1}"
8215 [(set_attr "type" "test")
8216 (set_attr "mode" "QI")])
8218 (define_insn "*testqi_ext_1_rex64"
8219 [(set (reg FLAGS_REG)
8223 (match_operand 0 "ext_register_operand" "Q")
8227 (match_operand:QI 1 "register_operand" "Q")))
8229 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8230 "test{b}\t{%1, %h0|%h0, %1}"
8231 [(set_attr "type" "test")
8232 (set_attr "mode" "QI")])
8234 (define_insn "*testqi_ext_2"
8235 [(set (reg FLAGS_REG)
8239 (match_operand 0 "ext_register_operand" "Q")
8243 (match_operand 1 "ext_register_operand" "Q")
8247 "ix86_match_ccmode (insn, CCNOmode)"
8248 "test{b}\t{%h1, %h0|%h0, %h1}"
8249 [(set_attr "type" "test")
8250 (set_attr "mode" "QI")])
8252 ;; Combine likes to form bit extractions for some tests. Humor it.
8253 (define_insn "*testqi_ext_3"
8254 [(set (reg FLAGS_REG)
8255 (compare (zero_extract:SI
8256 (match_operand 0 "nonimmediate_operand" "rm")
8257 (match_operand:SI 1 "const_int_operand" "")
8258 (match_operand:SI 2 "const_int_operand" ""))
8260 "ix86_match_ccmode (insn, CCNOmode)
8261 && INTVAL (operands[1]) > 0
8262 && INTVAL (operands[2]) >= 0
8263 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8264 && (GET_MODE (operands[0]) == SImode
8265 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8266 || GET_MODE (operands[0]) == HImode
8267 || GET_MODE (operands[0]) == QImode)"
8270 (define_insn "*testqi_ext_3_rex64"
8271 [(set (reg FLAGS_REG)
8272 (compare (zero_extract:DI
8273 (match_operand 0 "nonimmediate_operand" "rm")
8274 (match_operand:DI 1 "const_int_operand" "")
8275 (match_operand:DI 2 "const_int_operand" ""))
8278 && ix86_match_ccmode (insn, CCNOmode)
8279 && INTVAL (operands[1]) > 0
8280 && INTVAL (operands[2]) >= 0
8281 /* Ensure that resulting mask is zero or sign extended operand. */
8282 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8283 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8284 && INTVAL (operands[1]) > 32))
8285 && (GET_MODE (operands[0]) == SImode
8286 || GET_MODE (operands[0]) == DImode
8287 || GET_MODE (operands[0]) == HImode
8288 || GET_MODE (operands[0]) == QImode)"
8292 [(set (match_operand 0 "flags_reg_operand" "")
8293 (match_operator 1 "compare_operator"
8295 (match_operand 2 "nonimmediate_operand" "")
8296 (match_operand 3 "const_int_operand" "")
8297 (match_operand 4 "const_int_operand" ""))
8299 "ix86_match_ccmode (insn, CCNOmode)"
8300 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8302 rtx val = operands[2];
8303 HOST_WIDE_INT len = INTVAL (operands[3]);
8304 HOST_WIDE_INT pos = INTVAL (operands[4]);
8306 enum machine_mode mode, submode;
8308 mode = GET_MODE (val);
8311 /* ??? Combine likes to put non-volatile mem extractions in QImode
8312 no matter the size of the test. So find a mode that works. */
8313 if (! MEM_VOLATILE_P (val))
8315 mode = smallest_mode_for_size (pos + len, MODE_INT);
8316 val = adjust_address (val, mode, 0);
8319 else if (GET_CODE (val) == SUBREG
8320 && (submode = GET_MODE (SUBREG_REG (val)),
8321 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8322 && pos + len <= GET_MODE_BITSIZE (submode))
8324 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8326 val = SUBREG_REG (val);
8328 else if (mode == HImode && pos + len <= 8)
8330 /* Small HImode tests can be converted to QImode. */
8332 val = gen_lowpart (QImode, val);
8335 if (len == HOST_BITS_PER_WIDE_INT)
8338 mask = ((HOST_WIDE_INT)1 << len) - 1;
8341 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8344 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8345 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8346 ;; this is relatively important trick.
8347 ;; Do the conversion only post-reload to avoid limiting of the register class
8350 [(set (match_operand 0 "flags_reg_operand" "")
8351 (match_operator 1 "compare_operator"
8352 [(and (match_operand 2 "register_operand" "")
8353 (match_operand 3 "const_int_operand" ""))
8356 && QI_REG_P (operands[2])
8357 && GET_MODE (operands[2]) != QImode
8358 && ((ix86_match_ccmode (insn, CCZmode)
8359 && !(INTVAL (operands[3]) & ~(255 << 8)))
8360 || (ix86_match_ccmode (insn, CCNOmode)
8361 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8364 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8367 "operands[2] = gen_lowpart (SImode, operands[2]);
8368 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8371 [(set (match_operand 0 "flags_reg_operand" "")
8372 (match_operator 1 "compare_operator"
8373 [(and (match_operand 2 "nonimmediate_operand" "")
8374 (match_operand 3 "const_int_operand" ""))
8377 && GET_MODE (operands[2]) != QImode
8378 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8379 && ((ix86_match_ccmode (insn, CCZmode)
8380 && !(INTVAL (operands[3]) & ~255))
8381 || (ix86_match_ccmode (insn, CCNOmode)
8382 && !(INTVAL (operands[3]) & ~127)))"
8384 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8386 "operands[2] = gen_lowpart (QImode, operands[2]);
8387 operands[3] = gen_lowpart (QImode, operands[3]);")
8390 ;; %%% This used to optimize known byte-wide and operations to memory,
8391 ;; and sometimes to QImode registers. If this is considered useful,
8392 ;; it should be done with splitters.
8394 (define_expand "anddi3"
8395 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8396 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8397 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8398 (clobber (reg:CC FLAGS_REG))]
8400 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8402 (define_insn "*anddi_1_rex64"
8403 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8404 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8405 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8406 (clobber (reg:CC FLAGS_REG))]
8407 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8409 switch (get_attr_type (insn))
8413 enum machine_mode mode;
8415 gcc_assert (CONST_INT_P (operands[2]));
8416 if (INTVAL (operands[2]) == 0xff)
8420 gcc_assert (INTVAL (operands[2]) == 0xffff);
8424 operands[1] = gen_lowpart (mode, operands[1]);
8426 return "movz{bq|x}\t{%1,%0|%0, %1}";
8428 return "movz{wq|x}\t{%1,%0|%0, %1}";
8432 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8433 if (get_attr_mode (insn) == MODE_SI)
8434 return "and{l}\t{%k2, %k0|%k0, %k2}";
8436 return "and{q}\t{%2, %0|%0, %2}";
8439 [(set_attr "type" "alu,alu,alu,imovx")
8440 (set_attr "length_immediate" "*,*,*,0")
8441 (set_attr "mode" "SI,DI,DI,DI")])
8443 (define_insn "*anddi_2"
8444 [(set (reg FLAGS_REG)
8445 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8446 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8448 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8449 (and:DI (match_dup 1) (match_dup 2)))]
8450 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8451 && ix86_binary_operator_ok (AND, DImode, operands)"
8453 and{l}\t{%k2, %k0|%k0, %k2}
8454 and{q}\t{%2, %0|%0, %2}
8455 and{q}\t{%2, %0|%0, %2}"
8456 [(set_attr "type" "alu")
8457 (set_attr "mode" "SI,DI,DI")])
8459 (define_expand "andsi3"
8460 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8461 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8462 (match_operand:SI 2 "general_operand" "")))
8463 (clobber (reg:CC FLAGS_REG))]
8465 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8467 (define_insn "*andsi_1"
8468 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8469 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8470 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8471 (clobber (reg:CC FLAGS_REG))]
8472 "ix86_binary_operator_ok (AND, SImode, operands)"
8474 switch (get_attr_type (insn))
8478 enum machine_mode mode;
8480 gcc_assert (CONST_INT_P (operands[2]));
8481 if (INTVAL (operands[2]) == 0xff)
8485 gcc_assert (INTVAL (operands[2]) == 0xffff);
8489 operands[1] = gen_lowpart (mode, operands[1]);
8491 return "movz{bl|x}\t{%1,%0|%0, %1}";
8493 return "movz{wl|x}\t{%1,%0|%0, %1}";
8497 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8498 return "and{l}\t{%2, %0|%0, %2}";
8501 [(set_attr "type" "alu,alu,imovx")
8502 (set_attr "length_immediate" "*,*,0")
8503 (set_attr "mode" "SI")])
8506 [(set (match_operand 0 "register_operand" "")
8508 (const_int -65536)))
8509 (clobber (reg:CC FLAGS_REG))]
8510 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8511 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8512 "operands[1] = gen_lowpart (HImode, operands[0]);")
8515 [(set (match_operand 0 "ext_register_operand" "")
8518 (clobber (reg:CC FLAGS_REG))]
8519 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8520 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8521 "operands[1] = gen_lowpart (QImode, operands[0]);")
8524 [(set (match_operand 0 "ext_register_operand" "")
8526 (const_int -65281)))
8527 (clobber (reg:CC FLAGS_REG))]
8528 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8529 [(parallel [(set (zero_extract:SI (match_dup 0)
8533 (zero_extract:SI (match_dup 0)
8536 (zero_extract:SI (match_dup 0)
8539 (clobber (reg:CC FLAGS_REG))])]
8540 "operands[0] = gen_lowpart (SImode, operands[0]);")
8542 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8543 (define_insn "*andsi_1_zext"
8544 [(set (match_operand:DI 0 "register_operand" "=r")
8546 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8547 (match_operand:SI 2 "general_operand" "rim"))))
8548 (clobber (reg:CC FLAGS_REG))]
8549 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8550 "and{l}\t{%2, %k0|%k0, %2}"
8551 [(set_attr "type" "alu")
8552 (set_attr "mode" "SI")])
8554 (define_insn "*andsi_2"
8555 [(set (reg FLAGS_REG)
8556 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8557 (match_operand:SI 2 "general_operand" "rim,ri"))
8559 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8560 (and:SI (match_dup 1) (match_dup 2)))]
8561 "ix86_match_ccmode (insn, CCNOmode)
8562 && ix86_binary_operator_ok (AND, SImode, operands)"
8563 "and{l}\t{%2, %0|%0, %2}"
8564 [(set_attr "type" "alu")
8565 (set_attr "mode" "SI")])
8567 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8568 (define_insn "*andsi_2_zext"
8569 [(set (reg FLAGS_REG)
8570 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8571 (match_operand:SI 2 "general_operand" "rim"))
8573 (set (match_operand:DI 0 "register_operand" "=r")
8574 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8575 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8576 && ix86_binary_operator_ok (AND, SImode, operands)"
8577 "and{l}\t{%2, %k0|%k0, %2}"
8578 [(set_attr "type" "alu")
8579 (set_attr "mode" "SI")])
8581 (define_expand "andhi3"
8582 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8583 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8584 (match_operand:HI 2 "general_operand" "")))
8585 (clobber (reg:CC FLAGS_REG))]
8586 "TARGET_HIMODE_MATH"
8587 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8589 (define_insn "*andhi_1"
8590 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8591 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8592 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8593 (clobber (reg:CC FLAGS_REG))]
8594 "ix86_binary_operator_ok (AND, HImode, operands)"
8596 switch (get_attr_type (insn))
8599 gcc_assert (CONST_INT_P (operands[2]));
8600 gcc_assert (INTVAL (operands[2]) == 0xff);
8601 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8604 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8606 return "and{w}\t{%2, %0|%0, %2}";
8609 [(set_attr "type" "alu,alu,imovx")
8610 (set_attr "length_immediate" "*,*,0")
8611 (set_attr "mode" "HI,HI,SI")])
8613 (define_insn "*andhi_2"
8614 [(set (reg FLAGS_REG)
8615 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8616 (match_operand:HI 2 "general_operand" "rim,ri"))
8618 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8619 (and:HI (match_dup 1) (match_dup 2)))]
8620 "ix86_match_ccmode (insn, CCNOmode)
8621 && ix86_binary_operator_ok (AND, HImode, operands)"
8622 "and{w}\t{%2, %0|%0, %2}"
8623 [(set_attr "type" "alu")
8624 (set_attr "mode" "HI")])
8626 (define_expand "andqi3"
8627 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8628 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8629 (match_operand:QI 2 "general_operand" "")))
8630 (clobber (reg:CC FLAGS_REG))]
8631 "TARGET_QIMODE_MATH"
8632 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8634 ;; %%% Potential partial reg stall on alternative 2. What to do?
8635 (define_insn "*andqi_1"
8636 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8637 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8638 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8639 (clobber (reg:CC FLAGS_REG))]
8640 "ix86_binary_operator_ok (AND, QImode, operands)"
8642 and{b}\t{%2, %0|%0, %2}
8643 and{b}\t{%2, %0|%0, %2}
8644 and{l}\t{%k2, %k0|%k0, %k2}"
8645 [(set_attr "type" "alu")
8646 (set_attr "mode" "QI,QI,SI")])
8648 (define_insn "*andqi_1_slp"
8649 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8650 (and:QI (match_dup 0)
8651 (match_operand:QI 1 "general_operand" "qi,qmi")))
8652 (clobber (reg:CC FLAGS_REG))]
8653 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8654 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8655 "and{b}\t{%1, %0|%0, %1}"
8656 [(set_attr "type" "alu1")
8657 (set_attr "mode" "QI")])
8659 (define_insn "*andqi_2_maybe_si"
8660 [(set (reg FLAGS_REG)
8662 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8663 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8665 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8666 (and:QI (match_dup 1) (match_dup 2)))]
8667 "ix86_binary_operator_ok (AND, QImode, operands)
8668 && ix86_match_ccmode (insn,
8669 CONST_INT_P (operands[2])
8670 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8672 if (which_alternative == 2)
8674 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8675 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8676 return "and{l}\t{%2, %k0|%k0, %2}";
8678 return "and{b}\t{%2, %0|%0, %2}";
8680 [(set_attr "type" "alu")
8681 (set_attr "mode" "QI,QI,SI")])
8683 (define_insn "*andqi_2"
8684 [(set (reg FLAGS_REG)
8686 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8687 (match_operand:QI 2 "general_operand" "qim,qi"))
8689 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8690 (and:QI (match_dup 1) (match_dup 2)))]
8691 "ix86_match_ccmode (insn, CCNOmode)
8692 && ix86_binary_operator_ok (AND, QImode, operands)"
8693 "and{b}\t{%2, %0|%0, %2}"
8694 [(set_attr "type" "alu")
8695 (set_attr "mode" "QI")])
8697 (define_insn "*andqi_2_slp"
8698 [(set (reg FLAGS_REG)
8700 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8701 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8703 (set (strict_low_part (match_dup 0))
8704 (and:QI (match_dup 0) (match_dup 1)))]
8705 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8706 && ix86_match_ccmode (insn, CCNOmode)
8707 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8708 "and{b}\t{%1, %0|%0, %1}"
8709 [(set_attr "type" "alu1")
8710 (set_attr "mode" "QI")])
8712 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8713 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8714 ;; for a QImode operand, which of course failed.
8716 (define_insn "andqi_ext_0"
8717 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8722 (match_operand 1 "ext_register_operand" "0")
8725 (match_operand 2 "const_int_operand" "n")))
8726 (clobber (reg:CC FLAGS_REG))]
8728 "and{b}\t{%2, %h0|%h0, %2}"
8729 [(set_attr "type" "alu")
8730 (set_attr "length_immediate" "1")
8731 (set_attr "mode" "QI")])
8733 ;; Generated by peephole translating test to and. This shows up
8734 ;; often in fp comparisons.
8736 (define_insn "*andqi_ext_0_cc"
8737 [(set (reg FLAGS_REG)
8741 (match_operand 1 "ext_register_operand" "0")
8744 (match_operand 2 "const_int_operand" "n"))
8746 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8755 "ix86_match_ccmode (insn, CCNOmode)"
8756 "and{b}\t{%2, %h0|%h0, %2}"
8757 [(set_attr "type" "alu")
8758 (set_attr "length_immediate" "1")
8759 (set_attr "mode" "QI")])
8761 (define_insn "*andqi_ext_1"
8762 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8767 (match_operand 1 "ext_register_operand" "0")
8771 (match_operand:QI 2 "general_operand" "Qm"))))
8772 (clobber (reg:CC FLAGS_REG))]
8774 "and{b}\t{%2, %h0|%h0, %2}"
8775 [(set_attr "type" "alu")
8776 (set_attr "length_immediate" "0")
8777 (set_attr "mode" "QI")])
8779 (define_insn "*andqi_ext_1_rex64"
8780 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8785 (match_operand 1 "ext_register_operand" "0")
8789 (match_operand 2 "ext_register_operand" "Q"))))
8790 (clobber (reg:CC FLAGS_REG))]
8792 "and{b}\t{%2, %h0|%h0, %2}"
8793 [(set_attr "type" "alu")
8794 (set_attr "length_immediate" "0")
8795 (set_attr "mode" "QI")])
8797 (define_insn "*andqi_ext_2"
8798 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8803 (match_operand 1 "ext_register_operand" "%0")
8807 (match_operand 2 "ext_register_operand" "Q")
8810 (clobber (reg:CC FLAGS_REG))]
8812 "and{b}\t{%h2, %h0|%h0, %h2}"
8813 [(set_attr "type" "alu")
8814 (set_attr "length_immediate" "0")
8815 (set_attr "mode" "QI")])
8817 ;; Convert wide AND instructions with immediate operand to shorter QImode
8818 ;; equivalents when possible.
8819 ;; Don't do the splitting with memory operands, since it introduces risk
8820 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8821 ;; for size, but that can (should?) be handled by generic code instead.
8823 [(set (match_operand 0 "register_operand" "")
8824 (and (match_operand 1 "register_operand" "")
8825 (match_operand 2 "const_int_operand" "")))
8826 (clobber (reg:CC FLAGS_REG))]
8828 && QI_REG_P (operands[0])
8829 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8830 && !(~INTVAL (operands[2]) & ~(255 << 8))
8831 && GET_MODE (operands[0]) != QImode"
8832 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8833 (and:SI (zero_extract:SI (match_dup 1)
8834 (const_int 8) (const_int 8))
8836 (clobber (reg:CC FLAGS_REG))])]
8837 "operands[0] = gen_lowpart (SImode, operands[0]);
8838 operands[1] = gen_lowpart (SImode, operands[1]);
8839 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8841 ;; Since AND can be encoded with sign extended immediate, this is only
8842 ;; profitable when 7th bit is not set.
8844 [(set (match_operand 0 "register_operand" "")
8845 (and (match_operand 1 "general_operand" "")
8846 (match_operand 2 "const_int_operand" "")))
8847 (clobber (reg:CC FLAGS_REG))]
8849 && ANY_QI_REG_P (operands[0])
8850 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8851 && !(~INTVAL (operands[2]) & ~255)
8852 && !(INTVAL (operands[2]) & 128)
8853 && GET_MODE (operands[0]) != QImode"
8854 [(parallel [(set (strict_low_part (match_dup 0))
8855 (and:QI (match_dup 1)
8857 (clobber (reg:CC FLAGS_REG))])]
8858 "operands[0] = gen_lowpart (QImode, operands[0]);
8859 operands[1] = gen_lowpart (QImode, operands[1]);
8860 operands[2] = gen_lowpart (QImode, operands[2]);")
8862 ;; Logical inclusive OR instructions
8864 ;; %%% This used to optimize known byte-wide and operations to memory.
8865 ;; If this is considered useful, it should be done with splitters.
8867 (define_expand "iordi3"
8868 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8869 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8870 (match_operand:DI 2 "x86_64_general_operand" "")))
8871 (clobber (reg:CC FLAGS_REG))]
8873 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8875 (define_insn "*iordi_1_rex64"
8876 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8877 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8878 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8879 (clobber (reg:CC FLAGS_REG))]
8881 && ix86_binary_operator_ok (IOR, DImode, operands)"
8882 "or{q}\t{%2, %0|%0, %2}"
8883 [(set_attr "type" "alu")
8884 (set_attr "mode" "DI")])
8886 (define_insn "*iordi_2_rex64"
8887 [(set (reg FLAGS_REG)
8888 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8889 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8891 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8892 (ior:DI (match_dup 1) (match_dup 2)))]
8894 && ix86_match_ccmode (insn, CCNOmode)
8895 && ix86_binary_operator_ok (IOR, DImode, operands)"
8896 "or{q}\t{%2, %0|%0, %2}"
8897 [(set_attr "type" "alu")
8898 (set_attr "mode" "DI")])
8900 (define_insn "*iordi_3_rex64"
8901 [(set (reg FLAGS_REG)
8902 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8903 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8905 (clobber (match_scratch:DI 0 "=r"))]
8907 && ix86_match_ccmode (insn, CCNOmode)
8908 && ix86_binary_operator_ok (IOR, DImode, operands)"
8909 "or{q}\t{%2, %0|%0, %2}"
8910 [(set_attr "type" "alu")
8911 (set_attr "mode" "DI")])
8914 (define_expand "iorsi3"
8915 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8916 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8917 (match_operand:SI 2 "general_operand" "")))
8918 (clobber (reg:CC FLAGS_REG))]
8920 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8922 (define_insn "*iorsi_1"
8923 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8924 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8925 (match_operand:SI 2 "general_operand" "ri,rmi")))
8926 (clobber (reg:CC FLAGS_REG))]
8927 "ix86_binary_operator_ok (IOR, SImode, operands)"
8928 "or{l}\t{%2, %0|%0, %2}"
8929 [(set_attr "type" "alu")
8930 (set_attr "mode" "SI")])
8932 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8933 (define_insn "*iorsi_1_zext"
8934 [(set (match_operand:DI 0 "register_operand" "=rm")
8936 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8937 (match_operand:SI 2 "general_operand" "rim"))))
8938 (clobber (reg:CC FLAGS_REG))]
8939 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8940 "or{l}\t{%2, %k0|%k0, %2}"
8941 [(set_attr "type" "alu")
8942 (set_attr "mode" "SI")])
8944 (define_insn "*iorsi_1_zext_imm"
8945 [(set (match_operand:DI 0 "register_operand" "=rm")
8946 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8947 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8948 (clobber (reg:CC FLAGS_REG))]
8950 "or{l}\t{%2, %k0|%k0, %2}"
8951 [(set_attr "type" "alu")
8952 (set_attr "mode" "SI")])
8954 (define_insn "*iorsi_2"
8955 [(set (reg FLAGS_REG)
8956 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8957 (match_operand:SI 2 "general_operand" "rim,ri"))
8959 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8960 (ior:SI (match_dup 1) (match_dup 2)))]
8961 "ix86_match_ccmode (insn, CCNOmode)
8962 && ix86_binary_operator_ok (IOR, SImode, operands)"
8963 "or{l}\t{%2, %0|%0, %2}"
8964 [(set_attr "type" "alu")
8965 (set_attr "mode" "SI")])
8967 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8968 ;; ??? Special case for immediate operand is missing - it is tricky.
8969 (define_insn "*iorsi_2_zext"
8970 [(set (reg FLAGS_REG)
8971 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8972 (match_operand:SI 2 "general_operand" "rim"))
8974 (set (match_operand:DI 0 "register_operand" "=r")
8975 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8976 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8977 && ix86_binary_operator_ok (IOR, SImode, operands)"
8978 "or{l}\t{%2, %k0|%k0, %2}"
8979 [(set_attr "type" "alu")
8980 (set_attr "mode" "SI")])
8982 (define_insn "*iorsi_2_zext_imm"
8983 [(set (reg FLAGS_REG)
8984 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8985 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8987 (set (match_operand:DI 0 "register_operand" "=r")
8988 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8989 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8990 && ix86_binary_operator_ok (IOR, SImode, operands)"
8991 "or{l}\t{%2, %k0|%k0, %2}"
8992 [(set_attr "type" "alu")
8993 (set_attr "mode" "SI")])
8995 (define_insn "*iorsi_3"
8996 [(set (reg FLAGS_REG)
8997 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8998 (match_operand:SI 2 "general_operand" "rim"))
9000 (clobber (match_scratch:SI 0 "=r"))]
9001 "ix86_match_ccmode (insn, CCNOmode)
9002 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9003 "or{l}\t{%2, %0|%0, %2}"
9004 [(set_attr "type" "alu")
9005 (set_attr "mode" "SI")])
9007 (define_expand "iorhi3"
9008 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9009 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9010 (match_operand:HI 2 "general_operand" "")))
9011 (clobber (reg:CC FLAGS_REG))]
9012 "TARGET_HIMODE_MATH"
9013 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9015 (define_insn "*iorhi_1"
9016 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9017 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9018 (match_operand:HI 2 "general_operand" "rmi,ri")))
9019 (clobber (reg:CC FLAGS_REG))]
9020 "ix86_binary_operator_ok (IOR, HImode, operands)"
9021 "or{w}\t{%2, %0|%0, %2}"
9022 [(set_attr "type" "alu")
9023 (set_attr "mode" "HI")])
9025 (define_insn "*iorhi_2"
9026 [(set (reg FLAGS_REG)
9027 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9028 (match_operand:HI 2 "general_operand" "rim,ri"))
9030 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9031 (ior:HI (match_dup 1) (match_dup 2)))]
9032 "ix86_match_ccmode (insn, CCNOmode)
9033 && ix86_binary_operator_ok (IOR, HImode, operands)"
9034 "or{w}\t{%2, %0|%0, %2}"
9035 [(set_attr "type" "alu")
9036 (set_attr "mode" "HI")])
9038 (define_insn "*iorhi_3"
9039 [(set (reg FLAGS_REG)
9040 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9041 (match_operand:HI 2 "general_operand" "rim"))
9043 (clobber (match_scratch:HI 0 "=r"))]
9044 "ix86_match_ccmode (insn, CCNOmode)
9045 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9046 "or{w}\t{%2, %0|%0, %2}"
9047 [(set_attr "type" "alu")
9048 (set_attr "mode" "HI")])
9050 (define_expand "iorqi3"
9051 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9052 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9053 (match_operand:QI 2 "general_operand" "")))
9054 (clobber (reg:CC FLAGS_REG))]
9055 "TARGET_QIMODE_MATH"
9056 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9058 ;; %%% Potential partial reg stall on alternative 2. What to do?
9059 (define_insn "*iorqi_1"
9060 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9061 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9062 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9063 (clobber (reg:CC FLAGS_REG))]
9064 "ix86_binary_operator_ok (IOR, QImode, operands)"
9066 or{b}\t{%2, %0|%0, %2}
9067 or{b}\t{%2, %0|%0, %2}
9068 or{l}\t{%k2, %k0|%k0, %k2}"
9069 [(set_attr "type" "alu")
9070 (set_attr "mode" "QI,QI,SI")])
9072 (define_insn "*iorqi_1_slp"
9073 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9074 (ior:QI (match_dup 0)
9075 (match_operand:QI 1 "general_operand" "qmi,qi")))
9076 (clobber (reg:CC FLAGS_REG))]
9077 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9078 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9079 "or{b}\t{%1, %0|%0, %1}"
9080 [(set_attr "type" "alu1")
9081 (set_attr "mode" "QI")])
9083 (define_insn "*iorqi_2"
9084 [(set (reg FLAGS_REG)
9085 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9086 (match_operand:QI 2 "general_operand" "qim,qi"))
9088 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9089 (ior:QI (match_dup 1) (match_dup 2)))]
9090 "ix86_match_ccmode (insn, CCNOmode)
9091 && ix86_binary_operator_ok (IOR, QImode, operands)"
9092 "or{b}\t{%2, %0|%0, %2}"
9093 [(set_attr "type" "alu")
9094 (set_attr "mode" "QI")])
9096 (define_insn "*iorqi_2_slp"
9097 [(set (reg FLAGS_REG)
9098 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9099 (match_operand:QI 1 "general_operand" "qim,qi"))
9101 (set (strict_low_part (match_dup 0))
9102 (ior:QI (match_dup 0) (match_dup 1)))]
9103 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9104 && ix86_match_ccmode (insn, CCNOmode)
9105 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9106 "or{b}\t{%1, %0|%0, %1}"
9107 [(set_attr "type" "alu1")
9108 (set_attr "mode" "QI")])
9110 (define_insn "*iorqi_3"
9111 [(set (reg FLAGS_REG)
9112 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9113 (match_operand:QI 2 "general_operand" "qim"))
9115 (clobber (match_scratch:QI 0 "=q"))]
9116 "ix86_match_ccmode (insn, CCNOmode)
9117 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9118 "or{b}\t{%2, %0|%0, %2}"
9119 [(set_attr "type" "alu")
9120 (set_attr "mode" "QI")])
9122 (define_insn "iorqi_ext_0"
9123 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9128 (match_operand 1 "ext_register_operand" "0")
9131 (match_operand 2 "const_int_operand" "n")))
9132 (clobber (reg:CC FLAGS_REG))]
9133 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9134 "or{b}\t{%2, %h0|%h0, %2}"
9135 [(set_attr "type" "alu")
9136 (set_attr "length_immediate" "1")
9137 (set_attr "mode" "QI")])
9139 (define_insn "*iorqi_ext_1"
9140 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9145 (match_operand 1 "ext_register_operand" "0")
9149 (match_operand:QI 2 "general_operand" "Qm"))))
9150 (clobber (reg:CC FLAGS_REG))]
9152 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9153 "or{b}\t{%2, %h0|%h0, %2}"
9154 [(set_attr "type" "alu")
9155 (set_attr "length_immediate" "0")
9156 (set_attr "mode" "QI")])
9158 (define_insn "*iorqi_ext_1_rex64"
9159 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9164 (match_operand 1 "ext_register_operand" "0")
9168 (match_operand 2 "ext_register_operand" "Q"))))
9169 (clobber (reg:CC FLAGS_REG))]
9171 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9172 "or{b}\t{%2, %h0|%h0, %2}"
9173 [(set_attr "type" "alu")
9174 (set_attr "length_immediate" "0")
9175 (set_attr "mode" "QI")])
9177 (define_insn "*iorqi_ext_2"
9178 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9182 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9185 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9188 (clobber (reg:CC FLAGS_REG))]
9189 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9190 "ior{b}\t{%h2, %h0|%h0, %h2}"
9191 [(set_attr "type" "alu")
9192 (set_attr "length_immediate" "0")
9193 (set_attr "mode" "QI")])
9196 [(set (match_operand 0 "register_operand" "")
9197 (ior (match_operand 1 "register_operand" "")
9198 (match_operand 2 "const_int_operand" "")))
9199 (clobber (reg:CC FLAGS_REG))]
9201 && QI_REG_P (operands[0])
9202 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9203 && !(INTVAL (operands[2]) & ~(255 << 8))
9204 && GET_MODE (operands[0]) != QImode"
9205 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9206 (ior:SI (zero_extract:SI (match_dup 1)
9207 (const_int 8) (const_int 8))
9209 (clobber (reg:CC FLAGS_REG))])]
9210 "operands[0] = gen_lowpart (SImode, operands[0]);
9211 operands[1] = gen_lowpart (SImode, operands[1]);
9212 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9214 ;; Since OR can be encoded with sign extended immediate, this is only
9215 ;; profitable when 7th bit is set.
9217 [(set (match_operand 0 "register_operand" "")
9218 (ior (match_operand 1 "general_operand" "")
9219 (match_operand 2 "const_int_operand" "")))
9220 (clobber (reg:CC FLAGS_REG))]
9222 && ANY_QI_REG_P (operands[0])
9223 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9224 && !(INTVAL (operands[2]) & ~255)
9225 && (INTVAL (operands[2]) & 128)
9226 && GET_MODE (operands[0]) != QImode"
9227 [(parallel [(set (strict_low_part (match_dup 0))
9228 (ior:QI (match_dup 1)
9230 (clobber (reg:CC FLAGS_REG))])]
9231 "operands[0] = gen_lowpart (QImode, operands[0]);
9232 operands[1] = gen_lowpart (QImode, operands[1]);
9233 operands[2] = gen_lowpart (QImode, operands[2]);")
9235 ;; Logical XOR instructions
9237 ;; %%% This used to optimize known byte-wide and operations to memory.
9238 ;; If this is considered useful, it should be done with splitters.
9240 (define_expand "xordi3"
9241 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9242 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9243 (match_operand:DI 2 "x86_64_general_operand" "")))
9244 (clobber (reg:CC FLAGS_REG))]
9246 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9248 (define_insn "*xordi_1_rex64"
9249 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9250 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9251 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9252 (clobber (reg:CC FLAGS_REG))]
9254 && ix86_binary_operator_ok (XOR, DImode, operands)"
9256 xor{q}\t{%2, %0|%0, %2}
9257 xor{q}\t{%2, %0|%0, %2}"
9258 [(set_attr "type" "alu")
9259 (set_attr "mode" "DI,DI")])
9261 (define_insn "*xordi_2_rex64"
9262 [(set (reg FLAGS_REG)
9263 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9264 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9266 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9267 (xor:DI (match_dup 1) (match_dup 2)))]
9269 && ix86_match_ccmode (insn, CCNOmode)
9270 && ix86_binary_operator_ok (XOR, DImode, operands)"
9272 xor{q}\t{%2, %0|%0, %2}
9273 xor{q}\t{%2, %0|%0, %2}"
9274 [(set_attr "type" "alu")
9275 (set_attr "mode" "DI,DI")])
9277 (define_insn "*xordi_3_rex64"
9278 [(set (reg FLAGS_REG)
9279 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9280 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9282 (clobber (match_scratch:DI 0 "=r"))]
9284 && ix86_match_ccmode (insn, CCNOmode)
9285 && ix86_binary_operator_ok (XOR, DImode, operands)"
9286 "xor{q}\t{%2, %0|%0, %2}"
9287 [(set_attr "type" "alu")
9288 (set_attr "mode" "DI")])
9290 (define_expand "xorsi3"
9291 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9292 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9293 (match_operand:SI 2 "general_operand" "")))
9294 (clobber (reg:CC FLAGS_REG))]
9296 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9298 (define_insn "*xorsi_1"
9299 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9300 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9301 (match_operand:SI 2 "general_operand" "ri,rm")))
9302 (clobber (reg:CC FLAGS_REG))]
9303 "ix86_binary_operator_ok (XOR, SImode, operands)"
9304 "xor{l}\t{%2, %0|%0, %2}"
9305 [(set_attr "type" "alu")
9306 (set_attr "mode" "SI")])
9308 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9309 ;; Add speccase for immediates
9310 (define_insn "*xorsi_1_zext"
9311 [(set (match_operand:DI 0 "register_operand" "=r")
9313 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9314 (match_operand:SI 2 "general_operand" "rim"))))
9315 (clobber (reg:CC FLAGS_REG))]
9316 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9317 "xor{l}\t{%2, %k0|%k0, %2}"
9318 [(set_attr "type" "alu")
9319 (set_attr "mode" "SI")])
9321 (define_insn "*xorsi_1_zext_imm"
9322 [(set (match_operand:DI 0 "register_operand" "=r")
9323 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9324 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9325 (clobber (reg:CC FLAGS_REG))]
9326 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9327 "xor{l}\t{%2, %k0|%k0, %2}"
9328 [(set_attr "type" "alu")
9329 (set_attr "mode" "SI")])
9331 (define_insn "*xorsi_2"
9332 [(set (reg FLAGS_REG)
9333 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9334 (match_operand:SI 2 "general_operand" "rim,ri"))
9336 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9337 (xor:SI (match_dup 1) (match_dup 2)))]
9338 "ix86_match_ccmode (insn, CCNOmode)
9339 && ix86_binary_operator_ok (XOR, SImode, operands)"
9340 "xor{l}\t{%2, %0|%0, %2}"
9341 [(set_attr "type" "alu")
9342 (set_attr "mode" "SI")])
9344 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9345 ;; ??? Special case for immediate operand is missing - it is tricky.
9346 (define_insn "*xorsi_2_zext"
9347 [(set (reg FLAGS_REG)
9348 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9349 (match_operand:SI 2 "general_operand" "rim"))
9351 (set (match_operand:DI 0 "register_operand" "=r")
9352 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9353 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9354 && ix86_binary_operator_ok (XOR, SImode, operands)"
9355 "xor{l}\t{%2, %k0|%k0, %2}"
9356 [(set_attr "type" "alu")
9357 (set_attr "mode" "SI")])
9359 (define_insn "*xorsi_2_zext_imm"
9360 [(set (reg FLAGS_REG)
9361 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9362 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9364 (set (match_operand:DI 0 "register_operand" "=r")
9365 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9366 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9367 && ix86_binary_operator_ok (XOR, SImode, operands)"
9368 "xor{l}\t{%2, %k0|%k0, %2}"
9369 [(set_attr "type" "alu")
9370 (set_attr "mode" "SI")])
9372 (define_insn "*xorsi_3"
9373 [(set (reg FLAGS_REG)
9374 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9375 (match_operand:SI 2 "general_operand" "rim"))
9377 (clobber (match_scratch:SI 0 "=r"))]
9378 "ix86_match_ccmode (insn, CCNOmode)
9379 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9380 "xor{l}\t{%2, %0|%0, %2}"
9381 [(set_attr "type" "alu")
9382 (set_attr "mode" "SI")])
9384 (define_expand "xorhi3"
9385 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9386 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9387 (match_operand:HI 2 "general_operand" "")))
9388 (clobber (reg:CC FLAGS_REG))]
9389 "TARGET_HIMODE_MATH"
9390 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9392 (define_insn "*xorhi_1"
9393 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9394 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9395 (match_operand:HI 2 "general_operand" "rmi,ri")))
9396 (clobber (reg:CC FLAGS_REG))]
9397 "ix86_binary_operator_ok (XOR, HImode, operands)"
9398 "xor{w}\t{%2, %0|%0, %2}"
9399 [(set_attr "type" "alu")
9400 (set_attr "mode" "HI")])
9402 (define_insn "*xorhi_2"
9403 [(set (reg FLAGS_REG)
9404 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9405 (match_operand:HI 2 "general_operand" "rim,ri"))
9407 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9408 (xor:HI (match_dup 1) (match_dup 2)))]
9409 "ix86_match_ccmode (insn, CCNOmode)
9410 && ix86_binary_operator_ok (XOR, HImode, operands)"
9411 "xor{w}\t{%2, %0|%0, %2}"
9412 [(set_attr "type" "alu")
9413 (set_attr "mode" "HI")])
9415 (define_insn "*xorhi_3"
9416 [(set (reg FLAGS_REG)
9417 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9418 (match_operand:HI 2 "general_operand" "rim"))
9420 (clobber (match_scratch:HI 0 "=r"))]
9421 "ix86_match_ccmode (insn, CCNOmode)
9422 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9423 "xor{w}\t{%2, %0|%0, %2}"
9424 [(set_attr "type" "alu")
9425 (set_attr "mode" "HI")])
9427 (define_expand "xorqi3"
9428 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9429 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9430 (match_operand:QI 2 "general_operand" "")))
9431 (clobber (reg:CC FLAGS_REG))]
9432 "TARGET_QIMODE_MATH"
9433 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9435 ;; %%% Potential partial reg stall on alternative 2. What to do?
9436 (define_insn "*xorqi_1"
9437 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9438 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9439 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9440 (clobber (reg:CC FLAGS_REG))]
9441 "ix86_binary_operator_ok (XOR, QImode, operands)"
9443 xor{b}\t{%2, %0|%0, %2}
9444 xor{b}\t{%2, %0|%0, %2}
9445 xor{l}\t{%k2, %k0|%k0, %k2}"
9446 [(set_attr "type" "alu")
9447 (set_attr "mode" "QI,QI,SI")])
9449 (define_insn "*xorqi_1_slp"
9450 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9451 (xor:QI (match_dup 0)
9452 (match_operand:QI 1 "general_operand" "qi,qmi")))
9453 (clobber (reg:CC FLAGS_REG))]
9454 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9455 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9456 "xor{b}\t{%1, %0|%0, %1}"
9457 [(set_attr "type" "alu1")
9458 (set_attr "mode" "QI")])
9460 (define_insn "xorqi_ext_0"
9461 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9466 (match_operand 1 "ext_register_operand" "0")
9469 (match_operand 2 "const_int_operand" "n")))
9470 (clobber (reg:CC FLAGS_REG))]
9471 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9472 "xor{b}\t{%2, %h0|%h0, %2}"
9473 [(set_attr "type" "alu")
9474 (set_attr "length_immediate" "1")
9475 (set_attr "mode" "QI")])
9477 (define_insn "*xorqi_ext_1"
9478 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9483 (match_operand 1 "ext_register_operand" "0")
9487 (match_operand:QI 2 "general_operand" "Qm"))))
9488 (clobber (reg:CC FLAGS_REG))]
9490 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9491 "xor{b}\t{%2, %h0|%h0, %2}"
9492 [(set_attr "type" "alu")
9493 (set_attr "length_immediate" "0")
9494 (set_attr "mode" "QI")])
9496 (define_insn "*xorqi_ext_1_rex64"
9497 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9502 (match_operand 1 "ext_register_operand" "0")
9506 (match_operand 2 "ext_register_operand" "Q"))))
9507 (clobber (reg:CC FLAGS_REG))]
9509 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9510 "xor{b}\t{%2, %h0|%h0, %2}"
9511 [(set_attr "type" "alu")
9512 (set_attr "length_immediate" "0")
9513 (set_attr "mode" "QI")])
9515 (define_insn "*xorqi_ext_2"
9516 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9520 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9523 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9526 (clobber (reg:CC FLAGS_REG))]
9527 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9528 "xor{b}\t{%h2, %h0|%h0, %h2}"
9529 [(set_attr "type" "alu")
9530 (set_attr "length_immediate" "0")
9531 (set_attr "mode" "QI")])
9533 (define_insn "*xorqi_cc_1"
9534 [(set (reg FLAGS_REG)
9536 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9537 (match_operand:QI 2 "general_operand" "qim,qi"))
9539 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9540 (xor:QI (match_dup 1) (match_dup 2)))]
9541 "ix86_match_ccmode (insn, CCNOmode)
9542 && ix86_binary_operator_ok (XOR, QImode, operands)"
9543 "xor{b}\t{%2, %0|%0, %2}"
9544 [(set_attr "type" "alu")
9545 (set_attr "mode" "QI")])
9547 (define_insn "*xorqi_2_slp"
9548 [(set (reg FLAGS_REG)
9549 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9550 (match_operand:QI 1 "general_operand" "qim,qi"))
9552 (set (strict_low_part (match_dup 0))
9553 (xor:QI (match_dup 0) (match_dup 1)))]
9554 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9555 && ix86_match_ccmode (insn, CCNOmode)
9556 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9557 "xor{b}\t{%1, %0|%0, %1}"
9558 [(set_attr "type" "alu1")
9559 (set_attr "mode" "QI")])
9561 (define_insn "*xorqi_cc_2"
9562 [(set (reg FLAGS_REG)
9564 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9565 (match_operand:QI 2 "general_operand" "qim"))
9567 (clobber (match_scratch:QI 0 "=q"))]
9568 "ix86_match_ccmode (insn, CCNOmode)
9569 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9570 "xor{b}\t{%2, %0|%0, %2}"
9571 [(set_attr "type" "alu")
9572 (set_attr "mode" "QI")])
9574 (define_insn "*xorqi_cc_ext_1"
9575 [(set (reg FLAGS_REG)
9579 (match_operand 1 "ext_register_operand" "0")
9582 (match_operand:QI 2 "general_operand" "qmn"))
9584 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9588 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9590 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9591 "xor{b}\t{%2, %h0|%h0, %2}"
9592 [(set_attr "type" "alu")
9593 (set_attr "mode" "QI")])
9595 (define_insn "*xorqi_cc_ext_1_rex64"
9596 [(set (reg FLAGS_REG)
9600 (match_operand 1 "ext_register_operand" "0")
9603 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9605 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9609 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9611 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9612 "xor{b}\t{%2, %h0|%h0, %2}"
9613 [(set_attr "type" "alu")
9614 (set_attr "mode" "QI")])
9616 (define_expand "xorqi_cc_ext_1"
9618 (set (reg:CCNO FLAGS_REG)
9622 (match_operand 1 "ext_register_operand" "")
9625 (match_operand:QI 2 "general_operand" ""))
9627 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9631 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9637 [(set (match_operand 0 "register_operand" "")
9638 (xor (match_operand 1 "register_operand" "")
9639 (match_operand 2 "const_int_operand" "")))
9640 (clobber (reg:CC FLAGS_REG))]
9642 && QI_REG_P (operands[0])
9643 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9644 && !(INTVAL (operands[2]) & ~(255 << 8))
9645 && GET_MODE (operands[0]) != QImode"
9646 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9647 (xor:SI (zero_extract:SI (match_dup 1)
9648 (const_int 8) (const_int 8))
9650 (clobber (reg:CC FLAGS_REG))])]
9651 "operands[0] = gen_lowpart (SImode, operands[0]);
9652 operands[1] = gen_lowpart (SImode, operands[1]);
9653 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9655 ;; Since XOR can be encoded with sign extended immediate, this is only
9656 ;; profitable when 7th bit is set.
9658 [(set (match_operand 0 "register_operand" "")
9659 (xor (match_operand 1 "general_operand" "")
9660 (match_operand 2 "const_int_operand" "")))
9661 (clobber (reg:CC FLAGS_REG))]
9663 && ANY_QI_REG_P (operands[0])
9664 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9665 && !(INTVAL (operands[2]) & ~255)
9666 && (INTVAL (operands[2]) & 128)
9667 && GET_MODE (operands[0]) != QImode"
9668 [(parallel [(set (strict_low_part (match_dup 0))
9669 (xor:QI (match_dup 1)
9671 (clobber (reg:CC FLAGS_REG))])]
9672 "operands[0] = gen_lowpart (QImode, operands[0]);
9673 operands[1] = gen_lowpart (QImode, operands[1]);
9674 operands[2] = gen_lowpart (QImode, operands[2]);")
9676 ;; Negation instructions
9678 (define_expand "negti2"
9679 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9680 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9681 (clobber (reg:CC FLAGS_REG))])]
9683 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9685 (define_insn "*negti2_1"
9686 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9687 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9688 (clobber (reg:CC FLAGS_REG))]
9690 && ix86_unary_operator_ok (NEG, TImode, operands)"
9694 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9695 (neg:TI (match_operand:TI 1 "general_operand" "")))
9696 (clobber (reg:CC FLAGS_REG))]
9697 "TARGET_64BIT && reload_completed"
9699 [(set (reg:CCZ FLAGS_REG)
9700 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9701 (set (match_dup 0) (neg:DI (match_dup 2)))])
9704 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9707 (clobber (reg:CC FLAGS_REG))])
9710 (neg:DI (match_dup 1)))
9711 (clobber (reg:CC FLAGS_REG))])]
9712 "split_ti (operands+1, 1, operands+2, operands+3);
9713 split_ti (operands+0, 1, operands+0, operands+1);")
9715 (define_expand "negdi2"
9716 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9717 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9718 (clobber (reg:CC FLAGS_REG))])]
9720 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9722 (define_insn "*negdi2_1"
9723 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9724 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9725 (clobber (reg:CC FLAGS_REG))]
9727 && ix86_unary_operator_ok (NEG, DImode, operands)"
9731 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9732 (neg:DI (match_operand:DI 1 "general_operand" "")))
9733 (clobber (reg:CC FLAGS_REG))]
9734 "!TARGET_64BIT && reload_completed"
9736 [(set (reg:CCZ FLAGS_REG)
9737 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9738 (set (match_dup 0) (neg:SI (match_dup 2)))])
9741 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9744 (clobber (reg:CC FLAGS_REG))])
9747 (neg:SI (match_dup 1)))
9748 (clobber (reg:CC FLAGS_REG))])]
9749 "split_di (operands+1, 1, operands+2, operands+3);
9750 split_di (operands+0, 1, operands+0, operands+1);")
9752 (define_insn "*negdi2_1_rex64"
9753 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9754 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9755 (clobber (reg:CC FLAGS_REG))]
9756 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9758 [(set_attr "type" "negnot")
9759 (set_attr "mode" "DI")])
9761 ;; The problem with neg is that it does not perform (compare x 0),
9762 ;; it really performs (compare 0 x), which leaves us with the zero
9763 ;; flag being the only useful item.
9765 (define_insn "*negdi2_cmpz_rex64"
9766 [(set (reg:CCZ FLAGS_REG)
9767 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9769 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9770 (neg:DI (match_dup 1)))]
9771 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9773 [(set_attr "type" "negnot")
9774 (set_attr "mode" "DI")])
9777 (define_expand "negsi2"
9778 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9779 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9780 (clobber (reg:CC FLAGS_REG))])]
9782 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9784 (define_insn "*negsi2_1"
9785 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9786 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9787 (clobber (reg:CC FLAGS_REG))]
9788 "ix86_unary_operator_ok (NEG, SImode, operands)"
9790 [(set_attr "type" "negnot")
9791 (set_attr "mode" "SI")])
9793 ;; Combine is quite creative about this pattern.
9794 (define_insn "*negsi2_1_zext"
9795 [(set (match_operand:DI 0 "register_operand" "=r")
9796 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9799 (clobber (reg:CC FLAGS_REG))]
9800 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9802 [(set_attr "type" "negnot")
9803 (set_attr "mode" "SI")])
9805 ;; The problem with neg is that it does not perform (compare x 0),
9806 ;; it really performs (compare 0 x), which leaves us with the zero
9807 ;; flag being the only useful item.
9809 (define_insn "*negsi2_cmpz"
9810 [(set (reg:CCZ FLAGS_REG)
9811 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9813 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9814 (neg:SI (match_dup 1)))]
9815 "ix86_unary_operator_ok (NEG, SImode, operands)"
9817 [(set_attr "type" "negnot")
9818 (set_attr "mode" "SI")])
9820 (define_insn "*negsi2_cmpz_zext"
9821 [(set (reg:CCZ FLAGS_REG)
9822 (compare:CCZ (lshiftrt:DI
9824 (match_operand:DI 1 "register_operand" "0")
9828 (set (match_operand:DI 0 "register_operand" "=r")
9829 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9832 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9834 [(set_attr "type" "negnot")
9835 (set_attr "mode" "SI")])
9837 (define_expand "neghi2"
9838 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9839 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9840 (clobber (reg:CC FLAGS_REG))])]
9841 "TARGET_HIMODE_MATH"
9842 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9844 (define_insn "*neghi2_1"
9845 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9846 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9847 (clobber (reg:CC FLAGS_REG))]
9848 "ix86_unary_operator_ok (NEG, HImode, operands)"
9850 [(set_attr "type" "negnot")
9851 (set_attr "mode" "HI")])
9853 (define_insn "*neghi2_cmpz"
9854 [(set (reg:CCZ FLAGS_REG)
9855 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9857 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9858 (neg:HI (match_dup 1)))]
9859 "ix86_unary_operator_ok (NEG, HImode, operands)"
9861 [(set_attr "type" "negnot")
9862 (set_attr "mode" "HI")])
9864 (define_expand "negqi2"
9865 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9866 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9867 (clobber (reg:CC FLAGS_REG))])]
9868 "TARGET_QIMODE_MATH"
9869 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9871 (define_insn "*negqi2_1"
9872 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9873 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9874 (clobber (reg:CC FLAGS_REG))]
9875 "ix86_unary_operator_ok (NEG, QImode, operands)"
9877 [(set_attr "type" "negnot")
9878 (set_attr "mode" "QI")])
9880 (define_insn "*negqi2_cmpz"
9881 [(set (reg:CCZ FLAGS_REG)
9882 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9884 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9885 (neg:QI (match_dup 1)))]
9886 "ix86_unary_operator_ok (NEG, QImode, operands)"
9888 [(set_attr "type" "negnot")
9889 (set_attr "mode" "QI")])
9891 ;; Changing of sign for FP values is doable using integer unit too.
9893 (define_expand "negsf2"
9894 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9895 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9896 "TARGET_80387 || TARGET_SSE_MATH"
9897 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9899 (define_expand "abssf2"
9900 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9901 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9902 "TARGET_80387 || TARGET_SSE_MATH"
9903 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9905 (define_insn "*absnegsf2_mixed"
9906 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9907 (match_operator:SF 3 "absneg_operator"
9908 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9909 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9910 (clobber (reg:CC FLAGS_REG))]
9911 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9912 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9915 (define_insn "*absnegsf2_sse"
9916 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9917 (match_operator:SF 3 "absneg_operator"
9918 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9919 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9920 (clobber (reg:CC FLAGS_REG))]
9922 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9925 (define_insn "*absnegsf2_i387"
9926 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9927 (match_operator:SF 3 "absneg_operator"
9928 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9929 (use (match_operand 2 "" ""))
9930 (clobber (reg:CC FLAGS_REG))]
9931 "TARGET_80387 && !TARGET_SSE_MATH
9932 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9935 (define_expand "copysignsf3"
9936 [(match_operand:SF 0 "register_operand" "")
9937 (match_operand:SF 1 "nonmemory_operand" "")
9938 (match_operand:SF 2 "register_operand" "")]
9941 ix86_expand_copysign (operands);
9945 (define_insn_and_split "copysignsf3_const"
9946 [(set (match_operand:SF 0 "register_operand" "=x")
9948 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9949 (match_operand:SF 2 "register_operand" "0")
9950 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9954 "&& reload_completed"
9957 ix86_split_copysign_const (operands);
9961 (define_insn "copysignsf3_var"
9962 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9964 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9965 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9966 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9967 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9969 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9974 [(set (match_operand:SF 0 "register_operand" "")
9976 [(match_operand:SF 2 "register_operand" "")
9977 (match_operand:SF 3 "register_operand" "")
9978 (match_operand:V4SF 4 "" "")
9979 (match_operand:V4SF 5 "" "")]
9981 (clobber (match_scratch:V4SF 1 ""))]
9982 "TARGET_SSE_MATH && reload_completed"
9985 ix86_split_copysign_var (operands);
9989 (define_expand "negdf2"
9990 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9991 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9992 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9993 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9995 (define_expand "absdf2"
9996 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9997 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9998 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9999 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
10001 (define_insn "*absnegdf2_mixed"
10002 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
10003 (match_operator:DF 3 "absneg_operator"
10004 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
10005 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
10006 (clobber (reg:CC FLAGS_REG))]
10007 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10008 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10011 (define_insn "*absnegdf2_sse"
10012 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
10013 (match_operator:DF 3 "absneg_operator"
10014 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10015 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
10016 (clobber (reg:CC FLAGS_REG))]
10017 "TARGET_SSE2 && TARGET_SSE_MATH
10018 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10021 (define_insn "*absnegdf2_i387"
10022 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10023 (match_operator:DF 3 "absneg_operator"
10024 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10025 (use (match_operand 2 "" ""))
10026 (clobber (reg:CC FLAGS_REG))]
10027 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10028 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10031 (define_expand "copysigndf3"
10032 [(match_operand:DF 0 "register_operand" "")
10033 (match_operand:DF 1 "nonmemory_operand" "")
10034 (match_operand:DF 2 "register_operand" "")]
10035 "TARGET_SSE2 && TARGET_SSE_MATH"
10037 ix86_expand_copysign (operands);
10041 (define_insn_and_split "copysigndf3_const"
10042 [(set (match_operand:DF 0 "register_operand" "=x")
10044 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
10045 (match_operand:DF 2 "register_operand" "0")
10046 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
10048 "TARGET_SSE2 && TARGET_SSE_MATH"
10050 "&& reload_completed"
10053 ix86_split_copysign_const (operands);
10057 (define_insn "copysigndf3_var"
10058 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
10060 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
10061 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
10062 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
10063 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
10065 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
10066 "TARGET_SSE2 && TARGET_SSE_MATH"
10070 [(set (match_operand:DF 0 "register_operand" "")
10072 [(match_operand:DF 2 "register_operand" "")
10073 (match_operand:DF 3 "register_operand" "")
10074 (match_operand:V2DF 4 "" "")
10075 (match_operand:V2DF 5 "" "")]
10077 (clobber (match_scratch:V2DF 1 ""))]
10078 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10081 ix86_split_copysign_var (operands);
10085 (define_expand "negxf2"
10086 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10087 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10089 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10091 (define_expand "absxf2"
10092 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10093 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10095 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10097 (define_insn "*absnegxf2_i387"
10098 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10099 (match_operator:XF 3 "absneg_operator"
10100 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10101 (use (match_operand 2 "" ""))
10102 (clobber (reg:CC FLAGS_REG))]
10104 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10107 ;; Splitters for fp abs and neg.
10110 [(set (match_operand 0 "fp_register_operand" "")
10111 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10112 (use (match_operand 2 "" ""))
10113 (clobber (reg:CC FLAGS_REG))]
10115 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10118 [(set (match_operand 0 "register_operand" "")
10119 (match_operator 3 "absneg_operator"
10120 [(match_operand 1 "register_operand" "")]))
10121 (use (match_operand 2 "nonimmediate_operand" ""))
10122 (clobber (reg:CC FLAGS_REG))]
10123 "reload_completed && SSE_REG_P (operands[0])"
10124 [(set (match_dup 0) (match_dup 3))]
10126 enum machine_mode mode = GET_MODE (operands[0]);
10127 enum machine_mode vmode = GET_MODE (operands[2]);
10130 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10131 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10132 if (operands_match_p (operands[0], operands[2]))
10135 operands[1] = operands[2];
10138 if (GET_CODE (operands[3]) == ABS)
10139 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10141 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10146 [(set (match_operand:SF 0 "register_operand" "")
10147 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10148 (use (match_operand:V4SF 2 "" ""))
10149 (clobber (reg:CC FLAGS_REG))]
10151 [(parallel [(set (match_dup 0) (match_dup 1))
10152 (clobber (reg:CC FLAGS_REG))])]
10155 operands[0] = gen_lowpart (SImode, operands[0]);
10156 if (GET_CODE (operands[1]) == ABS)
10158 tmp = gen_int_mode (0x7fffffff, SImode);
10159 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10163 tmp = gen_int_mode (0x80000000, SImode);
10164 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10170 [(set (match_operand:DF 0 "register_operand" "")
10171 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10172 (use (match_operand 2 "" ""))
10173 (clobber (reg:CC FLAGS_REG))]
10175 [(parallel [(set (match_dup 0) (match_dup 1))
10176 (clobber (reg:CC FLAGS_REG))])]
10181 tmp = gen_lowpart (DImode, operands[0]);
10182 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10185 if (GET_CODE (operands[1]) == ABS)
10188 tmp = gen_rtx_NOT (DImode, tmp);
10192 operands[0] = gen_highpart (SImode, operands[0]);
10193 if (GET_CODE (operands[1]) == ABS)
10195 tmp = gen_int_mode (0x7fffffff, SImode);
10196 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10200 tmp = gen_int_mode (0x80000000, SImode);
10201 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10208 [(set (match_operand:XF 0 "register_operand" "")
10209 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10210 (use (match_operand 2 "" ""))
10211 (clobber (reg:CC FLAGS_REG))]
10213 [(parallel [(set (match_dup 0) (match_dup 1))
10214 (clobber (reg:CC FLAGS_REG))])]
10217 operands[0] = gen_rtx_REG (SImode,
10218 true_regnum (operands[0])
10219 + (TARGET_64BIT ? 1 : 2));
10220 if (GET_CODE (operands[1]) == ABS)
10222 tmp = GEN_INT (0x7fff);
10223 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10227 tmp = GEN_INT (0x8000);
10228 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10234 [(set (match_operand 0 "memory_operand" "")
10235 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10236 (use (match_operand 2 "" ""))
10237 (clobber (reg:CC FLAGS_REG))]
10239 [(parallel [(set (match_dup 0) (match_dup 1))
10240 (clobber (reg:CC FLAGS_REG))])]
10242 enum machine_mode mode = GET_MODE (operands[0]);
10243 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10246 operands[0] = adjust_address (operands[0], QImode, size - 1);
10247 if (GET_CODE (operands[1]) == ABS)
10249 tmp = gen_int_mode (0x7f, QImode);
10250 tmp = gen_rtx_AND (QImode, operands[0], tmp);
10254 tmp = gen_int_mode (0x80, QImode);
10255 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10260 ;; Conditionalize these after reload. If they match before reload, we
10261 ;; lose the clobber and ability to use integer instructions.
10263 (define_insn "*negsf2_1"
10264 [(set (match_operand:SF 0 "register_operand" "=f")
10265 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10266 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10268 [(set_attr "type" "fsgn")
10269 (set_attr "mode" "SF")])
10271 (define_insn "*negdf2_1"
10272 [(set (match_operand:DF 0 "register_operand" "=f")
10273 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10274 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10276 [(set_attr "type" "fsgn")
10277 (set_attr "mode" "DF")])
10279 (define_insn "*negxf2_1"
10280 [(set (match_operand:XF 0 "register_operand" "=f")
10281 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10284 [(set_attr "type" "fsgn")
10285 (set_attr "mode" "XF")])
10287 (define_insn "*abssf2_1"
10288 [(set (match_operand:SF 0 "register_operand" "=f")
10289 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10290 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10292 [(set_attr "type" "fsgn")
10293 (set_attr "mode" "SF")])
10295 (define_insn "*absdf2_1"
10296 [(set (match_operand:DF 0 "register_operand" "=f")
10297 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10298 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10300 [(set_attr "type" "fsgn")
10301 (set_attr "mode" "DF")])
10303 (define_insn "*absxf2_1"
10304 [(set (match_operand:XF 0 "register_operand" "=f")
10305 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10308 [(set_attr "type" "fsgn")
10309 (set_attr "mode" "DF")])
10311 (define_insn "*negextendsfdf2"
10312 [(set (match_operand:DF 0 "register_operand" "=f")
10313 (neg:DF (float_extend:DF
10314 (match_operand:SF 1 "register_operand" "0"))))]
10315 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10317 [(set_attr "type" "fsgn")
10318 (set_attr "mode" "DF")])
10320 (define_insn "*negextenddfxf2"
10321 [(set (match_operand:XF 0 "register_operand" "=f")
10322 (neg:XF (float_extend:XF
10323 (match_operand:DF 1 "register_operand" "0"))))]
10326 [(set_attr "type" "fsgn")
10327 (set_attr "mode" "XF")])
10329 (define_insn "*negextendsfxf2"
10330 [(set (match_operand:XF 0 "register_operand" "=f")
10331 (neg:XF (float_extend:XF
10332 (match_operand:SF 1 "register_operand" "0"))))]
10335 [(set_attr "type" "fsgn")
10336 (set_attr "mode" "XF")])
10338 (define_insn "*absextendsfdf2"
10339 [(set (match_operand:DF 0 "register_operand" "=f")
10340 (abs:DF (float_extend:DF
10341 (match_operand:SF 1 "register_operand" "0"))))]
10342 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10344 [(set_attr "type" "fsgn")
10345 (set_attr "mode" "DF")])
10347 (define_insn "*absextenddfxf2"
10348 [(set (match_operand:XF 0 "register_operand" "=f")
10349 (abs:XF (float_extend:XF
10350 (match_operand:DF 1 "register_operand" "0"))))]
10353 [(set_attr "type" "fsgn")
10354 (set_attr "mode" "XF")])
10356 (define_insn "*absextendsfxf2"
10357 [(set (match_operand:XF 0 "register_operand" "=f")
10358 (abs:XF (float_extend:XF
10359 (match_operand:SF 1 "register_operand" "0"))))]
10362 [(set_attr "type" "fsgn")
10363 (set_attr "mode" "XF")])
10365 ;; One complement instructions
10367 (define_expand "one_cmpldi2"
10368 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10369 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10371 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10373 (define_insn "*one_cmpldi2_1_rex64"
10374 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10375 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10376 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10378 [(set_attr "type" "negnot")
10379 (set_attr "mode" "DI")])
10381 (define_insn "*one_cmpldi2_2_rex64"
10382 [(set (reg FLAGS_REG)
10383 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10385 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10386 (not:DI (match_dup 1)))]
10387 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10388 && ix86_unary_operator_ok (NOT, DImode, operands)"
10390 [(set_attr "type" "alu1")
10391 (set_attr "mode" "DI")])
10394 [(set (match_operand 0 "flags_reg_operand" "")
10395 (match_operator 2 "compare_operator"
10396 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10398 (set (match_operand:DI 1 "nonimmediate_operand" "")
10399 (not:DI (match_dup 3)))]
10400 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10401 [(parallel [(set (match_dup 0)
10403 [(xor:DI (match_dup 3) (const_int -1))
10406 (xor:DI (match_dup 3) (const_int -1)))])]
10409 (define_expand "one_cmplsi2"
10410 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10411 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10413 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10415 (define_insn "*one_cmplsi2_1"
10416 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10417 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10418 "ix86_unary_operator_ok (NOT, SImode, operands)"
10420 [(set_attr "type" "negnot")
10421 (set_attr "mode" "SI")])
10423 ;; ??? Currently never generated - xor is used instead.
10424 (define_insn "*one_cmplsi2_1_zext"
10425 [(set (match_operand:DI 0 "register_operand" "=r")
10426 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10427 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10429 [(set_attr "type" "negnot")
10430 (set_attr "mode" "SI")])
10432 (define_insn "*one_cmplsi2_2"
10433 [(set (reg FLAGS_REG)
10434 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10436 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10437 (not:SI (match_dup 1)))]
10438 "ix86_match_ccmode (insn, CCNOmode)
10439 && ix86_unary_operator_ok (NOT, SImode, operands)"
10441 [(set_attr "type" "alu1")
10442 (set_attr "mode" "SI")])
10445 [(set (match_operand 0 "flags_reg_operand" "")
10446 (match_operator 2 "compare_operator"
10447 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10449 (set (match_operand:SI 1 "nonimmediate_operand" "")
10450 (not:SI (match_dup 3)))]
10451 "ix86_match_ccmode (insn, CCNOmode)"
10452 [(parallel [(set (match_dup 0)
10453 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10456 (xor:SI (match_dup 3) (const_int -1)))])]
10459 ;; ??? Currently never generated - xor is used instead.
10460 (define_insn "*one_cmplsi2_2_zext"
10461 [(set (reg FLAGS_REG)
10462 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10464 (set (match_operand:DI 0 "register_operand" "=r")
10465 (zero_extend:DI (not:SI (match_dup 1))))]
10466 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10467 && ix86_unary_operator_ok (NOT, SImode, operands)"
10469 [(set_attr "type" "alu1")
10470 (set_attr "mode" "SI")])
10473 [(set (match_operand 0 "flags_reg_operand" "")
10474 (match_operator 2 "compare_operator"
10475 [(not:SI (match_operand:SI 3 "register_operand" ""))
10477 (set (match_operand:DI 1 "register_operand" "")
10478 (zero_extend:DI (not:SI (match_dup 3))))]
10479 "ix86_match_ccmode (insn, CCNOmode)"
10480 [(parallel [(set (match_dup 0)
10481 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10484 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10487 (define_expand "one_cmplhi2"
10488 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10489 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10490 "TARGET_HIMODE_MATH"
10491 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10493 (define_insn "*one_cmplhi2_1"
10494 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10495 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10496 "ix86_unary_operator_ok (NOT, HImode, operands)"
10498 [(set_attr "type" "negnot")
10499 (set_attr "mode" "HI")])
10501 (define_insn "*one_cmplhi2_2"
10502 [(set (reg FLAGS_REG)
10503 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10505 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10506 (not:HI (match_dup 1)))]
10507 "ix86_match_ccmode (insn, CCNOmode)
10508 && ix86_unary_operator_ok (NEG, HImode, operands)"
10510 [(set_attr "type" "alu1")
10511 (set_attr "mode" "HI")])
10514 [(set (match_operand 0 "flags_reg_operand" "")
10515 (match_operator 2 "compare_operator"
10516 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10518 (set (match_operand:HI 1 "nonimmediate_operand" "")
10519 (not:HI (match_dup 3)))]
10520 "ix86_match_ccmode (insn, CCNOmode)"
10521 [(parallel [(set (match_dup 0)
10522 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10525 (xor:HI (match_dup 3) (const_int -1)))])]
10528 ;; %%% Potential partial reg stall on alternative 1. What to do?
10529 (define_expand "one_cmplqi2"
10530 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10531 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10532 "TARGET_QIMODE_MATH"
10533 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10535 (define_insn "*one_cmplqi2_1"
10536 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10537 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10538 "ix86_unary_operator_ok (NOT, QImode, operands)"
10542 [(set_attr "type" "negnot")
10543 (set_attr "mode" "QI,SI")])
10545 (define_insn "*one_cmplqi2_2"
10546 [(set (reg FLAGS_REG)
10547 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10549 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10550 (not:QI (match_dup 1)))]
10551 "ix86_match_ccmode (insn, CCNOmode)
10552 && ix86_unary_operator_ok (NOT, QImode, operands)"
10554 [(set_attr "type" "alu1")
10555 (set_attr "mode" "QI")])
10558 [(set (match_operand 0 "flags_reg_operand" "")
10559 (match_operator 2 "compare_operator"
10560 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10562 (set (match_operand:QI 1 "nonimmediate_operand" "")
10563 (not:QI (match_dup 3)))]
10564 "ix86_match_ccmode (insn, CCNOmode)"
10565 [(parallel [(set (match_dup 0)
10566 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10569 (xor:QI (match_dup 3) (const_int -1)))])]
10572 ;; Arithmetic shift instructions
10574 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10575 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10576 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10577 ;; from the assembler input.
10579 ;; This instruction shifts the target reg/mem as usual, but instead of
10580 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10581 ;; is a left shift double, bits are taken from the high order bits of
10582 ;; reg, else if the insn is a shift right double, bits are taken from the
10583 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10584 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10586 ;; Since sh[lr]d does not change the `reg' operand, that is done
10587 ;; separately, making all shifts emit pairs of shift double and normal
10588 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10589 ;; support a 63 bit shift, each shift where the count is in a reg expands
10590 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10592 ;; If the shift count is a constant, we need never emit more than one
10593 ;; shift pair, instead using moves and sign extension for counts greater
10596 (define_expand "ashlti3"
10597 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10598 (ashift:TI (match_operand:TI 1 "register_operand" "")
10599 (match_operand:QI 2 "nonmemory_operand" "")))
10600 (clobber (reg:CC FLAGS_REG))])]
10603 if (! immediate_operand (operands[2], QImode))
10605 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10608 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10612 (define_insn "ashlti3_1"
10613 [(set (match_operand:TI 0 "register_operand" "=r")
10614 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10615 (match_operand:QI 2 "register_operand" "c")))
10616 (clobber (match_scratch:DI 3 "=&r"))
10617 (clobber (reg:CC FLAGS_REG))]
10620 [(set_attr "type" "multi")])
10622 (define_insn "*ashlti3_2"
10623 [(set (match_operand:TI 0 "register_operand" "=r")
10624 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10625 (match_operand:QI 2 "immediate_operand" "O")))
10626 (clobber (reg:CC FLAGS_REG))]
10629 [(set_attr "type" "multi")])
10632 [(set (match_operand:TI 0 "register_operand" "")
10633 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10634 (match_operand:QI 2 "register_operand" "")))
10635 (clobber (match_scratch:DI 3 ""))
10636 (clobber (reg:CC FLAGS_REG))]
10637 "TARGET_64BIT && reload_completed"
10639 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10642 [(set (match_operand:TI 0 "register_operand" "")
10643 (ashift:TI (match_operand:TI 1 "register_operand" "")
10644 (match_operand:QI 2 "immediate_operand" "")))
10645 (clobber (reg:CC FLAGS_REG))]
10646 "TARGET_64BIT && reload_completed"
10648 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10650 (define_insn "x86_64_shld"
10651 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10652 (ior:DI (ashift:DI (match_dup 0)
10653 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10654 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10655 (minus:QI (const_int 64) (match_dup 2)))))
10656 (clobber (reg:CC FLAGS_REG))]
10659 shld{q}\t{%2, %1, %0|%0, %1, %2}
10660 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10661 [(set_attr "type" "ishift")
10662 (set_attr "prefix_0f" "1")
10663 (set_attr "mode" "DI")
10664 (set_attr "athlon_decode" "vector")
10665 (set_attr "amdfam10_decode" "vector")])
10667 (define_expand "x86_64_shift_adj"
10668 [(set (reg:CCZ FLAGS_REG)
10669 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10672 (set (match_operand:DI 0 "register_operand" "")
10673 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10674 (match_operand:DI 1 "register_operand" "")
10677 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10678 (match_operand:DI 3 "register_operand" "r")
10683 (define_expand "ashldi3"
10684 [(set (match_operand:DI 0 "shiftdi_operand" "")
10685 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10686 (match_operand:QI 2 "nonmemory_operand" "")))]
10688 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10690 (define_insn "*ashldi3_1_rex64"
10691 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10692 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10693 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10694 (clobber (reg:CC FLAGS_REG))]
10695 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10697 switch (get_attr_type (insn))
10700 gcc_assert (operands[2] == const1_rtx);
10701 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10702 return "add{q}\t%0, %0";
10705 gcc_assert (CONST_INT_P (operands[2]));
10706 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10707 operands[1] = gen_rtx_MULT (DImode, operands[1],
10708 GEN_INT (1 << INTVAL (operands[2])));
10709 return "lea{q}\t{%a1, %0|%0, %a1}";
10712 if (REG_P (operands[2]))
10713 return "sal{q}\t{%b2, %0|%0, %b2}";
10714 else if (operands[2] == const1_rtx
10715 && (TARGET_SHIFT1 || optimize_size))
10716 return "sal{q}\t%0";
10718 return "sal{q}\t{%2, %0|%0, %2}";
10721 [(set (attr "type")
10722 (cond [(eq_attr "alternative" "1")
10723 (const_string "lea")
10724 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10726 (match_operand 0 "register_operand" ""))
10727 (match_operand 2 "const1_operand" ""))
10728 (const_string "alu")
10730 (const_string "ishift")))
10731 (set_attr "mode" "DI")])
10733 ;; Convert lea to the lea pattern to avoid flags dependency.
10735 [(set (match_operand:DI 0 "register_operand" "")
10736 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10737 (match_operand:QI 2 "immediate_operand" "")))
10738 (clobber (reg:CC FLAGS_REG))]
10739 "TARGET_64BIT && reload_completed
10740 && true_regnum (operands[0]) != true_regnum (operands[1])"
10741 [(set (match_dup 0)
10742 (mult:DI (match_dup 1)
10744 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10746 ;; This pattern can't accept a variable shift count, since shifts by
10747 ;; zero don't affect the flags. We assume that shifts by constant
10748 ;; zero are optimized away.
10749 (define_insn "*ashldi3_cmp_rex64"
10750 [(set (reg FLAGS_REG)
10752 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10753 (match_operand:QI 2 "immediate_operand" "e"))
10755 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10756 (ashift:DI (match_dup 1) (match_dup 2)))]
10757 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10758 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10760 || !TARGET_PARTIAL_FLAG_REG_STALL
10761 || (operands[2] == const1_rtx
10763 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10765 switch (get_attr_type (insn))
10768 gcc_assert (operands[2] == const1_rtx);
10769 return "add{q}\t%0, %0";
10772 if (REG_P (operands[2]))
10773 return "sal{q}\t{%b2, %0|%0, %b2}";
10774 else if (operands[2] == const1_rtx
10775 && (TARGET_SHIFT1 || optimize_size))
10776 return "sal{q}\t%0";
10778 return "sal{q}\t{%2, %0|%0, %2}";
10781 [(set (attr "type")
10782 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10784 (match_operand 0 "register_operand" ""))
10785 (match_operand 2 "const1_operand" ""))
10786 (const_string "alu")
10788 (const_string "ishift")))
10789 (set_attr "mode" "DI")])
10791 (define_insn "*ashldi3_cconly_rex64"
10792 [(set (reg FLAGS_REG)
10794 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10795 (match_operand:QI 2 "immediate_operand" "e"))
10797 (clobber (match_scratch:DI 0 "=r"))]
10798 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10799 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10801 || !TARGET_PARTIAL_FLAG_REG_STALL
10802 || (operands[2] == const1_rtx
10804 || TARGET_DOUBLE_WITH_ADD)))"
10806 switch (get_attr_type (insn))
10809 gcc_assert (operands[2] == const1_rtx);
10810 return "add{q}\t%0, %0";
10813 if (REG_P (operands[2]))
10814 return "sal{q}\t{%b2, %0|%0, %b2}";
10815 else if (operands[2] == const1_rtx
10816 && (TARGET_SHIFT1 || optimize_size))
10817 return "sal{q}\t%0";
10819 return "sal{q}\t{%2, %0|%0, %2}";
10822 [(set (attr "type")
10823 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10825 (match_operand 0 "register_operand" ""))
10826 (match_operand 2 "const1_operand" ""))
10827 (const_string "alu")
10829 (const_string "ishift")))
10830 (set_attr "mode" "DI")])
10832 (define_insn "*ashldi3_1"
10833 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10834 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10835 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10836 (clobber (reg:CC FLAGS_REG))]
10839 [(set_attr "type" "multi")])
10841 ;; By default we don't ask for a scratch register, because when DImode
10842 ;; values are manipulated, registers are already at a premium. But if
10843 ;; we have one handy, we won't turn it away.
10845 [(match_scratch:SI 3 "r")
10846 (parallel [(set (match_operand:DI 0 "register_operand" "")
10847 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10848 (match_operand:QI 2 "nonmemory_operand" "")))
10849 (clobber (reg:CC FLAGS_REG))])
10851 "!TARGET_64BIT && TARGET_CMOVE"
10853 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10856 [(set (match_operand:DI 0 "register_operand" "")
10857 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10858 (match_operand:QI 2 "nonmemory_operand" "")))
10859 (clobber (reg:CC FLAGS_REG))]
10860 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10861 ? flow2_completed : reload_completed)"
10863 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10865 (define_insn "x86_shld_1"
10866 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10867 (ior:SI (ashift:SI (match_dup 0)
10868 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10869 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10870 (minus:QI (const_int 32) (match_dup 2)))))
10871 (clobber (reg:CC FLAGS_REG))]
10874 shld{l}\t{%2, %1, %0|%0, %1, %2}
10875 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10876 [(set_attr "type" "ishift")
10877 (set_attr "prefix_0f" "1")
10878 (set_attr "mode" "SI")
10879 (set_attr "pent_pair" "np")
10880 (set_attr "athlon_decode" "vector")
10881 (set_attr "amdfam10_decode" "vector")])
10883 (define_expand "x86_shift_adj_1"
10884 [(set (reg:CCZ FLAGS_REG)
10885 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10888 (set (match_operand:SI 0 "register_operand" "")
10889 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10890 (match_operand:SI 1 "register_operand" "")
10893 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10894 (match_operand:SI 3 "register_operand" "r")
10899 (define_expand "x86_shift_adj_2"
10900 [(use (match_operand:SI 0 "register_operand" ""))
10901 (use (match_operand:SI 1 "register_operand" ""))
10902 (use (match_operand:QI 2 "register_operand" ""))]
10905 rtx label = gen_label_rtx ();
10908 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10910 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10911 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10912 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10913 gen_rtx_LABEL_REF (VOIDmode, label),
10915 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10916 JUMP_LABEL (tmp) = label;
10918 emit_move_insn (operands[0], operands[1]);
10919 ix86_expand_clear (operands[1]);
10921 emit_label (label);
10922 LABEL_NUSES (label) = 1;
10927 (define_expand "ashlsi3"
10928 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10929 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10930 (match_operand:QI 2 "nonmemory_operand" "")))
10931 (clobber (reg:CC FLAGS_REG))]
10933 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10935 (define_insn "*ashlsi3_1"
10936 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10937 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10938 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10939 (clobber (reg:CC FLAGS_REG))]
10940 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10942 switch (get_attr_type (insn))
10945 gcc_assert (operands[2] == const1_rtx);
10946 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10947 return "add{l}\t%0, %0";
10953 if (REG_P (operands[2]))
10954 return "sal{l}\t{%b2, %0|%0, %b2}";
10955 else if (operands[2] == const1_rtx
10956 && (TARGET_SHIFT1 || optimize_size))
10957 return "sal{l}\t%0";
10959 return "sal{l}\t{%2, %0|%0, %2}";
10962 [(set (attr "type")
10963 (cond [(eq_attr "alternative" "1")
10964 (const_string "lea")
10965 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10967 (match_operand 0 "register_operand" ""))
10968 (match_operand 2 "const1_operand" ""))
10969 (const_string "alu")
10971 (const_string "ishift")))
10972 (set_attr "mode" "SI")])
10974 ;; Convert lea to the lea pattern to avoid flags dependency.
10976 [(set (match_operand 0 "register_operand" "")
10977 (ashift (match_operand 1 "index_register_operand" "")
10978 (match_operand:QI 2 "const_int_operand" "")))
10979 (clobber (reg:CC FLAGS_REG))]
10981 && true_regnum (operands[0]) != true_regnum (operands[1])
10982 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10986 enum machine_mode mode = GET_MODE (operands[0]);
10988 if (GET_MODE_SIZE (mode) < 4)
10989 operands[0] = gen_lowpart (SImode, operands[0]);
10991 operands[1] = gen_lowpart (Pmode, operands[1]);
10992 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10994 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10995 if (Pmode != SImode)
10996 pat = gen_rtx_SUBREG (SImode, pat, 0);
10997 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11001 ;; Rare case of shifting RSP is handled by generating move and shift
11003 [(set (match_operand 0 "register_operand" "")
11004 (ashift (match_operand 1 "register_operand" "")
11005 (match_operand:QI 2 "const_int_operand" "")))
11006 (clobber (reg:CC FLAGS_REG))]
11008 && true_regnum (operands[0]) != true_regnum (operands[1])"
11012 emit_move_insn (operands[0], operands[1]);
11013 pat = gen_rtx_SET (VOIDmode, operands[0],
11014 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11015 operands[0], operands[2]));
11016 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11017 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11021 (define_insn "*ashlsi3_1_zext"
11022 [(set (match_operand:DI 0 "register_operand" "=r,r")
11023 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11024 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11025 (clobber (reg:CC FLAGS_REG))]
11026 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11028 switch (get_attr_type (insn))
11031 gcc_assert (operands[2] == const1_rtx);
11032 return "add{l}\t%k0, %k0";
11038 if (REG_P (operands[2]))
11039 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11040 else if (operands[2] == const1_rtx
11041 && (TARGET_SHIFT1 || optimize_size))
11042 return "sal{l}\t%k0";
11044 return "sal{l}\t{%2, %k0|%k0, %2}";
11047 [(set (attr "type")
11048 (cond [(eq_attr "alternative" "1")
11049 (const_string "lea")
11050 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11052 (match_operand 2 "const1_operand" ""))
11053 (const_string "alu")
11055 (const_string "ishift")))
11056 (set_attr "mode" "SI")])
11058 ;; Convert lea to the lea pattern to avoid flags dependency.
11060 [(set (match_operand:DI 0 "register_operand" "")
11061 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11062 (match_operand:QI 2 "const_int_operand" ""))))
11063 (clobber (reg:CC FLAGS_REG))]
11064 "TARGET_64BIT && reload_completed
11065 && true_regnum (operands[0]) != true_regnum (operands[1])"
11066 [(set (match_dup 0) (zero_extend:DI
11067 (subreg:SI (mult:SI (match_dup 1)
11068 (match_dup 2)) 0)))]
11070 operands[1] = gen_lowpart (Pmode, operands[1]);
11071 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11074 ;; This pattern can't accept a variable shift count, since shifts by
11075 ;; zero don't affect the flags. We assume that shifts by constant
11076 ;; zero are optimized away.
11077 (define_insn "*ashlsi3_cmp"
11078 [(set (reg FLAGS_REG)
11080 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11081 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11083 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11084 (ashift:SI (match_dup 1) (match_dup 2)))]
11085 "ix86_match_ccmode (insn, CCGOCmode)
11086 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11088 || !TARGET_PARTIAL_FLAG_REG_STALL
11089 || (operands[2] == const1_rtx
11091 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11093 switch (get_attr_type (insn))
11096 gcc_assert (operands[2] == const1_rtx);
11097 return "add{l}\t%0, %0";
11100 if (REG_P (operands[2]))
11101 return "sal{l}\t{%b2, %0|%0, %b2}";
11102 else if (operands[2] == const1_rtx
11103 && (TARGET_SHIFT1 || optimize_size))
11104 return "sal{l}\t%0";
11106 return "sal{l}\t{%2, %0|%0, %2}";
11109 [(set (attr "type")
11110 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11112 (match_operand 0 "register_operand" ""))
11113 (match_operand 2 "const1_operand" ""))
11114 (const_string "alu")
11116 (const_string "ishift")))
11117 (set_attr "mode" "SI")])
11119 (define_insn "*ashlsi3_cconly"
11120 [(set (reg FLAGS_REG)
11122 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11123 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11125 (clobber (match_scratch:SI 0 "=r"))]
11126 "ix86_match_ccmode (insn, CCGOCmode)
11127 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11129 || !TARGET_PARTIAL_FLAG_REG_STALL
11130 || (operands[2] == const1_rtx
11132 || TARGET_DOUBLE_WITH_ADD)))"
11134 switch (get_attr_type (insn))
11137 gcc_assert (operands[2] == const1_rtx);
11138 return "add{l}\t%0, %0";
11141 if (REG_P (operands[2]))
11142 return "sal{l}\t{%b2, %0|%0, %b2}";
11143 else if (operands[2] == const1_rtx
11144 && (TARGET_SHIFT1 || optimize_size))
11145 return "sal{l}\t%0";
11147 return "sal{l}\t{%2, %0|%0, %2}";
11150 [(set (attr "type")
11151 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11153 (match_operand 0 "register_operand" ""))
11154 (match_operand 2 "const1_operand" ""))
11155 (const_string "alu")
11157 (const_string "ishift")))
11158 (set_attr "mode" "SI")])
11160 (define_insn "*ashlsi3_cmp_zext"
11161 [(set (reg FLAGS_REG)
11163 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11164 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11166 (set (match_operand:DI 0 "register_operand" "=r")
11167 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11168 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11169 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11171 || !TARGET_PARTIAL_FLAG_REG_STALL
11172 || (operands[2] == const1_rtx
11174 || TARGET_DOUBLE_WITH_ADD)))"
11176 switch (get_attr_type (insn))
11179 gcc_assert (operands[2] == const1_rtx);
11180 return "add{l}\t%k0, %k0";
11183 if (REG_P (operands[2]))
11184 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11185 else if (operands[2] == const1_rtx
11186 && (TARGET_SHIFT1 || optimize_size))
11187 return "sal{l}\t%k0";
11189 return "sal{l}\t{%2, %k0|%k0, %2}";
11192 [(set (attr "type")
11193 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11195 (match_operand 2 "const1_operand" ""))
11196 (const_string "alu")
11198 (const_string "ishift")))
11199 (set_attr "mode" "SI")])
11201 (define_expand "ashlhi3"
11202 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11203 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11204 (match_operand:QI 2 "nonmemory_operand" "")))
11205 (clobber (reg:CC FLAGS_REG))]
11206 "TARGET_HIMODE_MATH"
11207 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11209 (define_insn "*ashlhi3_1_lea"
11210 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11211 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11212 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11213 (clobber (reg:CC FLAGS_REG))]
11214 "!TARGET_PARTIAL_REG_STALL
11215 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11217 switch (get_attr_type (insn))
11222 gcc_assert (operands[2] == const1_rtx);
11223 return "add{w}\t%0, %0";
11226 if (REG_P (operands[2]))
11227 return "sal{w}\t{%b2, %0|%0, %b2}";
11228 else if (operands[2] == const1_rtx
11229 && (TARGET_SHIFT1 || optimize_size))
11230 return "sal{w}\t%0";
11232 return "sal{w}\t{%2, %0|%0, %2}";
11235 [(set (attr "type")
11236 (cond [(eq_attr "alternative" "1")
11237 (const_string "lea")
11238 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11240 (match_operand 0 "register_operand" ""))
11241 (match_operand 2 "const1_operand" ""))
11242 (const_string "alu")
11244 (const_string "ishift")))
11245 (set_attr "mode" "HI,SI")])
11247 (define_insn "*ashlhi3_1"
11248 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11249 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11250 (match_operand:QI 2 "nonmemory_operand" "cI")))
11251 (clobber (reg:CC FLAGS_REG))]
11252 "TARGET_PARTIAL_REG_STALL
11253 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11255 switch (get_attr_type (insn))
11258 gcc_assert (operands[2] == const1_rtx);
11259 return "add{w}\t%0, %0";
11262 if (REG_P (operands[2]))
11263 return "sal{w}\t{%b2, %0|%0, %b2}";
11264 else if (operands[2] == const1_rtx
11265 && (TARGET_SHIFT1 || optimize_size))
11266 return "sal{w}\t%0";
11268 return "sal{w}\t{%2, %0|%0, %2}";
11271 [(set (attr "type")
11272 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11274 (match_operand 0 "register_operand" ""))
11275 (match_operand 2 "const1_operand" ""))
11276 (const_string "alu")
11278 (const_string "ishift")))
11279 (set_attr "mode" "HI")])
11281 ;; This pattern can't accept a variable shift count, since shifts by
11282 ;; zero don't affect the flags. We assume that shifts by constant
11283 ;; zero are optimized away.
11284 (define_insn "*ashlhi3_cmp"
11285 [(set (reg FLAGS_REG)
11287 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11288 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11290 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11291 (ashift:HI (match_dup 1) (match_dup 2)))]
11292 "ix86_match_ccmode (insn, CCGOCmode)
11293 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11295 || !TARGET_PARTIAL_FLAG_REG_STALL
11296 || (operands[2] == const1_rtx
11298 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11300 switch (get_attr_type (insn))
11303 gcc_assert (operands[2] == const1_rtx);
11304 return "add{w}\t%0, %0";
11307 if (REG_P (operands[2]))
11308 return "sal{w}\t{%b2, %0|%0, %b2}";
11309 else if (operands[2] == const1_rtx
11310 && (TARGET_SHIFT1 || optimize_size))
11311 return "sal{w}\t%0";
11313 return "sal{w}\t{%2, %0|%0, %2}";
11316 [(set (attr "type")
11317 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11319 (match_operand 0 "register_operand" ""))
11320 (match_operand 2 "const1_operand" ""))
11321 (const_string "alu")
11323 (const_string "ishift")))
11324 (set_attr "mode" "HI")])
11326 (define_insn "*ashlhi3_cconly"
11327 [(set (reg FLAGS_REG)
11329 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11330 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11332 (clobber (match_scratch:HI 0 "=r"))]
11333 "ix86_match_ccmode (insn, CCGOCmode)
11334 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11336 || !TARGET_PARTIAL_FLAG_REG_STALL
11337 || (operands[2] == const1_rtx
11339 || TARGET_DOUBLE_WITH_ADD)))"
11341 switch (get_attr_type (insn))
11344 gcc_assert (operands[2] == const1_rtx);
11345 return "add{w}\t%0, %0";
11348 if (REG_P (operands[2]))
11349 return "sal{w}\t{%b2, %0|%0, %b2}";
11350 else if (operands[2] == const1_rtx
11351 && (TARGET_SHIFT1 || optimize_size))
11352 return "sal{w}\t%0";
11354 return "sal{w}\t{%2, %0|%0, %2}";
11357 [(set (attr "type")
11358 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11360 (match_operand 0 "register_operand" ""))
11361 (match_operand 2 "const1_operand" ""))
11362 (const_string "alu")
11364 (const_string "ishift")))
11365 (set_attr "mode" "HI")])
11367 (define_expand "ashlqi3"
11368 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11369 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11370 (match_operand:QI 2 "nonmemory_operand" "")))
11371 (clobber (reg:CC FLAGS_REG))]
11372 "TARGET_QIMODE_MATH"
11373 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11375 ;; %%% Potential partial reg stall on alternative 2. What to do?
11377 (define_insn "*ashlqi3_1_lea"
11378 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11379 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11380 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11381 (clobber (reg:CC FLAGS_REG))]
11382 "!TARGET_PARTIAL_REG_STALL
11383 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11385 switch (get_attr_type (insn))
11390 gcc_assert (operands[2] == const1_rtx);
11391 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11392 return "add{l}\t%k0, %k0";
11394 return "add{b}\t%0, %0";
11397 if (REG_P (operands[2]))
11399 if (get_attr_mode (insn) == MODE_SI)
11400 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11402 return "sal{b}\t{%b2, %0|%0, %b2}";
11404 else if (operands[2] == const1_rtx
11405 && (TARGET_SHIFT1 || optimize_size))
11407 if (get_attr_mode (insn) == MODE_SI)
11408 return "sal{l}\t%0";
11410 return "sal{b}\t%0";
11414 if (get_attr_mode (insn) == MODE_SI)
11415 return "sal{l}\t{%2, %k0|%k0, %2}";
11417 return "sal{b}\t{%2, %0|%0, %2}";
11421 [(set (attr "type")
11422 (cond [(eq_attr "alternative" "2")
11423 (const_string "lea")
11424 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11426 (match_operand 0 "register_operand" ""))
11427 (match_operand 2 "const1_operand" ""))
11428 (const_string "alu")
11430 (const_string "ishift")))
11431 (set_attr "mode" "QI,SI,SI")])
11433 (define_insn "*ashlqi3_1"
11434 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11435 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11436 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11437 (clobber (reg:CC FLAGS_REG))]
11438 "TARGET_PARTIAL_REG_STALL
11439 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11441 switch (get_attr_type (insn))
11444 gcc_assert (operands[2] == const1_rtx);
11445 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11446 return "add{l}\t%k0, %k0";
11448 return "add{b}\t%0, %0";
11451 if (REG_P (operands[2]))
11453 if (get_attr_mode (insn) == MODE_SI)
11454 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11456 return "sal{b}\t{%b2, %0|%0, %b2}";
11458 else if (operands[2] == const1_rtx
11459 && (TARGET_SHIFT1 || optimize_size))
11461 if (get_attr_mode (insn) == MODE_SI)
11462 return "sal{l}\t%0";
11464 return "sal{b}\t%0";
11468 if (get_attr_mode (insn) == MODE_SI)
11469 return "sal{l}\t{%2, %k0|%k0, %2}";
11471 return "sal{b}\t{%2, %0|%0, %2}";
11475 [(set (attr "type")
11476 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11478 (match_operand 0 "register_operand" ""))
11479 (match_operand 2 "const1_operand" ""))
11480 (const_string "alu")
11482 (const_string "ishift")))
11483 (set_attr "mode" "QI,SI")])
11485 ;; This pattern can't accept a variable shift count, since shifts by
11486 ;; zero don't affect the flags. We assume that shifts by constant
11487 ;; zero are optimized away.
11488 (define_insn "*ashlqi3_cmp"
11489 [(set (reg FLAGS_REG)
11491 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11492 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11494 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11495 (ashift:QI (match_dup 1) (match_dup 2)))]
11496 "ix86_match_ccmode (insn, CCGOCmode)
11497 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11499 || !TARGET_PARTIAL_FLAG_REG_STALL
11500 || (operands[2] == const1_rtx
11502 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11504 switch (get_attr_type (insn))
11507 gcc_assert (operands[2] == const1_rtx);
11508 return "add{b}\t%0, %0";
11511 if (REG_P (operands[2]))
11512 return "sal{b}\t{%b2, %0|%0, %b2}";
11513 else if (operands[2] == const1_rtx
11514 && (TARGET_SHIFT1 || optimize_size))
11515 return "sal{b}\t%0";
11517 return "sal{b}\t{%2, %0|%0, %2}";
11520 [(set (attr "type")
11521 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11523 (match_operand 0 "register_operand" ""))
11524 (match_operand 2 "const1_operand" ""))
11525 (const_string "alu")
11527 (const_string "ishift")))
11528 (set_attr "mode" "QI")])
11530 (define_insn "*ashlqi3_cconly"
11531 [(set (reg FLAGS_REG)
11533 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11534 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11536 (clobber (match_scratch:QI 0 "=q"))]
11537 "ix86_match_ccmode (insn, CCGOCmode)
11538 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11540 || !TARGET_PARTIAL_FLAG_REG_STALL
11541 || (operands[2] == const1_rtx
11543 || TARGET_DOUBLE_WITH_ADD)))"
11545 switch (get_attr_type (insn))
11548 gcc_assert (operands[2] == const1_rtx);
11549 return "add{b}\t%0, %0";
11552 if (REG_P (operands[2]))
11553 return "sal{b}\t{%b2, %0|%0, %b2}";
11554 else if (operands[2] == const1_rtx
11555 && (TARGET_SHIFT1 || optimize_size))
11556 return "sal{b}\t%0";
11558 return "sal{b}\t{%2, %0|%0, %2}";
11561 [(set (attr "type")
11562 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11564 (match_operand 0 "register_operand" ""))
11565 (match_operand 2 "const1_operand" ""))
11566 (const_string "alu")
11568 (const_string "ishift")))
11569 (set_attr "mode" "QI")])
11571 ;; See comment above `ashldi3' about how this works.
11573 (define_expand "ashrti3"
11574 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11575 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11576 (match_operand:QI 2 "nonmemory_operand" "")))
11577 (clobber (reg:CC FLAGS_REG))])]
11580 if (! immediate_operand (operands[2], QImode))
11582 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11585 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11589 (define_insn "ashrti3_1"
11590 [(set (match_operand:TI 0 "register_operand" "=r")
11591 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11592 (match_operand:QI 2 "register_operand" "c")))
11593 (clobber (match_scratch:DI 3 "=&r"))
11594 (clobber (reg:CC FLAGS_REG))]
11597 [(set_attr "type" "multi")])
11599 (define_insn "*ashrti3_2"
11600 [(set (match_operand:TI 0 "register_operand" "=r")
11601 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11602 (match_operand:QI 2 "immediate_operand" "O")))
11603 (clobber (reg:CC FLAGS_REG))]
11606 [(set_attr "type" "multi")])
11609 [(set (match_operand:TI 0 "register_operand" "")
11610 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11611 (match_operand:QI 2 "register_operand" "")))
11612 (clobber (match_scratch:DI 3 ""))
11613 (clobber (reg:CC FLAGS_REG))]
11614 "TARGET_64BIT && reload_completed"
11616 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11619 [(set (match_operand:TI 0 "register_operand" "")
11620 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11621 (match_operand:QI 2 "immediate_operand" "")))
11622 (clobber (reg:CC FLAGS_REG))]
11623 "TARGET_64BIT && reload_completed"
11625 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11627 (define_insn "x86_64_shrd"
11628 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11629 (ior:DI (ashiftrt:DI (match_dup 0)
11630 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11631 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11632 (minus:QI (const_int 64) (match_dup 2)))))
11633 (clobber (reg:CC FLAGS_REG))]
11636 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11637 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11638 [(set_attr "type" "ishift")
11639 (set_attr "prefix_0f" "1")
11640 (set_attr "mode" "DI")
11641 (set_attr "athlon_decode" "vector")
11642 (set_attr "amdfam10_decode" "vector")])
11644 (define_expand "ashrdi3"
11645 [(set (match_operand:DI 0 "shiftdi_operand" "")
11646 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11647 (match_operand:QI 2 "nonmemory_operand" "")))]
11649 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11651 (define_insn "*ashrdi3_63_rex64"
11652 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11653 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11654 (match_operand:DI 2 "const_int_operand" "i,i")))
11655 (clobber (reg:CC FLAGS_REG))]
11656 "TARGET_64BIT && INTVAL (operands[2]) == 63
11657 && (TARGET_USE_CLTD || optimize_size)
11658 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11661 sar{q}\t{%2, %0|%0, %2}"
11662 [(set_attr "type" "imovx,ishift")
11663 (set_attr "prefix_0f" "0,*")
11664 (set_attr "length_immediate" "0,*")
11665 (set_attr "modrm" "0,1")
11666 (set_attr "mode" "DI")])
11668 (define_insn "*ashrdi3_1_one_bit_rex64"
11669 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11670 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11671 (match_operand:QI 2 "const1_operand" "")))
11672 (clobber (reg:CC FLAGS_REG))]
11673 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11674 && (TARGET_SHIFT1 || optimize_size)"
11676 [(set_attr "type" "ishift")
11677 (set (attr "length")
11678 (if_then_else (match_operand:DI 0 "register_operand" "")
11680 (const_string "*")))])
11682 (define_insn "*ashrdi3_1_rex64"
11683 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11684 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11685 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11686 (clobber (reg:CC FLAGS_REG))]
11687 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11689 sar{q}\t{%2, %0|%0, %2}
11690 sar{q}\t{%b2, %0|%0, %b2}"
11691 [(set_attr "type" "ishift")
11692 (set_attr "mode" "DI")])
11694 ;; This pattern can't accept a variable shift count, since shifts by
11695 ;; zero don't affect the flags. We assume that shifts by constant
11696 ;; zero are optimized away.
11697 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11698 [(set (reg FLAGS_REG)
11700 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11701 (match_operand:QI 2 "const1_operand" ""))
11703 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11704 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11705 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11706 && (TARGET_SHIFT1 || optimize_size)
11707 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11709 [(set_attr "type" "ishift")
11710 (set (attr "length")
11711 (if_then_else (match_operand:DI 0 "register_operand" "")
11713 (const_string "*")))])
11715 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11716 [(set (reg FLAGS_REG)
11718 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11719 (match_operand:QI 2 "const1_operand" ""))
11721 (clobber (match_scratch:DI 0 "=r"))]
11722 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11723 && (TARGET_SHIFT1 || optimize_size)
11724 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11726 [(set_attr "type" "ishift")
11727 (set_attr "length" "2")])
11729 ;; This pattern can't accept a variable shift count, since shifts by
11730 ;; zero don't affect the flags. We assume that shifts by constant
11731 ;; zero are optimized away.
11732 (define_insn "*ashrdi3_cmp_rex64"
11733 [(set (reg FLAGS_REG)
11735 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11736 (match_operand:QI 2 "const_int_operand" "n"))
11738 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11739 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11740 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11741 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11743 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11744 "sar{q}\t{%2, %0|%0, %2}"
11745 [(set_attr "type" "ishift")
11746 (set_attr "mode" "DI")])
11748 (define_insn "*ashrdi3_cconly_rex64"
11749 [(set (reg FLAGS_REG)
11751 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11752 (match_operand:QI 2 "const_int_operand" "n"))
11754 (clobber (match_scratch:DI 0 "=r"))]
11755 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11756 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11758 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11759 "sar{q}\t{%2, %0|%0, %2}"
11760 [(set_attr "type" "ishift")
11761 (set_attr "mode" "DI")])
11763 (define_insn "*ashrdi3_1"
11764 [(set (match_operand:DI 0 "register_operand" "=r")
11765 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11766 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11767 (clobber (reg:CC FLAGS_REG))]
11770 [(set_attr "type" "multi")])
11772 ;; By default we don't ask for a scratch register, because when DImode
11773 ;; values are manipulated, registers are already at a premium. But if
11774 ;; we have one handy, we won't turn it away.
11776 [(match_scratch:SI 3 "r")
11777 (parallel [(set (match_operand:DI 0 "register_operand" "")
11778 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11779 (match_operand:QI 2 "nonmemory_operand" "")))
11780 (clobber (reg:CC FLAGS_REG))])
11782 "!TARGET_64BIT && TARGET_CMOVE"
11784 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11787 [(set (match_operand:DI 0 "register_operand" "")
11788 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11789 (match_operand:QI 2 "nonmemory_operand" "")))
11790 (clobber (reg:CC FLAGS_REG))]
11791 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11792 ? flow2_completed : reload_completed)"
11794 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11796 (define_insn "x86_shrd_1"
11797 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11798 (ior:SI (ashiftrt:SI (match_dup 0)
11799 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11800 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11801 (minus:QI (const_int 32) (match_dup 2)))))
11802 (clobber (reg:CC FLAGS_REG))]
11805 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11806 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11807 [(set_attr "type" "ishift")
11808 (set_attr "prefix_0f" "1")
11809 (set_attr "pent_pair" "np")
11810 (set_attr "mode" "SI")])
11812 (define_expand "x86_shift_adj_3"
11813 [(use (match_operand:SI 0 "register_operand" ""))
11814 (use (match_operand:SI 1 "register_operand" ""))
11815 (use (match_operand:QI 2 "register_operand" ""))]
11818 rtx label = gen_label_rtx ();
11821 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11823 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11824 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11825 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11826 gen_rtx_LABEL_REF (VOIDmode, label),
11828 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11829 JUMP_LABEL (tmp) = label;
11831 emit_move_insn (operands[0], operands[1]);
11832 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11834 emit_label (label);
11835 LABEL_NUSES (label) = 1;
11840 (define_insn "ashrsi3_31"
11841 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11842 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11843 (match_operand:SI 2 "const_int_operand" "i,i")))
11844 (clobber (reg:CC FLAGS_REG))]
11845 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11846 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11849 sar{l}\t{%2, %0|%0, %2}"
11850 [(set_attr "type" "imovx,ishift")
11851 (set_attr "prefix_0f" "0,*")
11852 (set_attr "length_immediate" "0,*")
11853 (set_attr "modrm" "0,1")
11854 (set_attr "mode" "SI")])
11856 (define_insn "*ashrsi3_31_zext"
11857 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11858 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11859 (match_operand:SI 2 "const_int_operand" "i,i"))))
11860 (clobber (reg:CC FLAGS_REG))]
11861 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11862 && INTVAL (operands[2]) == 31
11863 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11866 sar{l}\t{%2, %k0|%k0, %2}"
11867 [(set_attr "type" "imovx,ishift")
11868 (set_attr "prefix_0f" "0,*")
11869 (set_attr "length_immediate" "0,*")
11870 (set_attr "modrm" "0,1")
11871 (set_attr "mode" "SI")])
11873 (define_expand "ashrsi3"
11874 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11875 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11876 (match_operand:QI 2 "nonmemory_operand" "")))
11877 (clobber (reg:CC FLAGS_REG))]
11879 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11881 (define_insn "*ashrsi3_1_one_bit"
11882 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11883 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11884 (match_operand:QI 2 "const1_operand" "")))
11885 (clobber (reg:CC FLAGS_REG))]
11886 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11887 && (TARGET_SHIFT1 || optimize_size)"
11889 [(set_attr "type" "ishift")
11890 (set (attr "length")
11891 (if_then_else (match_operand:SI 0 "register_operand" "")
11893 (const_string "*")))])
11895 (define_insn "*ashrsi3_1_one_bit_zext"
11896 [(set (match_operand:DI 0 "register_operand" "=r")
11897 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11898 (match_operand:QI 2 "const1_operand" ""))))
11899 (clobber (reg:CC FLAGS_REG))]
11900 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11901 && (TARGET_SHIFT1 || optimize_size)"
11903 [(set_attr "type" "ishift")
11904 (set_attr "length" "2")])
11906 (define_insn "*ashrsi3_1"
11907 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11908 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11909 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11910 (clobber (reg:CC FLAGS_REG))]
11911 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11913 sar{l}\t{%2, %0|%0, %2}
11914 sar{l}\t{%b2, %0|%0, %b2}"
11915 [(set_attr "type" "ishift")
11916 (set_attr "mode" "SI")])
11918 (define_insn "*ashrsi3_1_zext"
11919 [(set (match_operand:DI 0 "register_operand" "=r,r")
11920 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11921 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11922 (clobber (reg:CC FLAGS_REG))]
11923 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11925 sar{l}\t{%2, %k0|%k0, %2}
11926 sar{l}\t{%b2, %k0|%k0, %b2}"
11927 [(set_attr "type" "ishift")
11928 (set_attr "mode" "SI")])
11930 ;; This pattern can't accept a variable shift count, since shifts by
11931 ;; zero don't affect the flags. We assume that shifts by constant
11932 ;; zero are optimized away.
11933 (define_insn "*ashrsi3_one_bit_cmp"
11934 [(set (reg FLAGS_REG)
11936 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11937 (match_operand:QI 2 "const1_operand" ""))
11939 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11940 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11941 "ix86_match_ccmode (insn, CCGOCmode)
11942 && (TARGET_SHIFT1 || optimize_size)
11943 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11945 [(set_attr "type" "ishift")
11946 (set (attr "length")
11947 (if_then_else (match_operand:SI 0 "register_operand" "")
11949 (const_string "*")))])
11951 (define_insn "*ashrsi3_one_bit_cconly"
11952 [(set (reg FLAGS_REG)
11954 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11955 (match_operand:QI 2 "const1_operand" ""))
11957 (clobber (match_scratch:SI 0 "=r"))]
11958 "ix86_match_ccmode (insn, CCGOCmode)
11959 && (TARGET_SHIFT1 || optimize_size)
11960 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11962 [(set_attr "type" "ishift")
11963 (set_attr "length" "2")])
11965 (define_insn "*ashrsi3_one_bit_cmp_zext"
11966 [(set (reg FLAGS_REG)
11968 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11969 (match_operand:QI 2 "const1_operand" ""))
11971 (set (match_operand:DI 0 "register_operand" "=r")
11972 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11973 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11974 && (TARGET_SHIFT1 || optimize_size)
11975 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11977 [(set_attr "type" "ishift")
11978 (set_attr "length" "2")])
11980 ;; This pattern can't accept a variable shift count, since shifts by
11981 ;; zero don't affect the flags. We assume that shifts by constant
11982 ;; zero are optimized away.
11983 (define_insn "*ashrsi3_cmp"
11984 [(set (reg FLAGS_REG)
11986 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11987 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11989 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11990 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11991 "ix86_match_ccmode (insn, CCGOCmode)
11992 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11994 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11995 "sar{l}\t{%2, %0|%0, %2}"
11996 [(set_attr "type" "ishift")
11997 (set_attr "mode" "SI")])
11999 (define_insn "*ashrsi3_cconly"
12000 [(set (reg FLAGS_REG)
12002 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12003 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12005 (clobber (match_scratch:SI 0 "=r"))]
12006 "ix86_match_ccmode (insn, CCGOCmode)
12007 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12009 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12010 "sar{l}\t{%2, %0|%0, %2}"
12011 [(set_attr "type" "ishift")
12012 (set_attr "mode" "SI")])
12014 (define_insn "*ashrsi3_cmp_zext"
12015 [(set (reg FLAGS_REG)
12017 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12018 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12020 (set (match_operand:DI 0 "register_operand" "=r")
12021 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12022 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12023 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12025 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12026 "sar{l}\t{%2, %k0|%k0, %2}"
12027 [(set_attr "type" "ishift")
12028 (set_attr "mode" "SI")])
12030 (define_expand "ashrhi3"
12031 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12032 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12033 (match_operand:QI 2 "nonmemory_operand" "")))
12034 (clobber (reg:CC FLAGS_REG))]
12035 "TARGET_HIMODE_MATH"
12036 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12038 (define_insn "*ashrhi3_1_one_bit"
12039 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12040 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12041 (match_operand:QI 2 "const1_operand" "")))
12042 (clobber (reg:CC FLAGS_REG))]
12043 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12044 && (TARGET_SHIFT1 || optimize_size)"
12046 [(set_attr "type" "ishift")
12047 (set (attr "length")
12048 (if_then_else (match_operand 0 "register_operand" "")
12050 (const_string "*")))])
12052 (define_insn "*ashrhi3_1"
12053 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12054 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12055 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12056 (clobber (reg:CC FLAGS_REG))]
12057 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12059 sar{w}\t{%2, %0|%0, %2}
12060 sar{w}\t{%b2, %0|%0, %b2}"
12061 [(set_attr "type" "ishift")
12062 (set_attr "mode" "HI")])
12064 ;; This pattern can't accept a variable shift count, since shifts by
12065 ;; zero don't affect the flags. We assume that shifts by constant
12066 ;; zero are optimized away.
12067 (define_insn "*ashrhi3_one_bit_cmp"
12068 [(set (reg FLAGS_REG)
12070 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12071 (match_operand:QI 2 "const1_operand" ""))
12073 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12074 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12075 "ix86_match_ccmode (insn, CCGOCmode)
12076 && (TARGET_SHIFT1 || optimize_size)
12077 && ix86_binary_operator_ok (ASHIFTRT, HImode, 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 "*ashrhi3_one_bit_cconly"
12086 [(set (reg FLAGS_REG)
12088 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12089 (match_operand:QI 2 "const1_operand" ""))
12091 (clobber (match_scratch:HI 0 "=r"))]
12092 "ix86_match_ccmode (insn, CCGOCmode)
12093 && (TARGET_SHIFT1 || optimize_size)
12094 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12096 [(set_attr "type" "ishift")
12097 (set_attr "length" "2")])
12099 ;; This pattern can't accept a variable shift count, since shifts by
12100 ;; zero don't affect the flags. We assume that shifts by constant
12101 ;; zero are optimized away.
12102 (define_insn "*ashrhi3_cmp"
12103 [(set (reg FLAGS_REG)
12105 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12106 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12108 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12109 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12110 "ix86_match_ccmode (insn, CCGOCmode)
12111 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12113 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12114 "sar{w}\t{%2, %0|%0, %2}"
12115 [(set_attr "type" "ishift")
12116 (set_attr "mode" "HI")])
12118 (define_insn "*ashrhi3_cconly"
12119 [(set (reg FLAGS_REG)
12121 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12122 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12124 (clobber (match_scratch:HI 0 "=r"))]
12125 "ix86_match_ccmode (insn, CCGOCmode)
12126 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12128 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12129 "sar{w}\t{%2, %0|%0, %2}"
12130 [(set_attr "type" "ishift")
12131 (set_attr "mode" "HI")])
12133 (define_expand "ashrqi3"
12134 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12135 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12136 (match_operand:QI 2 "nonmemory_operand" "")))
12137 (clobber (reg:CC FLAGS_REG))]
12138 "TARGET_QIMODE_MATH"
12139 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12141 (define_insn "*ashrqi3_1_one_bit"
12142 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12143 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12144 (match_operand:QI 2 "const1_operand" "")))
12145 (clobber (reg:CC FLAGS_REG))]
12146 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12147 && (TARGET_SHIFT1 || optimize_size)"
12149 [(set_attr "type" "ishift")
12150 (set (attr "length")
12151 (if_then_else (match_operand 0 "register_operand" "")
12153 (const_string "*")))])
12155 (define_insn "*ashrqi3_1_one_bit_slp"
12156 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12157 (ashiftrt:QI (match_dup 0)
12158 (match_operand:QI 1 "const1_operand" "")))
12159 (clobber (reg:CC FLAGS_REG))]
12160 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12161 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12162 && (TARGET_SHIFT1 || optimize_size)"
12164 [(set_attr "type" "ishift1")
12165 (set (attr "length")
12166 (if_then_else (match_operand 0 "register_operand" "")
12168 (const_string "*")))])
12170 (define_insn "*ashrqi3_1"
12171 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12172 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12173 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12174 (clobber (reg:CC FLAGS_REG))]
12175 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12177 sar{b}\t{%2, %0|%0, %2}
12178 sar{b}\t{%b2, %0|%0, %b2}"
12179 [(set_attr "type" "ishift")
12180 (set_attr "mode" "QI")])
12182 (define_insn "*ashrqi3_1_slp"
12183 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12184 (ashiftrt:QI (match_dup 0)
12185 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12186 (clobber (reg:CC FLAGS_REG))]
12187 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12188 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12190 sar{b}\t{%1, %0|%0, %1}
12191 sar{b}\t{%b1, %0|%0, %b1}"
12192 [(set_attr "type" "ishift1")
12193 (set_attr "mode" "QI")])
12195 ;; This pattern can't accept a variable shift count, since shifts by
12196 ;; zero don't affect the flags. We assume that shifts by constant
12197 ;; zero are optimized away.
12198 (define_insn "*ashrqi3_one_bit_cmp"
12199 [(set (reg FLAGS_REG)
12201 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12202 (match_operand:QI 2 "const1_operand" "I"))
12204 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12205 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12206 "ix86_match_ccmode (insn, CCGOCmode)
12207 && (TARGET_SHIFT1 || optimize_size)
12208 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12210 [(set_attr "type" "ishift")
12211 (set (attr "length")
12212 (if_then_else (match_operand 0 "register_operand" "")
12214 (const_string "*")))])
12216 (define_insn "*ashrqi3_one_bit_cconly"
12217 [(set (reg FLAGS_REG)
12219 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12220 (match_operand:QI 2 "const1_operand" "I"))
12222 (clobber (match_scratch:QI 0 "=q"))]
12223 "ix86_match_ccmode (insn, CCGOCmode)
12224 && (TARGET_SHIFT1 || optimize_size)
12225 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12227 [(set_attr "type" "ishift")
12228 (set_attr "length" "2")])
12230 ;; This pattern can't accept a variable shift count, since shifts by
12231 ;; zero don't affect the flags. We assume that shifts by constant
12232 ;; zero are optimized away.
12233 (define_insn "*ashrqi3_cmp"
12234 [(set (reg FLAGS_REG)
12236 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12237 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12239 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12240 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12241 "ix86_match_ccmode (insn, CCGOCmode)
12242 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12244 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12245 "sar{b}\t{%2, %0|%0, %2}"
12246 [(set_attr "type" "ishift")
12247 (set_attr "mode" "QI")])
12249 (define_insn "*ashrqi3_cconly"
12250 [(set (reg FLAGS_REG)
12252 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12253 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12255 (clobber (match_scratch:QI 0 "=q"))]
12256 "ix86_match_ccmode (insn, CCGOCmode)
12257 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12259 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12260 "sar{b}\t{%2, %0|%0, %2}"
12261 [(set_attr "type" "ishift")
12262 (set_attr "mode" "QI")])
12265 ;; Logical shift instructions
12267 ;; See comment above `ashldi3' about how this works.
12269 (define_expand "lshrti3"
12270 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12271 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12272 (match_operand:QI 2 "nonmemory_operand" "")))
12273 (clobber (reg:CC FLAGS_REG))])]
12276 if (! immediate_operand (operands[2], QImode))
12278 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12281 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12285 (define_insn "lshrti3_1"
12286 [(set (match_operand:TI 0 "register_operand" "=r")
12287 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12288 (match_operand:QI 2 "register_operand" "c")))
12289 (clobber (match_scratch:DI 3 "=&r"))
12290 (clobber (reg:CC FLAGS_REG))]
12293 [(set_attr "type" "multi")])
12295 (define_insn "*lshrti3_2"
12296 [(set (match_operand:TI 0 "register_operand" "=r")
12297 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12298 (match_operand:QI 2 "immediate_operand" "O")))
12299 (clobber (reg:CC FLAGS_REG))]
12302 [(set_attr "type" "multi")])
12305 [(set (match_operand:TI 0 "register_operand" "")
12306 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12307 (match_operand:QI 2 "register_operand" "")))
12308 (clobber (match_scratch:DI 3 ""))
12309 (clobber (reg:CC FLAGS_REG))]
12310 "TARGET_64BIT && reload_completed"
12312 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12315 [(set (match_operand:TI 0 "register_operand" "")
12316 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12317 (match_operand:QI 2 "immediate_operand" "")))
12318 (clobber (reg:CC FLAGS_REG))]
12319 "TARGET_64BIT && reload_completed"
12321 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12323 (define_expand "lshrdi3"
12324 [(set (match_operand:DI 0 "shiftdi_operand" "")
12325 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12326 (match_operand:QI 2 "nonmemory_operand" "")))]
12328 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12330 (define_insn "*lshrdi3_1_one_bit_rex64"
12331 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12332 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12333 (match_operand:QI 2 "const1_operand" "")))
12334 (clobber (reg:CC FLAGS_REG))]
12335 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12336 && (TARGET_SHIFT1 || optimize_size)"
12338 [(set_attr "type" "ishift")
12339 (set (attr "length")
12340 (if_then_else (match_operand:DI 0 "register_operand" "")
12342 (const_string "*")))])
12344 (define_insn "*lshrdi3_1_rex64"
12345 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12346 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12347 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12348 (clobber (reg:CC FLAGS_REG))]
12349 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12351 shr{q}\t{%2, %0|%0, %2}
12352 shr{q}\t{%b2, %0|%0, %b2}"
12353 [(set_attr "type" "ishift")
12354 (set_attr "mode" "DI")])
12356 ;; This pattern can't accept a variable shift count, since shifts by
12357 ;; zero don't affect the flags. We assume that shifts by constant
12358 ;; zero are optimized away.
12359 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12360 [(set (reg FLAGS_REG)
12362 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12363 (match_operand:QI 2 "const1_operand" ""))
12365 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12366 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12367 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12368 && (TARGET_SHIFT1 || optimize_size)
12369 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12371 [(set_attr "type" "ishift")
12372 (set (attr "length")
12373 (if_then_else (match_operand:DI 0 "register_operand" "")
12375 (const_string "*")))])
12377 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12378 [(set (reg FLAGS_REG)
12380 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12381 (match_operand:QI 2 "const1_operand" ""))
12383 (clobber (match_scratch:DI 0 "=r"))]
12384 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12385 && (TARGET_SHIFT1 || optimize_size)
12386 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12388 [(set_attr "type" "ishift")
12389 (set_attr "length" "2")])
12391 ;; This pattern can't accept a variable shift count, since shifts by
12392 ;; zero don't affect the flags. We assume that shifts by constant
12393 ;; zero are optimized away.
12394 (define_insn "*lshrdi3_cmp_rex64"
12395 [(set (reg FLAGS_REG)
12397 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12398 (match_operand:QI 2 "const_int_operand" "e"))
12400 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12401 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12402 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12403 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12405 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12406 "shr{q}\t{%2, %0|%0, %2}"
12407 [(set_attr "type" "ishift")
12408 (set_attr "mode" "DI")])
12410 (define_insn "*lshrdi3_cconly_rex64"
12411 [(set (reg FLAGS_REG)
12413 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12414 (match_operand:QI 2 "const_int_operand" "e"))
12416 (clobber (match_scratch:DI 0 "=r"))]
12417 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12418 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12420 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12421 "shr{q}\t{%2, %0|%0, %2}"
12422 [(set_attr "type" "ishift")
12423 (set_attr "mode" "DI")])
12425 (define_insn "*lshrdi3_1"
12426 [(set (match_operand:DI 0 "register_operand" "=r")
12427 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12428 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12429 (clobber (reg:CC FLAGS_REG))]
12432 [(set_attr "type" "multi")])
12434 ;; By default we don't ask for a scratch register, because when DImode
12435 ;; values are manipulated, registers are already at a premium. But if
12436 ;; we have one handy, we won't turn it away.
12438 [(match_scratch:SI 3 "r")
12439 (parallel [(set (match_operand:DI 0 "register_operand" "")
12440 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12441 (match_operand:QI 2 "nonmemory_operand" "")))
12442 (clobber (reg:CC FLAGS_REG))])
12444 "!TARGET_64BIT && TARGET_CMOVE"
12446 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12449 [(set (match_operand:DI 0 "register_operand" "")
12450 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12451 (match_operand:QI 2 "nonmemory_operand" "")))
12452 (clobber (reg:CC FLAGS_REG))]
12453 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12454 ? flow2_completed : reload_completed)"
12456 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12458 (define_expand "lshrsi3"
12459 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12460 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12461 (match_operand:QI 2 "nonmemory_operand" "")))
12462 (clobber (reg:CC FLAGS_REG))]
12464 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12466 (define_insn "*lshrsi3_1_one_bit"
12467 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12468 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12469 (match_operand:QI 2 "const1_operand" "")))
12470 (clobber (reg:CC FLAGS_REG))]
12471 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12472 && (TARGET_SHIFT1 || optimize_size)"
12474 [(set_attr "type" "ishift")
12475 (set (attr "length")
12476 (if_then_else (match_operand:SI 0 "register_operand" "")
12478 (const_string "*")))])
12480 (define_insn "*lshrsi3_1_one_bit_zext"
12481 [(set (match_operand:DI 0 "register_operand" "=r")
12482 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12483 (match_operand:QI 2 "const1_operand" "")))
12484 (clobber (reg:CC FLAGS_REG))]
12485 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12486 && (TARGET_SHIFT1 || optimize_size)"
12488 [(set_attr "type" "ishift")
12489 (set_attr "length" "2")])
12491 (define_insn "*lshrsi3_1"
12492 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12493 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12494 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12495 (clobber (reg:CC FLAGS_REG))]
12496 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12498 shr{l}\t{%2, %0|%0, %2}
12499 shr{l}\t{%b2, %0|%0, %b2}"
12500 [(set_attr "type" "ishift")
12501 (set_attr "mode" "SI")])
12503 (define_insn "*lshrsi3_1_zext"
12504 [(set (match_operand:DI 0 "register_operand" "=r,r")
12506 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12507 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12508 (clobber (reg:CC FLAGS_REG))]
12509 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12511 shr{l}\t{%2, %k0|%k0, %2}
12512 shr{l}\t{%b2, %k0|%k0, %b2}"
12513 [(set_attr "type" "ishift")
12514 (set_attr "mode" "SI")])
12516 ;; This pattern can't accept a variable shift count, since shifts by
12517 ;; zero don't affect the flags. We assume that shifts by constant
12518 ;; zero are optimized away.
12519 (define_insn "*lshrsi3_one_bit_cmp"
12520 [(set (reg FLAGS_REG)
12522 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12523 (match_operand:QI 2 "const1_operand" ""))
12525 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12526 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12527 "ix86_match_ccmode (insn, CCGOCmode)
12528 && (TARGET_SHIFT1 || optimize_size)
12529 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12531 [(set_attr "type" "ishift")
12532 (set (attr "length")
12533 (if_then_else (match_operand:SI 0 "register_operand" "")
12535 (const_string "*")))])
12537 (define_insn "*lshrsi3_one_bit_cconly"
12538 [(set (reg FLAGS_REG)
12540 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12541 (match_operand:QI 2 "const1_operand" ""))
12543 (clobber (match_scratch:SI 0 "=r"))]
12544 "ix86_match_ccmode (insn, CCGOCmode)
12545 && (TARGET_SHIFT1 || optimize_size)
12546 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12548 [(set_attr "type" "ishift")
12549 (set_attr "length" "2")])
12551 (define_insn "*lshrsi3_cmp_one_bit_zext"
12552 [(set (reg FLAGS_REG)
12554 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12555 (match_operand:QI 2 "const1_operand" ""))
12557 (set (match_operand:DI 0 "register_operand" "=r")
12558 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12559 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12560 && (TARGET_SHIFT1 || optimize_size)
12561 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12563 [(set_attr "type" "ishift")
12564 (set_attr "length" "2")])
12566 ;; This pattern can't accept a variable shift count, since shifts by
12567 ;; zero don't affect the flags. We assume that shifts by constant
12568 ;; zero are optimized away.
12569 (define_insn "*lshrsi3_cmp"
12570 [(set (reg FLAGS_REG)
12572 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12573 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12575 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12576 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12577 "ix86_match_ccmode (insn, CCGOCmode)
12578 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12580 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12581 "shr{l}\t{%2, %0|%0, %2}"
12582 [(set_attr "type" "ishift")
12583 (set_attr "mode" "SI")])
12585 (define_insn "*lshrsi3_cconly"
12586 [(set (reg FLAGS_REG)
12588 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12589 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12591 (clobber (match_scratch:SI 0 "=r"))]
12592 "ix86_match_ccmode (insn, CCGOCmode)
12593 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12595 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12596 "shr{l}\t{%2, %0|%0, %2}"
12597 [(set_attr "type" "ishift")
12598 (set_attr "mode" "SI")])
12600 (define_insn "*lshrsi3_cmp_zext"
12601 [(set (reg FLAGS_REG)
12603 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12604 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12606 (set (match_operand:DI 0 "register_operand" "=r")
12607 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12608 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12609 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12611 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12612 "shr{l}\t{%2, %k0|%k0, %2}"
12613 [(set_attr "type" "ishift")
12614 (set_attr "mode" "SI")])
12616 (define_expand "lshrhi3"
12617 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12618 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12619 (match_operand:QI 2 "nonmemory_operand" "")))
12620 (clobber (reg:CC FLAGS_REG))]
12621 "TARGET_HIMODE_MATH"
12622 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12624 (define_insn "*lshrhi3_1_one_bit"
12625 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12626 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12627 (match_operand:QI 2 "const1_operand" "")))
12628 (clobber (reg:CC FLAGS_REG))]
12629 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12630 && (TARGET_SHIFT1 || optimize_size)"
12632 [(set_attr "type" "ishift")
12633 (set (attr "length")
12634 (if_then_else (match_operand 0 "register_operand" "")
12636 (const_string "*")))])
12638 (define_insn "*lshrhi3_1"
12639 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12640 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12641 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12642 (clobber (reg:CC FLAGS_REG))]
12643 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12645 shr{w}\t{%2, %0|%0, %2}
12646 shr{w}\t{%b2, %0|%0, %b2}"
12647 [(set_attr "type" "ishift")
12648 (set_attr "mode" "HI")])
12650 ;; This pattern can't accept a variable shift count, since shifts by
12651 ;; zero don't affect the flags. We assume that shifts by constant
12652 ;; zero are optimized away.
12653 (define_insn "*lshrhi3_one_bit_cmp"
12654 [(set (reg FLAGS_REG)
12656 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12657 (match_operand:QI 2 "const1_operand" ""))
12659 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12660 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12661 "ix86_match_ccmode (insn, CCGOCmode)
12662 && (TARGET_SHIFT1 || optimize_size)
12663 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12665 [(set_attr "type" "ishift")
12666 (set (attr "length")
12667 (if_then_else (match_operand:SI 0 "register_operand" "")
12669 (const_string "*")))])
12671 (define_insn "*lshrhi3_one_bit_cconly"
12672 [(set (reg FLAGS_REG)
12674 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12675 (match_operand:QI 2 "const1_operand" ""))
12677 (clobber (match_scratch:HI 0 "=r"))]
12678 "ix86_match_ccmode (insn, CCGOCmode)
12679 && (TARGET_SHIFT1 || optimize_size)
12680 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12682 [(set_attr "type" "ishift")
12683 (set_attr "length" "2")])
12685 ;; This pattern can't accept a variable shift count, since shifts by
12686 ;; zero don't affect the flags. We assume that shifts by constant
12687 ;; zero are optimized away.
12688 (define_insn "*lshrhi3_cmp"
12689 [(set (reg FLAGS_REG)
12691 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12692 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12694 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12695 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12696 "ix86_match_ccmode (insn, CCGOCmode)
12697 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12699 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12700 "shr{w}\t{%2, %0|%0, %2}"
12701 [(set_attr "type" "ishift")
12702 (set_attr "mode" "HI")])
12704 (define_insn "*lshrhi3_cconly"
12705 [(set (reg FLAGS_REG)
12707 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12708 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12710 (clobber (match_scratch:HI 0 "=r"))]
12711 "ix86_match_ccmode (insn, CCGOCmode)
12712 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12714 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12715 "shr{w}\t{%2, %0|%0, %2}"
12716 [(set_attr "type" "ishift")
12717 (set_attr "mode" "HI")])
12719 (define_expand "lshrqi3"
12720 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12721 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12722 (match_operand:QI 2 "nonmemory_operand" "")))
12723 (clobber (reg:CC FLAGS_REG))]
12724 "TARGET_QIMODE_MATH"
12725 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12727 (define_insn "*lshrqi3_1_one_bit"
12728 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12729 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12730 (match_operand:QI 2 "const1_operand" "")))
12731 (clobber (reg:CC FLAGS_REG))]
12732 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12733 && (TARGET_SHIFT1 || optimize_size)"
12735 [(set_attr "type" "ishift")
12736 (set (attr "length")
12737 (if_then_else (match_operand 0 "register_operand" "")
12739 (const_string "*")))])
12741 (define_insn "*lshrqi3_1_one_bit_slp"
12742 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12743 (lshiftrt:QI (match_dup 0)
12744 (match_operand:QI 1 "const1_operand" "")))
12745 (clobber (reg:CC FLAGS_REG))]
12746 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12747 && (TARGET_SHIFT1 || optimize_size)"
12749 [(set_attr "type" "ishift1")
12750 (set (attr "length")
12751 (if_then_else (match_operand 0 "register_operand" "")
12753 (const_string "*")))])
12755 (define_insn "*lshrqi3_1"
12756 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12757 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12758 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12759 (clobber (reg:CC FLAGS_REG))]
12760 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12762 shr{b}\t{%2, %0|%0, %2}
12763 shr{b}\t{%b2, %0|%0, %b2}"
12764 [(set_attr "type" "ishift")
12765 (set_attr "mode" "QI")])
12767 (define_insn "*lshrqi3_1_slp"
12768 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12769 (lshiftrt:QI (match_dup 0)
12770 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12771 (clobber (reg:CC FLAGS_REG))]
12772 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12773 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12775 shr{b}\t{%1, %0|%0, %1}
12776 shr{b}\t{%b1, %0|%0, %b1}"
12777 [(set_attr "type" "ishift1")
12778 (set_attr "mode" "QI")])
12780 ;; This pattern can't accept a variable shift count, since shifts by
12781 ;; zero don't affect the flags. We assume that shifts by constant
12782 ;; zero are optimized away.
12783 (define_insn "*lshrqi2_one_bit_cmp"
12784 [(set (reg FLAGS_REG)
12786 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12787 (match_operand:QI 2 "const1_operand" ""))
12789 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12790 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12791 "ix86_match_ccmode (insn, CCGOCmode)
12792 && (TARGET_SHIFT1 || optimize_size)
12793 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12795 [(set_attr "type" "ishift")
12796 (set (attr "length")
12797 (if_then_else (match_operand:SI 0 "register_operand" "")
12799 (const_string "*")))])
12801 (define_insn "*lshrqi2_one_bit_cconly"
12802 [(set (reg FLAGS_REG)
12804 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12805 (match_operand:QI 2 "const1_operand" ""))
12807 (clobber (match_scratch:QI 0 "=q"))]
12808 "ix86_match_ccmode (insn, CCGOCmode)
12809 && (TARGET_SHIFT1 || optimize_size)
12810 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12812 [(set_attr "type" "ishift")
12813 (set_attr "length" "2")])
12815 ;; This pattern can't accept a variable shift count, since shifts by
12816 ;; zero don't affect the flags. We assume that shifts by constant
12817 ;; zero are optimized away.
12818 (define_insn "*lshrqi2_cmp"
12819 [(set (reg FLAGS_REG)
12821 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12822 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12824 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12825 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12826 "ix86_match_ccmode (insn, CCGOCmode)
12827 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12829 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12830 "shr{b}\t{%2, %0|%0, %2}"
12831 [(set_attr "type" "ishift")
12832 (set_attr "mode" "QI")])
12834 (define_insn "*lshrqi2_cconly"
12835 [(set (reg FLAGS_REG)
12837 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12838 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12840 (clobber (match_scratch:QI 0 "=q"))]
12841 "ix86_match_ccmode (insn, CCGOCmode)
12842 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12844 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12845 "shr{b}\t{%2, %0|%0, %2}"
12846 [(set_attr "type" "ishift")
12847 (set_attr "mode" "QI")])
12849 ;; Rotate instructions
12851 (define_expand "rotldi3"
12852 [(set (match_operand:DI 0 "shiftdi_operand" "")
12853 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12854 (match_operand:QI 2 "nonmemory_operand" "")))
12855 (clobber (reg:CC FLAGS_REG))]
12860 ix86_expand_binary_operator (ROTATE, DImode, operands);
12863 if (!const_1_to_31_operand (operands[2], VOIDmode))
12865 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12869 ;; Implement rotation using two double-precision shift instructions
12870 ;; and a scratch register.
12871 (define_insn_and_split "ix86_rotldi3"
12872 [(set (match_operand:DI 0 "register_operand" "=r")
12873 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12874 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12875 (clobber (reg:CC FLAGS_REG))
12876 (clobber (match_scratch:SI 3 "=&r"))]
12879 "&& reload_completed"
12880 [(set (match_dup 3) (match_dup 4))
12882 [(set (match_dup 4)
12883 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12884 (lshiftrt:SI (match_dup 5)
12885 (minus:QI (const_int 32) (match_dup 2)))))
12886 (clobber (reg:CC FLAGS_REG))])
12888 [(set (match_dup 5)
12889 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12890 (lshiftrt:SI (match_dup 3)
12891 (minus:QI (const_int 32) (match_dup 2)))))
12892 (clobber (reg:CC FLAGS_REG))])]
12893 "split_di (operands, 1, operands + 4, operands + 5);")
12895 (define_insn "*rotlsi3_1_one_bit_rex64"
12896 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12897 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12898 (match_operand:QI 2 "const1_operand" "")))
12899 (clobber (reg:CC FLAGS_REG))]
12900 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12901 && (TARGET_SHIFT1 || optimize_size)"
12903 [(set_attr "type" "rotate")
12904 (set (attr "length")
12905 (if_then_else (match_operand:DI 0 "register_operand" "")
12907 (const_string "*")))])
12909 (define_insn "*rotldi3_1_rex64"
12910 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12911 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12912 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12913 (clobber (reg:CC FLAGS_REG))]
12914 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12916 rol{q}\t{%2, %0|%0, %2}
12917 rol{q}\t{%b2, %0|%0, %b2}"
12918 [(set_attr "type" "rotate")
12919 (set_attr "mode" "DI")])
12921 (define_expand "rotlsi3"
12922 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12923 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12924 (match_operand:QI 2 "nonmemory_operand" "")))
12925 (clobber (reg:CC FLAGS_REG))]
12927 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12929 (define_insn "*rotlsi3_1_one_bit"
12930 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12931 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12932 (match_operand:QI 2 "const1_operand" "")))
12933 (clobber (reg:CC FLAGS_REG))]
12934 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12935 && (TARGET_SHIFT1 || optimize_size)"
12937 [(set_attr "type" "rotate")
12938 (set (attr "length")
12939 (if_then_else (match_operand:SI 0 "register_operand" "")
12941 (const_string "*")))])
12943 (define_insn "*rotlsi3_1_one_bit_zext"
12944 [(set (match_operand:DI 0 "register_operand" "=r")
12946 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12947 (match_operand:QI 2 "const1_operand" ""))))
12948 (clobber (reg:CC FLAGS_REG))]
12949 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12950 && (TARGET_SHIFT1 || optimize_size)"
12952 [(set_attr "type" "rotate")
12953 (set_attr "length" "2")])
12955 (define_insn "*rotlsi3_1"
12956 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12957 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12958 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12959 (clobber (reg:CC FLAGS_REG))]
12960 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12962 rol{l}\t{%2, %0|%0, %2}
12963 rol{l}\t{%b2, %0|%0, %b2}"
12964 [(set_attr "type" "rotate")
12965 (set_attr "mode" "SI")])
12967 (define_insn "*rotlsi3_1_zext"
12968 [(set (match_operand:DI 0 "register_operand" "=r,r")
12970 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12971 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12972 (clobber (reg:CC FLAGS_REG))]
12973 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12975 rol{l}\t{%2, %k0|%k0, %2}
12976 rol{l}\t{%b2, %k0|%k0, %b2}"
12977 [(set_attr "type" "rotate")
12978 (set_attr "mode" "SI")])
12980 (define_expand "rotlhi3"
12981 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12982 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12983 (match_operand:QI 2 "nonmemory_operand" "")))
12984 (clobber (reg:CC FLAGS_REG))]
12985 "TARGET_HIMODE_MATH"
12986 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12988 (define_insn "*rotlhi3_1_one_bit"
12989 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12990 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12991 (match_operand:QI 2 "const1_operand" "")))
12992 (clobber (reg:CC FLAGS_REG))]
12993 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12994 && (TARGET_SHIFT1 || optimize_size)"
12996 [(set_attr "type" "rotate")
12997 (set (attr "length")
12998 (if_then_else (match_operand 0 "register_operand" "")
13000 (const_string "*")))])
13002 (define_insn "*rotlhi3_1"
13003 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13004 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13005 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13006 (clobber (reg:CC FLAGS_REG))]
13007 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13009 rol{w}\t{%2, %0|%0, %2}
13010 rol{w}\t{%b2, %0|%0, %b2}"
13011 [(set_attr "type" "rotate")
13012 (set_attr "mode" "HI")])
13015 [(set (match_operand:HI 0 "register_operand" "")
13016 (rotate:HI (match_dup 0) (const_int 8)))
13017 (clobber (reg:CC FLAGS_REG))]
13019 [(parallel [(set (strict_low_part (match_dup 0))
13020 (bswap:HI (match_dup 0)))
13021 (clobber (reg:CC FLAGS_REG))])]
13024 (define_expand "rotlqi3"
13025 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13026 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13027 (match_operand:QI 2 "nonmemory_operand" "")))
13028 (clobber (reg:CC FLAGS_REG))]
13029 "TARGET_QIMODE_MATH"
13030 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13032 (define_insn "*rotlqi3_1_one_bit_slp"
13033 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13034 (rotate:QI (match_dup 0)
13035 (match_operand:QI 1 "const1_operand" "")))
13036 (clobber (reg:CC FLAGS_REG))]
13037 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13038 && (TARGET_SHIFT1 || optimize_size)"
13040 [(set_attr "type" "rotate1")
13041 (set (attr "length")
13042 (if_then_else (match_operand 0 "register_operand" "")
13044 (const_string "*")))])
13046 (define_insn "*rotlqi3_1_one_bit"
13047 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13048 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13049 (match_operand:QI 2 "const1_operand" "")))
13050 (clobber (reg:CC FLAGS_REG))]
13051 "ix86_binary_operator_ok (ROTATE, QImode, operands)
13052 && (TARGET_SHIFT1 || optimize_size)"
13054 [(set_attr "type" "rotate")
13055 (set (attr "length")
13056 (if_then_else (match_operand 0 "register_operand" "")
13058 (const_string "*")))])
13060 (define_insn "*rotlqi3_1_slp"
13061 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13062 (rotate:QI (match_dup 0)
13063 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13064 (clobber (reg:CC FLAGS_REG))]
13065 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13066 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13068 rol{b}\t{%1, %0|%0, %1}
13069 rol{b}\t{%b1, %0|%0, %b1}"
13070 [(set_attr "type" "rotate1")
13071 (set_attr "mode" "QI")])
13073 (define_insn "*rotlqi3_1"
13074 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13075 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13076 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13077 (clobber (reg:CC FLAGS_REG))]
13078 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13080 rol{b}\t{%2, %0|%0, %2}
13081 rol{b}\t{%b2, %0|%0, %b2}"
13082 [(set_attr "type" "rotate")
13083 (set_attr "mode" "QI")])
13085 (define_expand "rotrdi3"
13086 [(set (match_operand:DI 0 "shiftdi_operand" "")
13087 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13088 (match_operand:QI 2 "nonmemory_operand" "")))
13089 (clobber (reg:CC FLAGS_REG))]
13094 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13097 if (!const_1_to_31_operand (operands[2], VOIDmode))
13099 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13103 ;; Implement rotation using two double-precision shift instructions
13104 ;; and a scratch register.
13105 (define_insn_and_split "ix86_rotrdi3"
13106 [(set (match_operand:DI 0 "register_operand" "=r")
13107 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13108 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13109 (clobber (reg:CC FLAGS_REG))
13110 (clobber (match_scratch:SI 3 "=&r"))]
13113 "&& reload_completed"
13114 [(set (match_dup 3) (match_dup 4))
13116 [(set (match_dup 4)
13117 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13118 (ashift:SI (match_dup 5)
13119 (minus:QI (const_int 32) (match_dup 2)))))
13120 (clobber (reg:CC FLAGS_REG))])
13122 [(set (match_dup 5)
13123 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13124 (ashift:SI (match_dup 3)
13125 (minus:QI (const_int 32) (match_dup 2)))))
13126 (clobber (reg:CC FLAGS_REG))])]
13127 "split_di (operands, 1, operands + 4, operands + 5);")
13129 (define_insn "*rotrdi3_1_one_bit_rex64"
13130 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13131 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13132 (match_operand:QI 2 "const1_operand" "")))
13133 (clobber (reg:CC FLAGS_REG))]
13134 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13135 && (TARGET_SHIFT1 || optimize_size)"
13137 [(set_attr "type" "rotate")
13138 (set (attr "length")
13139 (if_then_else (match_operand:DI 0 "register_operand" "")
13141 (const_string "*")))])
13143 (define_insn "*rotrdi3_1_rex64"
13144 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13145 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13146 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13147 (clobber (reg:CC FLAGS_REG))]
13148 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13150 ror{q}\t{%2, %0|%0, %2}
13151 ror{q}\t{%b2, %0|%0, %b2}"
13152 [(set_attr "type" "rotate")
13153 (set_attr "mode" "DI")])
13155 (define_expand "rotrsi3"
13156 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13157 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13158 (match_operand:QI 2 "nonmemory_operand" "")))
13159 (clobber (reg:CC FLAGS_REG))]
13161 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13163 (define_insn "*rotrsi3_1_one_bit"
13164 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13165 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13166 (match_operand:QI 2 "const1_operand" "")))
13167 (clobber (reg:CC FLAGS_REG))]
13168 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13169 && (TARGET_SHIFT1 || optimize_size)"
13171 [(set_attr "type" "rotate")
13172 (set (attr "length")
13173 (if_then_else (match_operand:SI 0 "register_operand" "")
13175 (const_string "*")))])
13177 (define_insn "*rotrsi3_1_one_bit_zext"
13178 [(set (match_operand:DI 0 "register_operand" "=r")
13180 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13181 (match_operand:QI 2 "const1_operand" ""))))
13182 (clobber (reg:CC FLAGS_REG))]
13183 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13184 && (TARGET_SHIFT1 || optimize_size)"
13186 [(set_attr "type" "rotate")
13187 (set (attr "length")
13188 (if_then_else (match_operand:SI 0 "register_operand" "")
13190 (const_string "*")))])
13192 (define_insn "*rotrsi3_1"
13193 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13194 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13195 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13196 (clobber (reg:CC FLAGS_REG))]
13197 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13199 ror{l}\t{%2, %0|%0, %2}
13200 ror{l}\t{%b2, %0|%0, %b2}"
13201 [(set_attr "type" "rotate")
13202 (set_attr "mode" "SI")])
13204 (define_insn "*rotrsi3_1_zext"
13205 [(set (match_operand:DI 0 "register_operand" "=r,r")
13207 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13208 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13209 (clobber (reg:CC FLAGS_REG))]
13210 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13212 ror{l}\t{%2, %k0|%k0, %2}
13213 ror{l}\t{%b2, %k0|%k0, %b2}"
13214 [(set_attr "type" "rotate")
13215 (set_attr "mode" "SI")])
13217 (define_expand "rotrhi3"
13218 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13219 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13220 (match_operand:QI 2 "nonmemory_operand" "")))
13221 (clobber (reg:CC FLAGS_REG))]
13222 "TARGET_HIMODE_MATH"
13223 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13225 (define_insn "*rotrhi3_one_bit"
13226 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13227 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13228 (match_operand:QI 2 "const1_operand" "")))
13229 (clobber (reg:CC FLAGS_REG))]
13230 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13231 && (TARGET_SHIFT1 || optimize_size)"
13233 [(set_attr "type" "rotate")
13234 (set (attr "length")
13235 (if_then_else (match_operand 0 "register_operand" "")
13237 (const_string "*")))])
13239 (define_insn "*rotrhi3_1"
13240 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13241 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13242 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13243 (clobber (reg:CC FLAGS_REG))]
13244 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13246 ror{w}\t{%2, %0|%0, %2}
13247 ror{w}\t{%b2, %0|%0, %b2}"
13248 [(set_attr "type" "rotate")
13249 (set_attr "mode" "HI")])
13252 [(set (match_operand:HI 0 "register_operand" "")
13253 (rotatert:HI (match_dup 0) (const_int 8)))
13254 (clobber (reg:CC FLAGS_REG))]
13256 [(parallel [(set (strict_low_part (match_dup 0))
13257 (bswap:HI (match_dup 0)))
13258 (clobber (reg:CC FLAGS_REG))])]
13261 (define_expand "rotrqi3"
13262 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13263 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13264 (match_operand:QI 2 "nonmemory_operand" "")))
13265 (clobber (reg:CC FLAGS_REG))]
13266 "TARGET_QIMODE_MATH"
13267 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13269 (define_insn "*rotrqi3_1_one_bit"
13270 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13271 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13272 (match_operand:QI 2 "const1_operand" "")))
13273 (clobber (reg:CC FLAGS_REG))]
13274 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13275 && (TARGET_SHIFT1 || optimize_size)"
13277 [(set_attr "type" "rotate")
13278 (set (attr "length")
13279 (if_then_else (match_operand 0 "register_operand" "")
13281 (const_string "*")))])
13283 (define_insn "*rotrqi3_1_one_bit_slp"
13284 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13285 (rotatert:QI (match_dup 0)
13286 (match_operand:QI 1 "const1_operand" "")))
13287 (clobber (reg:CC FLAGS_REG))]
13288 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13289 && (TARGET_SHIFT1 || optimize_size)"
13291 [(set_attr "type" "rotate1")
13292 (set (attr "length")
13293 (if_then_else (match_operand 0 "register_operand" "")
13295 (const_string "*")))])
13297 (define_insn "*rotrqi3_1"
13298 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13299 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13300 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13301 (clobber (reg:CC FLAGS_REG))]
13302 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13304 ror{b}\t{%2, %0|%0, %2}
13305 ror{b}\t{%b2, %0|%0, %b2}"
13306 [(set_attr "type" "rotate")
13307 (set_attr "mode" "QI")])
13309 (define_insn "*rotrqi3_1_slp"
13310 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13311 (rotatert:QI (match_dup 0)
13312 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13313 (clobber (reg:CC FLAGS_REG))]
13314 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13315 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13317 ror{b}\t{%1, %0|%0, %1}
13318 ror{b}\t{%b1, %0|%0, %b1}"
13319 [(set_attr "type" "rotate1")
13320 (set_attr "mode" "QI")])
13322 ;; Bit set / bit test instructions
13324 (define_expand "extv"
13325 [(set (match_operand:SI 0 "register_operand" "")
13326 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13327 (match_operand:SI 2 "const8_operand" "")
13328 (match_operand:SI 3 "const8_operand" "")))]
13331 /* Handle extractions from %ah et al. */
13332 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13335 /* From mips.md: extract_bit_field doesn't verify that our source
13336 matches the predicate, so check it again here. */
13337 if (! ext_register_operand (operands[1], VOIDmode))
13341 (define_expand "extzv"
13342 [(set (match_operand:SI 0 "register_operand" "")
13343 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13344 (match_operand:SI 2 "const8_operand" "")
13345 (match_operand:SI 3 "const8_operand" "")))]
13348 /* Handle extractions from %ah et al. */
13349 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13352 /* From mips.md: extract_bit_field doesn't verify that our source
13353 matches the predicate, so check it again here. */
13354 if (! ext_register_operand (operands[1], VOIDmode))
13358 (define_expand "insv"
13359 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13360 (match_operand 1 "const8_operand" "")
13361 (match_operand 2 "const8_operand" ""))
13362 (match_operand 3 "register_operand" ""))]
13365 /* Handle insertions to %ah et al. */
13366 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13369 /* From mips.md: insert_bit_field doesn't verify that our source
13370 matches the predicate, so check it again here. */
13371 if (! ext_register_operand (operands[0], VOIDmode))
13375 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13377 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13382 ;; %%% bts, btr, btc, bt.
13383 ;; In general these instructions are *slow* when applied to memory,
13384 ;; since they enforce atomic operation. When applied to registers,
13385 ;; it depends on the cpu implementation. They're never faster than
13386 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13387 ;; no point. But in 64-bit, we can't hold the relevant immediates
13388 ;; within the instruction itself, so operating on bits in the high
13389 ;; 32-bits of a register becomes easier.
13391 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13392 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13393 ;; negdf respectively, so they can never be disabled entirely.
13395 (define_insn "*btsq"
13396 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13398 (match_operand:DI 1 "const_0_to_63_operand" ""))
13400 (clobber (reg:CC FLAGS_REG))]
13401 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13403 [(set_attr "type" "alu1")])
13405 (define_insn "*btrq"
13406 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13408 (match_operand:DI 1 "const_0_to_63_operand" ""))
13410 (clobber (reg:CC FLAGS_REG))]
13411 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13413 [(set_attr "type" "alu1")])
13415 (define_insn "*btcq"
13416 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13418 (match_operand:DI 1 "const_0_to_63_operand" ""))
13419 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13420 (clobber (reg:CC FLAGS_REG))]
13421 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13423 [(set_attr "type" "alu1")])
13425 ;; Allow Nocona to avoid these instructions if a register is available.
13428 [(match_scratch:DI 2 "r")
13429 (parallel [(set (zero_extract:DI
13430 (match_operand:DI 0 "register_operand" "")
13432 (match_operand:DI 1 "const_0_to_63_operand" ""))
13434 (clobber (reg:CC FLAGS_REG))])]
13435 "TARGET_64BIT && !TARGET_USE_BT"
13438 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13441 if (HOST_BITS_PER_WIDE_INT >= 64)
13442 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13443 else if (i < HOST_BITS_PER_WIDE_INT)
13444 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13446 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13448 op1 = immed_double_const (lo, hi, DImode);
13451 emit_move_insn (operands[2], op1);
13455 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13460 [(match_scratch:DI 2 "r")
13461 (parallel [(set (zero_extract:DI
13462 (match_operand:DI 0 "register_operand" "")
13464 (match_operand:DI 1 "const_0_to_63_operand" ""))
13466 (clobber (reg:CC FLAGS_REG))])]
13467 "TARGET_64BIT && !TARGET_USE_BT"
13470 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13473 if (HOST_BITS_PER_WIDE_INT >= 64)
13474 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13475 else if (i < HOST_BITS_PER_WIDE_INT)
13476 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13478 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13480 op1 = immed_double_const (~lo, ~hi, DImode);
13483 emit_move_insn (operands[2], op1);
13487 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13492 [(match_scratch:DI 2 "r")
13493 (parallel [(set (zero_extract:DI
13494 (match_operand:DI 0 "register_operand" "")
13496 (match_operand:DI 1 "const_0_to_63_operand" ""))
13497 (not:DI (zero_extract:DI
13498 (match_dup 0) (const_int 1) (match_dup 1))))
13499 (clobber (reg:CC FLAGS_REG))])]
13500 "TARGET_64BIT && !TARGET_USE_BT"
13503 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13506 if (HOST_BITS_PER_WIDE_INT >= 64)
13507 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13508 else if (i < HOST_BITS_PER_WIDE_INT)
13509 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13511 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13513 op1 = immed_double_const (lo, hi, DImode);
13516 emit_move_insn (operands[2], op1);
13520 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13524 ;; Store-flag instructions.
13526 ;; For all sCOND expanders, also expand the compare or test insn that
13527 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13529 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13530 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13531 ;; way, which can later delete the movzx if only QImode is needed.
13533 (define_expand "seq"
13534 [(set (match_operand:QI 0 "register_operand" "")
13535 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13537 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13539 (define_expand "sne"
13540 [(set (match_operand:QI 0 "register_operand" "")
13541 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13543 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13545 (define_expand "sgt"
13546 [(set (match_operand:QI 0 "register_operand" "")
13547 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13549 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13551 (define_expand "sgtu"
13552 [(set (match_operand:QI 0 "register_operand" "")
13553 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13555 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13557 (define_expand "slt"
13558 [(set (match_operand:QI 0 "register_operand" "")
13559 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13561 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13563 (define_expand "sltu"
13564 [(set (match_operand:QI 0 "register_operand" "")
13565 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13567 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13569 (define_expand "sge"
13570 [(set (match_operand:QI 0 "register_operand" "")
13571 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13573 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13575 (define_expand "sgeu"
13576 [(set (match_operand:QI 0 "register_operand" "")
13577 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13579 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13581 (define_expand "sle"
13582 [(set (match_operand:QI 0 "register_operand" "")
13583 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13585 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13587 (define_expand "sleu"
13588 [(set (match_operand:QI 0 "register_operand" "")
13589 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13591 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13593 (define_expand "sunordered"
13594 [(set (match_operand:QI 0 "register_operand" "")
13595 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13596 "TARGET_80387 || TARGET_SSE"
13597 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13599 (define_expand "sordered"
13600 [(set (match_operand:QI 0 "register_operand" "")
13601 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13603 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13605 (define_expand "suneq"
13606 [(set (match_operand:QI 0 "register_operand" "")
13607 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13608 "TARGET_80387 || TARGET_SSE"
13609 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13611 (define_expand "sunge"
13612 [(set (match_operand:QI 0 "register_operand" "")
13613 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13614 "TARGET_80387 || TARGET_SSE"
13615 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13617 (define_expand "sungt"
13618 [(set (match_operand:QI 0 "register_operand" "")
13619 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13620 "TARGET_80387 || TARGET_SSE"
13621 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13623 (define_expand "sunle"
13624 [(set (match_operand:QI 0 "register_operand" "")
13625 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13626 "TARGET_80387 || TARGET_SSE"
13627 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13629 (define_expand "sunlt"
13630 [(set (match_operand:QI 0 "register_operand" "")
13631 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13632 "TARGET_80387 || TARGET_SSE"
13633 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13635 (define_expand "sltgt"
13636 [(set (match_operand:QI 0 "register_operand" "")
13637 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13638 "TARGET_80387 || TARGET_SSE"
13639 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13641 (define_insn "*setcc_1"
13642 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13643 (match_operator:QI 1 "ix86_comparison_operator"
13644 [(reg FLAGS_REG) (const_int 0)]))]
13647 [(set_attr "type" "setcc")
13648 (set_attr "mode" "QI")])
13650 (define_insn "*setcc_2"
13651 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13652 (match_operator:QI 1 "ix86_comparison_operator"
13653 [(reg FLAGS_REG) (const_int 0)]))]
13656 [(set_attr "type" "setcc")
13657 (set_attr "mode" "QI")])
13659 ;; In general it is not safe to assume too much about CCmode registers,
13660 ;; so simplify-rtx stops when it sees a second one. Under certain
13661 ;; conditions this is safe on x86, so help combine not create
13668 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13669 (ne:QI (match_operator 1 "ix86_comparison_operator"
13670 [(reg FLAGS_REG) (const_int 0)])
13673 [(set (match_dup 0) (match_dup 1))]
13675 PUT_MODE (operands[1], QImode);
13679 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13680 (ne:QI (match_operator 1 "ix86_comparison_operator"
13681 [(reg FLAGS_REG) (const_int 0)])
13684 [(set (match_dup 0) (match_dup 1))]
13686 PUT_MODE (operands[1], QImode);
13690 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13691 (eq:QI (match_operator 1 "ix86_comparison_operator"
13692 [(reg FLAGS_REG) (const_int 0)])
13695 [(set (match_dup 0) (match_dup 1))]
13697 rtx new_op1 = copy_rtx (operands[1]);
13698 operands[1] = new_op1;
13699 PUT_MODE (new_op1, QImode);
13700 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13701 GET_MODE (XEXP (new_op1, 0))));
13703 /* Make sure that (a) the CCmode we have for the flags is strong
13704 enough for the reversed compare or (b) we have a valid FP compare. */
13705 if (! ix86_comparison_operator (new_op1, VOIDmode))
13710 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13711 (eq:QI (match_operator 1 "ix86_comparison_operator"
13712 [(reg FLAGS_REG) (const_int 0)])
13715 [(set (match_dup 0) (match_dup 1))]
13717 rtx new_op1 = copy_rtx (operands[1]);
13718 operands[1] = new_op1;
13719 PUT_MODE (new_op1, QImode);
13720 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13721 GET_MODE (XEXP (new_op1, 0))));
13723 /* Make sure that (a) the CCmode we have for the flags is strong
13724 enough for the reversed compare or (b) we have a valid FP compare. */
13725 if (! ix86_comparison_operator (new_op1, VOIDmode))
13729 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13730 ;; subsequent logical operations are used to imitate conditional moves.
13731 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13734 (define_insn "*sse_setccsf"
13735 [(set (match_operand:SF 0 "register_operand" "=x")
13736 (match_operator:SF 1 "sse_comparison_operator"
13737 [(match_operand:SF 2 "register_operand" "0")
13738 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13740 "cmp%D1ss\t{%3, %0|%0, %3}"
13741 [(set_attr "type" "ssecmp")
13742 (set_attr "mode" "SF")])
13744 (define_insn "*sse_setccdf"
13745 [(set (match_operand:DF 0 "register_operand" "=x")
13746 (match_operator:DF 1 "sse_comparison_operator"
13747 [(match_operand:DF 2 "register_operand" "0")
13748 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13750 "cmp%D1sd\t{%3, %0|%0, %3}"
13751 [(set_attr "type" "ssecmp")
13752 (set_attr "mode" "DF")])
13754 ;; Basic conditional jump instructions.
13755 ;; We ignore the overflow flag for signed branch instructions.
13757 ;; For all bCOND expanders, also expand the compare or test insn that
13758 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13760 (define_expand "beq"
13762 (if_then_else (match_dup 1)
13763 (label_ref (match_operand 0 "" ""))
13766 "ix86_expand_branch (EQ, operands[0]); DONE;")
13768 (define_expand "bne"
13770 (if_then_else (match_dup 1)
13771 (label_ref (match_operand 0 "" ""))
13774 "ix86_expand_branch (NE, operands[0]); DONE;")
13776 (define_expand "bgt"
13778 (if_then_else (match_dup 1)
13779 (label_ref (match_operand 0 "" ""))
13782 "ix86_expand_branch (GT, operands[0]); DONE;")
13784 (define_expand "bgtu"
13786 (if_then_else (match_dup 1)
13787 (label_ref (match_operand 0 "" ""))
13790 "ix86_expand_branch (GTU, operands[0]); DONE;")
13792 (define_expand "blt"
13794 (if_then_else (match_dup 1)
13795 (label_ref (match_operand 0 "" ""))
13798 "ix86_expand_branch (LT, operands[0]); DONE;")
13800 (define_expand "bltu"
13802 (if_then_else (match_dup 1)
13803 (label_ref (match_operand 0 "" ""))
13806 "ix86_expand_branch (LTU, operands[0]); DONE;")
13808 (define_expand "bge"
13810 (if_then_else (match_dup 1)
13811 (label_ref (match_operand 0 "" ""))
13814 "ix86_expand_branch (GE, operands[0]); DONE;")
13816 (define_expand "bgeu"
13818 (if_then_else (match_dup 1)
13819 (label_ref (match_operand 0 "" ""))
13822 "ix86_expand_branch (GEU, operands[0]); DONE;")
13824 (define_expand "ble"
13826 (if_then_else (match_dup 1)
13827 (label_ref (match_operand 0 "" ""))
13830 "ix86_expand_branch (LE, operands[0]); DONE;")
13832 (define_expand "bleu"
13834 (if_then_else (match_dup 1)
13835 (label_ref (match_operand 0 "" ""))
13838 "ix86_expand_branch (LEU, operands[0]); DONE;")
13840 (define_expand "bunordered"
13842 (if_then_else (match_dup 1)
13843 (label_ref (match_operand 0 "" ""))
13845 "TARGET_80387 || TARGET_SSE_MATH"
13846 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13848 (define_expand "bordered"
13850 (if_then_else (match_dup 1)
13851 (label_ref (match_operand 0 "" ""))
13853 "TARGET_80387 || TARGET_SSE_MATH"
13854 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13856 (define_expand "buneq"
13858 (if_then_else (match_dup 1)
13859 (label_ref (match_operand 0 "" ""))
13861 "TARGET_80387 || TARGET_SSE_MATH"
13862 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13864 (define_expand "bunge"
13866 (if_then_else (match_dup 1)
13867 (label_ref (match_operand 0 "" ""))
13869 "TARGET_80387 || TARGET_SSE_MATH"
13870 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13872 (define_expand "bungt"
13874 (if_then_else (match_dup 1)
13875 (label_ref (match_operand 0 "" ""))
13877 "TARGET_80387 || TARGET_SSE_MATH"
13878 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13880 (define_expand "bunle"
13882 (if_then_else (match_dup 1)
13883 (label_ref (match_operand 0 "" ""))
13885 "TARGET_80387 || TARGET_SSE_MATH"
13886 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13888 (define_expand "bunlt"
13890 (if_then_else (match_dup 1)
13891 (label_ref (match_operand 0 "" ""))
13893 "TARGET_80387 || TARGET_SSE_MATH"
13894 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13896 (define_expand "bltgt"
13898 (if_then_else (match_dup 1)
13899 (label_ref (match_operand 0 "" ""))
13901 "TARGET_80387 || TARGET_SSE_MATH"
13902 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13904 (define_insn "*jcc_1"
13906 (if_then_else (match_operator 1 "ix86_comparison_operator"
13907 [(reg FLAGS_REG) (const_int 0)])
13908 (label_ref (match_operand 0 "" ""))
13912 [(set_attr "type" "ibr")
13913 (set_attr "modrm" "0")
13914 (set (attr "length")
13915 (if_then_else (and (ge (minus (match_dup 0) (pc))
13917 (lt (minus (match_dup 0) (pc))
13922 (define_insn "*jcc_2"
13924 (if_then_else (match_operator 1 "ix86_comparison_operator"
13925 [(reg FLAGS_REG) (const_int 0)])
13927 (label_ref (match_operand 0 "" ""))))]
13930 [(set_attr "type" "ibr")
13931 (set_attr "modrm" "0")
13932 (set (attr "length")
13933 (if_then_else (and (ge (minus (match_dup 0) (pc))
13935 (lt (minus (match_dup 0) (pc))
13940 ;; In general it is not safe to assume too much about CCmode registers,
13941 ;; so simplify-rtx stops when it sees a second one. Under certain
13942 ;; conditions this is safe on x86, so help combine not create
13950 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13951 [(reg FLAGS_REG) (const_int 0)])
13953 (label_ref (match_operand 1 "" ""))
13957 (if_then_else (match_dup 0)
13958 (label_ref (match_dup 1))
13961 PUT_MODE (operands[0], VOIDmode);
13966 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13967 [(reg FLAGS_REG) (const_int 0)])
13969 (label_ref (match_operand 1 "" ""))
13973 (if_then_else (match_dup 0)
13974 (label_ref (match_dup 1))
13977 rtx new_op0 = copy_rtx (operands[0]);
13978 operands[0] = new_op0;
13979 PUT_MODE (new_op0, VOIDmode);
13980 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13981 GET_MODE (XEXP (new_op0, 0))));
13983 /* Make sure that (a) the CCmode we have for the flags is strong
13984 enough for the reversed compare or (b) we have a valid FP compare. */
13985 if (! ix86_comparison_operator (new_op0, VOIDmode))
13989 ;; Define combination compare-and-branch fp compare instructions to use
13990 ;; during early optimization. Splitting the operation apart early makes
13991 ;; for bad code when we want to reverse the operation.
13993 (define_insn "*fp_jcc_1_mixed"
13995 (if_then_else (match_operator 0 "comparison_operator"
13996 [(match_operand 1 "register_operand" "f,x")
13997 (match_operand 2 "nonimmediate_operand" "f,xm")])
13998 (label_ref (match_operand 3 "" ""))
14000 (clobber (reg:CCFP FPSR_REG))
14001 (clobber (reg:CCFP FLAGS_REG))]
14002 "TARGET_MIX_SSE_I387
14003 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14004 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14005 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14008 (define_insn "*fp_jcc_1_sse"
14010 (if_then_else (match_operator 0 "comparison_operator"
14011 [(match_operand 1 "register_operand" "x")
14012 (match_operand 2 "nonimmediate_operand" "xm")])
14013 (label_ref (match_operand 3 "" ""))
14015 (clobber (reg:CCFP FPSR_REG))
14016 (clobber (reg:CCFP FLAGS_REG))]
14018 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14019 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14020 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14023 (define_insn "*fp_jcc_1_387"
14025 (if_then_else (match_operator 0 "comparison_operator"
14026 [(match_operand 1 "register_operand" "f")
14027 (match_operand 2 "register_operand" "f")])
14028 (label_ref (match_operand 3 "" ""))
14030 (clobber (reg:CCFP FPSR_REG))
14031 (clobber (reg:CCFP FLAGS_REG))]
14032 "TARGET_CMOVE && TARGET_80387
14033 && FLOAT_MODE_P (GET_MODE (operands[1]))
14034 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14035 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14038 (define_insn "*fp_jcc_2_mixed"
14040 (if_then_else (match_operator 0 "comparison_operator"
14041 [(match_operand 1 "register_operand" "f,x")
14042 (match_operand 2 "nonimmediate_operand" "f,xm")])
14044 (label_ref (match_operand 3 "" ""))))
14045 (clobber (reg:CCFP FPSR_REG))
14046 (clobber (reg:CCFP FLAGS_REG))]
14047 "TARGET_MIX_SSE_I387
14048 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14049 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14050 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14053 (define_insn "*fp_jcc_2_sse"
14055 (if_then_else (match_operator 0 "comparison_operator"
14056 [(match_operand 1 "register_operand" "x")
14057 (match_operand 2 "nonimmediate_operand" "xm")])
14059 (label_ref (match_operand 3 "" ""))))
14060 (clobber (reg:CCFP FPSR_REG))
14061 (clobber (reg:CCFP FLAGS_REG))]
14063 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14064 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14065 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14068 (define_insn "*fp_jcc_2_387"
14070 (if_then_else (match_operator 0 "comparison_operator"
14071 [(match_operand 1 "register_operand" "f")
14072 (match_operand 2 "register_operand" "f")])
14074 (label_ref (match_operand 3 "" ""))))
14075 (clobber (reg:CCFP FPSR_REG))
14076 (clobber (reg:CCFP FLAGS_REG))]
14077 "TARGET_CMOVE && TARGET_80387
14078 && 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_3_387"
14085 (if_then_else (match_operator 0 "comparison_operator"
14086 [(match_operand 1 "register_operand" "f")
14087 (match_operand 2 "nonimmediate_operand" "fm")])
14088 (label_ref (match_operand 3 "" ""))
14090 (clobber (reg:CCFP FPSR_REG))
14091 (clobber (reg:CCFP FLAGS_REG))
14092 (clobber (match_scratch:HI 4 "=a"))]
14094 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14095 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14096 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14097 && SELECT_CC_MODE (GET_CODE (operands[0]),
14098 operands[1], operands[2]) == CCFPmode
14099 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14102 (define_insn "*fp_jcc_4_387"
14104 (if_then_else (match_operator 0 "comparison_operator"
14105 [(match_operand 1 "register_operand" "f")
14106 (match_operand 2 "nonimmediate_operand" "fm")])
14108 (label_ref (match_operand 3 "" ""))))
14109 (clobber (reg:CCFP FPSR_REG))
14110 (clobber (reg:CCFP FLAGS_REG))
14111 (clobber (match_scratch:HI 4 "=a"))]
14113 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14114 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14115 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14116 && SELECT_CC_MODE (GET_CODE (operands[0]),
14117 operands[1], operands[2]) == CCFPmode
14118 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14121 (define_insn "*fp_jcc_5_387"
14123 (if_then_else (match_operator 0 "comparison_operator"
14124 [(match_operand 1 "register_operand" "f")
14125 (match_operand 2 "register_operand" "f")])
14126 (label_ref (match_operand 3 "" ""))
14128 (clobber (reg:CCFP FPSR_REG))
14129 (clobber (reg:CCFP FLAGS_REG))
14130 (clobber (match_scratch:HI 4 "=a"))]
14132 && FLOAT_MODE_P (GET_MODE (operands[1]))
14133 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14134 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14137 (define_insn "*fp_jcc_6_387"
14139 (if_then_else (match_operator 0 "comparison_operator"
14140 [(match_operand 1 "register_operand" "f")
14141 (match_operand 2 "register_operand" "f")])
14143 (label_ref (match_operand 3 "" ""))))
14144 (clobber (reg:CCFP FPSR_REG))
14145 (clobber (reg:CCFP FLAGS_REG))
14146 (clobber (match_scratch:HI 4 "=a"))]
14148 && FLOAT_MODE_P (GET_MODE (operands[1]))
14149 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14150 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14153 (define_insn "*fp_jcc_7_387"
14155 (if_then_else (match_operator 0 "comparison_operator"
14156 [(match_operand 1 "register_operand" "f")
14157 (match_operand 2 "const0_operand" "X")])
14158 (label_ref (match_operand 3 "" ""))
14160 (clobber (reg:CCFP FPSR_REG))
14161 (clobber (reg:CCFP FLAGS_REG))
14162 (clobber (match_scratch:HI 4 "=a"))]
14164 && FLOAT_MODE_P (GET_MODE (operands[1]))
14165 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14166 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14167 && SELECT_CC_MODE (GET_CODE (operands[0]),
14168 operands[1], operands[2]) == CCFPmode
14169 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14172 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14173 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14174 ;; with a precedence over other operators and is always put in the first
14175 ;; place. Swap condition and operands to match ficom instruction.
14177 (define_insn "*fp_jcc_8<mode>_387"
14179 (if_then_else (match_operator 0 "comparison_operator"
14180 [(match_operator 1 "float_operator"
14181 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14182 (match_operand 3 "register_operand" "f,f")])
14183 (label_ref (match_operand 4 "" ""))
14185 (clobber (reg:CCFP FPSR_REG))
14186 (clobber (reg:CCFP FLAGS_REG))
14187 (clobber (match_scratch:HI 5 "=a,a"))]
14188 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14189 && FLOAT_MODE_P (GET_MODE (operands[3]))
14190 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14191 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14192 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14193 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14198 (if_then_else (match_operator 0 "comparison_operator"
14199 [(match_operand 1 "register_operand" "")
14200 (match_operand 2 "nonimmediate_operand" "")])
14201 (match_operand 3 "" "")
14202 (match_operand 4 "" "")))
14203 (clobber (reg:CCFP FPSR_REG))
14204 (clobber (reg:CCFP FLAGS_REG))]
14208 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14209 operands[3], operands[4], NULL_RTX, NULL_RTX);
14215 (if_then_else (match_operator 0 "comparison_operator"
14216 [(match_operand 1 "register_operand" "")
14217 (match_operand 2 "general_operand" "")])
14218 (match_operand 3 "" "")
14219 (match_operand 4 "" "")))
14220 (clobber (reg:CCFP FPSR_REG))
14221 (clobber (reg:CCFP FLAGS_REG))
14222 (clobber (match_scratch:HI 5 "=a"))]
14226 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14227 operands[3], operands[4], operands[5], NULL_RTX);
14233 (if_then_else (match_operator 0 "comparison_operator"
14234 [(match_operator 1 "float_operator"
14235 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14236 (match_operand 3 "register_operand" "")])
14237 (match_operand 4 "" "")
14238 (match_operand 5 "" "")))
14239 (clobber (reg:CCFP FPSR_REG))
14240 (clobber (reg:CCFP FLAGS_REG))
14241 (clobber (match_scratch:HI 6 "=a"))]
14245 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14246 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14247 operands[3], operands[7],
14248 operands[4], operands[5], operands[6], NULL_RTX);
14252 ;; %%% Kill this when reload knows how to do it.
14255 (if_then_else (match_operator 0 "comparison_operator"
14256 [(match_operator 1 "float_operator"
14257 [(match_operand:X87MODEI12 2 "register_operand" "")])
14258 (match_operand 3 "register_operand" "")])
14259 (match_operand 4 "" "")
14260 (match_operand 5 "" "")))
14261 (clobber (reg:CCFP FPSR_REG))
14262 (clobber (reg:CCFP FLAGS_REG))
14263 (clobber (match_scratch:HI 6 "=a"))]
14267 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14268 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14269 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14270 operands[3], operands[7],
14271 operands[4], operands[5], operands[6], operands[2]);
14275 ;; Unconditional and other jump instructions
14277 (define_insn "jump"
14279 (label_ref (match_operand 0 "" "")))]
14282 [(set_attr "type" "ibr")
14283 (set (attr "length")
14284 (if_then_else (and (ge (minus (match_dup 0) (pc))
14286 (lt (minus (match_dup 0) (pc))
14290 (set_attr "modrm" "0")])
14292 (define_expand "indirect_jump"
14293 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14297 (define_insn "*indirect_jump"
14298 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14301 [(set_attr "type" "ibr")
14302 (set_attr "length_immediate" "0")])
14304 (define_insn "*indirect_jump_rtx64"
14305 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14308 [(set_attr "type" "ibr")
14309 (set_attr "length_immediate" "0")])
14311 (define_expand "tablejump"
14312 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14313 (use (label_ref (match_operand 1 "" "")))])]
14316 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14317 relative. Convert the relative address to an absolute address. */
14321 enum rtx_code code;
14323 /* We can't use @GOTOFF for text labels on VxWorks;
14324 see gotoff_operand. */
14325 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14329 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14331 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14335 op1 = pic_offset_table_rtx;
14340 op0 = pic_offset_table_rtx;
14344 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14349 (define_insn "*tablejump_1"
14350 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14351 (use (label_ref (match_operand 1 "" "")))]
14354 [(set_attr "type" "ibr")
14355 (set_attr "length_immediate" "0")])
14357 (define_insn "*tablejump_1_rtx64"
14358 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14359 (use (label_ref (match_operand 1 "" "")))]
14362 [(set_attr "type" "ibr")
14363 (set_attr "length_immediate" "0")])
14365 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14368 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14369 (set (match_operand:QI 1 "register_operand" "")
14370 (match_operator:QI 2 "ix86_comparison_operator"
14371 [(reg FLAGS_REG) (const_int 0)]))
14372 (set (match_operand 3 "q_regs_operand" "")
14373 (zero_extend (match_dup 1)))]
14374 "(peep2_reg_dead_p (3, operands[1])
14375 || operands_match_p (operands[1], operands[3]))
14376 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14377 [(set (match_dup 4) (match_dup 0))
14378 (set (strict_low_part (match_dup 5))
14381 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14382 operands[5] = gen_lowpart (QImode, operands[3]);
14383 ix86_expand_clear (operands[3]);
14386 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14389 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14390 (set (match_operand:QI 1 "register_operand" "")
14391 (match_operator:QI 2 "ix86_comparison_operator"
14392 [(reg FLAGS_REG) (const_int 0)]))
14393 (parallel [(set (match_operand 3 "q_regs_operand" "")
14394 (zero_extend (match_dup 1)))
14395 (clobber (reg:CC FLAGS_REG))])]
14396 "(peep2_reg_dead_p (3, operands[1])
14397 || operands_match_p (operands[1], operands[3]))
14398 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14399 [(set (match_dup 4) (match_dup 0))
14400 (set (strict_low_part (match_dup 5))
14403 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14404 operands[5] = gen_lowpart (QImode, operands[3]);
14405 ix86_expand_clear (operands[3]);
14408 ;; Call instructions.
14410 ;; The predicates normally associated with named expanders are not properly
14411 ;; checked for calls. This is a bug in the generic code, but it isn't that
14412 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14414 ;; Call subroutine returning no value.
14416 (define_expand "call_pop"
14417 [(parallel [(call (match_operand:QI 0 "" "")
14418 (match_operand:SI 1 "" ""))
14419 (set (reg:SI SP_REG)
14420 (plus:SI (reg:SI SP_REG)
14421 (match_operand:SI 3 "" "")))])]
14424 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14428 (define_insn "*call_pop_0"
14429 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14430 (match_operand:SI 1 "" ""))
14431 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14432 (match_operand:SI 2 "immediate_operand" "")))]
14435 if (SIBLING_CALL_P (insn))
14438 return "call\t%P0";
14440 [(set_attr "type" "call")])
14442 (define_insn "*call_pop_1"
14443 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14444 (match_operand:SI 1 "" ""))
14445 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14446 (match_operand:SI 2 "immediate_operand" "i")))]
14449 if (constant_call_address_operand (operands[0], Pmode))
14451 if (SIBLING_CALL_P (insn))
14454 return "call\t%P0";
14456 if (SIBLING_CALL_P (insn))
14459 return "call\t%A0";
14461 [(set_attr "type" "call")])
14463 (define_expand "call"
14464 [(call (match_operand:QI 0 "" "")
14465 (match_operand 1 "" ""))
14466 (use (match_operand 2 "" ""))]
14469 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14473 (define_expand "sibcall"
14474 [(call (match_operand:QI 0 "" "")
14475 (match_operand 1 "" ""))
14476 (use (match_operand 2 "" ""))]
14479 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14483 (define_insn "*call_0"
14484 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14485 (match_operand 1 "" ""))]
14488 if (SIBLING_CALL_P (insn))
14491 return "call\t%P0";
14493 [(set_attr "type" "call")])
14495 (define_insn "*call_1"
14496 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14497 (match_operand 1 "" ""))]
14498 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14500 if (constant_call_address_operand (operands[0], Pmode))
14501 return "call\t%P0";
14502 return "call\t%A0";
14504 [(set_attr "type" "call")])
14506 (define_insn "*sibcall_1"
14507 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14508 (match_operand 1 "" ""))]
14509 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14511 if (constant_call_address_operand (operands[0], Pmode))
14515 [(set_attr "type" "call")])
14517 (define_insn "*call_1_rex64"
14518 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14519 (match_operand 1 "" ""))]
14520 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14521 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14523 if (constant_call_address_operand (operands[0], Pmode))
14524 return "call\t%P0";
14525 return "call\t%A0";
14527 [(set_attr "type" "call")])
14529 (define_insn "*call_1_rex64_large"
14530 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14531 (match_operand 1 "" ""))]
14532 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14534 [(set_attr "type" "call")])
14536 (define_insn "*sibcall_1_rex64"
14537 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14538 (match_operand 1 "" ""))]
14539 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14541 [(set_attr "type" "call")])
14543 (define_insn "*sibcall_1_rex64_v"
14544 [(call (mem:QI (reg:DI R11_REG))
14545 (match_operand 0 "" ""))]
14546 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14548 [(set_attr "type" "call")])
14551 ;; Call subroutine, returning value in operand 0
14553 (define_expand "call_value_pop"
14554 [(parallel [(set (match_operand 0 "" "")
14555 (call (match_operand:QI 1 "" "")
14556 (match_operand:SI 2 "" "")))
14557 (set (reg:SI SP_REG)
14558 (plus:SI (reg:SI SP_REG)
14559 (match_operand:SI 4 "" "")))])]
14562 ix86_expand_call (operands[0], operands[1], operands[2],
14563 operands[3], operands[4], 0);
14567 (define_expand "call_value"
14568 [(set (match_operand 0 "" "")
14569 (call (match_operand:QI 1 "" "")
14570 (match_operand:SI 2 "" "")))
14571 (use (match_operand:SI 3 "" ""))]
14572 ;; Operand 2 not used on the i386.
14575 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14579 (define_expand "sibcall_value"
14580 [(set (match_operand 0 "" "")
14581 (call (match_operand:QI 1 "" "")
14582 (match_operand:SI 2 "" "")))
14583 (use (match_operand:SI 3 "" ""))]
14584 ;; Operand 2 not used on the i386.
14587 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14591 ;; Call subroutine returning any type.
14593 (define_expand "untyped_call"
14594 [(parallel [(call (match_operand 0 "" "")
14596 (match_operand 1 "" "")
14597 (match_operand 2 "" "")])]
14602 /* In order to give reg-stack an easier job in validating two
14603 coprocessor registers as containing a possible return value,
14604 simply pretend the untyped call returns a complex long double
14607 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14608 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14609 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14612 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14614 rtx set = XVECEXP (operands[2], 0, i);
14615 emit_move_insn (SET_DEST (set), SET_SRC (set));
14618 /* The optimizer does not know that the call sets the function value
14619 registers we stored in the result block. We avoid problems by
14620 claiming that all hard registers are used and clobbered at this
14622 emit_insn (gen_blockage (const0_rtx));
14627 ;; Prologue and epilogue instructions
14629 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14630 ;; all of memory. This blocks insns from being moved across this point.
14632 (define_insn "blockage"
14633 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14636 [(set_attr "length" "0")])
14638 ;; Insn emitted into the body of a function to return from a function.
14639 ;; This is only done if the function's epilogue is known to be simple.
14640 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14642 (define_expand "return"
14644 "ix86_can_use_return_insn_p ()"
14646 if (current_function_pops_args)
14648 rtx popc = GEN_INT (current_function_pops_args);
14649 emit_jump_insn (gen_return_pop_internal (popc));
14654 (define_insn "return_internal"
14658 [(set_attr "length" "1")
14659 (set_attr "length_immediate" "0")
14660 (set_attr "modrm" "0")])
14662 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14663 ;; instruction Athlon and K8 have.
14665 (define_insn "return_internal_long"
14667 (unspec [(const_int 0)] UNSPEC_REP)]
14670 [(set_attr "length" "1")
14671 (set_attr "length_immediate" "0")
14672 (set_attr "prefix_rep" "1")
14673 (set_attr "modrm" "0")])
14675 (define_insn "return_pop_internal"
14677 (use (match_operand:SI 0 "const_int_operand" ""))]
14680 [(set_attr "length" "3")
14681 (set_attr "length_immediate" "2")
14682 (set_attr "modrm" "0")])
14684 (define_insn "return_indirect_internal"
14686 (use (match_operand:SI 0 "register_operand" "r"))]
14689 [(set_attr "type" "ibr")
14690 (set_attr "length_immediate" "0")])
14696 [(set_attr "length" "1")
14697 (set_attr "length_immediate" "0")
14698 (set_attr "modrm" "0")])
14700 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14701 ;; branch prediction penalty for the third jump in a 16-byte
14704 (define_insn "align"
14705 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14708 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14709 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14711 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14712 The align insn is used to avoid 3 jump instructions in the row to improve
14713 branch prediction and the benefits hardly outweigh the cost of extra 8
14714 nops on the average inserted by full alignment pseudo operation. */
14718 [(set_attr "length" "16")])
14720 (define_expand "prologue"
14723 "ix86_expand_prologue (); DONE;")
14725 (define_insn "set_got"
14726 [(set (match_operand:SI 0 "register_operand" "=r")
14727 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14728 (clobber (reg:CC FLAGS_REG))]
14730 { return output_set_got (operands[0], NULL_RTX); }
14731 [(set_attr "type" "multi")
14732 (set_attr "length" "12")])
14734 (define_insn "set_got_labelled"
14735 [(set (match_operand:SI 0 "register_operand" "=r")
14736 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14738 (clobber (reg:CC FLAGS_REG))]
14740 { return output_set_got (operands[0], operands[1]); }
14741 [(set_attr "type" "multi")
14742 (set_attr "length" "12")])
14744 (define_insn "set_got_rex64"
14745 [(set (match_operand:DI 0 "register_operand" "=r")
14746 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14748 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14749 [(set_attr "type" "lea")
14750 (set_attr "length" "6")])
14752 (define_insn "set_rip_rex64"
14753 [(set (match_operand:DI 0 "register_operand" "=r")
14754 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14756 "lea{q}\t%l1(%%rip), %0"
14757 [(set_attr "type" "lea")
14758 (set_attr "length" "6")])
14760 (define_insn "set_got_offset_rex64"
14761 [(set (match_operand:DI 0 "register_operand" "=r")
14762 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14764 "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
14765 [(set_attr "type" "imov")
14766 (set_attr "length" "11")])
14768 (define_expand "epilogue"
14771 "ix86_expand_epilogue (1); DONE;")
14773 (define_expand "sibcall_epilogue"
14776 "ix86_expand_epilogue (0); DONE;")
14778 (define_expand "eh_return"
14779 [(use (match_operand 0 "register_operand" ""))]
14782 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14784 /* Tricky bit: we write the address of the handler to which we will
14785 be returning into someone else's stack frame, one word below the
14786 stack address we wish to restore. */
14787 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14788 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14789 tmp = gen_rtx_MEM (Pmode, tmp);
14790 emit_move_insn (tmp, ra);
14792 if (Pmode == SImode)
14793 emit_jump_insn (gen_eh_return_si (sa));
14795 emit_jump_insn (gen_eh_return_di (sa));
14800 (define_insn_and_split "eh_return_si"
14802 (unspec [(match_operand:SI 0 "register_operand" "c")]
14803 UNSPEC_EH_RETURN))]
14808 "ix86_expand_epilogue (2); DONE;")
14810 (define_insn_and_split "eh_return_di"
14812 (unspec [(match_operand:DI 0 "register_operand" "c")]
14813 UNSPEC_EH_RETURN))]
14818 "ix86_expand_epilogue (2); DONE;")
14820 (define_insn "leave"
14821 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14822 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14823 (clobber (mem:BLK (scratch)))]
14826 [(set_attr "type" "leave")])
14828 (define_insn "leave_rex64"
14829 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14830 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14831 (clobber (mem:BLK (scratch)))]
14834 [(set_attr "type" "leave")])
14836 (define_expand "ffssi2"
14838 [(set (match_operand:SI 0 "register_operand" "")
14839 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14840 (clobber (match_scratch:SI 2 ""))
14841 (clobber (reg:CC FLAGS_REG))])]
14845 (define_insn_and_split "*ffs_cmove"
14846 [(set (match_operand:SI 0 "register_operand" "=r")
14847 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14848 (clobber (match_scratch:SI 2 "=&r"))
14849 (clobber (reg:CC FLAGS_REG))]
14852 "&& reload_completed"
14853 [(set (match_dup 2) (const_int -1))
14854 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14855 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14856 (set (match_dup 0) (if_then_else:SI
14857 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14860 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14861 (clobber (reg:CC FLAGS_REG))])]
14864 (define_insn_and_split "*ffs_no_cmove"
14865 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14866 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14867 (clobber (match_scratch:SI 2 "=&q"))
14868 (clobber (reg:CC FLAGS_REG))]
14872 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14873 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14874 (set (strict_low_part (match_dup 3))
14875 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14876 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14877 (clobber (reg:CC FLAGS_REG))])
14878 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14879 (clobber (reg:CC FLAGS_REG))])
14880 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14881 (clobber (reg:CC FLAGS_REG))])]
14883 operands[3] = gen_lowpart (QImode, operands[2]);
14884 ix86_expand_clear (operands[2]);
14887 (define_insn "*ffssi_1"
14888 [(set (reg:CCZ FLAGS_REG)
14889 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14891 (set (match_operand:SI 0 "register_operand" "=r")
14892 (ctz:SI (match_dup 1)))]
14894 "bsf{l}\t{%1, %0|%0, %1}"
14895 [(set_attr "prefix_0f" "1")])
14897 (define_expand "ffsdi2"
14899 [(set (match_operand:DI 0 "register_operand" "")
14900 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14901 (clobber (match_scratch:DI 2 ""))
14902 (clobber (reg:CC FLAGS_REG))])]
14903 "TARGET_64BIT && TARGET_CMOVE"
14906 (define_insn_and_split "*ffs_rex64"
14907 [(set (match_operand:DI 0 "register_operand" "=r")
14908 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14909 (clobber (match_scratch:DI 2 "=&r"))
14910 (clobber (reg:CC FLAGS_REG))]
14911 "TARGET_64BIT && TARGET_CMOVE"
14913 "&& reload_completed"
14914 [(set (match_dup 2) (const_int -1))
14915 (parallel [(set (reg:CCZ FLAGS_REG)
14916 (compare:CCZ (match_dup 1) (const_int 0)))
14917 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14918 (set (match_dup 0) (if_then_else:DI
14919 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14922 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14923 (clobber (reg:CC FLAGS_REG))])]
14926 (define_insn "*ffsdi_1"
14927 [(set (reg:CCZ FLAGS_REG)
14928 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14930 (set (match_operand:DI 0 "register_operand" "=r")
14931 (ctz:DI (match_dup 1)))]
14933 "bsf{q}\t{%1, %0|%0, %1}"
14934 [(set_attr "prefix_0f" "1")])
14936 (define_insn "ctzsi2"
14937 [(set (match_operand:SI 0 "register_operand" "=r")
14938 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14939 (clobber (reg:CC FLAGS_REG))]
14941 "bsf{l}\t{%1, %0|%0, %1}"
14942 [(set_attr "prefix_0f" "1")])
14944 (define_insn "ctzdi2"
14945 [(set (match_operand:DI 0 "register_operand" "=r")
14946 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14947 (clobber (reg:CC FLAGS_REG))]
14949 "bsf{q}\t{%1, %0|%0, %1}"
14950 [(set_attr "prefix_0f" "1")])
14952 (define_expand "clzsi2"
14954 [(set (match_operand:SI 0 "register_operand" "")
14955 (minus:SI (const_int 31)
14956 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14957 (clobber (reg:CC FLAGS_REG))])
14959 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14960 (clobber (reg:CC FLAGS_REG))])]
14965 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14970 (define_insn "clzsi2_abm"
14971 [(set (match_operand:SI 0 "register_operand" "=r")
14972 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14973 (clobber (reg:CC FLAGS_REG))]
14975 "lzcnt{l}\t{%1, %0|%0, %1}"
14976 [(set_attr "prefix_rep" "1")
14977 (set_attr "type" "bitmanip")
14978 (set_attr "mode" "SI")])
14980 (define_insn "*bsr"
14981 [(set (match_operand:SI 0 "register_operand" "=r")
14982 (minus:SI (const_int 31)
14983 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14984 (clobber (reg:CC FLAGS_REG))]
14986 "bsr{l}\t{%1, %0|%0, %1}"
14987 [(set_attr "prefix_0f" "1")
14988 (set_attr "mode" "SI")])
14990 (define_insn "popcountsi2"
14991 [(set (match_operand:SI 0 "register_operand" "=r")
14992 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14993 (clobber (reg:CC FLAGS_REG))]
14995 "popcnt{l}\t{%1, %0|%0, %1}"
14996 [(set_attr "prefix_rep" "1")
14997 (set_attr "type" "bitmanip")
14998 (set_attr "mode" "SI")])
15000 (define_insn "*popcountsi2_cmp"
15001 [(set (reg FLAGS_REG)
15003 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15005 (set (match_operand:SI 0 "register_operand" "=r")
15006 (popcount:SI (match_dup 1)))]
15007 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15008 "popcnt{l}\t{%1, %0|%0, %1}"
15009 [(set_attr "prefix_rep" "1")
15010 (set_attr "type" "bitmanip")
15011 (set_attr "mode" "SI")])
15013 (define_insn "*popcountsi2_cmp_zext"
15014 [(set (reg FLAGS_REG)
15016 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15018 (set (match_operand:DI 0 "register_operand" "=r")
15019 (zero_extend:DI(popcount:SI (match_dup 1))))]
15020 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15021 "popcnt{l}\t{%1, %0|%0, %1}"
15022 [(set_attr "prefix_rep" "1")
15023 (set_attr "type" "bitmanip")
15024 (set_attr "mode" "SI")])
15026 (define_expand "bswapsi2"
15027 [(set (match_operand:SI 0 "register_operand" "")
15028 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15033 rtx x = operands[0];
15035 emit_move_insn (x, operands[1]);
15036 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15037 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15038 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15043 (define_insn "*bswapsi_1"
15044 [(set (match_operand:SI 0 "register_operand" "=r")
15045 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15048 [(set_attr "prefix_0f" "1")
15049 (set_attr "length" "2")])
15051 (define_insn "*bswaphi_lowpart_1"
15052 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15053 (bswap:HI (match_dup 0)))
15054 (clobber (reg:CC FLAGS_REG))]
15055 "TARGET_USE_XCHGB || optimize_size"
15057 xchg{b}\t{%h0, %b0|%b0, %h0}
15058 rol{w}\t{$8, %0|%0, 8}"
15059 [(set_attr "length" "2,4")
15060 (set_attr "mode" "QI,HI")])
15062 (define_insn "bswaphi_lowpart"
15063 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15064 (bswap:HI (match_dup 0)))
15065 (clobber (reg:CC FLAGS_REG))]
15067 "rol{w}\t{$8, %0|%0, 8}"
15068 [(set_attr "length" "4")
15069 (set_attr "mode" "HI")])
15071 (define_insn "bswapdi2"
15072 [(set (match_operand:DI 0 "register_operand" "=r")
15073 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15076 [(set_attr "prefix_0f" "1")
15077 (set_attr "length" "3")])
15079 (define_expand "clzdi2"
15081 [(set (match_operand:DI 0 "register_operand" "")
15082 (minus:DI (const_int 63)
15083 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15084 (clobber (reg:CC FLAGS_REG))])
15086 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15087 (clobber (reg:CC FLAGS_REG))])]
15092 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15097 (define_insn "clzdi2_abm"
15098 [(set (match_operand:DI 0 "register_operand" "=r")
15099 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15100 (clobber (reg:CC FLAGS_REG))]
15101 "TARGET_64BIT && TARGET_ABM"
15102 "lzcnt{q}\t{%1, %0|%0, %1}"
15103 [(set_attr "prefix_rep" "1")
15104 (set_attr "type" "bitmanip")
15105 (set_attr "mode" "DI")])
15107 (define_insn "*bsr_rex64"
15108 [(set (match_operand:DI 0 "register_operand" "=r")
15109 (minus:DI (const_int 63)
15110 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15111 (clobber (reg:CC FLAGS_REG))]
15113 "bsr{q}\t{%1, %0|%0, %1}"
15114 [(set_attr "prefix_0f" "1")
15115 (set_attr "mode" "DI")])
15117 (define_insn "popcountdi2"
15118 [(set (match_operand:DI 0 "register_operand" "=r")
15119 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15120 (clobber (reg:CC FLAGS_REG))]
15121 "TARGET_64BIT && TARGET_POPCNT"
15122 "popcnt{q}\t{%1, %0|%0, %1}"
15123 [(set_attr "prefix_rep" "1")
15124 (set_attr "type" "bitmanip")
15125 (set_attr "mode" "DI")])
15127 (define_insn "*popcountdi2_cmp"
15128 [(set (reg FLAGS_REG)
15130 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15132 (set (match_operand:DI 0 "register_operand" "=r")
15133 (popcount:DI (match_dup 1)))]
15134 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15135 "popcnt{q}\t{%1, %0|%0, %1}"
15136 [(set_attr "prefix_rep" "1")
15137 (set_attr "type" "bitmanip")
15138 (set_attr "mode" "DI")])
15140 (define_expand "clzhi2"
15142 [(set (match_operand:HI 0 "register_operand" "")
15143 (minus:HI (const_int 15)
15144 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15145 (clobber (reg:CC FLAGS_REG))])
15147 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15148 (clobber (reg:CC FLAGS_REG))])]
15153 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15158 (define_insn "clzhi2_abm"
15159 [(set (match_operand:HI 0 "register_operand" "=r")
15160 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15161 (clobber (reg:CC FLAGS_REG))]
15163 "lzcnt{w}\t{%1, %0|%0, %1}"
15164 [(set_attr "prefix_rep" "1")
15165 (set_attr "type" "bitmanip")
15166 (set_attr "mode" "HI")])
15168 (define_insn "*bsrhi"
15169 [(set (match_operand:HI 0 "register_operand" "=r")
15170 (minus:HI (const_int 15)
15171 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15172 (clobber (reg:CC FLAGS_REG))]
15174 "bsr{w}\t{%1, %0|%0, %1}"
15175 [(set_attr "prefix_0f" "1")
15176 (set_attr "mode" "HI")])
15178 (define_insn "popcounthi2"
15179 [(set (match_operand:HI 0 "register_operand" "=r")
15180 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15181 (clobber (reg:CC FLAGS_REG))]
15183 "popcnt{w}\t{%1, %0|%0, %1}"
15184 [(set_attr "prefix_rep" "1")
15185 (set_attr "type" "bitmanip")
15186 (set_attr "mode" "HI")])
15188 (define_insn "*popcounthi2_cmp"
15189 [(set (reg FLAGS_REG)
15191 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15193 (set (match_operand:HI 0 "register_operand" "=r")
15194 (popcount:HI (match_dup 1)))]
15195 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15196 "popcnt{w}\t{%1, %0|%0, %1}"
15197 [(set_attr "prefix_rep" "1")
15198 (set_attr "type" "bitmanip")
15199 (set_attr "mode" "HI")])
15201 (define_expand "paritydi2"
15202 [(set (match_operand:DI 0 "register_operand" "")
15203 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15206 rtx scratch = gen_reg_rtx (QImode);
15209 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15210 NULL_RTX, operands[1]));
15212 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15213 gen_rtx_REG (CCmode, FLAGS_REG),
15215 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15218 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15221 rtx tmp = gen_reg_rtx (SImode);
15223 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15224 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15229 (define_insn_and_split "paritydi2_cmp"
15230 [(set (reg:CC FLAGS_REG)
15231 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15232 (clobber (match_scratch:DI 0 "=r,X"))
15233 (clobber (match_scratch:SI 1 "=r,r"))
15234 (clobber (match_scratch:HI 2 "=Q,Q"))]
15237 "&& reload_completed"
15239 [(set (match_dup 1)
15240 (xor:SI (match_dup 1) (match_dup 4)))
15241 (clobber (reg:CC FLAGS_REG))])
15243 [(set (reg:CC FLAGS_REG)
15244 (parity:CC (match_dup 1)))
15245 (clobber (match_dup 1))
15246 (clobber (match_dup 2))])]
15248 operands[4] = gen_lowpart (SImode, operands[3]);
15250 if (MEM_P (operands[3]))
15251 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15252 else if (! TARGET_64BIT)
15253 operands[1] = gen_highpart (SImode, operands[3]);
15256 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15257 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15261 (define_expand "paritysi2"
15262 [(set (match_operand:SI 0 "register_operand" "")
15263 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15266 rtx scratch = gen_reg_rtx (QImode);
15269 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15271 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15272 gen_rtx_REG (CCmode, FLAGS_REG),
15274 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15276 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15280 (define_insn_and_split "paritysi2_cmp"
15281 [(set (reg:CC FLAGS_REG)
15282 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15283 (clobber (match_scratch:SI 0 "=r,X"))
15284 (clobber (match_scratch:HI 1 "=Q,Q"))]
15287 "&& reload_completed"
15289 [(set (match_dup 1)
15290 (xor:HI (match_dup 1) (match_dup 3)))
15291 (clobber (reg:CC FLAGS_REG))])
15293 [(set (reg:CC FLAGS_REG)
15294 (parity:CC (match_dup 1)))
15295 (clobber (match_dup 1))])]
15297 operands[3] = gen_lowpart (HImode, operands[2]);
15299 if (MEM_P (operands[2]))
15300 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15303 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15304 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15308 (define_insn "*parityhi2_cmp"
15309 [(set (reg:CC FLAGS_REG)
15310 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15311 (clobber (match_scratch:HI 0 "=Q"))]
15313 "xor{b}\t{%h0, %b0|%b0, %h0}"
15314 [(set_attr "length" "2")
15315 (set_attr "mode" "HI")])
15317 (define_insn "*parityqi2_cmp"
15318 [(set (reg:CC FLAGS_REG)
15319 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15322 [(set_attr "length" "2")
15323 (set_attr "mode" "QI")])
15325 ;; Thread-local storage patterns for ELF.
15327 ;; Note that these code sequences must appear exactly as shown
15328 ;; in order to allow linker relaxation.
15330 (define_insn "*tls_global_dynamic_32_gnu"
15331 [(set (match_operand:SI 0 "register_operand" "=a")
15332 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15333 (match_operand:SI 2 "tls_symbolic_operand" "")
15334 (match_operand:SI 3 "call_insn_operand" "")]
15336 (clobber (match_scratch:SI 4 "=d"))
15337 (clobber (match_scratch:SI 5 "=c"))
15338 (clobber (reg:CC FLAGS_REG))]
15339 "!TARGET_64BIT && TARGET_GNU_TLS"
15340 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15341 [(set_attr "type" "multi")
15342 (set_attr "length" "12")])
15344 (define_insn "*tls_global_dynamic_32_sun"
15345 [(set (match_operand:SI 0 "register_operand" "=a")
15346 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15347 (match_operand:SI 2 "tls_symbolic_operand" "")
15348 (match_operand:SI 3 "call_insn_operand" "")]
15350 (clobber (match_scratch:SI 4 "=d"))
15351 (clobber (match_scratch:SI 5 "=c"))
15352 (clobber (reg:CC FLAGS_REG))]
15353 "!TARGET_64BIT && TARGET_SUN_TLS"
15354 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15355 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15356 [(set_attr "type" "multi")
15357 (set_attr "length" "14")])
15359 (define_expand "tls_global_dynamic_32"
15360 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15363 (match_operand:SI 1 "tls_symbolic_operand" "")
15366 (clobber (match_scratch:SI 4 ""))
15367 (clobber (match_scratch:SI 5 ""))
15368 (clobber (reg:CC FLAGS_REG))])]
15372 operands[2] = pic_offset_table_rtx;
15375 operands[2] = gen_reg_rtx (Pmode);
15376 emit_insn (gen_set_got (operands[2]));
15378 if (TARGET_GNU2_TLS)
15380 emit_insn (gen_tls_dynamic_gnu2_32
15381 (operands[0], operands[1], operands[2]));
15384 operands[3] = ix86_tls_get_addr ();
15387 (define_insn "*tls_global_dynamic_64"
15388 [(set (match_operand:DI 0 "register_operand" "=a")
15389 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15390 (match_operand:DI 3 "" "")))
15391 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15394 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15395 [(set_attr "type" "multi")
15396 (set_attr "length" "16")])
15398 (define_expand "tls_global_dynamic_64"
15399 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15400 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15401 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15405 if (TARGET_GNU2_TLS)
15407 emit_insn (gen_tls_dynamic_gnu2_64
15408 (operands[0], operands[1]));
15411 operands[2] = ix86_tls_get_addr ();
15414 (define_insn "*tls_local_dynamic_base_32_gnu"
15415 [(set (match_operand:SI 0 "register_operand" "=a")
15416 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15417 (match_operand:SI 2 "call_insn_operand" "")]
15418 UNSPEC_TLS_LD_BASE))
15419 (clobber (match_scratch:SI 3 "=d"))
15420 (clobber (match_scratch:SI 4 "=c"))
15421 (clobber (reg:CC FLAGS_REG))]
15422 "!TARGET_64BIT && TARGET_GNU_TLS"
15423 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15424 [(set_attr "type" "multi")
15425 (set_attr "length" "11")])
15427 (define_insn "*tls_local_dynamic_base_32_sun"
15428 [(set (match_operand:SI 0 "register_operand" "=a")
15429 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15430 (match_operand:SI 2 "call_insn_operand" "")]
15431 UNSPEC_TLS_LD_BASE))
15432 (clobber (match_scratch:SI 3 "=d"))
15433 (clobber (match_scratch:SI 4 "=c"))
15434 (clobber (reg:CC FLAGS_REG))]
15435 "!TARGET_64BIT && TARGET_SUN_TLS"
15436 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15437 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15438 [(set_attr "type" "multi")
15439 (set_attr "length" "13")])
15441 (define_expand "tls_local_dynamic_base_32"
15442 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15443 (unspec:SI [(match_dup 1) (match_dup 2)]
15444 UNSPEC_TLS_LD_BASE))
15445 (clobber (match_scratch:SI 3 ""))
15446 (clobber (match_scratch:SI 4 ""))
15447 (clobber (reg:CC FLAGS_REG))])]
15451 operands[1] = pic_offset_table_rtx;
15454 operands[1] = gen_reg_rtx (Pmode);
15455 emit_insn (gen_set_got (operands[1]));
15457 if (TARGET_GNU2_TLS)
15459 emit_insn (gen_tls_dynamic_gnu2_32
15460 (operands[0], ix86_tls_module_base (), operands[1]));
15463 operands[2] = ix86_tls_get_addr ();
15466 (define_insn "*tls_local_dynamic_base_64"
15467 [(set (match_operand:DI 0 "register_operand" "=a")
15468 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15469 (match_operand:DI 2 "" "")))
15470 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15472 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15473 [(set_attr "type" "multi")
15474 (set_attr "length" "12")])
15476 (define_expand "tls_local_dynamic_base_64"
15477 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15478 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15479 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15482 if (TARGET_GNU2_TLS)
15484 emit_insn (gen_tls_dynamic_gnu2_64
15485 (operands[0], ix86_tls_module_base ()));
15488 operands[1] = ix86_tls_get_addr ();
15491 ;; Local dynamic of a single variable is a lose. Show combine how
15492 ;; to convert that back to global dynamic.
15494 (define_insn_and_split "*tls_local_dynamic_32_once"
15495 [(set (match_operand:SI 0 "register_operand" "=a")
15496 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15497 (match_operand:SI 2 "call_insn_operand" "")]
15498 UNSPEC_TLS_LD_BASE)
15499 (const:SI (unspec:SI
15500 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15502 (clobber (match_scratch:SI 4 "=d"))
15503 (clobber (match_scratch:SI 5 "=c"))
15504 (clobber (reg:CC FLAGS_REG))]
15508 [(parallel [(set (match_dup 0)
15509 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15511 (clobber (match_dup 4))
15512 (clobber (match_dup 5))
15513 (clobber (reg:CC FLAGS_REG))])]
15516 ;; Load and add the thread base pointer from %gs:0.
15518 (define_insn "*load_tp_si"
15519 [(set (match_operand:SI 0 "register_operand" "=r")
15520 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15522 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15523 [(set_attr "type" "imov")
15524 (set_attr "modrm" "0")
15525 (set_attr "length" "7")
15526 (set_attr "memory" "load")
15527 (set_attr "imm_disp" "false")])
15529 (define_insn "*add_tp_si"
15530 [(set (match_operand:SI 0 "register_operand" "=r")
15531 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15532 (match_operand:SI 1 "register_operand" "0")))
15533 (clobber (reg:CC FLAGS_REG))]
15535 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15536 [(set_attr "type" "alu")
15537 (set_attr "modrm" "0")
15538 (set_attr "length" "7")
15539 (set_attr "memory" "load")
15540 (set_attr "imm_disp" "false")])
15542 (define_insn "*load_tp_di"
15543 [(set (match_operand:DI 0 "register_operand" "=r")
15544 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15546 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15547 [(set_attr "type" "imov")
15548 (set_attr "modrm" "0")
15549 (set_attr "length" "7")
15550 (set_attr "memory" "load")
15551 (set_attr "imm_disp" "false")])
15553 (define_insn "*add_tp_di"
15554 [(set (match_operand:DI 0 "register_operand" "=r")
15555 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15556 (match_operand:DI 1 "register_operand" "0")))
15557 (clobber (reg:CC FLAGS_REG))]
15559 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15560 [(set_attr "type" "alu")
15561 (set_attr "modrm" "0")
15562 (set_attr "length" "7")
15563 (set_attr "memory" "load")
15564 (set_attr "imm_disp" "false")])
15566 ;; GNU2 TLS patterns can be split.
15568 (define_expand "tls_dynamic_gnu2_32"
15569 [(set (match_dup 3)
15570 (plus:SI (match_operand:SI 2 "register_operand" "")
15572 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15575 [(set (match_operand:SI 0 "register_operand" "")
15576 (unspec:SI [(match_dup 1) (match_dup 3)
15577 (match_dup 2) (reg:SI SP_REG)]
15579 (clobber (reg:CC FLAGS_REG))])]
15580 "!TARGET_64BIT && TARGET_GNU2_TLS"
15582 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15583 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15586 (define_insn "*tls_dynamic_lea_32"
15587 [(set (match_operand:SI 0 "register_operand" "=r")
15588 (plus:SI (match_operand:SI 1 "register_operand" "b")
15590 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15591 UNSPEC_TLSDESC))))]
15592 "!TARGET_64BIT && TARGET_GNU2_TLS"
15593 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15594 [(set_attr "type" "lea")
15595 (set_attr "mode" "SI")
15596 (set_attr "length" "6")
15597 (set_attr "length_address" "4")])
15599 (define_insn "*tls_dynamic_call_32"
15600 [(set (match_operand:SI 0 "register_operand" "=a")
15601 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15602 (match_operand:SI 2 "register_operand" "0")
15603 ;; we have to make sure %ebx still points to the GOT
15604 (match_operand:SI 3 "register_operand" "b")
15607 (clobber (reg:CC FLAGS_REG))]
15608 "!TARGET_64BIT && TARGET_GNU2_TLS"
15609 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15610 [(set_attr "type" "call")
15611 (set_attr "length" "2")
15612 (set_attr "length_address" "0")])
15614 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15615 [(set (match_operand:SI 0 "register_operand" "=&a")
15617 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15618 (match_operand:SI 4 "" "")
15619 (match_operand:SI 2 "register_operand" "b")
15622 (const:SI (unspec:SI
15623 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15625 (clobber (reg:CC FLAGS_REG))]
15626 "!TARGET_64BIT && TARGET_GNU2_TLS"
15629 [(set (match_dup 0) (match_dup 5))]
15631 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15632 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15635 (define_expand "tls_dynamic_gnu2_64"
15636 [(set (match_dup 2)
15637 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15640 [(set (match_operand:DI 0 "register_operand" "")
15641 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15643 (clobber (reg:CC FLAGS_REG))])]
15644 "TARGET_64BIT && TARGET_GNU2_TLS"
15646 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15647 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15650 (define_insn "*tls_dynamic_lea_64"
15651 [(set (match_operand:DI 0 "register_operand" "=r")
15652 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15654 "TARGET_64BIT && TARGET_GNU2_TLS"
15655 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15656 [(set_attr "type" "lea")
15657 (set_attr "mode" "DI")
15658 (set_attr "length" "7")
15659 (set_attr "length_address" "4")])
15661 (define_insn "*tls_dynamic_call_64"
15662 [(set (match_operand:DI 0 "register_operand" "=a")
15663 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15664 (match_operand:DI 2 "register_operand" "0")
15667 (clobber (reg:CC FLAGS_REG))]
15668 "TARGET_64BIT && TARGET_GNU2_TLS"
15669 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15670 [(set_attr "type" "call")
15671 (set_attr "length" "2")
15672 (set_attr "length_address" "0")])
15674 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15675 [(set (match_operand:DI 0 "register_operand" "=&a")
15677 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15678 (match_operand:DI 3 "" "")
15681 (const:DI (unspec:DI
15682 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15684 (clobber (reg:CC FLAGS_REG))]
15685 "TARGET_64BIT && TARGET_GNU2_TLS"
15688 [(set (match_dup 0) (match_dup 4))]
15690 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15691 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15696 ;; These patterns match the binary 387 instructions for addM3, subM3,
15697 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15698 ;; SFmode. The first is the normal insn, the second the same insn but
15699 ;; with one operand a conversion, and the third the same insn but with
15700 ;; the other operand a conversion. The conversion may be SFmode or
15701 ;; SImode if the target mode DFmode, but only SImode if the target mode
15704 ;; Gcc is slightly more smart about handling normal two address instructions
15705 ;; so use special patterns for add and mull.
15707 (define_insn "*fop_sf_comm_mixed"
15708 [(set (match_operand:SF 0 "register_operand" "=f,x")
15709 (match_operator:SF 3 "binary_fp_operator"
15710 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15711 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15712 "TARGET_MIX_SSE_I387
15713 && COMMUTATIVE_ARITH_P (operands[3])
15714 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15715 "* return output_387_binary_op (insn, operands);"
15716 [(set (attr "type")
15717 (if_then_else (eq_attr "alternative" "1")
15718 (if_then_else (match_operand:SF 3 "mult_operator" "")
15719 (const_string "ssemul")
15720 (const_string "sseadd"))
15721 (if_then_else (match_operand:SF 3 "mult_operator" "")
15722 (const_string "fmul")
15723 (const_string "fop"))))
15724 (set_attr "mode" "SF")])
15726 (define_insn "*fop_sf_comm_sse"
15727 [(set (match_operand:SF 0 "register_operand" "=x")
15728 (match_operator:SF 3 "binary_fp_operator"
15729 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15730 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15732 && COMMUTATIVE_ARITH_P (operands[3])
15733 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15734 "* return output_387_binary_op (insn, operands);"
15735 [(set (attr "type")
15736 (if_then_else (match_operand:SF 3 "mult_operator" "")
15737 (const_string "ssemul")
15738 (const_string "sseadd")))
15739 (set_attr "mode" "SF")])
15741 (define_insn "*fop_sf_comm_i387"
15742 [(set (match_operand:SF 0 "register_operand" "=f")
15743 (match_operator:SF 3 "binary_fp_operator"
15744 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15745 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15747 && COMMUTATIVE_ARITH_P (operands[3])
15748 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15749 "* return output_387_binary_op (insn, operands);"
15750 [(set (attr "type")
15751 (if_then_else (match_operand:SF 3 "mult_operator" "")
15752 (const_string "fmul")
15753 (const_string "fop")))
15754 (set_attr "mode" "SF")])
15756 (define_insn "*fop_sf_1_mixed"
15757 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15758 (match_operator:SF 3 "binary_fp_operator"
15759 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15760 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15761 "TARGET_MIX_SSE_I387
15762 && !COMMUTATIVE_ARITH_P (operands[3])
15763 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15764 "* return output_387_binary_op (insn, operands);"
15765 [(set (attr "type")
15766 (cond [(and (eq_attr "alternative" "2")
15767 (match_operand:SF 3 "mult_operator" ""))
15768 (const_string "ssemul")
15769 (and (eq_attr "alternative" "2")
15770 (match_operand:SF 3 "div_operator" ""))
15771 (const_string "ssediv")
15772 (eq_attr "alternative" "2")
15773 (const_string "sseadd")
15774 (match_operand:SF 3 "mult_operator" "")
15775 (const_string "fmul")
15776 (match_operand:SF 3 "div_operator" "")
15777 (const_string "fdiv")
15779 (const_string "fop")))
15780 (set_attr "mode" "SF")])
15782 (define_insn "*fop_sf_1_sse"
15783 [(set (match_operand:SF 0 "register_operand" "=x")
15784 (match_operator:SF 3 "binary_fp_operator"
15785 [(match_operand:SF 1 "register_operand" "0")
15786 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15788 && !COMMUTATIVE_ARITH_P (operands[3])"
15789 "* return output_387_binary_op (insn, operands);"
15790 [(set (attr "type")
15791 (cond [(match_operand:SF 3 "mult_operator" "")
15792 (const_string "ssemul")
15793 (match_operand:SF 3 "div_operator" "")
15794 (const_string "ssediv")
15796 (const_string "sseadd")))
15797 (set_attr "mode" "SF")])
15799 ;; This pattern is not fully shadowed by the pattern above.
15800 (define_insn "*fop_sf_1_i387"
15801 [(set (match_operand:SF 0 "register_operand" "=f,f")
15802 (match_operator:SF 3 "binary_fp_operator"
15803 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15804 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15805 "TARGET_80387 && !TARGET_SSE_MATH
15806 && !COMMUTATIVE_ARITH_P (operands[3])
15807 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15808 "* return output_387_binary_op (insn, operands);"
15809 [(set (attr "type")
15810 (cond [(match_operand:SF 3 "mult_operator" "")
15811 (const_string "fmul")
15812 (match_operand:SF 3 "div_operator" "")
15813 (const_string "fdiv")
15815 (const_string "fop")))
15816 (set_attr "mode" "SF")])
15818 ;; ??? Add SSE splitters for these!
15819 (define_insn "*fop_sf_2<mode>_i387"
15820 [(set (match_operand:SF 0 "register_operand" "=f,f")
15821 (match_operator:SF 3 "binary_fp_operator"
15822 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15823 (match_operand:SF 2 "register_operand" "0,0")]))]
15824 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15825 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15826 [(set (attr "type")
15827 (cond [(match_operand:SF 3 "mult_operator" "")
15828 (const_string "fmul")
15829 (match_operand:SF 3 "div_operator" "")
15830 (const_string "fdiv")
15832 (const_string "fop")))
15833 (set_attr "fp_int_src" "true")
15834 (set_attr "mode" "<MODE>")])
15836 (define_insn "*fop_sf_3<mode>_i387"
15837 [(set (match_operand:SF 0 "register_operand" "=f,f")
15838 (match_operator:SF 3 "binary_fp_operator"
15839 [(match_operand:SF 1 "register_operand" "0,0")
15840 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15841 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15842 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15843 [(set (attr "type")
15844 (cond [(match_operand:SF 3 "mult_operator" "")
15845 (const_string "fmul")
15846 (match_operand:SF 3 "div_operator" "")
15847 (const_string "fdiv")
15849 (const_string "fop")))
15850 (set_attr "fp_int_src" "true")
15851 (set_attr "mode" "<MODE>")])
15853 (define_insn "*fop_df_comm_mixed"
15854 [(set (match_operand:DF 0 "register_operand" "=f,x")
15855 (match_operator:DF 3 "binary_fp_operator"
15856 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15857 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15858 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15859 && COMMUTATIVE_ARITH_P (operands[3])
15860 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15861 "* return output_387_binary_op (insn, operands);"
15862 [(set (attr "type")
15863 (if_then_else (eq_attr "alternative" "1")
15864 (if_then_else (match_operand:DF 3 "mult_operator" "")
15865 (const_string "ssemul")
15866 (const_string "sseadd"))
15867 (if_then_else (match_operand:DF 3 "mult_operator" "")
15868 (const_string "fmul")
15869 (const_string "fop"))))
15870 (set_attr "mode" "DF")])
15872 (define_insn "*fop_df_comm_sse"
15873 [(set (match_operand:DF 0 "register_operand" "=x")
15874 (match_operator:DF 3 "binary_fp_operator"
15875 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15876 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15877 "TARGET_SSE2 && TARGET_SSE_MATH
15878 && COMMUTATIVE_ARITH_P (operands[3])
15879 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15880 "* return output_387_binary_op (insn, operands);"
15881 [(set (attr "type")
15882 (if_then_else (match_operand:DF 3 "mult_operator" "")
15883 (const_string "ssemul")
15884 (const_string "sseadd")))
15885 (set_attr "mode" "DF")])
15887 (define_insn "*fop_df_comm_i387"
15888 [(set (match_operand:DF 0 "register_operand" "=f")
15889 (match_operator:DF 3 "binary_fp_operator"
15890 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15891 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15893 && COMMUTATIVE_ARITH_P (operands[3])
15894 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15895 "* return output_387_binary_op (insn, operands);"
15896 [(set (attr "type")
15897 (if_then_else (match_operand:DF 3 "mult_operator" "")
15898 (const_string "fmul")
15899 (const_string "fop")))
15900 (set_attr "mode" "DF")])
15902 (define_insn "*fop_df_1_mixed"
15903 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15904 (match_operator:DF 3 "binary_fp_operator"
15905 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15906 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15907 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15908 && !COMMUTATIVE_ARITH_P (operands[3])
15909 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15910 "* return output_387_binary_op (insn, operands);"
15911 [(set (attr "type")
15912 (cond [(and (eq_attr "alternative" "2")
15913 (match_operand:DF 3 "mult_operator" ""))
15914 (const_string "ssemul")
15915 (and (eq_attr "alternative" "2")
15916 (match_operand:DF 3 "div_operator" ""))
15917 (const_string "ssediv")
15918 (eq_attr "alternative" "2")
15919 (const_string "sseadd")
15920 (match_operand:DF 3 "mult_operator" "")
15921 (const_string "fmul")
15922 (match_operand:DF 3 "div_operator" "")
15923 (const_string "fdiv")
15925 (const_string "fop")))
15926 (set_attr "mode" "DF")])
15928 (define_insn "*fop_df_1_sse"
15929 [(set (match_operand:DF 0 "register_operand" "=x")
15930 (match_operator:DF 3 "binary_fp_operator"
15931 [(match_operand:DF 1 "register_operand" "0")
15932 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15933 "TARGET_SSE2 && TARGET_SSE_MATH
15934 && !COMMUTATIVE_ARITH_P (operands[3])"
15935 "* return output_387_binary_op (insn, operands);"
15936 [(set_attr "mode" "DF")
15938 (cond [(match_operand:DF 3 "mult_operator" "")
15939 (const_string "ssemul")
15940 (match_operand:DF 3 "div_operator" "")
15941 (const_string "ssediv")
15943 (const_string "sseadd")))])
15945 ;; This pattern is not fully shadowed by the pattern above.
15946 (define_insn "*fop_df_1_i387"
15947 [(set (match_operand:DF 0 "register_operand" "=f,f")
15948 (match_operator:DF 3 "binary_fp_operator"
15949 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15950 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15951 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15952 && !COMMUTATIVE_ARITH_P (operands[3])
15953 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15954 "* return output_387_binary_op (insn, operands);"
15955 [(set (attr "type")
15956 (cond [(match_operand:DF 3 "mult_operator" "")
15957 (const_string "fmul")
15958 (match_operand:DF 3 "div_operator" "")
15959 (const_string "fdiv")
15961 (const_string "fop")))
15962 (set_attr "mode" "DF")])
15964 ;; ??? Add SSE splitters for these!
15965 (define_insn "*fop_df_2<mode>_i387"
15966 [(set (match_operand:DF 0 "register_operand" "=f,f")
15967 (match_operator:DF 3 "binary_fp_operator"
15968 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15969 (match_operand:DF 2 "register_operand" "0,0")]))]
15970 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15971 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15972 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15973 [(set (attr "type")
15974 (cond [(match_operand:DF 3 "mult_operator" "")
15975 (const_string "fmul")
15976 (match_operand:DF 3 "div_operator" "")
15977 (const_string "fdiv")
15979 (const_string "fop")))
15980 (set_attr "fp_int_src" "true")
15981 (set_attr "mode" "<MODE>")])
15983 (define_insn "*fop_df_3<mode>_i387"
15984 [(set (match_operand:DF 0 "register_operand" "=f,f")
15985 (match_operator:DF 3 "binary_fp_operator"
15986 [(match_operand:DF 1 "register_operand" "0,0")
15987 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15988 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15989 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15990 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15991 [(set (attr "type")
15992 (cond [(match_operand:DF 3 "mult_operator" "")
15993 (const_string "fmul")
15994 (match_operand:DF 3 "div_operator" "")
15995 (const_string "fdiv")
15997 (const_string "fop")))
15998 (set_attr "fp_int_src" "true")
15999 (set_attr "mode" "<MODE>")])
16001 (define_insn "*fop_df_4_i387"
16002 [(set (match_operand:DF 0 "register_operand" "=f,f")
16003 (match_operator:DF 3 "binary_fp_operator"
16004 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16005 (match_operand:DF 2 "register_operand" "0,f")]))]
16006 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16007 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16008 "* return output_387_binary_op (insn, operands);"
16009 [(set (attr "type")
16010 (cond [(match_operand:DF 3 "mult_operator" "")
16011 (const_string "fmul")
16012 (match_operand:DF 3 "div_operator" "")
16013 (const_string "fdiv")
16015 (const_string "fop")))
16016 (set_attr "mode" "SF")])
16018 (define_insn "*fop_df_5_i387"
16019 [(set (match_operand:DF 0 "register_operand" "=f,f")
16020 (match_operator:DF 3 "binary_fp_operator"
16021 [(match_operand:DF 1 "register_operand" "0,f")
16023 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16024 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16025 "* return output_387_binary_op (insn, operands);"
16026 [(set (attr "type")
16027 (cond [(match_operand:DF 3 "mult_operator" "")
16028 (const_string "fmul")
16029 (match_operand:DF 3 "div_operator" "")
16030 (const_string "fdiv")
16032 (const_string "fop")))
16033 (set_attr "mode" "SF")])
16035 (define_insn "*fop_df_6_i387"
16036 [(set (match_operand:DF 0 "register_operand" "=f,f")
16037 (match_operator:DF 3 "binary_fp_operator"
16039 (match_operand:SF 1 "register_operand" "0,f"))
16041 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16042 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16043 "* return output_387_binary_op (insn, operands);"
16044 [(set (attr "type")
16045 (cond [(match_operand:DF 3 "mult_operator" "")
16046 (const_string "fmul")
16047 (match_operand:DF 3 "div_operator" "")
16048 (const_string "fdiv")
16050 (const_string "fop")))
16051 (set_attr "mode" "SF")])
16053 (define_insn "*fop_xf_comm_i387"
16054 [(set (match_operand:XF 0 "register_operand" "=f")
16055 (match_operator:XF 3 "binary_fp_operator"
16056 [(match_operand:XF 1 "register_operand" "%0")
16057 (match_operand:XF 2 "register_operand" "f")]))]
16059 && COMMUTATIVE_ARITH_P (operands[3])"
16060 "* return output_387_binary_op (insn, operands);"
16061 [(set (attr "type")
16062 (if_then_else (match_operand:XF 3 "mult_operator" "")
16063 (const_string "fmul")
16064 (const_string "fop")))
16065 (set_attr "mode" "XF")])
16067 (define_insn "*fop_xf_1_i387"
16068 [(set (match_operand:XF 0 "register_operand" "=f,f")
16069 (match_operator:XF 3 "binary_fp_operator"
16070 [(match_operand:XF 1 "register_operand" "0,f")
16071 (match_operand:XF 2 "register_operand" "f,0")]))]
16073 && !COMMUTATIVE_ARITH_P (operands[3])"
16074 "* return output_387_binary_op (insn, operands);"
16075 [(set (attr "type")
16076 (cond [(match_operand:XF 3 "mult_operator" "")
16077 (const_string "fmul")
16078 (match_operand:XF 3 "div_operator" "")
16079 (const_string "fdiv")
16081 (const_string "fop")))
16082 (set_attr "mode" "XF")])
16084 (define_insn "*fop_xf_2<mode>_i387"
16085 [(set (match_operand:XF 0 "register_operand" "=f,f")
16086 (match_operator:XF 3 "binary_fp_operator"
16087 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16088 (match_operand:XF 2 "register_operand" "0,0")]))]
16089 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16090 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16091 [(set (attr "type")
16092 (cond [(match_operand:XF 3 "mult_operator" "")
16093 (const_string "fmul")
16094 (match_operand:XF 3 "div_operator" "")
16095 (const_string "fdiv")
16097 (const_string "fop")))
16098 (set_attr "fp_int_src" "true")
16099 (set_attr "mode" "<MODE>")])
16101 (define_insn "*fop_xf_3<mode>_i387"
16102 [(set (match_operand:XF 0 "register_operand" "=f,f")
16103 (match_operator:XF 3 "binary_fp_operator"
16104 [(match_operand:XF 1 "register_operand" "0,0")
16105 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16106 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16107 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16108 [(set (attr "type")
16109 (cond [(match_operand:XF 3 "mult_operator" "")
16110 (const_string "fmul")
16111 (match_operand:XF 3 "div_operator" "")
16112 (const_string "fdiv")
16114 (const_string "fop")))
16115 (set_attr "fp_int_src" "true")
16116 (set_attr "mode" "<MODE>")])
16118 (define_insn "*fop_xf_4_i387"
16119 [(set (match_operand:XF 0 "register_operand" "=f,f")
16120 (match_operator:XF 3 "binary_fp_operator"
16122 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
16123 (match_operand:XF 2 "register_operand" "0,f")]))]
16125 "* return output_387_binary_op (insn, operands);"
16126 [(set (attr "type")
16127 (cond [(match_operand:XF 3 "mult_operator" "")
16128 (const_string "fmul")
16129 (match_operand:XF 3 "div_operator" "")
16130 (const_string "fdiv")
16132 (const_string "fop")))
16133 (set_attr "mode" "SF")])
16135 (define_insn "*fop_xf_5_i387"
16136 [(set (match_operand:XF 0 "register_operand" "=f,f")
16137 (match_operator:XF 3 "binary_fp_operator"
16138 [(match_operand:XF 1 "register_operand" "0,f")
16140 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16142 "* return output_387_binary_op (insn, operands);"
16143 [(set (attr "type")
16144 (cond [(match_operand:XF 3 "mult_operator" "")
16145 (const_string "fmul")
16146 (match_operand:XF 3 "div_operator" "")
16147 (const_string "fdiv")
16149 (const_string "fop")))
16150 (set_attr "mode" "SF")])
16152 (define_insn "*fop_xf_6_i387"
16153 [(set (match_operand:XF 0 "register_operand" "=f,f")
16154 (match_operator:XF 3 "binary_fp_operator"
16156 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
16158 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16160 "* return output_387_binary_op (insn, operands);"
16161 [(set (attr "type")
16162 (cond [(match_operand:XF 3 "mult_operator" "")
16163 (const_string "fmul")
16164 (match_operand:XF 3 "div_operator" "")
16165 (const_string "fdiv")
16167 (const_string "fop")))
16168 (set_attr "mode" "SF")])
16171 [(set (match_operand 0 "register_operand" "")
16172 (match_operator 3 "binary_fp_operator"
16173 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16174 (match_operand 2 "register_operand" "")]))]
16175 "TARGET_80387 && reload_completed
16176 && FLOAT_MODE_P (GET_MODE (operands[0]))"
16179 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16180 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16181 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16182 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16183 GET_MODE (operands[3]),
16186 ix86_free_from_memory (GET_MODE (operands[1]));
16191 [(set (match_operand 0 "register_operand" "")
16192 (match_operator 3 "binary_fp_operator"
16193 [(match_operand 1 "register_operand" "")
16194 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16195 "TARGET_80387 && reload_completed
16196 && FLOAT_MODE_P (GET_MODE (operands[0]))"
16199 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16200 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16201 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16202 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16203 GET_MODE (operands[3]),
16206 ix86_free_from_memory (GET_MODE (operands[2]));
16210 ;; FPU special functions.
16212 ;; This pattern implements a no-op XFmode truncation for
16213 ;; all fancy i386 XFmode math functions.
16215 (define_insn "truncxf<mode>2_i387_noop_unspec"
16216 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16217 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16218 UNSPEC_TRUNC_NOOP))]
16219 "TARGET_USE_FANCY_MATH_387"
16220 "* return output_387_reg_move (insn, operands);"
16221 [(set_attr "type" "fmov")
16222 (set_attr "mode" "<MODE>")])
16224 (define_insn "sqrtxf2"
16225 [(set (match_operand:XF 0 "register_operand" "=f")
16226 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16227 "TARGET_USE_FANCY_MATH_387"
16229 [(set_attr "type" "fpspc")
16230 (set_attr "mode" "XF")
16231 (set_attr "athlon_decode" "direct")
16232 (set_attr "amdfam10_decode" "direct")])
16234 (define_insn "sqrt_extend<mode>xf2_i387"
16235 [(set (match_operand:XF 0 "register_operand" "=f")
16238 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16239 "TARGET_USE_FANCY_MATH_387"
16241 [(set_attr "type" "fpspc")
16242 (set_attr "mode" "XF")
16243 (set_attr "athlon_decode" "direct")
16244 (set_attr "amdfam10_decode" "direct")])
16246 (define_insn "*sqrt<mode>2_sse"
16247 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16249 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16250 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16251 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16252 [(set_attr "type" "sse")
16253 (set_attr "mode" "<MODE>")
16254 (set_attr "athlon_decode" "*")
16255 (set_attr "amdfam10_decode" "*")])
16257 (define_expand "sqrt<mode>2"
16258 [(set (match_operand:X87MODEF12 0 "register_operand" "")
16260 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16261 "TARGET_USE_FANCY_MATH_387
16262 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16264 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16266 rtx op0 = gen_reg_rtx (XFmode);
16267 rtx op1 = force_reg (<MODE>mode, operands[1]);
16269 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16270 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16275 (define_insn "fpremxf4_i387"
16276 [(set (match_operand:XF 0 "register_operand" "=f")
16277 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16278 (match_operand:XF 3 "register_operand" "1")]
16280 (set (match_operand:XF 1 "register_operand" "=u")
16281 (unspec:XF [(match_dup 2) (match_dup 3)]
16283 (set (reg:CCFP FPSR_REG)
16284 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16286 "TARGET_USE_FANCY_MATH_387"
16288 [(set_attr "type" "fpspc")
16289 (set_attr "mode" "XF")])
16291 (define_expand "fmodxf3"
16292 [(use (match_operand:XF 0 "register_operand" ""))
16293 (use (match_operand:XF 1 "register_operand" ""))
16294 (use (match_operand:XF 2 "register_operand" ""))]
16295 "TARGET_USE_FANCY_MATH_387"
16297 rtx label = gen_label_rtx ();
16299 emit_label (label);
16301 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16302 operands[1], operands[2]));
16303 ix86_emit_fp_unordered_jump (label);
16304 LABEL_NUSES (label) = 1;
16306 emit_move_insn (operands[0], operands[1]);
16310 (define_expand "fmod<mode>3"
16311 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16312 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16313 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16314 "TARGET_USE_FANCY_MATH_387"
16316 rtx label = gen_label_rtx ();
16318 rtx op1 = gen_reg_rtx (XFmode);
16319 rtx op2 = gen_reg_rtx (XFmode);
16321 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16322 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16324 emit_label (label);
16325 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16326 ix86_emit_fp_unordered_jump (label);
16327 LABEL_NUSES (label) = 1;
16329 /* Truncate the result properly for strict SSE math. */
16330 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16331 && !TARGET_MIX_SSE_I387)
16332 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16334 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16339 (define_insn "fprem1xf4_i387"
16340 [(set (match_operand:XF 0 "register_operand" "=f")
16341 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16342 (match_operand:XF 3 "register_operand" "1")]
16344 (set (match_operand:XF 1 "register_operand" "=u")
16345 (unspec:XF [(match_dup 2) (match_dup 3)]
16347 (set (reg:CCFP FPSR_REG)
16348 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16350 "TARGET_USE_FANCY_MATH_387"
16352 [(set_attr "type" "fpspc")
16353 (set_attr "mode" "XF")])
16355 (define_expand "remainderxf3"
16356 [(use (match_operand:XF 0 "register_operand" ""))
16357 (use (match_operand:XF 1 "register_operand" ""))
16358 (use (match_operand:XF 2 "register_operand" ""))]
16359 "TARGET_USE_FANCY_MATH_387"
16361 rtx label = gen_label_rtx ();
16363 emit_label (label);
16365 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16366 operands[1], operands[2]));
16367 ix86_emit_fp_unordered_jump (label);
16368 LABEL_NUSES (label) = 1;
16370 emit_move_insn (operands[0], operands[1]);
16374 (define_expand "remainder<mode>3"
16375 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16376 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16377 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16378 "TARGET_USE_FANCY_MATH_387"
16380 rtx label = gen_label_rtx ();
16382 rtx op1 = gen_reg_rtx (XFmode);
16383 rtx op2 = gen_reg_rtx (XFmode);
16385 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16386 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16388 emit_label (label);
16390 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16391 ix86_emit_fp_unordered_jump (label);
16392 LABEL_NUSES (label) = 1;
16394 /* Truncate the result properly for strict SSE math. */
16395 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16396 && !TARGET_MIX_SSE_I387)
16397 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16399 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16404 (define_insn "*sinxf2_i387"
16405 [(set (match_operand:XF 0 "register_operand" "=f")
16406 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16407 "TARGET_USE_FANCY_MATH_387
16408 && flag_unsafe_math_optimizations"
16410 [(set_attr "type" "fpspc")
16411 (set_attr "mode" "XF")])
16413 (define_insn "*sin_extend<mode>xf2_i387"
16414 [(set (match_operand:XF 0 "register_operand" "=f")
16415 (unspec:XF [(float_extend:XF
16416 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16418 "TARGET_USE_FANCY_MATH_387
16419 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16420 || TARGET_MIX_SSE_I387)
16421 && flag_unsafe_math_optimizations"
16423 [(set_attr "type" "fpspc")
16424 (set_attr "mode" "XF")])
16426 (define_insn "*cosxf2_i387"
16427 [(set (match_operand:XF 0 "register_operand" "=f")
16428 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16429 "TARGET_USE_FANCY_MATH_387
16430 && flag_unsafe_math_optimizations"
16432 [(set_attr "type" "fpspc")
16433 (set_attr "mode" "XF")])
16435 (define_insn "*cos_extend<mode>xf2_i387"
16436 [(set (match_operand:XF 0 "register_operand" "=f")
16437 (unspec:XF [(float_extend:XF
16438 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16440 "TARGET_USE_FANCY_MATH_387
16441 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16442 || TARGET_MIX_SSE_I387)
16443 && flag_unsafe_math_optimizations"
16445 [(set_attr "type" "fpspc")
16446 (set_attr "mode" "XF")])
16448 ;; When sincos pattern is defined, sin and cos builtin functions will be
16449 ;; expanded to sincos pattern with one of its outputs left unused.
16450 ;; CSE pass will figure out if two sincos patterns can be combined,
16451 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16452 ;; depending on the unused output.
16454 (define_insn "sincosxf3"
16455 [(set (match_operand:XF 0 "register_operand" "=f")
16456 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16457 UNSPEC_SINCOS_COS))
16458 (set (match_operand:XF 1 "register_operand" "=u")
16459 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16460 "TARGET_USE_FANCY_MATH_387
16461 && flag_unsafe_math_optimizations"
16463 [(set_attr "type" "fpspc")
16464 (set_attr "mode" "XF")])
16467 [(set (match_operand:XF 0 "register_operand" "")
16468 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16469 UNSPEC_SINCOS_COS))
16470 (set (match_operand:XF 1 "register_operand" "")
16471 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16472 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16473 && !reload_completed && !reload_in_progress"
16474 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16478 [(set (match_operand:XF 0 "register_operand" "")
16479 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16480 UNSPEC_SINCOS_COS))
16481 (set (match_operand:XF 1 "register_operand" "")
16482 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16483 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16484 && !reload_completed && !reload_in_progress"
16485 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16488 (define_insn "sincos_extend<mode>xf3_i387"
16489 [(set (match_operand:XF 0 "register_operand" "=f")
16490 (unspec:XF [(float_extend:XF
16491 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16492 UNSPEC_SINCOS_COS))
16493 (set (match_operand:XF 1 "register_operand" "=u")
16494 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16495 "TARGET_USE_FANCY_MATH_387
16496 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16497 || TARGET_MIX_SSE_I387)
16498 && flag_unsafe_math_optimizations"
16500 [(set_attr "type" "fpspc")
16501 (set_attr "mode" "XF")])
16504 [(set (match_operand:XF 0 "register_operand" "")
16505 (unspec:XF [(float_extend:XF
16506 (match_operand:X87MODEF12 2 "register_operand" ""))]
16507 UNSPEC_SINCOS_COS))
16508 (set (match_operand:XF 1 "register_operand" "")
16509 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16510 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16511 && !reload_completed && !reload_in_progress"
16512 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16516 [(set (match_operand:XF 0 "register_operand" "")
16517 (unspec:XF [(float_extend:XF
16518 (match_operand:X87MODEF12 2 "register_operand" ""))]
16519 UNSPEC_SINCOS_COS))
16520 (set (match_operand:XF 1 "register_operand" "")
16521 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16522 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16523 && !reload_completed && !reload_in_progress"
16524 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16527 (define_expand "sincos<mode>3"
16528 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16529 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16530 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16531 "TARGET_USE_FANCY_MATH_387
16532 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16533 || TARGET_MIX_SSE_I387)
16534 && flag_unsafe_math_optimizations"
16536 rtx op0 = gen_reg_rtx (XFmode);
16537 rtx op1 = gen_reg_rtx (XFmode);
16539 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16540 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16541 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16545 (define_insn "fptanxf4_i387"
16546 [(set (match_operand:XF 0 "register_operand" "=f")
16547 (match_operand:XF 3 "const_double_operand" "F"))
16548 (set (match_operand:XF 1 "register_operand" "=u")
16549 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16551 "TARGET_USE_FANCY_MATH_387
16552 && flag_unsafe_math_optimizations
16553 && standard_80387_constant_p (operands[3]) == 2"
16555 [(set_attr "type" "fpspc")
16556 (set_attr "mode" "XF")])
16558 (define_insn "fptan_extend<mode>xf4_i387"
16559 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16560 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16561 (set (match_operand:XF 1 "register_operand" "=u")
16562 (unspec:XF [(float_extend:XF
16563 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16565 "TARGET_USE_FANCY_MATH_387
16566 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16567 || TARGET_MIX_SSE_I387)
16568 && flag_unsafe_math_optimizations
16569 && standard_80387_constant_p (operands[3]) == 2"
16571 [(set_attr "type" "fpspc")
16572 (set_attr "mode" "XF")])
16574 (define_expand "tanxf2"
16575 [(use (match_operand:XF 0 "register_operand" ""))
16576 (use (match_operand:XF 1 "register_operand" ""))]
16577 "TARGET_USE_FANCY_MATH_387
16578 && flag_unsafe_math_optimizations"
16580 rtx one = gen_reg_rtx (XFmode);
16581 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16583 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16587 (define_expand "tan<mode>2"
16588 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16589 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16590 "TARGET_USE_FANCY_MATH_387
16591 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16592 || TARGET_MIX_SSE_I387)
16593 && flag_unsafe_math_optimizations"
16595 rtx op0 = gen_reg_rtx (XFmode);
16597 rtx one = gen_reg_rtx (<MODE>mode);
16598 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16600 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16601 operands[1], op2));
16602 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16606 (define_insn "*fpatanxf3_i387"
16607 [(set (match_operand:XF 0 "register_operand" "=f")
16608 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16609 (match_operand:XF 2 "register_operand" "u")]
16611 (clobber (match_scratch:XF 3 "=2"))]
16612 "TARGET_USE_FANCY_MATH_387
16613 && flag_unsafe_math_optimizations"
16615 [(set_attr "type" "fpspc")
16616 (set_attr "mode" "XF")])
16618 (define_insn "fpatan_extend<mode>xf3_i387"
16619 [(set (match_operand:XF 0 "register_operand" "=f")
16620 (unspec:XF [(float_extend:XF
16621 (match_operand:X87MODEF12 1 "register_operand" "0"))
16623 (match_operand:X87MODEF12 2 "register_operand" "u"))]
16625 (clobber (match_scratch:XF 3 "=2"))]
16626 "TARGET_USE_FANCY_MATH_387
16627 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16628 || TARGET_MIX_SSE_I387)
16629 && flag_unsafe_math_optimizations"
16631 [(set_attr "type" "fpspc")
16632 (set_attr "mode" "XF")])
16634 (define_expand "atan2xf3"
16635 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16636 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16637 (match_operand:XF 1 "register_operand" "")]
16639 (clobber (match_scratch:XF 3 ""))])]
16640 "TARGET_USE_FANCY_MATH_387
16641 && flag_unsafe_math_optimizations"
16644 (define_expand "atan2<mode>3"
16645 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16646 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16647 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16648 "TARGET_USE_FANCY_MATH_387
16649 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16650 || TARGET_MIX_SSE_I387)
16651 && flag_unsafe_math_optimizations"
16653 rtx op0 = gen_reg_rtx (XFmode);
16655 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16656 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16660 (define_expand "atanxf2"
16661 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16662 (unspec:XF [(match_dup 2)
16663 (match_operand:XF 1 "register_operand" "")]
16665 (clobber (match_scratch:XF 3 ""))])]
16666 "TARGET_USE_FANCY_MATH_387
16667 && flag_unsafe_math_optimizations"
16669 operands[2] = gen_reg_rtx (XFmode);
16670 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16673 (define_expand "atan<mode>2"
16674 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16675 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16676 "TARGET_USE_FANCY_MATH_387
16677 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16678 || TARGET_MIX_SSE_I387)
16679 && flag_unsafe_math_optimizations"
16681 rtx op0 = gen_reg_rtx (XFmode);
16683 rtx op2 = gen_reg_rtx (<MODE>mode);
16684 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16686 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16687 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16691 (define_expand "asinxf2"
16692 [(set (match_dup 2)
16693 (mult:XF (match_operand:XF 1 "register_operand" "")
16695 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16696 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16697 (parallel [(set (match_operand:XF 0 "register_operand" "")
16698 (unspec:XF [(match_dup 5) (match_dup 1)]
16700 (clobber (match_scratch:XF 6 ""))])]
16701 "TARGET_USE_FANCY_MATH_387
16702 && flag_unsafe_math_optimizations && !optimize_size"
16706 for (i = 2; i < 6; i++)
16707 operands[i] = gen_reg_rtx (XFmode);
16709 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16712 (define_expand "asin<mode>2"
16713 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16714 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16715 "TARGET_USE_FANCY_MATH_387
16716 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16717 || TARGET_MIX_SSE_I387)
16718 && flag_unsafe_math_optimizations && !optimize_size"
16720 rtx op0 = gen_reg_rtx (XFmode);
16721 rtx op1 = gen_reg_rtx (XFmode);
16723 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16724 emit_insn (gen_asinxf2 (op0, op1));
16725 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16729 (define_expand "acosxf2"
16730 [(set (match_dup 2)
16731 (mult:XF (match_operand:XF 1 "register_operand" "")
16733 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16734 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16735 (parallel [(set (match_operand:XF 0 "register_operand" "")
16736 (unspec:XF [(match_dup 1) (match_dup 5)]
16738 (clobber (match_scratch:XF 6 ""))])]
16739 "TARGET_USE_FANCY_MATH_387
16740 && flag_unsafe_math_optimizations && !optimize_size"
16744 for (i = 2; i < 6; i++)
16745 operands[i] = gen_reg_rtx (XFmode);
16747 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16750 (define_expand "acos<mode>2"
16751 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16752 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16753 "TARGET_USE_FANCY_MATH_387
16754 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16755 || TARGET_MIX_SSE_I387)
16756 && flag_unsafe_math_optimizations && !optimize_size"
16758 rtx op0 = gen_reg_rtx (XFmode);
16759 rtx op1 = gen_reg_rtx (XFmode);
16761 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16762 emit_insn (gen_acosxf2 (op0, op1));
16763 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16767 (define_insn "fyl2xxf3_i387"
16768 [(set (match_operand:XF 0 "register_operand" "=f")
16769 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16770 (match_operand:XF 2 "register_operand" "u")]
16772 (clobber (match_scratch:XF 3 "=2"))]
16773 "TARGET_USE_FANCY_MATH_387
16774 && flag_unsafe_math_optimizations"
16776 [(set_attr "type" "fpspc")
16777 (set_attr "mode" "XF")])
16779 (define_insn "fyl2x_extend<mode>xf3_i387"
16780 [(set (match_operand:XF 0 "register_operand" "=f")
16781 (unspec:XF [(float_extend:XF
16782 (match_operand:X87MODEF12 1 "register_operand" "0"))
16783 (match_operand:XF 2 "register_operand" "u")]
16785 (clobber (match_scratch:XF 3 "=2"))]
16786 "TARGET_USE_FANCY_MATH_387
16787 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16788 || TARGET_MIX_SSE_I387)
16789 && flag_unsafe_math_optimizations"
16791 [(set_attr "type" "fpspc")
16792 (set_attr "mode" "XF")])
16794 (define_expand "logxf2"
16795 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16796 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16797 (match_dup 2)] UNSPEC_FYL2X))
16798 (clobber (match_scratch:XF 3 ""))])]
16799 "TARGET_USE_FANCY_MATH_387
16800 && flag_unsafe_math_optimizations"
16802 operands[2] = gen_reg_rtx (XFmode);
16803 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16806 (define_expand "log<mode>2"
16807 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16808 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16809 "TARGET_USE_FANCY_MATH_387
16810 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16811 || TARGET_MIX_SSE_I387)
16812 && flag_unsafe_math_optimizations"
16814 rtx op0 = gen_reg_rtx (XFmode);
16816 rtx op2 = gen_reg_rtx (XFmode);
16817 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16819 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16820 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16824 (define_expand "log10xf2"
16825 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16826 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16827 (match_dup 2)] UNSPEC_FYL2X))
16828 (clobber (match_scratch:XF 3 ""))])]
16829 "TARGET_USE_FANCY_MATH_387
16830 && flag_unsafe_math_optimizations"
16832 operands[2] = gen_reg_rtx (XFmode);
16833 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16836 (define_expand "log10<mode>2"
16837 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16838 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16839 "TARGET_USE_FANCY_MATH_387
16840 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16841 || TARGET_MIX_SSE_I387)
16842 && flag_unsafe_math_optimizations"
16844 rtx op0 = gen_reg_rtx (XFmode);
16846 rtx op2 = gen_reg_rtx (XFmode);
16847 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16849 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16850 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16854 (define_expand "log2xf2"
16855 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16856 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16857 (match_dup 2)] UNSPEC_FYL2X))
16858 (clobber (match_scratch:XF 3 ""))])]
16859 "TARGET_USE_FANCY_MATH_387
16860 && flag_unsafe_math_optimizations"
16862 operands[2] = gen_reg_rtx (XFmode);
16863 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16866 (define_expand "log2<mode>2"
16867 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16868 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16869 "TARGET_USE_FANCY_MATH_387
16870 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16871 || TARGET_MIX_SSE_I387)
16872 && flag_unsafe_math_optimizations"
16874 rtx op0 = gen_reg_rtx (XFmode);
16876 rtx op2 = gen_reg_rtx (XFmode);
16877 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16879 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16880 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16884 (define_insn "fyl2xp1xf3_i387"
16885 [(set (match_operand:XF 0 "register_operand" "=f")
16886 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16887 (match_operand:XF 2 "register_operand" "u")]
16889 (clobber (match_scratch:XF 3 "=2"))]
16890 "TARGET_USE_FANCY_MATH_387
16891 && flag_unsafe_math_optimizations"
16893 [(set_attr "type" "fpspc")
16894 (set_attr "mode" "XF")])
16896 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16897 [(set (match_operand:XF 0 "register_operand" "=f")
16898 (unspec:XF [(float_extend:XF
16899 (match_operand:X87MODEF12 1 "register_operand" "0"))
16900 (match_operand:XF 2 "register_operand" "u")]
16902 (clobber (match_scratch:XF 3 "=2"))]
16903 "TARGET_USE_FANCY_MATH_387
16904 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16905 || TARGET_MIX_SSE_I387)
16906 && flag_unsafe_math_optimizations"
16908 [(set_attr "type" "fpspc")
16909 (set_attr "mode" "XF")])
16911 (define_expand "log1pxf2"
16912 [(use (match_operand:XF 0 "register_operand" ""))
16913 (use (match_operand:XF 1 "register_operand" ""))]
16914 "TARGET_USE_FANCY_MATH_387
16915 && flag_unsafe_math_optimizations && !optimize_size"
16917 ix86_emit_i387_log1p (operands[0], operands[1]);
16921 (define_expand "log1p<mode>2"
16922 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16923 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16924 "TARGET_USE_FANCY_MATH_387
16925 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16926 || TARGET_MIX_SSE_I387)
16927 && flag_unsafe_math_optimizations && !optimize_size"
16929 rtx op0 = gen_reg_rtx (XFmode);
16931 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16933 ix86_emit_i387_log1p (op0, operands[1]);
16934 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16938 (define_insn "fxtractxf3_i387"
16939 [(set (match_operand:XF 0 "register_operand" "=f")
16940 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16941 UNSPEC_XTRACT_FRACT))
16942 (set (match_operand:XF 1 "register_operand" "=u")
16943 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16944 "TARGET_USE_FANCY_MATH_387
16945 && flag_unsafe_math_optimizations"
16947 [(set_attr "type" "fpspc")
16948 (set_attr "mode" "XF")])
16950 (define_insn "fxtract_extend<mode>xf3_i387"
16951 [(set (match_operand:XF 0 "register_operand" "=f")
16952 (unspec:XF [(float_extend:XF
16953 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16954 UNSPEC_XTRACT_FRACT))
16955 (set (match_operand:XF 1 "register_operand" "=u")
16956 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16957 "TARGET_USE_FANCY_MATH_387
16958 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16959 || TARGET_MIX_SSE_I387)
16960 && flag_unsafe_math_optimizations"
16962 [(set_attr "type" "fpspc")
16963 (set_attr "mode" "XF")])
16965 (define_expand "logbxf2"
16966 [(parallel [(set (match_dup 2)
16967 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16968 UNSPEC_XTRACT_FRACT))
16969 (set (match_operand:XF 0 "register_operand" "")
16970 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16971 "TARGET_USE_FANCY_MATH_387
16972 && flag_unsafe_math_optimizations"
16974 operands[2] = gen_reg_rtx (XFmode);
16977 (define_expand "logb<mode>2"
16978 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16979 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16980 "TARGET_USE_FANCY_MATH_387
16981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16982 || TARGET_MIX_SSE_I387)
16983 && flag_unsafe_math_optimizations"
16985 rtx op0 = gen_reg_rtx (XFmode);
16986 rtx op1 = gen_reg_rtx (XFmode);
16988 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16989 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16993 (define_expand "ilogbxf2"
16994 [(use (match_operand:SI 0 "register_operand" ""))
16995 (use (match_operand:XF 1 "register_operand" ""))]
16996 "TARGET_USE_FANCY_MATH_387
16997 && flag_unsafe_math_optimizations && !optimize_size"
16999 rtx op0 = gen_reg_rtx (XFmode);
17000 rtx op1 = gen_reg_rtx (XFmode);
17002 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17003 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17007 (define_expand "ilogb<mode>2"
17008 [(use (match_operand:SI 0 "register_operand" ""))
17009 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
17010 "TARGET_USE_FANCY_MATH_387
17011 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17012 || TARGET_MIX_SSE_I387)
17013 && flag_unsafe_math_optimizations && !optimize_size"
17015 rtx op0 = gen_reg_rtx (XFmode);
17016 rtx op1 = gen_reg_rtx (XFmode);
17018 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17019 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17023 (define_insn "*f2xm1xf2_i387"
17024 [(set (match_operand:XF 0 "register_operand" "=f")
17025 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17027 "TARGET_USE_FANCY_MATH_387
17028 && flag_unsafe_math_optimizations"
17030 [(set_attr "type" "fpspc")
17031 (set_attr "mode" "XF")])
17033 (define_insn "*fscalexf4_i387"
17034 [(set (match_operand:XF 0 "register_operand" "=f")
17035 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17036 (match_operand:XF 3 "register_operand" "1")]
17037 UNSPEC_FSCALE_FRACT))
17038 (set (match_operand:XF 1 "register_operand" "=u")
17039 (unspec:XF [(match_dup 2) (match_dup 3)]
17040 UNSPEC_FSCALE_EXP))]
17041 "TARGET_USE_FANCY_MATH_387
17042 && flag_unsafe_math_optimizations"
17044 [(set_attr "type" "fpspc")
17045 (set_attr "mode" "XF")])
17047 (define_expand "expNcorexf3"
17048 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17049 (match_operand:XF 2 "register_operand" "")))
17050 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17051 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17052 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17053 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17054 (parallel [(set (match_operand:XF 0 "register_operand" "")
17055 (unspec:XF [(match_dup 8) (match_dup 4)]
17056 UNSPEC_FSCALE_FRACT))
17058 (unspec:XF [(match_dup 8) (match_dup 4)]
17059 UNSPEC_FSCALE_EXP))])]
17060 "TARGET_USE_FANCY_MATH_387
17061 && flag_unsafe_math_optimizations && !optimize_size"
17065 for (i = 3; i < 10; i++)
17066 operands[i] = gen_reg_rtx (XFmode);
17068 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17071 (define_expand "expxf2"
17072 [(use (match_operand:XF 0 "register_operand" ""))
17073 (use (match_operand:XF 1 "register_operand" ""))]
17074 "TARGET_USE_FANCY_MATH_387
17075 && flag_unsafe_math_optimizations && !optimize_size"
17077 rtx op2 = gen_reg_rtx (XFmode);
17078 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17080 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17084 (define_expand "exp<mode>2"
17085 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17086 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17087 "TARGET_USE_FANCY_MATH_387
17088 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17089 || TARGET_MIX_SSE_I387)
17090 && flag_unsafe_math_optimizations && !optimize_size"
17092 rtx op0 = gen_reg_rtx (XFmode);
17093 rtx op1 = gen_reg_rtx (XFmode);
17095 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17096 emit_insn (gen_expxf2 (op0, op1));
17097 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17101 (define_expand "exp10xf2"
17102 [(use (match_operand:XF 0 "register_operand" ""))
17103 (use (match_operand:XF 1 "register_operand" ""))]
17104 "TARGET_USE_FANCY_MATH_387
17105 && flag_unsafe_math_optimizations && !optimize_size"
17107 rtx op2 = gen_reg_rtx (XFmode);
17108 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17110 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17114 (define_expand "exp10<mode>2"
17115 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17116 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17117 "TARGET_USE_FANCY_MATH_387
17118 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17119 || TARGET_MIX_SSE_I387)
17120 && flag_unsafe_math_optimizations && !optimize_size"
17122 rtx op0 = gen_reg_rtx (XFmode);
17123 rtx op1 = gen_reg_rtx (XFmode);
17125 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17126 emit_insn (gen_exp10xf2 (op0, op1));
17127 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17131 (define_expand "exp2xf2"
17132 [(use (match_operand:XF 0 "register_operand" ""))
17133 (use (match_operand:XF 1 "register_operand" ""))]
17134 "TARGET_USE_FANCY_MATH_387
17135 && flag_unsafe_math_optimizations && !optimize_size"
17137 rtx op2 = gen_reg_rtx (XFmode);
17138 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17140 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17144 (define_expand "exp2<mode>2"
17145 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17146 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17147 "TARGET_USE_FANCY_MATH_387
17148 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17149 || TARGET_MIX_SSE_I387)
17150 && flag_unsafe_math_optimizations && !optimize_size"
17152 rtx op0 = gen_reg_rtx (XFmode);
17153 rtx op1 = gen_reg_rtx (XFmode);
17155 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17156 emit_insn (gen_exp2xf2 (op0, op1));
17157 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17161 (define_expand "expm1xf2"
17162 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17164 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17165 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17166 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17167 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17168 (parallel [(set (match_dup 7)
17169 (unspec:XF [(match_dup 6) (match_dup 4)]
17170 UNSPEC_FSCALE_FRACT))
17172 (unspec:XF [(match_dup 6) (match_dup 4)]
17173 UNSPEC_FSCALE_EXP))])
17174 (parallel [(set (match_dup 10)
17175 (unspec:XF [(match_dup 9) (match_dup 8)]
17176 UNSPEC_FSCALE_FRACT))
17177 (set (match_dup 11)
17178 (unspec:XF [(match_dup 9) (match_dup 8)]
17179 UNSPEC_FSCALE_EXP))])
17180 (set (match_dup 12) (minus:XF (match_dup 10)
17181 (float_extend:XF (match_dup 13))))
17182 (set (match_operand:XF 0 "register_operand" "")
17183 (plus:XF (match_dup 12) (match_dup 7)))]
17184 "TARGET_USE_FANCY_MATH_387
17185 && flag_unsafe_math_optimizations && !optimize_size"
17189 for (i = 2; i < 13; i++)
17190 operands[i] = gen_reg_rtx (XFmode);
17193 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17195 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17198 (define_expand "expm1<mode>2"
17199 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17200 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17201 "TARGET_USE_FANCY_MATH_387
17202 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17203 || TARGET_MIX_SSE_I387)
17204 && flag_unsafe_math_optimizations && !optimize_size"
17206 rtx op0 = gen_reg_rtx (XFmode);
17207 rtx op1 = gen_reg_rtx (XFmode);
17209 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17210 emit_insn (gen_expm1xf2 (op0, op1));
17211 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17215 (define_expand "ldexpxf3"
17216 [(set (match_dup 3)
17217 (float:XF (match_operand:SI 2 "register_operand" "")))
17218 (parallel [(set (match_operand:XF 0 " register_operand" "")
17219 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17221 UNSPEC_FSCALE_FRACT))
17223 (unspec:XF [(match_dup 1) (match_dup 3)]
17224 UNSPEC_FSCALE_EXP))])]
17225 "TARGET_USE_FANCY_MATH_387
17226 && flag_unsafe_math_optimizations && !optimize_size"
17228 operands[3] = gen_reg_rtx (XFmode);
17229 operands[4] = gen_reg_rtx (XFmode);
17232 (define_expand "ldexp<mode>3"
17233 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17234 (use (match_operand:X87MODEF12 1 "general_operand" ""))
17235 (use (match_operand:SI 2 "register_operand" ""))]
17236 "TARGET_USE_FANCY_MATH_387
17237 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17238 || TARGET_MIX_SSE_I387)
17239 && flag_unsafe_math_optimizations && !optimize_size"
17241 rtx op0 = gen_reg_rtx (XFmode);
17242 rtx op1 = gen_reg_rtx (XFmode);
17244 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17245 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17246 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17250 (define_expand "scalbxf3"
17251 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17252 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17253 (match_operand:XF 2 "register_operand" "")]
17254 UNSPEC_FSCALE_FRACT))
17256 (unspec:XF [(match_dup 1) (match_dup 2)]
17257 UNSPEC_FSCALE_EXP))])]
17258 "TARGET_USE_FANCY_MATH_387
17259 && flag_unsafe_math_optimizations && !optimize_size"
17261 operands[3] = gen_reg_rtx (XFmode);
17264 (define_expand "scalb<mode>3"
17265 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17266 (use (match_operand:X87MODEF12 1 "general_operand" ""))
17267 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
17268 "TARGET_USE_FANCY_MATH_387
17269 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17270 || TARGET_MIX_SSE_I387)
17271 && flag_unsafe_math_optimizations && !optimize_size"
17273 rtx op0 = gen_reg_rtx (XFmode);
17274 rtx op1 = gen_reg_rtx (XFmode);
17275 rtx op2 = gen_reg_rtx (XFmode);
17277 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17278 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17279 emit_insn (gen_scalbxf3 (op0, op1, op2));
17280 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17285 (define_insn "rintxf2"
17286 [(set (match_operand:XF 0 "register_operand" "=f")
17287 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17289 "TARGET_USE_FANCY_MATH_387
17290 && flag_unsafe_math_optimizations"
17292 [(set_attr "type" "fpspc")
17293 (set_attr "mode" "XF")])
17295 (define_expand "rint<mode>2"
17296 [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17297 (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17298 "(TARGET_USE_FANCY_MATH_387
17299 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17300 || TARGET_MIX_SSE_I387)
17301 && flag_unsafe_math_optimizations)
17302 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17303 && !flag_trapping_math
17304 && !optimize_size)"
17306 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17307 && !flag_trapping_math
17309 ix86_expand_rint (operand0, operand1);
17312 rtx op0 = gen_reg_rtx (XFmode);
17313 rtx op1 = gen_reg_rtx (XFmode);
17315 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17316 emit_insn (gen_rintxf2 (op0, op1));
17318 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17323 (define_expand "round<mode>2"
17324 [(match_operand:SSEMODEF 0 "register_operand" "")
17325 (match_operand:SSEMODEF 1 "nonimmediate_operand" "")]
17326 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17327 && !flag_trapping_math && !flag_rounding_math
17330 if ((<MODE>mode != DFmode) || TARGET_64BIT)
17331 ix86_expand_round (operand0, operand1);
17333 ix86_expand_rounddf_32 (operand0, operand1);
17337 (define_insn_and_split "*fistdi2_1"
17338 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17339 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17341 "TARGET_USE_FANCY_MATH_387
17342 && !(reload_completed || reload_in_progress)"
17347 if (memory_operand (operands[0], VOIDmode))
17348 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17351 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17352 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17357 [(set_attr "type" "fpspc")
17358 (set_attr "mode" "DI")])
17360 (define_insn "fistdi2"
17361 [(set (match_operand:DI 0 "memory_operand" "=m")
17362 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17364 (clobber (match_scratch:XF 2 "=&1f"))]
17365 "TARGET_USE_FANCY_MATH_387"
17366 "* return output_fix_trunc (insn, operands, 0);"
17367 [(set_attr "type" "fpspc")
17368 (set_attr "mode" "DI")])
17370 (define_insn "fistdi2_with_temp"
17371 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17372 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17374 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17375 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17376 "TARGET_USE_FANCY_MATH_387"
17378 [(set_attr "type" "fpspc")
17379 (set_attr "mode" "DI")])
17382 [(set (match_operand:DI 0 "register_operand" "")
17383 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17385 (clobber (match_operand:DI 2 "memory_operand" ""))
17386 (clobber (match_scratch 3 ""))]
17388 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17389 (clobber (match_dup 3))])
17390 (set (match_dup 0) (match_dup 2))]
17394 [(set (match_operand:DI 0 "memory_operand" "")
17395 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17397 (clobber (match_operand:DI 2 "memory_operand" ""))
17398 (clobber (match_scratch 3 ""))]
17400 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17401 (clobber (match_dup 3))])]
17404 (define_insn_and_split "*fist<mode>2_1"
17405 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17406 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17408 "TARGET_USE_FANCY_MATH_387
17409 && !(reload_completed || reload_in_progress)"
17414 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17415 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17419 [(set_attr "type" "fpspc")
17420 (set_attr "mode" "<MODE>")])
17422 (define_insn "fist<mode>2"
17423 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17424 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17426 "TARGET_USE_FANCY_MATH_387"
17427 "* return output_fix_trunc (insn, operands, 0);"
17428 [(set_attr "type" "fpspc")
17429 (set_attr "mode" "<MODE>")])
17431 (define_insn "fist<mode>2_with_temp"
17432 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17433 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17435 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17436 "TARGET_USE_FANCY_MATH_387"
17438 [(set_attr "type" "fpspc")
17439 (set_attr "mode" "<MODE>")])
17442 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17443 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17445 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17447 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17448 (set (match_dup 0) (match_dup 2))]
17452 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17453 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17455 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17457 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17460 (define_expand "lrintxf<mode>2"
17461 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17462 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17464 "TARGET_USE_FANCY_MATH_387"
17467 (define_expand "lrint<SSEMODEF:mode><SSEMODEI24:mode>2"
17468 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17469 (unspec:SSEMODEI24 [(match_operand:SSEMODEF 1 "register_operand" "")]
17470 UNSPEC_FIX_NOTRUNC))]
17471 "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17472 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17475 (define_expand "lround<SSEMODEF:mode><SSEMODEI24:mode>2"
17476 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17477 (match_operand:SSEMODEF 1 "register_operand" "")]
17478 "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17479 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17480 && !flag_trapping_math && !flag_rounding_math
17483 ix86_expand_lround (operand0, operand1);
17487 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17488 (define_insn_and_split "frndintxf2_floor"
17489 [(set (match_operand:XF 0 "register_operand" "=f")
17490 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17491 UNSPEC_FRNDINT_FLOOR))
17492 (clobber (reg:CC FLAGS_REG))]
17493 "TARGET_USE_FANCY_MATH_387
17494 && flag_unsafe_math_optimizations
17495 && !(reload_completed || reload_in_progress)"
17500 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17502 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17503 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17505 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17506 operands[2], operands[3]));
17509 [(set_attr "type" "frndint")
17510 (set_attr "i387_cw" "floor")
17511 (set_attr "mode" "XF")])
17513 (define_insn "frndintxf2_floor_i387"
17514 [(set (match_operand:XF 0 "register_operand" "=f")
17515 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17516 UNSPEC_FRNDINT_FLOOR))
17517 (use (match_operand:HI 2 "memory_operand" "m"))
17518 (use (match_operand:HI 3 "memory_operand" "m"))]
17519 "TARGET_USE_FANCY_MATH_387
17520 && flag_unsafe_math_optimizations"
17521 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17522 [(set_attr "type" "frndint")
17523 (set_attr "i387_cw" "floor")
17524 (set_attr "mode" "XF")])
17526 (define_expand "floorxf2"
17527 [(use (match_operand:XF 0 "register_operand" ""))
17528 (use (match_operand:XF 1 "register_operand" ""))]
17529 "TARGET_USE_FANCY_MATH_387
17530 && flag_unsafe_math_optimizations && !optimize_size"
17532 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17536 (define_expand "floordf2"
17537 [(use (match_operand:DF 0 "register_operand" ""))
17538 (use (match_operand:DF 1 "register_operand" ""))]
17539 "((TARGET_USE_FANCY_MATH_387
17540 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17541 && flag_unsafe_math_optimizations)
17542 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17543 && !flag_trapping_math))
17546 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17547 && !flag_trapping_math)
17550 ix86_expand_floorceil (operand0, operand1, true);
17552 ix86_expand_floorceildf_32 (operand0, operand1, true);
17556 rtx op0 = gen_reg_rtx (XFmode);
17557 rtx op1 = gen_reg_rtx (XFmode);
17559 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17560 emit_insn (gen_frndintxf2_floor (op0, op1));
17562 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17567 (define_expand "floorsf2"
17568 [(use (match_operand:SF 0 "register_operand" ""))
17569 (use (match_operand:SF 1 "register_operand" ""))]
17570 "((TARGET_USE_FANCY_MATH_387
17571 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17572 && flag_unsafe_math_optimizations)
17573 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17574 && !flag_trapping_math))
17577 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17578 && !flag_trapping_math)
17579 ix86_expand_floorceil (operand0, operand1, true);
17582 rtx op0 = gen_reg_rtx (XFmode);
17583 rtx op1 = gen_reg_rtx (XFmode);
17585 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17586 emit_insn (gen_frndintxf2_floor (op0, op1));
17588 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17593 (define_insn_and_split "*fist<mode>2_floor_1"
17594 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17595 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17596 UNSPEC_FIST_FLOOR))
17597 (clobber (reg:CC FLAGS_REG))]
17598 "TARGET_USE_FANCY_MATH_387
17599 && flag_unsafe_math_optimizations
17600 && !(reload_completed || reload_in_progress)"
17605 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17607 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17608 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17609 if (memory_operand (operands[0], VOIDmode))
17610 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17611 operands[2], operands[3]));
17614 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17615 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17616 operands[2], operands[3],
17621 [(set_attr "type" "fistp")
17622 (set_attr "i387_cw" "floor")
17623 (set_attr "mode" "<MODE>")])
17625 (define_insn "fistdi2_floor"
17626 [(set (match_operand:DI 0 "memory_operand" "=m")
17627 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17628 UNSPEC_FIST_FLOOR))
17629 (use (match_operand:HI 2 "memory_operand" "m"))
17630 (use (match_operand:HI 3 "memory_operand" "m"))
17631 (clobber (match_scratch:XF 4 "=&1f"))]
17632 "TARGET_USE_FANCY_MATH_387
17633 && flag_unsafe_math_optimizations"
17634 "* return output_fix_trunc (insn, operands, 0);"
17635 [(set_attr "type" "fistp")
17636 (set_attr "i387_cw" "floor")
17637 (set_attr "mode" "DI")])
17639 (define_insn "fistdi2_floor_with_temp"
17640 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17641 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17642 UNSPEC_FIST_FLOOR))
17643 (use (match_operand:HI 2 "memory_operand" "m,m"))
17644 (use (match_operand:HI 3 "memory_operand" "m,m"))
17645 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17646 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17647 "TARGET_USE_FANCY_MATH_387
17648 && flag_unsafe_math_optimizations"
17650 [(set_attr "type" "fistp")
17651 (set_attr "i387_cw" "floor")
17652 (set_attr "mode" "DI")])
17655 [(set (match_operand:DI 0 "register_operand" "")
17656 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17657 UNSPEC_FIST_FLOOR))
17658 (use (match_operand:HI 2 "memory_operand" ""))
17659 (use (match_operand:HI 3 "memory_operand" ""))
17660 (clobber (match_operand:DI 4 "memory_operand" ""))
17661 (clobber (match_scratch 5 ""))]
17663 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17664 (use (match_dup 2))
17665 (use (match_dup 3))
17666 (clobber (match_dup 5))])
17667 (set (match_dup 0) (match_dup 4))]
17671 [(set (match_operand:DI 0 "memory_operand" "")
17672 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17673 UNSPEC_FIST_FLOOR))
17674 (use (match_operand:HI 2 "memory_operand" ""))
17675 (use (match_operand:HI 3 "memory_operand" ""))
17676 (clobber (match_operand:DI 4 "memory_operand" ""))
17677 (clobber (match_scratch 5 ""))]
17679 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17680 (use (match_dup 2))
17681 (use (match_dup 3))
17682 (clobber (match_dup 5))])]
17685 (define_insn "fist<mode>2_floor"
17686 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17687 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17688 UNSPEC_FIST_FLOOR))
17689 (use (match_operand:HI 2 "memory_operand" "m"))
17690 (use (match_operand:HI 3 "memory_operand" "m"))]
17691 "TARGET_USE_FANCY_MATH_387
17692 && flag_unsafe_math_optimizations"
17693 "* return output_fix_trunc (insn, operands, 0);"
17694 [(set_attr "type" "fistp")
17695 (set_attr "i387_cw" "floor")
17696 (set_attr "mode" "<MODE>")])
17698 (define_insn "fist<mode>2_floor_with_temp"
17699 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17700 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17701 UNSPEC_FIST_FLOOR))
17702 (use (match_operand:HI 2 "memory_operand" "m,m"))
17703 (use (match_operand:HI 3 "memory_operand" "m,m"))
17704 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17705 "TARGET_USE_FANCY_MATH_387
17706 && flag_unsafe_math_optimizations"
17708 [(set_attr "type" "fistp")
17709 (set_attr "i387_cw" "floor")
17710 (set_attr "mode" "<MODE>")])
17713 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17714 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17715 UNSPEC_FIST_FLOOR))
17716 (use (match_operand:HI 2 "memory_operand" ""))
17717 (use (match_operand:HI 3 "memory_operand" ""))
17718 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17720 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17721 UNSPEC_FIST_FLOOR))
17722 (use (match_dup 2))
17723 (use (match_dup 3))])
17724 (set (match_dup 0) (match_dup 4))]
17728 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17729 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17730 UNSPEC_FIST_FLOOR))
17731 (use (match_operand:HI 2 "memory_operand" ""))
17732 (use (match_operand:HI 3 "memory_operand" ""))
17733 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17735 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17736 UNSPEC_FIST_FLOOR))
17737 (use (match_dup 2))
17738 (use (match_dup 3))])]
17741 (define_expand "lfloorxf<mode>2"
17742 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17743 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17744 UNSPEC_FIST_FLOOR))
17745 (clobber (reg:CC FLAGS_REG))])]
17746 "TARGET_USE_FANCY_MATH_387
17747 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17748 && flag_unsafe_math_optimizations"
17751 (define_expand "lfloor<mode>di2"
17752 [(match_operand:DI 0 "nonimmediate_operand" "")
17753 (match_operand:SSEMODEF 1 "register_operand" "")]
17754 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17755 && !flag_trapping_math
17758 ix86_expand_lfloorceil (operand0, operand1, true);
17762 (define_expand "lfloor<mode>si2"
17763 [(match_operand:SI 0 "nonimmediate_operand" "")
17764 (match_operand:SSEMODEF 1 "register_operand" "")]
17765 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17766 && !flag_trapping_math
17767 && (!optimize_size || !TARGET_64BIT)"
17769 ix86_expand_lfloorceil (operand0, operand1, true);
17773 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17774 (define_insn_and_split "frndintxf2_ceil"
17775 [(set (match_operand:XF 0 "register_operand" "=f")
17776 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17777 UNSPEC_FRNDINT_CEIL))
17778 (clobber (reg:CC FLAGS_REG))]
17779 "TARGET_USE_FANCY_MATH_387
17780 && flag_unsafe_math_optimizations
17781 && !(reload_completed || reload_in_progress)"
17786 ix86_optimize_mode_switching[I387_CEIL] = 1;
17788 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17789 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17791 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17792 operands[2], operands[3]));
17795 [(set_attr "type" "frndint")
17796 (set_attr "i387_cw" "ceil")
17797 (set_attr "mode" "XF")])
17799 (define_insn "frndintxf2_ceil_i387"
17800 [(set (match_operand:XF 0 "register_operand" "=f")
17801 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17802 UNSPEC_FRNDINT_CEIL))
17803 (use (match_operand:HI 2 "memory_operand" "m"))
17804 (use (match_operand:HI 3 "memory_operand" "m"))]
17805 "TARGET_USE_FANCY_MATH_387
17806 && flag_unsafe_math_optimizations"
17807 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17808 [(set_attr "type" "frndint")
17809 (set_attr "i387_cw" "ceil")
17810 (set_attr "mode" "XF")])
17812 (define_expand "ceilxf2"
17813 [(use (match_operand:XF 0 "register_operand" ""))
17814 (use (match_operand:XF 1 "register_operand" ""))]
17815 "TARGET_USE_FANCY_MATH_387
17816 && flag_unsafe_math_optimizations && !optimize_size"
17818 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17822 (define_expand "ceildf2"
17823 [(use (match_operand:DF 0 "register_operand" ""))
17824 (use (match_operand:DF 1 "register_operand" ""))]
17825 "((TARGET_USE_FANCY_MATH_387
17826 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17827 && flag_unsafe_math_optimizations)
17828 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17829 && !flag_trapping_math))
17832 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17833 && !flag_trapping_math)
17836 ix86_expand_floorceil (operand0, operand1, false);
17838 ix86_expand_floorceildf_32 (operand0, operand1, false);
17842 rtx op0 = gen_reg_rtx (XFmode);
17843 rtx op1 = gen_reg_rtx (XFmode);
17845 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17846 emit_insn (gen_frndintxf2_ceil (op0, op1));
17848 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17853 (define_expand "ceilsf2"
17854 [(use (match_operand:SF 0 "register_operand" ""))
17855 (use (match_operand:SF 1 "register_operand" ""))]
17856 "((TARGET_USE_FANCY_MATH_387
17857 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17858 && flag_unsafe_math_optimizations)
17859 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17860 && !flag_trapping_math))
17863 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17864 && !flag_trapping_math)
17865 ix86_expand_floorceil (operand0, operand1, false);
17868 rtx op0 = gen_reg_rtx (XFmode);
17869 rtx op1 = gen_reg_rtx (XFmode);
17871 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17872 emit_insn (gen_frndintxf2_ceil (op0, op1));
17874 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17879 (define_insn_and_split "*fist<mode>2_ceil_1"
17880 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17881 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17883 (clobber (reg:CC FLAGS_REG))]
17884 "TARGET_USE_FANCY_MATH_387
17885 && flag_unsafe_math_optimizations
17886 && !(reload_completed || reload_in_progress)"
17891 ix86_optimize_mode_switching[I387_CEIL] = 1;
17893 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17894 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17895 if (memory_operand (operands[0], VOIDmode))
17896 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17897 operands[2], operands[3]));
17900 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17901 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17902 operands[2], operands[3],
17907 [(set_attr "type" "fistp")
17908 (set_attr "i387_cw" "ceil")
17909 (set_attr "mode" "<MODE>")])
17911 (define_insn "fistdi2_ceil"
17912 [(set (match_operand:DI 0 "memory_operand" "=m")
17913 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17915 (use (match_operand:HI 2 "memory_operand" "m"))
17916 (use (match_operand:HI 3 "memory_operand" "m"))
17917 (clobber (match_scratch:XF 4 "=&1f"))]
17918 "TARGET_USE_FANCY_MATH_387
17919 && flag_unsafe_math_optimizations"
17920 "* return output_fix_trunc (insn, operands, 0);"
17921 [(set_attr "type" "fistp")
17922 (set_attr "i387_cw" "ceil")
17923 (set_attr "mode" "DI")])
17925 (define_insn "fistdi2_ceil_with_temp"
17926 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17927 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17929 (use (match_operand:HI 2 "memory_operand" "m,m"))
17930 (use (match_operand:HI 3 "memory_operand" "m,m"))
17931 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17932 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17933 "TARGET_USE_FANCY_MATH_387
17934 && flag_unsafe_math_optimizations"
17936 [(set_attr "type" "fistp")
17937 (set_attr "i387_cw" "ceil")
17938 (set_attr "mode" "DI")])
17941 [(set (match_operand:DI 0 "register_operand" "")
17942 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17944 (use (match_operand:HI 2 "memory_operand" ""))
17945 (use (match_operand:HI 3 "memory_operand" ""))
17946 (clobber (match_operand:DI 4 "memory_operand" ""))
17947 (clobber (match_scratch 5 ""))]
17949 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17950 (use (match_dup 2))
17951 (use (match_dup 3))
17952 (clobber (match_dup 5))])
17953 (set (match_dup 0) (match_dup 4))]
17957 [(set (match_operand:DI 0 "memory_operand" "")
17958 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17960 (use (match_operand:HI 2 "memory_operand" ""))
17961 (use (match_operand:HI 3 "memory_operand" ""))
17962 (clobber (match_operand:DI 4 "memory_operand" ""))
17963 (clobber (match_scratch 5 ""))]
17965 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17966 (use (match_dup 2))
17967 (use (match_dup 3))
17968 (clobber (match_dup 5))])]
17971 (define_insn "fist<mode>2_ceil"
17972 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17973 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17975 (use (match_operand:HI 2 "memory_operand" "m"))
17976 (use (match_operand:HI 3 "memory_operand" "m"))]
17977 "TARGET_USE_FANCY_MATH_387
17978 && flag_unsafe_math_optimizations"
17979 "* return output_fix_trunc (insn, operands, 0);"
17980 [(set_attr "type" "fistp")
17981 (set_attr "i387_cw" "ceil")
17982 (set_attr "mode" "<MODE>")])
17984 (define_insn "fist<mode>2_ceil_with_temp"
17985 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17986 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17988 (use (match_operand:HI 2 "memory_operand" "m,m"))
17989 (use (match_operand:HI 3 "memory_operand" "m,m"))
17990 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17991 "TARGET_USE_FANCY_MATH_387
17992 && flag_unsafe_math_optimizations"
17994 [(set_attr "type" "fistp")
17995 (set_attr "i387_cw" "ceil")
17996 (set_attr "mode" "<MODE>")])
17999 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18000 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18002 (use (match_operand:HI 2 "memory_operand" ""))
18003 (use (match_operand:HI 3 "memory_operand" ""))
18004 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18006 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18008 (use (match_dup 2))
18009 (use (match_dup 3))])
18010 (set (match_dup 0) (match_dup 4))]
18014 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18015 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18017 (use (match_operand:HI 2 "memory_operand" ""))
18018 (use (match_operand:HI 3 "memory_operand" ""))
18019 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18021 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18023 (use (match_dup 2))
18024 (use (match_dup 3))])]
18027 (define_expand "lceilxf<mode>2"
18028 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18029 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18031 (clobber (reg:CC FLAGS_REG))])]
18032 "TARGET_USE_FANCY_MATH_387
18033 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18034 && flag_unsafe_math_optimizations"
18037 (define_expand "lceil<mode>di2"
18038 [(match_operand:DI 0 "nonimmediate_operand" "")
18039 (match_operand:SSEMODEF 1 "register_operand" "")]
18040 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18041 && !flag_trapping_math"
18043 ix86_expand_lfloorceil (operand0, operand1, false);
18047 (define_expand "lceil<mode>si2"
18048 [(match_operand:SI 0 "nonimmediate_operand" "")
18049 (match_operand:SSEMODEF 1 "register_operand" "")]
18050 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18051 && !flag_trapping_math"
18053 ix86_expand_lfloorceil (operand0, operand1, false);
18057 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18058 (define_insn_and_split "frndintxf2_trunc"
18059 [(set (match_operand:XF 0 "register_operand" "=f")
18060 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18061 UNSPEC_FRNDINT_TRUNC))
18062 (clobber (reg:CC FLAGS_REG))]
18063 "TARGET_USE_FANCY_MATH_387
18064 && flag_unsafe_math_optimizations
18065 && !(reload_completed || reload_in_progress)"
18070 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18072 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18073 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18075 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18076 operands[2], operands[3]));
18079 [(set_attr "type" "frndint")
18080 (set_attr "i387_cw" "trunc")
18081 (set_attr "mode" "XF")])
18083 (define_insn "frndintxf2_trunc_i387"
18084 [(set (match_operand:XF 0 "register_operand" "=f")
18085 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18086 UNSPEC_FRNDINT_TRUNC))
18087 (use (match_operand:HI 2 "memory_operand" "m"))
18088 (use (match_operand:HI 3 "memory_operand" "m"))]
18089 "TARGET_USE_FANCY_MATH_387
18090 && flag_unsafe_math_optimizations"
18091 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18092 [(set_attr "type" "frndint")
18093 (set_attr "i387_cw" "trunc")
18094 (set_attr "mode" "XF")])
18096 (define_expand "btruncxf2"
18097 [(use (match_operand:XF 0 "register_operand" ""))
18098 (use (match_operand:XF 1 "register_operand" ""))]
18099 "TARGET_USE_FANCY_MATH_387
18100 && flag_unsafe_math_optimizations && !optimize_size"
18102 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18106 (define_expand "btruncdf2"
18107 [(use (match_operand:DF 0 "register_operand" ""))
18108 (use (match_operand:DF 1 "register_operand" ""))]
18109 "((TARGET_USE_FANCY_MATH_387
18110 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18111 && flag_unsafe_math_optimizations)
18112 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18113 && !flag_trapping_math))
18116 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18117 && !flag_trapping_math)
18120 ix86_expand_trunc (operand0, operand1);
18122 ix86_expand_truncdf_32 (operand0, operand1);
18126 rtx op0 = gen_reg_rtx (XFmode);
18127 rtx op1 = gen_reg_rtx (XFmode);
18129 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18130 emit_insn (gen_frndintxf2_trunc (op0, op1));
18132 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18137 (define_expand "btruncsf2"
18138 [(use (match_operand:SF 0 "register_operand" ""))
18139 (use (match_operand:SF 1 "register_operand" ""))]
18140 "((TARGET_USE_FANCY_MATH_387
18141 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18142 && flag_unsafe_math_optimizations)
18143 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18144 && !flag_trapping_math))
18147 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18148 && !flag_trapping_math)
18149 ix86_expand_trunc (operand0, operand1);
18152 rtx op0 = gen_reg_rtx (XFmode);
18153 rtx op1 = gen_reg_rtx (XFmode);
18155 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18156 emit_insn (gen_frndintxf2_trunc (op0, op1));
18158 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18163 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18164 (define_insn_and_split "frndintxf2_mask_pm"
18165 [(set (match_operand:XF 0 "register_operand" "=f")
18166 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18167 UNSPEC_FRNDINT_MASK_PM))
18168 (clobber (reg:CC FLAGS_REG))]
18169 "TARGET_USE_FANCY_MATH_387
18170 && flag_unsafe_math_optimizations
18171 && !(reload_completed || reload_in_progress)"
18176 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18178 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18179 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18181 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18182 operands[2], operands[3]));
18185 [(set_attr "type" "frndint")
18186 (set_attr "i387_cw" "mask_pm")
18187 (set_attr "mode" "XF")])
18189 (define_insn "frndintxf2_mask_pm_i387"
18190 [(set (match_operand:XF 0 "register_operand" "=f")
18191 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18192 UNSPEC_FRNDINT_MASK_PM))
18193 (use (match_operand:HI 2 "memory_operand" "m"))
18194 (use (match_operand:HI 3 "memory_operand" "m"))]
18195 "TARGET_USE_FANCY_MATH_387
18196 && flag_unsafe_math_optimizations"
18197 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18198 [(set_attr "type" "frndint")
18199 (set_attr "i387_cw" "mask_pm")
18200 (set_attr "mode" "XF")])
18202 (define_expand "nearbyintxf2"
18203 [(use (match_operand:XF 0 "register_operand" ""))
18204 (use (match_operand:XF 1 "register_operand" ""))]
18205 "TARGET_USE_FANCY_MATH_387
18206 && flag_unsafe_math_optimizations"
18208 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18213 (define_expand "nearbyintdf2"
18214 [(use (match_operand:DF 0 "register_operand" ""))
18215 (use (match_operand:DF 1 "register_operand" ""))]
18216 "TARGET_USE_FANCY_MATH_387
18217 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18218 && flag_unsafe_math_optimizations"
18220 rtx op0 = gen_reg_rtx (XFmode);
18221 rtx op1 = gen_reg_rtx (XFmode);
18223 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18224 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18226 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18230 (define_expand "nearbyintsf2"
18231 [(use (match_operand:SF 0 "register_operand" ""))
18232 (use (match_operand:SF 1 "register_operand" ""))]
18233 "TARGET_USE_FANCY_MATH_387
18234 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18235 && flag_unsafe_math_optimizations"
18237 rtx op0 = gen_reg_rtx (XFmode);
18238 rtx op1 = gen_reg_rtx (XFmode);
18240 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18241 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18243 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18247 (define_insn "fxam<mode>2_i387"
18248 [(set (match_operand:HI 0 "register_operand" "=a")
18250 [(match_operand:X87MODEF 1 "register_operand" "f")]
18252 "TARGET_USE_FANCY_MATH_387"
18253 "fxam\n\tfnstsw\t%0"
18254 [(set_attr "type" "multi")
18255 (set_attr "unit" "i387")
18256 (set_attr "mode" "<MODE>")])
18258 (define_expand "isinf<mode>2"
18259 [(use (match_operand:SI 0 "register_operand" ""))
18260 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18261 "TARGET_USE_FANCY_MATH_387
18262 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18263 || TARGET_MIX_SSE_I387)"
18265 rtx mask = GEN_INT (0x45);
18266 rtx val = GEN_INT (0x05);
18270 rtx scratch = gen_reg_rtx (HImode);
18271 rtx res = gen_reg_rtx (QImode);
18273 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18274 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18275 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18276 cond = gen_rtx_fmt_ee (EQ, QImode,
18277 gen_rtx_REG (CCmode, FLAGS_REG),
18279 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18280 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18285 ;; Block operation instructions
18287 (define_expand "movmemsi"
18288 [(use (match_operand:BLK 0 "memory_operand" ""))
18289 (use (match_operand:BLK 1 "memory_operand" ""))
18290 (use (match_operand:SI 2 "nonmemory_operand" ""))
18291 (use (match_operand:SI 3 "const_int_operand" ""))
18292 (use (match_operand:SI 4 "const_int_operand" ""))
18293 (use (match_operand:SI 5 "const_int_operand" ""))]
18296 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18297 operands[4], operands[5]))
18303 (define_expand "movmemdi"
18304 [(use (match_operand:BLK 0 "memory_operand" ""))
18305 (use (match_operand:BLK 1 "memory_operand" ""))
18306 (use (match_operand:DI 2 "nonmemory_operand" ""))
18307 (use (match_operand:DI 3 "const_int_operand" ""))
18308 (use (match_operand:SI 4 "const_int_operand" ""))
18309 (use (match_operand:SI 5 "const_int_operand" ""))]
18312 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18313 operands[4], operands[5]))
18319 ;; Most CPUs don't like single string operations
18320 ;; Handle this case here to simplify previous expander.
18322 (define_expand "strmov"
18323 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18324 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18325 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18326 (clobber (reg:CC FLAGS_REG))])
18327 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18328 (clobber (reg:CC FLAGS_REG))])]
18331 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18333 /* If .md ever supports :P for Pmode, these can be directly
18334 in the pattern above. */
18335 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18336 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18338 if (TARGET_SINGLE_STRINGOP || optimize_size)
18340 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18341 operands[2], operands[3],
18342 operands[5], operands[6]));
18346 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18349 (define_expand "strmov_singleop"
18350 [(parallel [(set (match_operand 1 "memory_operand" "")
18351 (match_operand 3 "memory_operand" ""))
18352 (set (match_operand 0 "register_operand" "")
18353 (match_operand 4 "" ""))
18354 (set (match_operand 2 "register_operand" "")
18355 (match_operand 5 "" ""))])]
18356 "TARGET_SINGLE_STRINGOP || optimize_size"
18359 (define_insn "*strmovdi_rex_1"
18360 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18361 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18362 (set (match_operand:DI 0 "register_operand" "=D")
18363 (plus:DI (match_dup 2)
18365 (set (match_operand:DI 1 "register_operand" "=S")
18366 (plus:DI (match_dup 3)
18368 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18370 [(set_attr "type" "str")
18371 (set_attr "mode" "DI")
18372 (set_attr "memory" "both")])
18374 (define_insn "*strmovsi_1"
18375 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18376 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18377 (set (match_operand:SI 0 "register_operand" "=D")
18378 (plus:SI (match_dup 2)
18380 (set (match_operand:SI 1 "register_operand" "=S")
18381 (plus:SI (match_dup 3)
18383 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18385 [(set_attr "type" "str")
18386 (set_attr "mode" "SI")
18387 (set_attr "memory" "both")])
18389 (define_insn "*strmovsi_rex_1"
18390 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18391 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18392 (set (match_operand:DI 0 "register_operand" "=D")
18393 (plus:DI (match_dup 2)
18395 (set (match_operand:DI 1 "register_operand" "=S")
18396 (plus:DI (match_dup 3)
18398 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18400 [(set_attr "type" "str")
18401 (set_attr "mode" "SI")
18402 (set_attr "memory" "both")])
18404 (define_insn "*strmovhi_1"
18405 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18406 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18407 (set (match_operand:SI 0 "register_operand" "=D")
18408 (plus:SI (match_dup 2)
18410 (set (match_operand:SI 1 "register_operand" "=S")
18411 (plus:SI (match_dup 3)
18413 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18415 [(set_attr "type" "str")
18416 (set_attr "memory" "both")
18417 (set_attr "mode" "HI")])
18419 (define_insn "*strmovhi_rex_1"
18420 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18421 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18422 (set (match_operand:DI 0 "register_operand" "=D")
18423 (plus:DI (match_dup 2)
18425 (set (match_operand:DI 1 "register_operand" "=S")
18426 (plus:DI (match_dup 3)
18428 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18430 [(set_attr "type" "str")
18431 (set_attr "memory" "both")
18432 (set_attr "mode" "HI")])
18434 (define_insn "*strmovqi_1"
18435 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18436 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18437 (set (match_operand:SI 0 "register_operand" "=D")
18438 (plus:SI (match_dup 2)
18440 (set (match_operand:SI 1 "register_operand" "=S")
18441 (plus:SI (match_dup 3)
18443 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18445 [(set_attr "type" "str")
18446 (set_attr "memory" "both")
18447 (set_attr "mode" "QI")])
18449 (define_insn "*strmovqi_rex_1"
18450 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18451 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18452 (set (match_operand:DI 0 "register_operand" "=D")
18453 (plus:DI (match_dup 2)
18455 (set (match_operand:DI 1 "register_operand" "=S")
18456 (plus:DI (match_dup 3)
18458 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18460 [(set_attr "type" "str")
18461 (set_attr "memory" "both")
18462 (set_attr "mode" "QI")])
18464 (define_expand "rep_mov"
18465 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18466 (set (match_operand 0 "register_operand" "")
18467 (match_operand 5 "" ""))
18468 (set (match_operand 2 "register_operand" "")
18469 (match_operand 6 "" ""))
18470 (set (match_operand 1 "memory_operand" "")
18471 (match_operand 3 "memory_operand" ""))
18472 (use (match_dup 4))])]
18476 (define_insn "*rep_movdi_rex64"
18477 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18478 (set (match_operand:DI 0 "register_operand" "=D")
18479 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18481 (match_operand:DI 3 "register_operand" "0")))
18482 (set (match_operand:DI 1 "register_operand" "=S")
18483 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18484 (match_operand:DI 4 "register_operand" "1")))
18485 (set (mem:BLK (match_dup 3))
18486 (mem:BLK (match_dup 4)))
18487 (use (match_dup 5))]
18489 "{rep\;movsq|rep movsq}"
18490 [(set_attr "type" "str")
18491 (set_attr "prefix_rep" "1")
18492 (set_attr "memory" "both")
18493 (set_attr "mode" "DI")])
18495 (define_insn "*rep_movsi"
18496 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18497 (set (match_operand:SI 0 "register_operand" "=D")
18498 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18500 (match_operand:SI 3 "register_operand" "0")))
18501 (set (match_operand:SI 1 "register_operand" "=S")
18502 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18503 (match_operand:SI 4 "register_operand" "1")))
18504 (set (mem:BLK (match_dup 3))
18505 (mem:BLK (match_dup 4)))
18506 (use (match_dup 5))]
18508 "{rep\;movsl|rep movsd}"
18509 [(set_attr "type" "str")
18510 (set_attr "prefix_rep" "1")
18511 (set_attr "memory" "both")
18512 (set_attr "mode" "SI")])
18514 (define_insn "*rep_movsi_rex64"
18515 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18516 (set (match_operand:DI 0 "register_operand" "=D")
18517 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18519 (match_operand:DI 3 "register_operand" "0")))
18520 (set (match_operand:DI 1 "register_operand" "=S")
18521 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18522 (match_operand:DI 4 "register_operand" "1")))
18523 (set (mem:BLK (match_dup 3))
18524 (mem:BLK (match_dup 4)))
18525 (use (match_dup 5))]
18527 "{rep\;movsl|rep movsd}"
18528 [(set_attr "type" "str")
18529 (set_attr "prefix_rep" "1")
18530 (set_attr "memory" "both")
18531 (set_attr "mode" "SI")])
18533 (define_insn "*rep_movqi"
18534 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18535 (set (match_operand:SI 0 "register_operand" "=D")
18536 (plus:SI (match_operand:SI 3 "register_operand" "0")
18537 (match_operand:SI 5 "register_operand" "2")))
18538 (set (match_operand:SI 1 "register_operand" "=S")
18539 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18540 (set (mem:BLK (match_dup 3))
18541 (mem:BLK (match_dup 4)))
18542 (use (match_dup 5))]
18544 "{rep\;movsb|rep movsb}"
18545 [(set_attr "type" "str")
18546 (set_attr "prefix_rep" "1")
18547 (set_attr "memory" "both")
18548 (set_attr "mode" "SI")])
18550 (define_insn "*rep_movqi_rex64"
18551 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18552 (set (match_operand:DI 0 "register_operand" "=D")
18553 (plus:DI (match_operand:DI 3 "register_operand" "0")
18554 (match_operand:DI 5 "register_operand" "2")))
18555 (set (match_operand:DI 1 "register_operand" "=S")
18556 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18557 (set (mem:BLK (match_dup 3))
18558 (mem:BLK (match_dup 4)))
18559 (use (match_dup 5))]
18561 "{rep\;movsb|rep movsb}"
18562 [(set_attr "type" "str")
18563 (set_attr "prefix_rep" "1")
18564 (set_attr "memory" "both")
18565 (set_attr "mode" "SI")])
18567 (define_expand "setmemsi"
18568 [(use (match_operand:BLK 0 "memory_operand" ""))
18569 (use (match_operand:SI 1 "nonmemory_operand" ""))
18570 (use (match_operand 2 "const_int_operand" ""))
18571 (use (match_operand 3 "const_int_operand" ""))
18572 (use (match_operand:SI 4 "const_int_operand" ""))
18573 (use (match_operand:SI 5 "const_int_operand" ""))]
18576 if (ix86_expand_setmem (operands[0], operands[1],
18577 operands[2], operands[3],
18578 operands[4], operands[5]))
18584 (define_expand "setmemdi"
18585 [(use (match_operand:BLK 0 "memory_operand" ""))
18586 (use (match_operand:DI 1 "nonmemory_operand" ""))
18587 (use (match_operand 2 "const_int_operand" ""))
18588 (use (match_operand 3 "const_int_operand" ""))
18589 (use (match_operand 4 "const_int_operand" ""))
18590 (use (match_operand 5 "const_int_operand" ""))]
18593 if (ix86_expand_setmem (operands[0], operands[1],
18594 operands[2], operands[3],
18595 operands[4], operands[5]))
18601 ;; Most CPUs don't like single string operations
18602 ;; Handle this case here to simplify previous expander.
18604 (define_expand "strset"
18605 [(set (match_operand 1 "memory_operand" "")
18606 (match_operand 2 "register_operand" ""))
18607 (parallel [(set (match_operand 0 "register_operand" "")
18609 (clobber (reg:CC FLAGS_REG))])]
18612 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18613 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18615 /* If .md ever supports :P for Pmode, this can be directly
18616 in the pattern above. */
18617 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18618 GEN_INT (GET_MODE_SIZE (GET_MODE
18620 if (TARGET_SINGLE_STRINGOP || optimize_size)
18622 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18628 (define_expand "strset_singleop"
18629 [(parallel [(set (match_operand 1 "memory_operand" "")
18630 (match_operand 2 "register_operand" ""))
18631 (set (match_operand 0 "register_operand" "")
18632 (match_operand 3 "" ""))])]
18633 "TARGET_SINGLE_STRINGOP || optimize_size"
18636 (define_insn "*strsetdi_rex_1"
18637 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18638 (match_operand:DI 2 "register_operand" "a"))
18639 (set (match_operand:DI 0 "register_operand" "=D")
18640 (plus:DI (match_dup 1)
18642 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18644 [(set_attr "type" "str")
18645 (set_attr "memory" "store")
18646 (set_attr "mode" "DI")])
18648 (define_insn "*strsetsi_1"
18649 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18650 (match_operand:SI 2 "register_operand" "a"))
18651 (set (match_operand:SI 0 "register_operand" "=D")
18652 (plus:SI (match_dup 1)
18654 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18656 [(set_attr "type" "str")
18657 (set_attr "memory" "store")
18658 (set_attr "mode" "SI")])
18660 (define_insn "*strsetsi_rex_1"
18661 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18662 (match_operand:SI 2 "register_operand" "a"))
18663 (set (match_operand:DI 0 "register_operand" "=D")
18664 (plus:DI (match_dup 1)
18666 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18668 [(set_attr "type" "str")
18669 (set_attr "memory" "store")
18670 (set_attr "mode" "SI")])
18672 (define_insn "*strsethi_1"
18673 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18674 (match_operand:HI 2 "register_operand" "a"))
18675 (set (match_operand:SI 0 "register_operand" "=D")
18676 (plus:SI (match_dup 1)
18678 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18680 [(set_attr "type" "str")
18681 (set_attr "memory" "store")
18682 (set_attr "mode" "HI")])
18684 (define_insn "*strsethi_rex_1"
18685 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18686 (match_operand:HI 2 "register_operand" "a"))
18687 (set (match_operand:DI 0 "register_operand" "=D")
18688 (plus:DI (match_dup 1)
18690 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18692 [(set_attr "type" "str")
18693 (set_attr "memory" "store")
18694 (set_attr "mode" "HI")])
18696 (define_insn "*strsetqi_1"
18697 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18698 (match_operand:QI 2 "register_operand" "a"))
18699 (set (match_operand:SI 0 "register_operand" "=D")
18700 (plus:SI (match_dup 1)
18702 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18704 [(set_attr "type" "str")
18705 (set_attr "memory" "store")
18706 (set_attr "mode" "QI")])
18708 (define_insn "*strsetqi_rex_1"
18709 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18710 (match_operand:QI 2 "register_operand" "a"))
18711 (set (match_operand:DI 0 "register_operand" "=D")
18712 (plus:DI (match_dup 1)
18714 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18716 [(set_attr "type" "str")
18717 (set_attr "memory" "store")
18718 (set_attr "mode" "QI")])
18720 (define_expand "rep_stos"
18721 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18722 (set (match_operand 0 "register_operand" "")
18723 (match_operand 4 "" ""))
18724 (set (match_operand 2 "memory_operand" "") (const_int 0))
18725 (use (match_operand 3 "register_operand" ""))
18726 (use (match_dup 1))])]
18730 (define_insn "*rep_stosdi_rex64"
18731 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18732 (set (match_operand:DI 0 "register_operand" "=D")
18733 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18735 (match_operand:DI 3 "register_operand" "0")))
18736 (set (mem:BLK (match_dup 3))
18738 (use (match_operand:DI 2 "register_operand" "a"))
18739 (use (match_dup 4))]
18741 "{rep\;stosq|rep stosq}"
18742 [(set_attr "type" "str")
18743 (set_attr "prefix_rep" "1")
18744 (set_attr "memory" "store")
18745 (set_attr "mode" "DI")])
18747 (define_insn "*rep_stossi"
18748 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18749 (set (match_operand:SI 0 "register_operand" "=D")
18750 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18752 (match_operand:SI 3 "register_operand" "0")))
18753 (set (mem:BLK (match_dup 3))
18755 (use (match_operand:SI 2 "register_operand" "a"))
18756 (use (match_dup 4))]
18758 "{rep\;stosl|rep stosd}"
18759 [(set_attr "type" "str")
18760 (set_attr "prefix_rep" "1")
18761 (set_attr "memory" "store")
18762 (set_attr "mode" "SI")])
18764 (define_insn "*rep_stossi_rex64"
18765 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18766 (set (match_operand:DI 0 "register_operand" "=D")
18767 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18769 (match_operand:DI 3 "register_operand" "0")))
18770 (set (mem:BLK (match_dup 3))
18772 (use (match_operand:SI 2 "register_operand" "a"))
18773 (use (match_dup 4))]
18775 "{rep\;stosl|rep stosd}"
18776 [(set_attr "type" "str")
18777 (set_attr "prefix_rep" "1")
18778 (set_attr "memory" "store")
18779 (set_attr "mode" "SI")])
18781 (define_insn "*rep_stosqi"
18782 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18783 (set (match_operand:SI 0 "register_operand" "=D")
18784 (plus:SI (match_operand:SI 3 "register_operand" "0")
18785 (match_operand:SI 4 "register_operand" "1")))
18786 (set (mem:BLK (match_dup 3))
18788 (use (match_operand:QI 2 "register_operand" "a"))
18789 (use (match_dup 4))]
18791 "{rep\;stosb|rep stosb}"
18792 [(set_attr "type" "str")
18793 (set_attr "prefix_rep" "1")
18794 (set_attr "memory" "store")
18795 (set_attr "mode" "QI")])
18797 (define_insn "*rep_stosqi_rex64"
18798 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18799 (set (match_operand:DI 0 "register_operand" "=D")
18800 (plus:DI (match_operand:DI 3 "register_operand" "0")
18801 (match_operand:DI 4 "register_operand" "1")))
18802 (set (mem:BLK (match_dup 3))
18804 (use (match_operand:QI 2 "register_operand" "a"))
18805 (use (match_dup 4))]
18807 "{rep\;stosb|rep stosb}"
18808 [(set_attr "type" "str")
18809 (set_attr "prefix_rep" "1")
18810 (set_attr "memory" "store")
18811 (set_attr "mode" "QI")])
18813 (define_expand "cmpstrnsi"
18814 [(set (match_operand:SI 0 "register_operand" "")
18815 (compare:SI (match_operand:BLK 1 "general_operand" "")
18816 (match_operand:BLK 2 "general_operand" "")))
18817 (use (match_operand 3 "general_operand" ""))
18818 (use (match_operand 4 "immediate_operand" ""))]
18819 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18821 rtx addr1, addr2, out, outlow, count, countreg, align;
18823 /* Can't use this if the user has appropriated esi or edi. */
18824 if (global_regs[4] || global_regs[5])
18829 out = gen_reg_rtx (SImode);
18831 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18832 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18833 if (addr1 != XEXP (operands[1], 0))
18834 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18835 if (addr2 != XEXP (operands[2], 0))
18836 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18838 count = operands[3];
18839 countreg = ix86_zero_extend_to_Pmode (count);
18841 /* %%% Iff we are testing strict equality, we can use known alignment
18842 to good advantage. This may be possible with combine, particularly
18843 once cc0 is dead. */
18844 align = operands[4];
18846 if (CONST_INT_P (count))
18848 if (INTVAL (count) == 0)
18850 emit_move_insn (operands[0], const0_rtx);
18853 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18854 operands[1], operands[2]));
18859 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18861 emit_insn (gen_cmpsi_1 (countreg, countreg));
18862 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18863 operands[1], operands[2]));
18866 outlow = gen_lowpart (QImode, out);
18867 emit_insn (gen_cmpintqi (outlow));
18868 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18870 if (operands[0] != out)
18871 emit_move_insn (operands[0], out);
18876 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18878 (define_expand "cmpintqi"
18879 [(set (match_dup 1)
18880 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18882 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18883 (parallel [(set (match_operand:QI 0 "register_operand" "")
18884 (minus:QI (match_dup 1)
18886 (clobber (reg:CC FLAGS_REG))])]
18888 "operands[1] = gen_reg_rtx (QImode);
18889 operands[2] = gen_reg_rtx (QImode);")
18891 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18892 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18894 (define_expand "cmpstrnqi_nz_1"
18895 [(parallel [(set (reg:CC FLAGS_REG)
18896 (compare:CC (match_operand 4 "memory_operand" "")
18897 (match_operand 5 "memory_operand" "")))
18898 (use (match_operand 2 "register_operand" ""))
18899 (use (match_operand:SI 3 "immediate_operand" ""))
18900 (clobber (match_operand 0 "register_operand" ""))
18901 (clobber (match_operand 1 "register_operand" ""))
18902 (clobber (match_dup 2))])]
18906 (define_insn "*cmpstrnqi_nz_1"
18907 [(set (reg:CC FLAGS_REG)
18908 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18909 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18910 (use (match_operand:SI 6 "register_operand" "2"))
18911 (use (match_operand:SI 3 "immediate_operand" "i"))
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_nz_rex_1"
18922 [(set (reg:CC FLAGS_REG)
18923 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18924 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18925 (use (match_operand:DI 6 "register_operand" "2"))
18926 (use (match_operand:SI 3 "immediate_operand" "i"))
18927 (clobber (match_operand:DI 0 "register_operand" "=S"))
18928 (clobber (match_operand:DI 1 "register_operand" "=D"))
18929 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18932 [(set_attr "type" "str")
18933 (set_attr "mode" "QI")
18934 (set_attr "prefix_rep" "1")])
18936 ;; The same, but the count is not known to not be zero.
18938 (define_expand "cmpstrnqi_1"
18939 [(parallel [(set (reg:CC FLAGS_REG)
18940 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18942 (compare:CC (match_operand 4 "memory_operand" "")
18943 (match_operand 5 "memory_operand" ""))
18945 (use (match_operand:SI 3 "immediate_operand" ""))
18946 (use (reg:CC FLAGS_REG))
18947 (clobber (match_operand 0 "register_operand" ""))
18948 (clobber (match_operand 1 "register_operand" ""))
18949 (clobber (match_dup 2))])]
18953 (define_insn "*cmpstrnqi_1"
18954 [(set (reg:CC FLAGS_REG)
18955 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18957 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18958 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18960 (use (match_operand:SI 3 "immediate_operand" "i"))
18961 (use (reg:CC FLAGS_REG))
18962 (clobber (match_operand:SI 0 "register_operand" "=S"))
18963 (clobber (match_operand:SI 1 "register_operand" "=D"))
18964 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18967 [(set_attr "type" "str")
18968 (set_attr "mode" "QI")
18969 (set_attr "prefix_rep" "1")])
18971 (define_insn "*cmpstrnqi_rex_1"
18972 [(set (reg:CC FLAGS_REG)
18973 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18975 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18976 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18978 (use (match_operand:SI 3 "immediate_operand" "i"))
18979 (use (reg:CC FLAGS_REG))
18980 (clobber (match_operand:DI 0 "register_operand" "=S"))
18981 (clobber (match_operand:DI 1 "register_operand" "=D"))
18982 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18985 [(set_attr "type" "str")
18986 (set_attr "mode" "QI")
18987 (set_attr "prefix_rep" "1")])
18989 (define_expand "strlensi"
18990 [(set (match_operand:SI 0 "register_operand" "")
18991 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18992 (match_operand:QI 2 "immediate_operand" "")
18993 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18996 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19002 (define_expand "strlendi"
19003 [(set (match_operand:DI 0 "register_operand" "")
19004 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19005 (match_operand:QI 2 "immediate_operand" "")
19006 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19009 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19015 (define_expand "strlenqi_1"
19016 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19017 (clobber (match_operand 1 "register_operand" ""))
19018 (clobber (reg:CC FLAGS_REG))])]
19022 (define_insn "*strlenqi_1"
19023 [(set (match_operand:SI 0 "register_operand" "=&c")
19024 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19025 (match_operand:QI 2 "register_operand" "a")
19026 (match_operand:SI 3 "immediate_operand" "i")
19027 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19028 (clobber (match_operand:SI 1 "register_operand" "=D"))
19029 (clobber (reg:CC FLAGS_REG))]
19032 [(set_attr "type" "str")
19033 (set_attr "mode" "QI")
19034 (set_attr "prefix_rep" "1")])
19036 (define_insn "*strlenqi_rex_1"
19037 [(set (match_operand:DI 0 "register_operand" "=&c")
19038 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19039 (match_operand:QI 2 "register_operand" "a")
19040 (match_operand:DI 3 "immediate_operand" "i")
19041 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19042 (clobber (match_operand:DI 1 "register_operand" "=D"))
19043 (clobber (reg:CC FLAGS_REG))]
19046 [(set_attr "type" "str")
19047 (set_attr "mode" "QI")
19048 (set_attr "prefix_rep" "1")])
19050 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19051 ;; handled in combine, but it is not currently up to the task.
19052 ;; When used for their truth value, the cmpstrn* expanders generate
19061 ;; The intermediate three instructions are unnecessary.
19063 ;; This one handles cmpstrn*_nz_1...
19066 (set (reg:CC FLAGS_REG)
19067 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19068 (mem:BLK (match_operand 5 "register_operand" ""))))
19069 (use (match_operand 6 "register_operand" ""))
19070 (use (match_operand:SI 3 "immediate_operand" ""))
19071 (clobber (match_operand 0 "register_operand" ""))
19072 (clobber (match_operand 1 "register_operand" ""))
19073 (clobber (match_operand 2 "register_operand" ""))])
19074 (set (match_operand:QI 7 "register_operand" "")
19075 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19076 (set (match_operand:QI 8 "register_operand" "")
19077 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19078 (set (reg FLAGS_REG)
19079 (compare (match_dup 7) (match_dup 8)))
19081 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19083 (set (reg:CC FLAGS_REG)
19084 (compare:CC (mem:BLK (match_dup 4))
19085 (mem:BLK (match_dup 5))))
19086 (use (match_dup 6))
19087 (use (match_dup 3))
19088 (clobber (match_dup 0))
19089 (clobber (match_dup 1))
19090 (clobber (match_dup 2))])]
19093 ;; ...and this one handles cmpstrn*_1.
19096 (set (reg:CC FLAGS_REG)
19097 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19099 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19100 (mem:BLK (match_operand 5 "register_operand" "")))
19102 (use (match_operand:SI 3 "immediate_operand" ""))
19103 (use (reg:CC FLAGS_REG))
19104 (clobber (match_operand 0 "register_operand" ""))
19105 (clobber (match_operand 1 "register_operand" ""))
19106 (clobber (match_operand 2 "register_operand" ""))])
19107 (set (match_operand:QI 7 "register_operand" "")
19108 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19109 (set (match_operand:QI 8 "register_operand" "")
19110 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19111 (set (reg FLAGS_REG)
19112 (compare (match_dup 7) (match_dup 8)))
19114 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19116 (set (reg:CC FLAGS_REG)
19117 (if_then_else:CC (ne (match_dup 6)
19119 (compare:CC (mem:BLK (match_dup 4))
19120 (mem:BLK (match_dup 5)))
19122 (use (match_dup 3))
19123 (use (reg:CC FLAGS_REG))
19124 (clobber (match_dup 0))
19125 (clobber (match_dup 1))
19126 (clobber (match_dup 2))])]
19131 ;; Conditional move instructions.
19133 (define_expand "movdicc"
19134 [(set (match_operand:DI 0 "register_operand" "")
19135 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19136 (match_operand:DI 2 "general_operand" "")
19137 (match_operand:DI 3 "general_operand" "")))]
19139 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19141 (define_insn "x86_movdicc_0_m1_rex64"
19142 [(set (match_operand:DI 0 "register_operand" "=r")
19143 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19146 (clobber (reg:CC FLAGS_REG))]
19149 ; Since we don't have the proper number of operands for an alu insn,
19150 ; fill in all the blanks.
19151 [(set_attr "type" "alu")
19152 (set_attr "pent_pair" "pu")
19153 (set_attr "memory" "none")
19154 (set_attr "imm_disp" "false")
19155 (set_attr "mode" "DI")
19156 (set_attr "length_immediate" "0")])
19158 (define_insn "*movdicc_c_rex64"
19159 [(set (match_operand:DI 0 "register_operand" "=r,r")
19160 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19161 [(reg FLAGS_REG) (const_int 0)])
19162 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19163 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19164 "TARGET_64BIT && TARGET_CMOVE
19165 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19167 cmov%O2%C1\t{%2, %0|%0, %2}
19168 cmov%O2%c1\t{%3, %0|%0, %3}"
19169 [(set_attr "type" "icmov")
19170 (set_attr "mode" "DI")])
19172 (define_expand "movsicc"
19173 [(set (match_operand:SI 0 "register_operand" "")
19174 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19175 (match_operand:SI 2 "general_operand" "")
19176 (match_operand:SI 3 "general_operand" "")))]
19178 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19180 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19181 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19182 ;; So just document what we're doing explicitly.
19184 (define_insn "x86_movsicc_0_m1"
19185 [(set (match_operand:SI 0 "register_operand" "=r")
19186 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19189 (clobber (reg:CC FLAGS_REG))]
19192 ; Since we don't have the proper number of operands for an alu insn,
19193 ; fill in all the blanks.
19194 [(set_attr "type" "alu")
19195 (set_attr "pent_pair" "pu")
19196 (set_attr "memory" "none")
19197 (set_attr "imm_disp" "false")
19198 (set_attr "mode" "SI")
19199 (set_attr "length_immediate" "0")])
19201 (define_insn "*movsicc_noc"
19202 [(set (match_operand:SI 0 "register_operand" "=r,r")
19203 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19204 [(reg FLAGS_REG) (const_int 0)])
19205 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19206 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19208 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19210 cmov%O2%C1\t{%2, %0|%0, %2}
19211 cmov%O2%c1\t{%3, %0|%0, %3}"
19212 [(set_attr "type" "icmov")
19213 (set_attr "mode" "SI")])
19215 (define_expand "movhicc"
19216 [(set (match_operand:HI 0 "register_operand" "")
19217 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19218 (match_operand:HI 2 "general_operand" "")
19219 (match_operand:HI 3 "general_operand" "")))]
19220 "TARGET_HIMODE_MATH"
19221 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19223 (define_insn "*movhicc_noc"
19224 [(set (match_operand:HI 0 "register_operand" "=r,r")
19225 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19226 [(reg FLAGS_REG) (const_int 0)])
19227 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19228 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19230 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19232 cmov%O2%C1\t{%2, %0|%0, %2}
19233 cmov%O2%c1\t{%3, %0|%0, %3}"
19234 [(set_attr "type" "icmov")
19235 (set_attr "mode" "HI")])
19237 (define_expand "movqicc"
19238 [(set (match_operand:QI 0 "register_operand" "")
19239 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19240 (match_operand:QI 2 "general_operand" "")
19241 (match_operand:QI 3 "general_operand" "")))]
19242 "TARGET_QIMODE_MATH"
19243 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19245 (define_insn_and_split "*movqicc_noc"
19246 [(set (match_operand:QI 0 "register_operand" "=r,r")
19247 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19248 [(match_operand 4 "flags_reg_operand" "")
19250 (match_operand:QI 2 "register_operand" "r,0")
19251 (match_operand:QI 3 "register_operand" "0,r")))]
19252 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19254 "&& reload_completed"
19255 [(set (match_dup 0)
19256 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19259 "operands[0] = gen_lowpart (SImode, operands[0]);
19260 operands[2] = gen_lowpart (SImode, operands[2]);
19261 operands[3] = gen_lowpart (SImode, operands[3]);"
19262 [(set_attr "type" "icmov")
19263 (set_attr "mode" "SI")])
19265 (define_expand "movsfcc"
19266 [(set (match_operand:SF 0 "register_operand" "")
19267 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19268 (match_operand:SF 2 "register_operand" "")
19269 (match_operand:SF 3 "register_operand" "")))]
19270 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19271 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19273 (define_insn "*movsfcc_1_387"
19274 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19275 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19276 [(reg FLAGS_REG) (const_int 0)])
19277 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19278 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19279 "TARGET_80387 && TARGET_CMOVE
19280 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19282 fcmov%F1\t{%2, %0|%0, %2}
19283 fcmov%f1\t{%3, %0|%0, %3}
19284 cmov%O2%C1\t{%2, %0|%0, %2}
19285 cmov%O2%c1\t{%3, %0|%0, %3}"
19286 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19287 (set_attr "mode" "SF,SF,SI,SI")])
19289 (define_expand "movdfcc"
19290 [(set (match_operand:DF 0 "register_operand" "")
19291 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19292 (match_operand:DF 2 "register_operand" "")
19293 (match_operand:DF 3 "register_operand" "")))]
19294 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19295 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19297 (define_insn "*movdfcc_1"
19298 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19299 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19300 [(reg FLAGS_REG) (const_int 0)])
19301 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19302 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19303 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19304 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19306 fcmov%F1\t{%2, %0|%0, %2}
19307 fcmov%f1\t{%3, %0|%0, %3}
19310 [(set_attr "type" "fcmov,fcmov,multi,multi")
19311 (set_attr "mode" "DF")])
19313 (define_insn "*movdfcc_1_rex64"
19314 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19315 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19316 [(reg FLAGS_REG) (const_int 0)])
19317 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19318 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19319 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19320 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19322 fcmov%F1\t{%2, %0|%0, %2}
19323 fcmov%f1\t{%3, %0|%0, %3}
19324 cmov%O2%C1\t{%2, %0|%0, %2}
19325 cmov%O2%c1\t{%3, %0|%0, %3}"
19326 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19327 (set_attr "mode" "DF")])
19330 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19331 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19332 [(match_operand 4 "flags_reg_operand" "")
19334 (match_operand:DF 2 "nonimmediate_operand" "")
19335 (match_operand:DF 3 "nonimmediate_operand" "")))]
19336 "!TARGET_64BIT && reload_completed"
19337 [(set (match_dup 2)
19338 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19342 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19345 "split_di (operands+2, 1, operands+5, operands+6);
19346 split_di (operands+3, 1, operands+7, operands+8);
19347 split_di (operands, 1, operands+2, operands+3);")
19349 (define_expand "movxfcc"
19350 [(set (match_operand:XF 0 "register_operand" "")
19351 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19352 (match_operand:XF 2 "register_operand" "")
19353 (match_operand:XF 3 "register_operand" "")))]
19354 "TARGET_80387 && TARGET_CMOVE"
19355 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19357 (define_insn "*movxfcc_1"
19358 [(set (match_operand:XF 0 "register_operand" "=f,f")
19359 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19360 [(reg FLAGS_REG) (const_int 0)])
19361 (match_operand:XF 2 "register_operand" "f,0")
19362 (match_operand:XF 3 "register_operand" "0,f")))]
19363 "TARGET_80387 && TARGET_CMOVE"
19365 fcmov%F1\t{%2, %0|%0, %2}
19366 fcmov%f1\t{%3, %0|%0, %3}"
19367 [(set_attr "type" "fcmov")
19368 (set_attr "mode" "XF")])
19370 ;; These versions of the min/max patterns are intentionally ignorant of
19371 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19372 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19373 ;; are undefined in this condition, we're certain this is correct.
19375 (define_insn "sminsf3"
19376 [(set (match_operand:SF 0 "register_operand" "=x")
19377 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19378 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19380 "minss\t{%2, %0|%0, %2}"
19381 [(set_attr "type" "sseadd")
19382 (set_attr "mode" "SF")])
19384 (define_insn "smaxsf3"
19385 [(set (match_operand:SF 0 "register_operand" "=x")
19386 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19387 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19389 "maxss\t{%2, %0|%0, %2}"
19390 [(set_attr "type" "sseadd")
19391 (set_attr "mode" "SF")])
19393 (define_insn "smindf3"
19394 [(set (match_operand:DF 0 "register_operand" "=x")
19395 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19396 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19397 "TARGET_SSE2 && TARGET_SSE_MATH"
19398 "minsd\t{%2, %0|%0, %2}"
19399 [(set_attr "type" "sseadd")
19400 (set_attr "mode" "DF")])
19402 (define_insn "smaxdf3"
19403 [(set (match_operand:DF 0 "register_operand" "=x")
19404 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19405 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19406 "TARGET_SSE2 && TARGET_SSE_MATH"
19407 "maxsd\t{%2, %0|%0, %2}"
19408 [(set_attr "type" "sseadd")
19409 (set_attr "mode" "DF")])
19411 ;; These versions of the min/max patterns implement exactly the operations
19412 ;; min = (op1 < op2 ? op1 : op2)
19413 ;; max = (!(op1 < op2) ? op1 : op2)
19414 ;; Their operands are not commutative, and thus they may be used in the
19415 ;; presence of -0.0 and NaN.
19417 (define_insn "*ieee_sminsf3"
19418 [(set (match_operand:SF 0 "register_operand" "=x")
19419 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19420 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19423 "minss\t{%2, %0|%0, %2}"
19424 [(set_attr "type" "sseadd")
19425 (set_attr "mode" "SF")])
19427 (define_insn "*ieee_smaxsf3"
19428 [(set (match_operand:SF 0 "register_operand" "=x")
19429 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19430 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19433 "maxss\t{%2, %0|%0, %2}"
19434 [(set_attr "type" "sseadd")
19435 (set_attr "mode" "SF")])
19437 (define_insn "*ieee_smindf3"
19438 [(set (match_operand:DF 0 "register_operand" "=x")
19439 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19440 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19442 "TARGET_SSE2 && TARGET_SSE_MATH"
19443 "minsd\t{%2, %0|%0, %2}"
19444 [(set_attr "type" "sseadd")
19445 (set_attr "mode" "DF")])
19447 (define_insn "*ieee_smaxdf3"
19448 [(set (match_operand:DF 0 "register_operand" "=x")
19449 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19450 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19452 "TARGET_SSE2 && TARGET_SSE_MATH"
19453 "maxsd\t{%2, %0|%0, %2}"
19454 [(set_attr "type" "sseadd")
19455 (set_attr "mode" "DF")])
19457 ;; Make two stack loads independent:
19459 ;; fld %st(0) -> fld bb
19460 ;; fmul bb fmul %st(1), %st
19462 ;; Actually we only match the last two instructions for simplicity.
19464 [(set (match_operand 0 "fp_register_operand" "")
19465 (match_operand 1 "fp_register_operand" ""))
19467 (match_operator 2 "binary_fp_operator"
19469 (match_operand 3 "memory_operand" "")]))]
19470 "REGNO (operands[0]) != REGNO (operands[1])"
19471 [(set (match_dup 0) (match_dup 3))
19472 (set (match_dup 0) (match_dup 4))]
19474 ;; The % modifier is not operational anymore in peephole2's, so we have to
19475 ;; swap the operands manually in the case of addition and multiplication.
19476 "if (COMMUTATIVE_ARITH_P (operands[2]))
19477 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19478 operands[0], operands[1]);
19480 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19481 operands[1], operands[0]);")
19483 ;; Conditional addition patterns
19484 (define_expand "addqicc"
19485 [(match_operand:QI 0 "register_operand" "")
19486 (match_operand 1 "comparison_operator" "")
19487 (match_operand:QI 2 "register_operand" "")
19488 (match_operand:QI 3 "const_int_operand" "")]
19490 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19492 (define_expand "addhicc"
19493 [(match_operand:HI 0 "register_operand" "")
19494 (match_operand 1 "comparison_operator" "")
19495 (match_operand:HI 2 "register_operand" "")
19496 (match_operand:HI 3 "const_int_operand" "")]
19498 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19500 (define_expand "addsicc"
19501 [(match_operand:SI 0 "register_operand" "")
19502 (match_operand 1 "comparison_operator" "")
19503 (match_operand:SI 2 "register_operand" "")
19504 (match_operand:SI 3 "const_int_operand" "")]
19506 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19508 (define_expand "adddicc"
19509 [(match_operand:DI 0 "register_operand" "")
19510 (match_operand 1 "comparison_operator" "")
19511 (match_operand:DI 2 "register_operand" "")
19512 (match_operand:DI 3 "const_int_operand" "")]
19514 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19517 ;; Misc patterns (?)
19519 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19520 ;; Otherwise there will be nothing to keep
19522 ;; [(set (reg ebp) (reg esp))]
19523 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19524 ;; (clobber (eflags)]
19525 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19527 ;; in proper program order.
19528 (define_insn "pro_epilogue_adjust_stack_1"
19529 [(set (match_operand:SI 0 "register_operand" "=r,r")
19530 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19531 (match_operand:SI 2 "immediate_operand" "i,i")))
19532 (clobber (reg:CC FLAGS_REG))
19533 (clobber (mem:BLK (scratch)))]
19536 switch (get_attr_type (insn))
19539 return "mov{l}\t{%1, %0|%0, %1}";
19542 if (CONST_INT_P (operands[2])
19543 && (INTVAL (operands[2]) == 128
19544 || (INTVAL (operands[2]) < 0
19545 && INTVAL (operands[2]) != -128)))
19547 operands[2] = GEN_INT (-INTVAL (operands[2]));
19548 return "sub{l}\t{%2, %0|%0, %2}";
19550 return "add{l}\t{%2, %0|%0, %2}";
19553 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19554 return "lea{l}\t{%a2, %0|%0, %a2}";
19557 gcc_unreachable ();
19560 [(set (attr "type")
19561 (cond [(eq_attr "alternative" "0")
19562 (const_string "alu")
19563 (match_operand:SI 2 "const0_operand" "")
19564 (const_string "imov")
19566 (const_string "lea")))
19567 (set_attr "mode" "SI")])
19569 (define_insn "pro_epilogue_adjust_stack_rex64"
19570 [(set (match_operand:DI 0 "register_operand" "=r,r")
19571 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19572 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19573 (clobber (reg:CC FLAGS_REG))
19574 (clobber (mem:BLK (scratch)))]
19577 switch (get_attr_type (insn))
19580 return "mov{q}\t{%1, %0|%0, %1}";
19583 if (CONST_INT_P (operands[2])
19584 /* Avoid overflows. */
19585 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19586 && (INTVAL (operands[2]) == 128
19587 || (INTVAL (operands[2]) < 0
19588 && INTVAL (operands[2]) != -128)))
19590 operands[2] = GEN_INT (-INTVAL (operands[2]));
19591 return "sub{q}\t{%2, %0|%0, %2}";
19593 return "add{q}\t{%2, %0|%0, %2}";
19596 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19597 return "lea{q}\t{%a2, %0|%0, %a2}";
19600 gcc_unreachable ();
19603 [(set (attr "type")
19604 (cond [(eq_attr "alternative" "0")
19605 (const_string "alu")
19606 (match_operand:DI 2 "const0_operand" "")
19607 (const_string "imov")
19609 (const_string "lea")))
19610 (set_attr "mode" "DI")])
19612 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19613 [(set (match_operand:DI 0 "register_operand" "=r,r")
19614 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19615 (match_operand:DI 3 "immediate_operand" "i,i")))
19616 (use (match_operand:DI 2 "register_operand" "r,r"))
19617 (clobber (reg:CC FLAGS_REG))
19618 (clobber (mem:BLK (scratch)))]
19621 switch (get_attr_type (insn))
19624 return "add{q}\t{%2, %0|%0, %2}";
19627 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19628 return "lea{q}\t{%a2, %0|%0, %a2}";
19631 gcc_unreachable ();
19634 [(set_attr "type" "alu,lea")
19635 (set_attr "mode" "DI")])
19637 (define_expand "allocate_stack_worker"
19638 [(match_operand:SI 0 "register_operand" "")]
19639 "TARGET_STACK_PROBE"
19641 if (reload_completed)
19644 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19646 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19651 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19653 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19658 (define_insn "allocate_stack_worker_1"
19659 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19660 UNSPECV_STACK_PROBE)
19661 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19662 (clobber (match_scratch:SI 1 "=0"))
19663 (clobber (reg:CC FLAGS_REG))]
19664 "!TARGET_64BIT && TARGET_STACK_PROBE"
19666 [(set_attr "type" "multi")
19667 (set_attr "length" "5")])
19669 (define_expand "allocate_stack_worker_postreload"
19670 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19671 UNSPECV_STACK_PROBE)
19672 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19673 (clobber (match_dup 0))
19674 (clobber (reg:CC FLAGS_REG))])]
19678 (define_insn "allocate_stack_worker_rex64"
19679 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19680 UNSPECV_STACK_PROBE)
19681 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19682 (clobber (match_scratch:DI 1 "=0"))
19683 (clobber (reg:CC FLAGS_REG))]
19684 "TARGET_64BIT && TARGET_STACK_PROBE"
19686 [(set_attr "type" "multi")
19687 (set_attr "length" "5")])
19689 (define_expand "allocate_stack_worker_rex64_postreload"
19690 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19691 UNSPECV_STACK_PROBE)
19692 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19693 (clobber (match_dup 0))
19694 (clobber (reg:CC FLAGS_REG))])]
19698 (define_expand "allocate_stack"
19699 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19700 (minus:SI (reg:SI SP_REG)
19701 (match_operand:SI 1 "general_operand" "")))
19702 (clobber (reg:CC FLAGS_REG))])
19703 (parallel [(set (reg:SI SP_REG)
19704 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19705 (clobber (reg:CC FLAGS_REG))])]
19706 "TARGET_STACK_PROBE"
19708 #ifdef CHECK_STACK_LIMIT
19709 if (CONST_INT_P (operands[1])
19710 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19711 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19715 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19718 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19722 (define_expand "builtin_setjmp_receiver"
19723 [(label_ref (match_operand 0 "" ""))]
19724 "!TARGET_64BIT && flag_pic"
19729 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19730 rtx label_rtx = gen_label_rtx ();
19731 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19732 xops[0] = xops[1] = picreg;
19733 xops[2] = gen_rtx_CONST (SImode,
19734 gen_rtx_MINUS (SImode,
19735 gen_rtx_LABEL_REF (SImode, label_rtx),
19736 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19737 ix86_expand_binary_operator (MINUS, SImode, xops);
19740 emit_insn (gen_set_got (pic_offset_table_rtx));
19744 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19747 [(set (match_operand 0 "register_operand" "")
19748 (match_operator 3 "promotable_binary_operator"
19749 [(match_operand 1 "register_operand" "")
19750 (match_operand 2 "aligned_operand" "")]))
19751 (clobber (reg:CC FLAGS_REG))]
19752 "! TARGET_PARTIAL_REG_STALL && reload_completed
19753 && ((GET_MODE (operands[0]) == HImode
19754 && ((!optimize_size && !TARGET_FAST_PREFIX)
19755 /* ??? next two lines just !satisfies_constraint_K (...) */
19756 || !CONST_INT_P (operands[2])
19757 || satisfies_constraint_K (operands[2])))
19758 || (GET_MODE (operands[0]) == QImode
19759 && (TARGET_PROMOTE_QImode || optimize_size)))"
19760 [(parallel [(set (match_dup 0)
19761 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19762 (clobber (reg:CC FLAGS_REG))])]
19763 "operands[0] = gen_lowpart (SImode, operands[0]);
19764 operands[1] = gen_lowpart (SImode, operands[1]);
19765 if (GET_CODE (operands[3]) != ASHIFT)
19766 operands[2] = gen_lowpart (SImode, operands[2]);
19767 PUT_MODE (operands[3], SImode);")
19769 ; Promote the QImode tests, as i386 has encoding of the AND
19770 ; instruction with 32-bit sign-extended immediate and thus the
19771 ; instruction size is unchanged, except in the %eax case for
19772 ; which it is increased by one byte, hence the ! optimize_size.
19774 [(set (match_operand 0 "flags_reg_operand" "")
19775 (match_operator 2 "compare_operator"
19776 [(and (match_operand 3 "aligned_operand" "")
19777 (match_operand 4 "const_int_operand" ""))
19779 (set (match_operand 1 "register_operand" "")
19780 (and (match_dup 3) (match_dup 4)))]
19781 "! TARGET_PARTIAL_REG_STALL && reload_completed
19782 /* Ensure that the operand will remain sign-extended immediate. */
19783 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19785 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19786 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19787 [(parallel [(set (match_dup 0)
19788 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19791 (and:SI (match_dup 3) (match_dup 4)))])]
19794 = gen_int_mode (INTVAL (operands[4])
19795 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19796 operands[1] = gen_lowpart (SImode, operands[1]);
19797 operands[3] = gen_lowpart (SImode, operands[3]);
19800 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19801 ; the TEST instruction with 32-bit sign-extended immediate and thus
19802 ; the instruction size would at least double, which is not what we
19803 ; want even with ! optimize_size.
19805 [(set (match_operand 0 "flags_reg_operand" "")
19806 (match_operator 1 "compare_operator"
19807 [(and (match_operand:HI 2 "aligned_operand" "")
19808 (match_operand:HI 3 "const_int_operand" ""))
19810 "! TARGET_PARTIAL_REG_STALL && reload_completed
19811 /* Ensure that the operand will remain sign-extended immediate. */
19812 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19813 && ! TARGET_FAST_PREFIX
19814 && ! optimize_size"
19815 [(set (match_dup 0)
19816 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19820 = gen_int_mode (INTVAL (operands[3])
19821 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19822 operands[2] = gen_lowpart (SImode, operands[2]);
19826 [(set (match_operand 0 "register_operand" "")
19827 (neg (match_operand 1 "register_operand" "")))
19828 (clobber (reg:CC FLAGS_REG))]
19829 "! TARGET_PARTIAL_REG_STALL && reload_completed
19830 && (GET_MODE (operands[0]) == HImode
19831 || (GET_MODE (operands[0]) == QImode
19832 && (TARGET_PROMOTE_QImode || optimize_size)))"
19833 [(parallel [(set (match_dup 0)
19834 (neg:SI (match_dup 1)))
19835 (clobber (reg:CC FLAGS_REG))])]
19836 "operands[0] = gen_lowpart (SImode, operands[0]);
19837 operands[1] = gen_lowpart (SImode, operands[1]);")
19840 [(set (match_operand 0 "register_operand" "")
19841 (not (match_operand 1 "register_operand" "")))]
19842 "! TARGET_PARTIAL_REG_STALL && reload_completed
19843 && (GET_MODE (operands[0]) == HImode
19844 || (GET_MODE (operands[0]) == QImode
19845 && (TARGET_PROMOTE_QImode || optimize_size)))"
19846 [(set (match_dup 0)
19847 (not:SI (match_dup 1)))]
19848 "operands[0] = gen_lowpart (SImode, operands[0]);
19849 operands[1] = gen_lowpart (SImode, operands[1]);")
19852 [(set (match_operand 0 "register_operand" "")
19853 (if_then_else (match_operator 1 "comparison_operator"
19854 [(reg FLAGS_REG) (const_int 0)])
19855 (match_operand 2 "register_operand" "")
19856 (match_operand 3 "register_operand" "")))]
19857 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19858 && (GET_MODE (operands[0]) == HImode
19859 || (GET_MODE (operands[0]) == QImode
19860 && (TARGET_PROMOTE_QImode || optimize_size)))"
19861 [(set (match_dup 0)
19862 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19863 "operands[0] = gen_lowpart (SImode, operands[0]);
19864 operands[2] = gen_lowpart (SImode, operands[2]);
19865 operands[3] = gen_lowpart (SImode, operands[3]);")
19868 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19869 ;; transform a complex memory operation into two memory to register operations.
19871 ;; Don't push memory operands
19873 [(set (match_operand:SI 0 "push_operand" "")
19874 (match_operand:SI 1 "memory_operand" ""))
19875 (match_scratch:SI 2 "r")]
19876 "!optimize_size && !TARGET_PUSH_MEMORY
19877 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19878 [(set (match_dup 2) (match_dup 1))
19879 (set (match_dup 0) (match_dup 2))]
19883 [(set (match_operand:DI 0 "push_operand" "")
19884 (match_operand:DI 1 "memory_operand" ""))
19885 (match_scratch:DI 2 "r")]
19886 "!optimize_size && !TARGET_PUSH_MEMORY
19887 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19888 [(set (match_dup 2) (match_dup 1))
19889 (set (match_dup 0) (match_dup 2))]
19892 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19895 [(set (match_operand:SF 0 "push_operand" "")
19896 (match_operand:SF 1 "memory_operand" ""))
19897 (match_scratch:SF 2 "r")]
19898 "!optimize_size && !TARGET_PUSH_MEMORY
19899 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19900 [(set (match_dup 2) (match_dup 1))
19901 (set (match_dup 0) (match_dup 2))]
19905 [(set (match_operand:HI 0 "push_operand" "")
19906 (match_operand:HI 1 "memory_operand" ""))
19907 (match_scratch:HI 2 "r")]
19908 "!optimize_size && !TARGET_PUSH_MEMORY
19909 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19910 [(set (match_dup 2) (match_dup 1))
19911 (set (match_dup 0) (match_dup 2))]
19915 [(set (match_operand:QI 0 "push_operand" "")
19916 (match_operand:QI 1 "memory_operand" ""))
19917 (match_scratch:QI 2 "q")]
19918 "!optimize_size && !TARGET_PUSH_MEMORY
19919 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19920 [(set (match_dup 2) (match_dup 1))
19921 (set (match_dup 0) (match_dup 2))]
19924 ;; Don't move an immediate directly to memory when the instruction
19927 [(match_scratch:SI 1 "r")
19928 (set (match_operand:SI 0 "memory_operand" "")
19931 && ! TARGET_USE_MOV0
19932 && TARGET_SPLIT_LONG_MOVES
19933 && get_attr_length (insn) >= ix86_cost->large_insn
19934 && peep2_regno_dead_p (0, FLAGS_REG)"
19935 [(parallel [(set (match_dup 1) (const_int 0))
19936 (clobber (reg:CC FLAGS_REG))])
19937 (set (match_dup 0) (match_dup 1))]
19941 [(match_scratch:HI 1 "r")
19942 (set (match_operand:HI 0 "memory_operand" "")
19945 && ! TARGET_USE_MOV0
19946 && TARGET_SPLIT_LONG_MOVES
19947 && get_attr_length (insn) >= ix86_cost->large_insn
19948 && peep2_regno_dead_p (0, FLAGS_REG)"
19949 [(parallel [(set (match_dup 2) (const_int 0))
19950 (clobber (reg:CC FLAGS_REG))])
19951 (set (match_dup 0) (match_dup 1))]
19952 "operands[2] = gen_lowpart (SImode, operands[1]);")
19955 [(match_scratch:QI 1 "q")
19956 (set (match_operand:QI 0 "memory_operand" "")
19959 && ! TARGET_USE_MOV0
19960 && TARGET_SPLIT_LONG_MOVES
19961 && get_attr_length (insn) >= ix86_cost->large_insn
19962 && peep2_regno_dead_p (0, FLAGS_REG)"
19963 [(parallel [(set (match_dup 2) (const_int 0))
19964 (clobber (reg:CC FLAGS_REG))])
19965 (set (match_dup 0) (match_dup 1))]
19966 "operands[2] = gen_lowpart (SImode, operands[1]);")
19969 [(match_scratch:SI 2 "r")
19970 (set (match_operand:SI 0 "memory_operand" "")
19971 (match_operand:SI 1 "immediate_operand" ""))]
19973 && get_attr_length (insn) >= ix86_cost->large_insn
19974 && TARGET_SPLIT_LONG_MOVES"
19975 [(set (match_dup 2) (match_dup 1))
19976 (set (match_dup 0) (match_dup 2))]
19980 [(match_scratch:HI 2 "r")
19981 (set (match_operand:HI 0 "memory_operand" "")
19982 (match_operand:HI 1 "immediate_operand" ""))]
19983 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19984 && TARGET_SPLIT_LONG_MOVES"
19985 [(set (match_dup 2) (match_dup 1))
19986 (set (match_dup 0) (match_dup 2))]
19990 [(match_scratch:QI 2 "q")
19991 (set (match_operand:QI 0 "memory_operand" "")
19992 (match_operand:QI 1 "immediate_operand" ""))]
19993 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19994 && TARGET_SPLIT_LONG_MOVES"
19995 [(set (match_dup 2) (match_dup 1))
19996 (set (match_dup 0) (match_dup 2))]
19999 ;; Don't compare memory with zero, load and use a test instead.
20001 [(set (match_operand 0 "flags_reg_operand" "")
20002 (match_operator 1 "compare_operator"
20003 [(match_operand:SI 2 "memory_operand" "")
20005 (match_scratch:SI 3 "r")]
20006 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
20007 [(set (match_dup 3) (match_dup 2))
20008 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20011 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20012 ;; Don't split NOTs with a displacement operand, because resulting XOR
20013 ;; will not be pairable anyway.
20015 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20016 ;; represented using a modRM byte. The XOR replacement is long decoded,
20017 ;; so this split helps here as well.
20019 ;; Note: Can't do this as a regular split because we can't get proper
20020 ;; lifetime information then.
20023 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20024 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20026 && peep2_regno_dead_p (0, FLAGS_REG)
20027 && ((TARGET_PENTIUM
20028 && (!MEM_P (operands[0])
20029 || !memory_displacement_operand (operands[0], SImode)))
20030 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20031 [(parallel [(set (match_dup 0)
20032 (xor:SI (match_dup 1) (const_int -1)))
20033 (clobber (reg:CC FLAGS_REG))])]
20037 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20038 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20040 && peep2_regno_dead_p (0, FLAGS_REG)
20041 && ((TARGET_PENTIUM
20042 && (!MEM_P (operands[0])
20043 || !memory_displacement_operand (operands[0], HImode)))
20044 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20045 [(parallel [(set (match_dup 0)
20046 (xor:HI (match_dup 1) (const_int -1)))
20047 (clobber (reg:CC FLAGS_REG))])]
20051 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20052 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20054 && peep2_regno_dead_p (0, FLAGS_REG)
20055 && ((TARGET_PENTIUM
20056 && (!MEM_P (operands[0])
20057 || !memory_displacement_operand (operands[0], QImode)))
20058 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20059 [(parallel [(set (match_dup 0)
20060 (xor:QI (match_dup 1) (const_int -1)))
20061 (clobber (reg:CC FLAGS_REG))])]
20064 ;; Non pairable "test imm, reg" instructions can be translated to
20065 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20066 ;; byte opcode instead of two, have a short form for byte operands),
20067 ;; so do it for other CPUs as well. Given that the value was dead,
20068 ;; this should not create any new dependencies. Pass on the sub-word
20069 ;; versions if we're concerned about partial register stalls.
20072 [(set (match_operand 0 "flags_reg_operand" "")
20073 (match_operator 1 "compare_operator"
20074 [(and:SI (match_operand:SI 2 "register_operand" "")
20075 (match_operand:SI 3 "immediate_operand" ""))
20077 "ix86_match_ccmode (insn, CCNOmode)
20078 && (true_regnum (operands[2]) != 0
20079 || satisfies_constraint_K (operands[3]))
20080 && peep2_reg_dead_p (1, operands[2])"
20082 [(set (match_dup 0)
20083 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20086 (and:SI (match_dup 2) (match_dup 3)))])]
20089 ;; We don't need to handle HImode case, because it will be promoted to SImode
20090 ;; on ! TARGET_PARTIAL_REG_STALL
20093 [(set (match_operand 0 "flags_reg_operand" "")
20094 (match_operator 1 "compare_operator"
20095 [(and:QI (match_operand:QI 2 "register_operand" "")
20096 (match_operand:QI 3 "immediate_operand" ""))
20098 "! TARGET_PARTIAL_REG_STALL
20099 && ix86_match_ccmode (insn, CCNOmode)
20100 && true_regnum (operands[2]) != 0
20101 && peep2_reg_dead_p (1, operands[2])"
20103 [(set (match_dup 0)
20104 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20107 (and:QI (match_dup 2) (match_dup 3)))])]
20111 [(set (match_operand 0 "flags_reg_operand" "")
20112 (match_operator 1 "compare_operator"
20115 (match_operand 2 "ext_register_operand" "")
20118 (match_operand 3 "const_int_operand" ""))
20120 "! TARGET_PARTIAL_REG_STALL
20121 && ix86_match_ccmode (insn, CCNOmode)
20122 && true_regnum (operands[2]) != 0
20123 && peep2_reg_dead_p (1, operands[2])"
20124 [(parallel [(set (match_dup 0)
20133 (set (zero_extract:SI (match_dup 2)
20144 ;; Don't do logical operations with memory inputs.
20146 [(match_scratch:SI 2 "r")
20147 (parallel [(set (match_operand:SI 0 "register_operand" "")
20148 (match_operator:SI 3 "arith_or_logical_operator"
20150 (match_operand:SI 1 "memory_operand" "")]))
20151 (clobber (reg:CC FLAGS_REG))])]
20152 "! optimize_size && ! TARGET_READ_MODIFY"
20153 [(set (match_dup 2) (match_dup 1))
20154 (parallel [(set (match_dup 0)
20155 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20156 (clobber (reg:CC FLAGS_REG))])]
20160 [(match_scratch:SI 2 "r")
20161 (parallel [(set (match_operand:SI 0 "register_operand" "")
20162 (match_operator:SI 3 "arith_or_logical_operator"
20163 [(match_operand:SI 1 "memory_operand" "")
20165 (clobber (reg:CC FLAGS_REG))])]
20166 "! optimize_size && ! TARGET_READ_MODIFY"
20167 [(set (match_dup 2) (match_dup 1))
20168 (parallel [(set (match_dup 0)
20169 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20170 (clobber (reg:CC FLAGS_REG))])]
20173 ; Don't do logical operations with memory outputs
20175 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20176 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20177 ; the same decoder scheduling characteristics as the original.
20180 [(match_scratch:SI 2 "r")
20181 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20182 (match_operator:SI 3 "arith_or_logical_operator"
20184 (match_operand:SI 1 "nonmemory_operand" "")]))
20185 (clobber (reg:CC FLAGS_REG))])]
20186 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20187 [(set (match_dup 2) (match_dup 0))
20188 (parallel [(set (match_dup 2)
20189 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20190 (clobber (reg:CC FLAGS_REG))])
20191 (set (match_dup 0) (match_dup 2))]
20195 [(match_scratch:SI 2 "r")
20196 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20197 (match_operator:SI 3 "arith_or_logical_operator"
20198 [(match_operand:SI 1 "nonmemory_operand" "")
20200 (clobber (reg:CC FLAGS_REG))])]
20201 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20202 [(set (match_dup 2) (match_dup 0))
20203 (parallel [(set (match_dup 2)
20204 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20205 (clobber (reg:CC FLAGS_REG))])
20206 (set (match_dup 0) (match_dup 2))]
20209 ;; Attempt to always use XOR for zeroing registers.
20211 [(set (match_operand 0 "register_operand" "")
20212 (match_operand 1 "const0_operand" ""))]
20213 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20214 && (! TARGET_USE_MOV0 || optimize_size)
20215 && GENERAL_REG_P (operands[0])
20216 && peep2_regno_dead_p (0, FLAGS_REG)"
20217 [(parallel [(set (match_dup 0) (const_int 0))
20218 (clobber (reg:CC FLAGS_REG))])]
20220 operands[0] = gen_lowpart (word_mode, operands[0]);
20224 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20226 "(GET_MODE (operands[0]) == QImode
20227 || GET_MODE (operands[0]) == HImode)
20228 && (! TARGET_USE_MOV0 || optimize_size)
20229 && peep2_regno_dead_p (0, FLAGS_REG)"
20230 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20231 (clobber (reg:CC FLAGS_REG))])])
20233 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20235 [(set (match_operand 0 "register_operand" "")
20237 "(GET_MODE (operands[0]) == HImode
20238 || GET_MODE (operands[0]) == SImode
20239 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20240 && (optimize_size || TARGET_PENTIUM)
20241 && peep2_regno_dead_p (0, FLAGS_REG)"
20242 [(parallel [(set (match_dup 0) (const_int -1))
20243 (clobber (reg:CC FLAGS_REG))])]
20244 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20247 ;; Attempt to convert simple leas to adds. These can be created by
20250 [(set (match_operand:SI 0 "register_operand" "")
20251 (plus:SI (match_dup 0)
20252 (match_operand:SI 1 "nonmemory_operand" "")))]
20253 "peep2_regno_dead_p (0, FLAGS_REG)"
20254 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20255 (clobber (reg:CC FLAGS_REG))])]
20259 [(set (match_operand:SI 0 "register_operand" "")
20260 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20261 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20262 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20263 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20264 (clobber (reg:CC FLAGS_REG))])]
20265 "operands[2] = gen_lowpart (SImode, operands[2]);")
20268 [(set (match_operand:DI 0 "register_operand" "")
20269 (plus:DI (match_dup 0)
20270 (match_operand:DI 1 "x86_64_general_operand" "")))]
20271 "peep2_regno_dead_p (0, FLAGS_REG)"
20272 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20273 (clobber (reg:CC FLAGS_REG))])]
20277 [(set (match_operand:SI 0 "register_operand" "")
20278 (mult:SI (match_dup 0)
20279 (match_operand:SI 1 "const_int_operand" "")))]
20280 "exact_log2 (INTVAL (operands[1])) >= 0
20281 && peep2_regno_dead_p (0, FLAGS_REG)"
20282 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20283 (clobber (reg:CC FLAGS_REG))])]
20284 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20287 [(set (match_operand:DI 0 "register_operand" "")
20288 (mult:DI (match_dup 0)
20289 (match_operand:DI 1 "const_int_operand" "")))]
20290 "exact_log2 (INTVAL (operands[1])) >= 0
20291 && peep2_regno_dead_p (0, FLAGS_REG)"
20292 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20293 (clobber (reg:CC FLAGS_REG))])]
20294 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20297 [(set (match_operand:SI 0 "register_operand" "")
20298 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20299 (match_operand:DI 2 "const_int_operand" "")) 0))]
20300 "exact_log2 (INTVAL (operands[2])) >= 0
20301 && REGNO (operands[0]) == REGNO (operands[1])
20302 && peep2_regno_dead_p (0, FLAGS_REG)"
20303 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20304 (clobber (reg:CC FLAGS_REG))])]
20305 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20307 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20308 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20309 ;; many CPUs it is also faster, since special hardware to avoid esp
20310 ;; dependencies is present.
20312 ;; While some of these conversions may be done using splitters, we use peepholes
20313 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20315 ;; Convert prologue esp subtractions to push.
20316 ;; We need register to push. In order to keep verify_flow_info happy we have
20318 ;; - use scratch and clobber it in order to avoid dependencies
20319 ;; - use already live register
20320 ;; We can't use the second way right now, since there is no reliable way how to
20321 ;; verify that given register is live. First choice will also most likely in
20322 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20323 ;; call clobbered registers are dead. We may want to use base pointer as an
20324 ;; alternative when no register is available later.
20327 [(match_scratch:SI 0 "r")
20328 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20329 (clobber (reg:CC FLAGS_REG))
20330 (clobber (mem:BLK (scratch)))])]
20331 "optimize_size || !TARGET_SUB_ESP_4"
20332 [(clobber (match_dup 0))
20333 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20334 (clobber (mem:BLK (scratch)))])])
20337 [(match_scratch:SI 0 "r")
20338 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20339 (clobber (reg:CC FLAGS_REG))
20340 (clobber (mem:BLK (scratch)))])]
20341 "optimize_size || !TARGET_SUB_ESP_8"
20342 [(clobber (match_dup 0))
20343 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20344 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20345 (clobber (mem:BLK (scratch)))])])
20347 ;; Convert esp subtractions to push.
20349 [(match_scratch:SI 0 "r")
20350 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20351 (clobber (reg:CC FLAGS_REG))])]
20352 "optimize_size || !TARGET_SUB_ESP_4"
20353 [(clobber (match_dup 0))
20354 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20357 [(match_scratch:SI 0 "r")
20358 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20359 (clobber (reg:CC FLAGS_REG))])]
20360 "optimize_size || !TARGET_SUB_ESP_8"
20361 [(clobber (match_dup 0))
20362 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20363 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20365 ;; Convert epilogue deallocator to pop.
20367 [(match_scratch:SI 0 "r")
20368 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20369 (clobber (reg:CC FLAGS_REG))
20370 (clobber (mem:BLK (scratch)))])]
20371 "optimize_size || !TARGET_ADD_ESP_4"
20372 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20373 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20374 (clobber (mem:BLK (scratch)))])]
20377 ;; Two pops case is tricky, since pop causes dependency on destination register.
20378 ;; We use two registers if available.
20380 [(match_scratch:SI 0 "r")
20381 (match_scratch:SI 1 "r")
20382 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20383 (clobber (reg:CC FLAGS_REG))
20384 (clobber (mem:BLK (scratch)))])]
20385 "optimize_size || !TARGET_ADD_ESP_8"
20386 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20387 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20388 (clobber (mem:BLK (scratch)))])
20389 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20390 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20394 [(match_scratch:SI 0 "r")
20395 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20396 (clobber (reg:CC FLAGS_REG))
20397 (clobber (mem:BLK (scratch)))])]
20399 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20400 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20401 (clobber (mem:BLK (scratch)))])
20402 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20403 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20406 ;; Convert esp additions to pop.
20408 [(match_scratch:SI 0 "r")
20409 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20410 (clobber (reg:CC FLAGS_REG))])]
20412 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20413 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20416 ;; Two pops case is tricky, since pop causes dependency on destination register.
20417 ;; We use two registers if available.
20419 [(match_scratch:SI 0 "r")
20420 (match_scratch:SI 1 "r")
20421 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20422 (clobber (reg:CC FLAGS_REG))])]
20424 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20425 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20426 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20427 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20431 [(match_scratch:SI 0 "r")
20432 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20433 (clobber (reg:CC FLAGS_REG))])]
20435 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20436 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20437 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20438 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20441 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20442 ;; required and register dies. Similarly for 128 to plus -128.
20444 [(set (match_operand 0 "flags_reg_operand" "")
20445 (match_operator 1 "compare_operator"
20446 [(match_operand 2 "register_operand" "")
20447 (match_operand 3 "const_int_operand" "")]))]
20448 "(INTVAL (operands[3]) == -1
20449 || INTVAL (operands[3]) == 1
20450 || INTVAL (operands[3]) == 128)
20451 && ix86_match_ccmode (insn, CCGCmode)
20452 && peep2_reg_dead_p (1, operands[2])"
20453 [(parallel [(set (match_dup 0)
20454 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20455 (clobber (match_dup 2))])]
20459 [(match_scratch:DI 0 "r")
20460 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20461 (clobber (reg:CC FLAGS_REG))
20462 (clobber (mem:BLK (scratch)))])]
20463 "optimize_size || !TARGET_SUB_ESP_4"
20464 [(clobber (match_dup 0))
20465 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20466 (clobber (mem:BLK (scratch)))])])
20469 [(match_scratch:DI 0 "r")
20470 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20471 (clobber (reg:CC FLAGS_REG))
20472 (clobber (mem:BLK (scratch)))])]
20473 "optimize_size || !TARGET_SUB_ESP_8"
20474 [(clobber (match_dup 0))
20475 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20476 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20477 (clobber (mem:BLK (scratch)))])])
20479 ;; Convert esp subtractions to push.
20481 [(match_scratch:DI 0 "r")
20482 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20483 (clobber (reg:CC FLAGS_REG))])]
20484 "optimize_size || !TARGET_SUB_ESP_4"
20485 [(clobber (match_dup 0))
20486 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20489 [(match_scratch:DI 0 "r")
20490 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20491 (clobber (reg:CC FLAGS_REG))])]
20492 "optimize_size || !TARGET_SUB_ESP_8"
20493 [(clobber (match_dup 0))
20494 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20495 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20497 ;; Convert epilogue deallocator to pop.
20499 [(match_scratch:DI 0 "r")
20500 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20501 (clobber (reg:CC FLAGS_REG))
20502 (clobber (mem:BLK (scratch)))])]
20503 "optimize_size || !TARGET_ADD_ESP_4"
20504 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20505 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20506 (clobber (mem:BLK (scratch)))])]
20509 ;; Two pops case is tricky, since pop causes dependency on destination register.
20510 ;; We use two registers if available.
20512 [(match_scratch:DI 0 "r")
20513 (match_scratch:DI 1 "r")
20514 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20515 (clobber (reg:CC FLAGS_REG))
20516 (clobber (mem:BLK (scratch)))])]
20517 "optimize_size || !TARGET_ADD_ESP_8"
20518 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20519 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20520 (clobber (mem:BLK (scratch)))])
20521 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20522 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20526 [(match_scratch:DI 0 "r")
20527 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20528 (clobber (reg:CC FLAGS_REG))
20529 (clobber (mem:BLK (scratch)))])]
20531 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20532 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20533 (clobber (mem:BLK (scratch)))])
20534 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20535 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20538 ;; Convert esp additions to pop.
20540 [(match_scratch:DI 0 "r")
20541 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20542 (clobber (reg:CC FLAGS_REG))])]
20544 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20545 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20548 ;; Two pops case is tricky, since pop causes dependency on destination register.
20549 ;; We use two registers if available.
20551 [(match_scratch:DI 0 "r")
20552 (match_scratch:DI 1 "r")
20553 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20554 (clobber (reg:CC FLAGS_REG))])]
20556 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20557 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20558 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20559 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20563 [(match_scratch:DI 0 "r")
20564 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20565 (clobber (reg:CC FLAGS_REG))])]
20567 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20568 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20569 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20570 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20573 ;; Convert imul by three, five and nine into lea
20576 [(set (match_operand:SI 0 "register_operand" "")
20577 (mult:SI (match_operand:SI 1 "register_operand" "")
20578 (match_operand:SI 2 "const_int_operand" "")))
20579 (clobber (reg:CC FLAGS_REG))])]
20580 "INTVAL (operands[2]) == 3
20581 || INTVAL (operands[2]) == 5
20582 || INTVAL (operands[2]) == 9"
20583 [(set (match_dup 0)
20584 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20586 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20590 [(set (match_operand:SI 0 "register_operand" "")
20591 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20592 (match_operand:SI 2 "const_int_operand" "")))
20593 (clobber (reg:CC FLAGS_REG))])]
20595 && (INTVAL (operands[2]) == 3
20596 || INTVAL (operands[2]) == 5
20597 || INTVAL (operands[2]) == 9)"
20598 [(set (match_dup 0) (match_dup 1))
20600 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20602 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20606 [(set (match_operand:DI 0 "register_operand" "")
20607 (mult:DI (match_operand:DI 1 "register_operand" "")
20608 (match_operand:DI 2 "const_int_operand" "")))
20609 (clobber (reg:CC FLAGS_REG))])]
20611 && (INTVAL (operands[2]) == 3
20612 || INTVAL (operands[2]) == 5
20613 || INTVAL (operands[2]) == 9)"
20614 [(set (match_dup 0)
20615 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20617 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20621 [(set (match_operand:DI 0 "register_operand" "")
20622 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20623 (match_operand:DI 2 "const_int_operand" "")))
20624 (clobber (reg:CC FLAGS_REG))])]
20627 && (INTVAL (operands[2]) == 3
20628 || INTVAL (operands[2]) == 5
20629 || INTVAL (operands[2]) == 9)"
20630 [(set (match_dup 0) (match_dup 1))
20632 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20634 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20636 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20637 ;; imul $32bit_imm, reg, reg is direct decoded.
20639 [(match_scratch:DI 3 "r")
20640 (parallel [(set (match_operand:DI 0 "register_operand" "")
20641 (mult:DI (match_operand:DI 1 "memory_operand" "")
20642 (match_operand:DI 2 "immediate_operand" "")))
20643 (clobber (reg:CC FLAGS_REG))])]
20644 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20645 && !satisfies_constraint_K (operands[2])"
20646 [(set (match_dup 3) (match_dup 1))
20647 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20648 (clobber (reg:CC FLAGS_REG))])]
20652 [(match_scratch:SI 3 "r")
20653 (parallel [(set (match_operand:SI 0 "register_operand" "")
20654 (mult:SI (match_operand:SI 1 "memory_operand" "")
20655 (match_operand:SI 2 "immediate_operand" "")))
20656 (clobber (reg:CC FLAGS_REG))])]
20657 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20658 && !satisfies_constraint_K (operands[2])"
20659 [(set (match_dup 3) (match_dup 1))
20660 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20661 (clobber (reg:CC FLAGS_REG))])]
20665 [(match_scratch:SI 3 "r")
20666 (parallel [(set (match_operand:DI 0 "register_operand" "")
20668 (mult:SI (match_operand:SI 1 "memory_operand" "")
20669 (match_operand:SI 2 "immediate_operand" ""))))
20670 (clobber (reg:CC FLAGS_REG))])]
20671 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20672 && !satisfies_constraint_K (operands[2])"
20673 [(set (match_dup 3) (match_dup 1))
20674 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20675 (clobber (reg:CC FLAGS_REG))])]
20678 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20679 ;; Convert it into imul reg, reg
20680 ;; It would be better to force assembler to encode instruction using long
20681 ;; immediate, but there is apparently no way to do so.
20683 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20684 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20685 (match_operand:DI 2 "const_int_operand" "")))
20686 (clobber (reg:CC FLAGS_REG))])
20687 (match_scratch:DI 3 "r")]
20688 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20689 && satisfies_constraint_K (operands[2])"
20690 [(set (match_dup 3) (match_dup 2))
20691 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20692 (clobber (reg:CC FLAGS_REG))])]
20694 if (!rtx_equal_p (operands[0], operands[1]))
20695 emit_move_insn (operands[0], operands[1]);
20699 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20700 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20701 (match_operand:SI 2 "const_int_operand" "")))
20702 (clobber (reg:CC FLAGS_REG))])
20703 (match_scratch:SI 3 "r")]
20704 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20705 && satisfies_constraint_K (operands[2])"
20706 [(set (match_dup 3) (match_dup 2))
20707 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20708 (clobber (reg:CC FLAGS_REG))])]
20710 if (!rtx_equal_p (operands[0], operands[1]))
20711 emit_move_insn (operands[0], operands[1]);
20715 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20716 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20717 (match_operand:HI 2 "immediate_operand" "")))
20718 (clobber (reg:CC FLAGS_REG))])
20719 (match_scratch:HI 3 "r")]
20720 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20721 [(set (match_dup 3) (match_dup 2))
20722 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20723 (clobber (reg:CC FLAGS_REG))])]
20725 if (!rtx_equal_p (operands[0], operands[1]))
20726 emit_move_insn (operands[0], operands[1]);
20729 ;; After splitting up read-modify operations, array accesses with memory
20730 ;; operands might end up in form:
20732 ;; movl 4(%esp), %edx
20734 ;; instead of pre-splitting:
20736 ;; addl 4(%esp), %eax
20738 ;; movl 4(%esp), %edx
20739 ;; leal (%edx,%eax,4), %eax
20742 [(parallel [(set (match_operand 0 "register_operand" "")
20743 (ashift (match_operand 1 "register_operand" "")
20744 (match_operand 2 "const_int_operand" "")))
20745 (clobber (reg:CC FLAGS_REG))])
20746 (set (match_operand 3 "register_operand")
20747 (match_operand 4 "x86_64_general_operand" ""))
20748 (parallel [(set (match_operand 5 "register_operand" "")
20749 (plus (match_operand 6 "register_operand" "")
20750 (match_operand 7 "register_operand" "")))
20751 (clobber (reg:CC FLAGS_REG))])]
20752 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20753 /* Validate MODE for lea. */
20754 && ((!TARGET_PARTIAL_REG_STALL
20755 && (GET_MODE (operands[0]) == QImode
20756 || GET_MODE (operands[0]) == HImode))
20757 || GET_MODE (operands[0]) == SImode
20758 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20759 /* We reorder load and the shift. */
20760 && !rtx_equal_p (operands[1], operands[3])
20761 && !reg_overlap_mentioned_p (operands[0], operands[4])
20762 /* Last PLUS must consist of operand 0 and 3. */
20763 && !rtx_equal_p (operands[0], operands[3])
20764 && (rtx_equal_p (operands[3], operands[6])
20765 || rtx_equal_p (operands[3], operands[7]))
20766 && (rtx_equal_p (operands[0], operands[6])
20767 || rtx_equal_p (operands[0], operands[7]))
20768 /* The intermediate operand 0 must die or be same as output. */
20769 && (rtx_equal_p (operands[0], operands[5])
20770 || peep2_reg_dead_p (3, operands[0]))"
20771 [(set (match_dup 3) (match_dup 4))
20772 (set (match_dup 0) (match_dup 1))]
20774 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20775 int scale = 1 << INTVAL (operands[2]);
20776 rtx index = gen_lowpart (Pmode, operands[1]);
20777 rtx base = gen_lowpart (Pmode, operands[3]);
20778 rtx dest = gen_lowpart (mode, operands[5]);
20780 operands[1] = gen_rtx_PLUS (Pmode, base,
20781 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20783 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20784 operands[0] = dest;
20787 ;; Call-value patterns last so that the wildcard operand does not
20788 ;; disrupt insn-recog's switch tables.
20790 (define_insn "*call_value_pop_0"
20791 [(set (match_operand 0 "" "")
20792 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20793 (match_operand:SI 2 "" "")))
20794 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20795 (match_operand:SI 3 "immediate_operand" "")))]
20798 if (SIBLING_CALL_P (insn))
20801 return "call\t%P1";
20803 [(set_attr "type" "callv")])
20805 (define_insn "*call_value_pop_1"
20806 [(set (match_operand 0 "" "")
20807 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20808 (match_operand:SI 2 "" "")))
20809 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20810 (match_operand:SI 3 "immediate_operand" "i")))]
20813 if (constant_call_address_operand (operands[1], Pmode))
20815 if (SIBLING_CALL_P (insn))
20818 return "call\t%P1";
20820 if (SIBLING_CALL_P (insn))
20823 return "call\t%A1";
20825 [(set_attr "type" "callv")])
20827 (define_insn "*call_value_0"
20828 [(set (match_operand 0 "" "")
20829 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20830 (match_operand:SI 2 "" "")))]
20833 if (SIBLING_CALL_P (insn))
20836 return "call\t%P1";
20838 [(set_attr "type" "callv")])
20840 (define_insn "*call_value_0_rex64"
20841 [(set (match_operand 0 "" "")
20842 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20843 (match_operand:DI 2 "const_int_operand" "")))]
20846 if (SIBLING_CALL_P (insn))
20849 return "call\t%P1";
20851 [(set_attr "type" "callv")])
20853 (define_insn "*call_value_1"
20854 [(set (match_operand 0 "" "")
20855 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20856 (match_operand:SI 2 "" "")))]
20857 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20859 if (constant_call_address_operand (operands[1], Pmode))
20860 return "call\t%P1";
20861 return "call\t%A1";
20863 [(set_attr "type" "callv")])
20865 (define_insn "*sibcall_value_1"
20866 [(set (match_operand 0 "" "")
20867 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20868 (match_operand:SI 2 "" "")))]
20869 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20871 if (constant_call_address_operand (operands[1], Pmode))
20875 [(set_attr "type" "callv")])
20877 (define_insn "*call_value_1_rex64"
20878 [(set (match_operand 0 "" "")
20879 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20880 (match_operand:DI 2 "" "")))]
20881 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20882 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20884 if (constant_call_address_operand (operands[1], Pmode))
20885 return "call\t%P1";
20886 return "call\t%A1";
20888 [(set_attr "type" "callv")])
20890 (define_insn "*call_value_1_rex64_large"
20891 [(set (match_operand 0 "" "")
20892 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20893 (match_operand:DI 2 "" "")))]
20894 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20896 [(set_attr "type" "callv")])
20898 (define_insn "*sibcall_value_1_rex64"
20899 [(set (match_operand 0 "" "")
20900 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20901 (match_operand:DI 2 "" "")))]
20902 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20904 [(set_attr "type" "callv")])
20906 (define_insn "*sibcall_value_1_rex64_v"
20907 [(set (match_operand 0 "" "")
20908 (call (mem:QI (reg:DI R11_REG))
20909 (match_operand:DI 1 "" "")))]
20910 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20912 [(set_attr "type" "callv")])
20914 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20915 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20916 ;; caught for use by garbage collectors and the like. Using an insn that
20917 ;; maps to SIGILL makes it more likely the program will rightfully die.
20918 ;; Keeping with tradition, "6" is in honor of #UD.
20919 (define_insn "trap"
20920 [(trap_if (const_int 1) (const_int 6))]
20922 { return ASM_SHORT "0x0b0f"; }
20923 [(set_attr "length" "2")])
20925 (define_expand "sse_prologue_save"
20926 [(parallel [(set (match_operand:BLK 0 "" "")
20927 (unspec:BLK [(reg:DI 21)
20934 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20935 (use (match_operand:DI 1 "register_operand" ""))
20936 (use (match_operand:DI 2 "immediate_operand" ""))
20937 (use (label_ref:DI (match_operand 3 "" "")))])]
20941 (define_insn "*sse_prologue_save_insn"
20942 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20943 (match_operand:DI 4 "const_int_operand" "n")))
20944 (unspec:BLK [(reg:DI 21)
20951 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20952 (use (match_operand:DI 1 "register_operand" "r"))
20953 (use (match_operand:DI 2 "const_int_operand" "i"))
20954 (use (label_ref:DI (match_operand 3 "" "X")))]
20956 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20957 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20961 operands[0] = gen_rtx_MEM (Pmode,
20962 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20963 output_asm_insn (\"jmp\\t%A1\", operands);
20964 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20966 operands[4] = adjust_address (operands[0], DImode, i*16);
20967 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20968 PUT_MODE (operands[4], TImode);
20969 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20970 output_asm_insn (\"rex\", operands);
20971 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20973 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20974 CODE_LABEL_NUMBER (operands[3]));
20978 [(set_attr "type" "other")
20979 (set_attr "length_immediate" "0")
20980 (set_attr "length_address" "0")
20981 (set_attr "length" "135")
20982 (set_attr "memory" "store")
20983 (set_attr "modrm" "0")
20984 (set_attr "mode" "DI")])
20986 (define_expand "prefetch"
20987 [(prefetch (match_operand 0 "address_operand" "")
20988 (match_operand:SI 1 "const_int_operand" "")
20989 (match_operand:SI 2 "const_int_operand" ""))]
20990 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20992 int rw = INTVAL (operands[1]);
20993 int locality = INTVAL (operands[2]);
20995 gcc_assert (rw == 0 || rw == 1);
20996 gcc_assert (locality >= 0 && locality <= 3);
20997 gcc_assert (GET_MODE (operands[0]) == Pmode
20998 || GET_MODE (operands[0]) == VOIDmode);
21000 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21001 supported by SSE counterpart or the SSE prefetch is not available
21002 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21004 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21005 operands[2] = GEN_INT (3);
21007 operands[1] = const0_rtx;
21010 (define_insn "*prefetch_sse"
21011 [(prefetch (match_operand:SI 0 "address_operand" "p")
21013 (match_operand:SI 1 "const_int_operand" ""))]
21014 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21016 static const char * const patterns[4] = {
21017 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21020 int locality = INTVAL (operands[1]);
21021 gcc_assert (locality >= 0 && locality <= 3);
21023 return patterns[locality];
21025 [(set_attr "type" "sse")
21026 (set_attr "memory" "none")])
21028 (define_insn "*prefetch_sse_rex"
21029 [(prefetch (match_operand:DI 0 "address_operand" "p")
21031 (match_operand:SI 1 "const_int_operand" ""))]
21032 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21034 static const char * const patterns[4] = {
21035 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21038 int locality = INTVAL (operands[1]);
21039 gcc_assert (locality >= 0 && locality <= 3);
21041 return patterns[locality];
21043 [(set_attr "type" "sse")
21044 (set_attr "memory" "none")])
21046 (define_insn "*prefetch_3dnow"
21047 [(prefetch (match_operand:SI 0 "address_operand" "p")
21048 (match_operand:SI 1 "const_int_operand" "n")
21050 "TARGET_3DNOW && !TARGET_64BIT"
21052 if (INTVAL (operands[1]) == 0)
21053 return "prefetch\t%a0";
21055 return "prefetchw\t%a0";
21057 [(set_attr "type" "mmx")
21058 (set_attr "memory" "none")])
21060 (define_insn "*prefetch_3dnow_rex"
21061 [(prefetch (match_operand:DI 0 "address_operand" "p")
21062 (match_operand:SI 1 "const_int_operand" "n")
21064 "TARGET_3DNOW && TARGET_64BIT"
21066 if (INTVAL (operands[1]) == 0)
21067 return "prefetch\t%a0";
21069 return "prefetchw\t%a0";
21071 [(set_attr "type" "mmx")
21072 (set_attr "memory" "none")])
21074 (define_expand "stack_protect_set"
21075 [(match_operand 0 "memory_operand" "")
21076 (match_operand 1 "memory_operand" "")]
21079 #ifdef TARGET_THREAD_SSP_OFFSET
21081 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21082 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21084 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21085 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21088 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21090 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21095 (define_insn "stack_protect_set_si"
21096 [(set (match_operand:SI 0 "memory_operand" "=m")
21097 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21098 (set (match_scratch:SI 2 "=&r") (const_int 0))
21099 (clobber (reg:CC FLAGS_REG))]
21101 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21102 [(set_attr "type" "multi")])
21104 (define_insn "stack_protect_set_di"
21105 [(set (match_operand:DI 0 "memory_operand" "=m")
21106 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21107 (set (match_scratch:DI 2 "=&r") (const_int 0))
21108 (clobber (reg:CC FLAGS_REG))]
21110 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21111 [(set_attr "type" "multi")])
21113 (define_insn "stack_tls_protect_set_si"
21114 [(set (match_operand:SI 0 "memory_operand" "=m")
21115 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21116 (set (match_scratch:SI 2 "=&r") (const_int 0))
21117 (clobber (reg:CC FLAGS_REG))]
21119 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21120 [(set_attr "type" "multi")])
21122 (define_insn "stack_tls_protect_set_di"
21123 [(set (match_operand:DI 0 "memory_operand" "=m")
21124 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21125 (set (match_scratch:DI 2 "=&r") (const_int 0))
21126 (clobber (reg:CC FLAGS_REG))]
21129 /* The kernel uses a different segment register for performance reasons; a
21130 system call would not have to trash the userspace segment register,
21131 which would be expensive */
21132 if (ix86_cmodel != CM_KERNEL)
21133 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21135 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21137 [(set_attr "type" "multi")])
21139 (define_expand "stack_protect_test"
21140 [(match_operand 0 "memory_operand" "")
21141 (match_operand 1 "memory_operand" "")
21142 (match_operand 2 "" "")]
21145 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21146 ix86_compare_op0 = operands[0];
21147 ix86_compare_op1 = operands[1];
21148 ix86_compare_emitted = flags;
21150 #ifdef TARGET_THREAD_SSP_OFFSET
21152 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21153 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21155 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21156 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21159 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21161 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21163 emit_jump_insn (gen_beq (operands[2]));
21167 (define_insn "stack_protect_test_si"
21168 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21169 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21170 (match_operand:SI 2 "memory_operand" "m")]
21172 (clobber (match_scratch:SI 3 "=&r"))]
21174 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21175 [(set_attr "type" "multi")])
21177 (define_insn "stack_protect_test_di"
21178 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21179 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21180 (match_operand:DI 2 "memory_operand" "m")]
21182 (clobber (match_scratch:DI 3 "=&r"))]
21184 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21185 [(set_attr "type" "multi")])
21187 (define_insn "stack_tls_protect_test_si"
21188 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21189 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21190 (match_operand:SI 2 "const_int_operand" "i")]
21191 UNSPEC_SP_TLS_TEST))
21192 (clobber (match_scratch:SI 3 "=r"))]
21194 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21195 [(set_attr "type" "multi")])
21197 (define_insn "stack_tls_protect_test_di"
21198 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21199 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21200 (match_operand:DI 2 "const_int_operand" "i")]
21201 UNSPEC_SP_TLS_TEST))
21202 (clobber (match_scratch:DI 3 "=r"))]
21205 /* The kernel uses a different segment register for performance reasons; a
21206 system call would not have to trash the userspace segment register,
21207 which would be expensive */
21208 if (ix86_cmodel != CM_KERNEL)
21209 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21211 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21213 [(set_attr "type" "multi")])
21217 (include "sync.md")