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
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 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
88 (UNSPEC_TRUNC_NOOP 29)
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 30)
99 (UNSPEC_NOP 38) ; prevents combiner cleverness
110 ; Generic math support
112 (UNSPEC_IEEE_MIN 51) ; not commutative
113 (UNSPEC_IEEE_MAX 52) ; not commutative
126 (UNSPEC_FRNDINT_FLOOR 70)
127 (UNSPEC_FRNDINT_CEIL 71)
128 (UNSPEC_FRNDINT_TRUNC 72)
129 (UNSPEC_FRNDINT_MASK_PM 73)
130 (UNSPEC_FIST_FLOOR 74)
131 (UNSPEC_FIST_CEIL 75)
133 ; x87 Double output FP
134 (UNSPEC_SINCOS_COS 80)
135 (UNSPEC_SINCOS_SIN 81)
138 (UNSPEC_XTRACT_FRACT 84)
139 (UNSPEC_XTRACT_EXP 85)
140 (UNSPEC_FSCALE_FRACT 86)
141 (UNSPEC_FSCALE_EXP 87)
150 (UNSPEC_SP_TLS_SET 102)
151 (UNSPEC_SP_TLS_TEST 103)
160 [(UNSPECV_BLOCKAGE 0)
161 (UNSPECV_STACK_PROBE 1)
170 (UNSPECV_CMPXCHG_1 10)
171 (UNSPECV_CMPXCHG_2 11)
176 ;; Registers by name.
188 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
191 ;; In C guard expressions, put expressions which may be compile-time
192 ;; constants first. This allows for better optimization. For
193 ;; example, write "TARGET_64BIT && reload_completed", not
194 ;; "reload_completed && TARGET_64BIT".
197 ;; Processor type. This attribute must exactly match the processor_type
198 ;; enumeration in i386.h.
199 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
200 (const (symbol_ref "ix86_tune")))
202 ;; A basic instruction type. Refinements due to arguments to be
203 ;; provided in other attributes.
206 alu,alu1,negnot,imov,imovx,lea,
207 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
208 icmp,test,ibr,setcc,icmov,
209 push,pop,call,callv,leave,
211 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
212 sselog,sselog1,sseiadd,sseishft,sseimul,
213 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
214 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
215 (const_string "other"))
217 ;; Main data type used by the insn
219 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
220 (const_string "unknown"))
222 ;; The CPU unit operations uses.
223 (define_attr "unit" "integer,i387,sse,mmx,unknown"
224 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
225 (const_string "i387")
226 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
227 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
229 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
231 (eq_attr "type" "other")
232 (const_string "unknown")]
233 (const_string "integer")))
235 ;; The (bounding maximum) length of an instruction immediate.
236 (define_attr "length_immediate" ""
237 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
239 (eq_attr "unit" "i387,sse,mmx")
241 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
243 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
244 (eq_attr "type" "imov,test")
245 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
246 (eq_attr "type" "call")
247 (if_then_else (match_operand 0 "constant_call_address_operand" "")
250 (eq_attr "type" "callv")
251 (if_then_else (match_operand 1 "constant_call_address_operand" "")
254 ;; We don't know the size before shorten_branches. Expect
255 ;; the instruction to fit for better scheduling.
256 (eq_attr "type" "ibr")
259 (symbol_ref "/* Update immediate_length and other attributes! */
260 gcc_unreachable (),1")))
262 ;; The (bounding maximum) length of an instruction address.
263 (define_attr "length_address" ""
264 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
266 (and (eq_attr "type" "call")
267 (match_operand 0 "constant_call_address_operand" ""))
269 (and (eq_attr "type" "callv")
270 (match_operand 1 "constant_call_address_operand" ""))
273 (symbol_ref "ix86_attr_length_address_default (insn)")))
275 ;; Set when length prefix is used.
276 (define_attr "prefix_data16" ""
277 (if_then_else (ior (eq_attr "mode" "HI")
278 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
282 ;; Set when string REP prefix is used.
283 (define_attr "prefix_rep" ""
284 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
288 ;; Set when 0f opcode prefix is used.
289 (define_attr "prefix_0f" ""
291 (ior (eq_attr "type" "imovx,setcc,icmov")
292 (eq_attr "unit" "sse,mmx"))
296 ;; Set when REX opcode prefix is used.
297 (define_attr "prefix_rex" ""
298 (cond [(and (eq_attr "mode" "DI")
299 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
301 (and (eq_attr "mode" "QI")
302 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
305 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
311 ;; Set when modrm byte is used.
312 (define_attr "modrm" ""
313 (cond [(eq_attr "type" "str,cld,leave")
315 (eq_attr "unit" "i387")
317 (and (eq_attr "type" "incdec")
318 (ior (match_operand:SI 1 "register_operand" "")
319 (match_operand:HI 1 "register_operand" "")))
321 (and (eq_attr "type" "push")
322 (not (match_operand 1 "memory_operand" "")))
324 (and (eq_attr "type" "pop")
325 (not (match_operand 0 "memory_operand" "")))
327 (and (eq_attr "type" "imov")
328 (ior (and (match_operand 0 "register_operand" "")
329 (match_operand 1 "immediate_operand" ""))
330 (ior (and (match_operand 0 "ax_reg_operand" "")
331 (match_operand 1 "memory_displacement_only_operand" ""))
332 (and (match_operand 0 "memory_displacement_only_operand" "")
333 (match_operand 1 "ax_reg_operand" "")))))
335 (and (eq_attr "type" "call")
336 (match_operand 0 "constant_call_address_operand" ""))
338 (and (eq_attr "type" "callv")
339 (match_operand 1 "constant_call_address_operand" ""))
344 ;; The (bounding maximum) length of an instruction in bytes.
345 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
346 ;; Later we may want to split them and compute proper length as for
348 (define_attr "length" ""
349 (cond [(eq_attr "type" "other,multi,fistp,frndint")
351 (eq_attr "type" "fcmp")
353 (eq_attr "unit" "i387")
355 (plus (attr "prefix_data16")
356 (attr "length_address")))]
357 (plus (plus (attr "modrm")
358 (plus (attr "prefix_0f")
359 (plus (attr "prefix_rex")
361 (plus (attr "prefix_rep")
362 (plus (attr "prefix_data16")
363 (plus (attr "length_immediate")
364 (attr "length_address")))))))
366 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
367 ;; `store' if there is a simple memory reference therein, or `unknown'
368 ;; if the instruction is complex.
370 (define_attr "memory" "none,load,store,both,unknown"
371 (cond [(eq_attr "type" "other,multi,str")
372 (const_string "unknown")
373 (eq_attr "type" "lea,fcmov,fpspc,cld")
374 (const_string "none")
375 (eq_attr "type" "fistp,leave")
376 (const_string "both")
377 (eq_attr "type" "frndint")
378 (const_string "load")
379 (eq_attr "type" "push")
380 (if_then_else (match_operand 1 "memory_operand" "")
381 (const_string "both")
382 (const_string "store"))
383 (eq_attr "type" "pop")
384 (if_then_else (match_operand 0 "memory_operand" "")
385 (const_string "both")
386 (const_string "load"))
387 (eq_attr "type" "setcc")
388 (if_then_else (match_operand 0 "memory_operand" "")
389 (const_string "store")
390 (const_string "none"))
391 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
392 (if_then_else (ior (match_operand 0 "memory_operand" "")
393 (match_operand 1 "memory_operand" ""))
394 (const_string "load")
395 (const_string "none"))
396 (eq_attr "type" "ibr")
397 (if_then_else (match_operand 0 "memory_operand" "")
398 (const_string "load")
399 (const_string "none"))
400 (eq_attr "type" "call")
401 (if_then_else (match_operand 0 "constant_call_address_operand" "")
402 (const_string "none")
403 (const_string "load"))
404 (eq_attr "type" "callv")
405 (if_then_else (match_operand 1 "constant_call_address_operand" "")
406 (const_string "none")
407 (const_string "load"))
408 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
409 (match_operand 1 "memory_operand" ""))
410 (const_string "both")
411 (and (match_operand 0 "memory_operand" "")
412 (match_operand 1 "memory_operand" ""))
413 (const_string "both")
414 (match_operand 0 "memory_operand" "")
415 (const_string "store")
416 (match_operand 1 "memory_operand" "")
417 (const_string "load")
419 "!alu1,negnot,ishift1,
420 imov,imovx,icmp,test,
422 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
423 mmx,mmxmov,mmxcmp,mmxcvt")
424 (match_operand 2 "memory_operand" ""))
425 (const_string "load")
426 (and (eq_attr "type" "icmov")
427 (match_operand 3 "memory_operand" ""))
428 (const_string "load")
430 (const_string "none")))
432 ;; Indicates if an instruction has both an immediate and a displacement.
434 (define_attr "imm_disp" "false,true,unknown"
435 (cond [(eq_attr "type" "other,multi")
436 (const_string "unknown")
437 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
438 (and (match_operand 0 "memory_displacement_operand" "")
439 (match_operand 1 "immediate_operand" "")))
440 (const_string "true")
441 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
442 (and (match_operand 0 "memory_displacement_operand" "")
443 (match_operand 2 "immediate_operand" "")))
444 (const_string "true")
446 (const_string "false")))
448 ;; Indicates if an FP operation has an integer source.
450 (define_attr "fp_int_src" "false,true"
451 (const_string "false"))
453 ;; Defines rounding mode of an FP operation.
455 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
456 (const_string "any"))
458 ;; Describe a user's asm statement.
459 (define_asm_attributes
460 [(set_attr "length" "128")
461 (set_attr "type" "multi")])
463 ;; All x87 floating point modes
464 (define_mode_macro X87MODEF [SF DF XF])
466 ;; x87 SFmode and DFMode floating point modes
467 (define_mode_macro X87MODEF12 [SF DF])
469 ;; All integer modes handled by x87 fisttp operator.
470 (define_mode_macro X87MODEI [HI SI DI])
472 ;; All integer modes handled by integer x87 operators.
473 (define_mode_macro X87MODEI12 [HI SI])
475 ;; All SSE floating point modes
476 (define_mode_macro SSEMODEF [SF DF])
478 ;; All integer modes handled by SSE cvtts?2si* operators.
479 (define_mode_macro SSEMODEI24 [SI DI])
481 ;; SSE asm suffix for floating point modes
482 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
485 ;; Scheduling descriptions
487 (include "pentium.md")
490 (include "athlon.md")
494 ;; Operand and operator predicates and constraints
496 (include "predicates.md")
497 (include "constraints.md")
500 ;; Compare instructions.
502 ;; All compare insns have expanders that save the operands away without
503 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
504 ;; after the cmp) will actually emit the cmpM.
506 (define_expand "cmpti"
507 [(set (reg:CC FLAGS_REG)
508 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
509 (match_operand:TI 1 "x86_64_general_operand" "")))]
512 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
513 operands[0] = force_reg (TImode, operands[0]);
514 ix86_compare_op0 = operands[0];
515 ix86_compare_op1 = operands[1];
519 (define_expand "cmpdi"
520 [(set (reg:CC FLAGS_REG)
521 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
522 (match_operand:DI 1 "x86_64_general_operand" "")))]
525 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
526 operands[0] = force_reg (DImode, operands[0]);
527 ix86_compare_op0 = operands[0];
528 ix86_compare_op1 = operands[1];
532 (define_expand "cmpsi"
533 [(set (reg:CC FLAGS_REG)
534 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
535 (match_operand:SI 1 "general_operand" "")))]
538 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
539 operands[0] = force_reg (SImode, operands[0]);
540 ix86_compare_op0 = operands[0];
541 ix86_compare_op1 = operands[1];
545 (define_expand "cmphi"
546 [(set (reg:CC FLAGS_REG)
547 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
548 (match_operand:HI 1 "general_operand" "")))]
551 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
552 operands[0] = force_reg (HImode, operands[0]);
553 ix86_compare_op0 = operands[0];
554 ix86_compare_op1 = operands[1];
558 (define_expand "cmpqi"
559 [(set (reg:CC FLAGS_REG)
560 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
561 (match_operand:QI 1 "general_operand" "")))]
564 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
565 operands[0] = force_reg (QImode, operands[0]);
566 ix86_compare_op0 = operands[0];
567 ix86_compare_op1 = operands[1];
571 (define_insn "cmpdi_ccno_1_rex64"
572 [(set (reg FLAGS_REG)
573 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
574 (match_operand:DI 1 "const0_operand" "n,n")))]
575 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
577 test{q}\t{%0, %0|%0, %0}
578 cmp{q}\t{%1, %0|%0, %1}"
579 [(set_attr "type" "test,icmp")
580 (set_attr "length_immediate" "0,1")
581 (set_attr "mode" "DI")])
583 (define_insn "*cmpdi_minus_1_rex64"
584 [(set (reg FLAGS_REG)
585 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
586 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
588 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
589 "cmp{q}\t{%1, %0|%0, %1}"
590 [(set_attr "type" "icmp")
591 (set_attr "mode" "DI")])
593 (define_expand "cmpdi_1_rex64"
594 [(set (reg:CC FLAGS_REG)
595 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
596 (match_operand:DI 1 "general_operand" "")))]
600 (define_insn "cmpdi_1_insn_rex64"
601 [(set (reg FLAGS_REG)
602 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
603 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
604 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
605 "cmp{q}\t{%1, %0|%0, %1}"
606 [(set_attr "type" "icmp")
607 (set_attr "mode" "DI")])
610 (define_insn "*cmpsi_ccno_1"
611 [(set (reg FLAGS_REG)
612 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
613 (match_operand:SI 1 "const0_operand" "n,n")))]
614 "ix86_match_ccmode (insn, CCNOmode)"
616 test{l}\t{%0, %0|%0, %0}
617 cmp{l}\t{%1, %0|%0, %1}"
618 [(set_attr "type" "test,icmp")
619 (set_attr "length_immediate" "0,1")
620 (set_attr "mode" "SI")])
622 (define_insn "*cmpsi_minus_1"
623 [(set (reg FLAGS_REG)
624 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
625 (match_operand:SI 1 "general_operand" "ri,mr"))
627 "ix86_match_ccmode (insn, CCGOCmode)"
628 "cmp{l}\t{%1, %0|%0, %1}"
629 [(set_attr "type" "icmp")
630 (set_attr "mode" "SI")])
632 (define_expand "cmpsi_1"
633 [(set (reg:CC FLAGS_REG)
634 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
635 (match_operand:SI 1 "general_operand" "ri,mr")))]
639 (define_insn "*cmpsi_1_insn"
640 [(set (reg FLAGS_REG)
641 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
642 (match_operand:SI 1 "general_operand" "ri,mr")))]
643 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
644 && ix86_match_ccmode (insn, CCmode)"
645 "cmp{l}\t{%1, %0|%0, %1}"
646 [(set_attr "type" "icmp")
647 (set_attr "mode" "SI")])
649 (define_insn "*cmphi_ccno_1"
650 [(set (reg FLAGS_REG)
651 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
652 (match_operand:HI 1 "const0_operand" "n,n")))]
653 "ix86_match_ccmode (insn, CCNOmode)"
655 test{w}\t{%0, %0|%0, %0}
656 cmp{w}\t{%1, %0|%0, %1}"
657 [(set_attr "type" "test,icmp")
658 (set_attr "length_immediate" "0,1")
659 (set_attr "mode" "HI")])
661 (define_insn "*cmphi_minus_1"
662 [(set (reg FLAGS_REG)
663 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
664 (match_operand:HI 1 "general_operand" "ri,mr"))
666 "ix86_match_ccmode (insn, CCGOCmode)"
667 "cmp{w}\t{%1, %0|%0, %1}"
668 [(set_attr "type" "icmp")
669 (set_attr "mode" "HI")])
671 (define_insn "*cmphi_1"
672 [(set (reg FLAGS_REG)
673 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
674 (match_operand:HI 1 "general_operand" "ri,mr")))]
675 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
676 && ix86_match_ccmode (insn, CCmode)"
677 "cmp{w}\t{%1, %0|%0, %1}"
678 [(set_attr "type" "icmp")
679 (set_attr "mode" "HI")])
681 (define_insn "*cmpqi_ccno_1"
682 [(set (reg FLAGS_REG)
683 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
684 (match_operand:QI 1 "const0_operand" "n,n")))]
685 "ix86_match_ccmode (insn, CCNOmode)"
687 test{b}\t{%0, %0|%0, %0}
688 cmp{b}\t{$0, %0|%0, 0}"
689 [(set_attr "type" "test,icmp")
690 (set_attr "length_immediate" "0,1")
691 (set_attr "mode" "QI")])
693 (define_insn "*cmpqi_1"
694 [(set (reg FLAGS_REG)
695 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
696 (match_operand:QI 1 "general_operand" "qi,mq")))]
697 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
698 && ix86_match_ccmode (insn, CCmode)"
699 "cmp{b}\t{%1, %0|%0, %1}"
700 [(set_attr "type" "icmp")
701 (set_attr "mode" "QI")])
703 (define_insn "*cmpqi_minus_1"
704 [(set (reg FLAGS_REG)
705 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
706 (match_operand:QI 1 "general_operand" "qi,mq"))
708 "ix86_match_ccmode (insn, CCGOCmode)"
709 "cmp{b}\t{%1, %0|%0, %1}"
710 [(set_attr "type" "icmp")
711 (set_attr "mode" "QI")])
713 (define_insn "*cmpqi_ext_1"
714 [(set (reg FLAGS_REG)
716 (match_operand:QI 0 "general_operand" "Qm")
719 (match_operand 1 "ext_register_operand" "Q")
722 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
723 "cmp{b}\t{%h1, %0|%0, %h1}"
724 [(set_attr "type" "icmp")
725 (set_attr "mode" "QI")])
727 (define_insn "*cmpqi_ext_1_rex64"
728 [(set (reg FLAGS_REG)
730 (match_operand:QI 0 "register_operand" "Q")
733 (match_operand 1 "ext_register_operand" "Q")
736 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
737 "cmp{b}\t{%h1, %0|%0, %h1}"
738 [(set_attr "type" "icmp")
739 (set_attr "mode" "QI")])
741 (define_insn "*cmpqi_ext_2"
742 [(set (reg FLAGS_REG)
746 (match_operand 0 "ext_register_operand" "Q")
749 (match_operand:QI 1 "const0_operand" "n")))]
750 "ix86_match_ccmode (insn, CCNOmode)"
752 [(set_attr "type" "test")
753 (set_attr "length_immediate" "0")
754 (set_attr "mode" "QI")])
756 (define_expand "cmpqi_ext_3"
757 [(set (reg:CC FLAGS_REG)
761 (match_operand 0 "ext_register_operand" "")
764 (match_operand:QI 1 "general_operand" "")))]
768 (define_insn "cmpqi_ext_3_insn"
769 [(set (reg FLAGS_REG)
773 (match_operand 0 "ext_register_operand" "Q")
776 (match_operand:QI 1 "general_operand" "Qmn")))]
777 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
778 "cmp{b}\t{%1, %h0|%h0, %1}"
779 [(set_attr "type" "icmp")
780 (set_attr "mode" "QI")])
782 (define_insn "cmpqi_ext_3_insn_rex64"
783 [(set (reg FLAGS_REG)
787 (match_operand 0 "ext_register_operand" "Q")
790 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
791 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
792 "cmp{b}\t{%1, %h0|%h0, %1}"
793 [(set_attr "type" "icmp")
794 (set_attr "mode" "QI")])
796 (define_insn "*cmpqi_ext_4"
797 [(set (reg FLAGS_REG)
801 (match_operand 0 "ext_register_operand" "Q")
806 (match_operand 1 "ext_register_operand" "Q")
809 "ix86_match_ccmode (insn, CCmode)"
810 "cmp{b}\t{%h1, %h0|%h0, %h1}"
811 [(set_attr "type" "icmp")
812 (set_attr "mode" "QI")])
814 ;; These implement float point compares.
815 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
816 ;; which would allow mix and match FP modes on the compares. Which is what
817 ;; the old patterns did, but with many more of them.
819 (define_expand "cmpxf"
820 [(set (reg:CC FLAGS_REG)
821 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
822 (match_operand:XF 1 "nonmemory_operand" "")))]
825 ix86_compare_op0 = operands[0];
826 ix86_compare_op1 = operands[1];
830 (define_expand "cmpdf"
831 [(set (reg:CC FLAGS_REG)
832 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
833 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
834 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
836 ix86_compare_op0 = operands[0];
837 ix86_compare_op1 = operands[1];
841 (define_expand "cmpsf"
842 [(set (reg:CC FLAGS_REG)
843 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
844 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
845 "TARGET_80387 || TARGET_SSE_MATH"
847 ix86_compare_op0 = operands[0];
848 ix86_compare_op1 = operands[1];
852 ;; FP compares, step 1:
853 ;; Set the FP condition codes.
855 ;; CCFPmode compare with exceptions
856 ;; CCFPUmode compare with no exceptions
858 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
859 ;; used to manage the reg stack popping would not be preserved.
861 (define_insn "*cmpfp_0"
862 [(set (match_operand:HI 0 "register_operand" "=a")
865 (match_operand 1 "register_operand" "f")
866 (match_operand 2 "const0_operand" "X"))]
869 && FLOAT_MODE_P (GET_MODE (operands[1]))
870 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
871 "* return output_fp_compare (insn, operands, 0, 0);"
872 [(set_attr "type" "multi")
873 (set_attr "unit" "i387")
875 (cond [(match_operand:SF 1 "" "")
877 (match_operand:DF 1 "" "")
880 (const_string "XF")))])
882 (define_insn "*cmpfp_sf"
883 [(set (match_operand:HI 0 "register_operand" "=a")
886 (match_operand:SF 1 "register_operand" "f")
887 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
890 "* return output_fp_compare (insn, operands, 0, 0);"
891 [(set_attr "type" "multi")
892 (set_attr "unit" "i387")
893 (set_attr "mode" "SF")])
895 (define_insn "*cmpfp_df"
896 [(set (match_operand:HI 0 "register_operand" "=a")
899 (match_operand:DF 1 "register_operand" "f")
900 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
903 "* return output_fp_compare (insn, operands, 0, 0);"
904 [(set_attr "type" "multi")
905 (set_attr "unit" "i387")
906 (set_attr "mode" "DF")])
908 (define_insn "*cmpfp_xf"
909 [(set (match_operand:HI 0 "register_operand" "=a")
912 (match_operand:XF 1 "register_operand" "f")
913 (match_operand:XF 2 "register_operand" "f"))]
916 "* return output_fp_compare (insn, operands, 0, 0);"
917 [(set_attr "type" "multi")
918 (set_attr "unit" "i387")
919 (set_attr "mode" "XF")])
921 (define_insn "*cmpfp_u"
922 [(set (match_operand:HI 0 "register_operand" "=a")
925 (match_operand 1 "register_operand" "f")
926 (match_operand 2 "register_operand" "f"))]
929 && FLOAT_MODE_P (GET_MODE (operands[1]))
930 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
931 "* return output_fp_compare (insn, operands, 0, 1);"
932 [(set_attr "type" "multi")
933 (set_attr "unit" "i387")
935 (cond [(match_operand:SF 1 "" "")
937 (match_operand:DF 1 "" "")
940 (const_string "XF")))])
942 (define_insn "*cmpfp_<mode>"
943 [(set (match_operand:HI 0 "register_operand" "=a")
946 (match_operand 1 "register_operand" "f")
947 (match_operator 3 "float_operator"
948 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
950 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
951 && FLOAT_MODE_P (GET_MODE (operands[1]))
952 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
953 "* return output_fp_compare (insn, operands, 0, 0);"
954 [(set_attr "type" "multi")
955 (set_attr "unit" "i387")
956 (set_attr "fp_int_src" "true")
957 (set_attr "mode" "<MODE>")])
959 ;; FP compares, step 2
960 ;; Move the fpsw to ax.
962 (define_insn "x86_fnstsw_1"
963 [(set (match_operand:HI 0 "register_operand" "=a")
964 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
967 [(set_attr "length" "2")
968 (set_attr "mode" "SI")
969 (set_attr "unit" "i387")])
971 ;; FP compares, step 3
972 ;; Get ax into flags, general case.
974 (define_insn "x86_sahf_1"
975 [(set (reg:CC FLAGS_REG)
976 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
979 [(set_attr "length" "1")
980 (set_attr "athlon_decode" "vector")
981 (set_attr "mode" "SI")])
983 ;; Pentium Pro can do steps 1 through 3 in one go.
985 (define_insn "*cmpfp_i_mixed"
986 [(set (reg:CCFP FLAGS_REG)
987 (compare:CCFP (match_operand 0 "register_operand" "f,x")
988 (match_operand 1 "nonimmediate_operand" "f,xm")))]
990 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
991 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
992 "* return output_fp_compare (insn, operands, 1, 0);"
993 [(set_attr "type" "fcmp,ssecomi")
995 (if_then_else (match_operand:SF 1 "" "")
997 (const_string "DF")))
998 (set_attr "athlon_decode" "vector")])
1000 (define_insn "*cmpfp_i_sse"
1001 [(set (reg:CCFP FLAGS_REG)
1002 (compare:CCFP (match_operand 0 "register_operand" "x")
1003 (match_operand 1 "nonimmediate_operand" "xm")))]
1005 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1006 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007 "* return output_fp_compare (insn, operands, 1, 0);"
1008 [(set_attr "type" "ssecomi")
1010 (if_then_else (match_operand:SF 1 "" "")
1012 (const_string "DF")))
1013 (set_attr "athlon_decode" "vector")])
1015 (define_insn "*cmpfp_i_i387"
1016 [(set (reg:CCFP FLAGS_REG)
1017 (compare:CCFP (match_operand 0 "register_operand" "f")
1018 (match_operand 1 "register_operand" "f")))]
1019 "TARGET_80387 && TARGET_CMOVE
1020 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1021 && FLOAT_MODE_P (GET_MODE (operands[0]))
1022 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1023 "* return output_fp_compare (insn, operands, 1, 0);"
1024 [(set_attr "type" "fcmp")
1026 (cond [(match_operand:SF 1 "" "")
1028 (match_operand:DF 1 "" "")
1031 (const_string "XF")))
1032 (set_attr "athlon_decode" "vector")])
1034 (define_insn "*cmpfp_iu_mixed"
1035 [(set (reg:CCFPU FLAGS_REG)
1036 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1037 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1038 "TARGET_MIX_SSE_I387
1039 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1040 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1041 "* return output_fp_compare (insn, operands, 1, 1);"
1042 [(set_attr "type" "fcmp,ssecomi")
1044 (if_then_else (match_operand:SF 1 "" "")
1046 (const_string "DF")))
1047 (set_attr "athlon_decode" "vector")])
1049 (define_insn "*cmpfp_iu_sse"
1050 [(set (reg:CCFPU FLAGS_REG)
1051 (compare:CCFPU (match_operand 0 "register_operand" "x")
1052 (match_operand 1 "nonimmediate_operand" "xm")))]
1054 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1055 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1056 "* return output_fp_compare (insn, operands, 1, 1);"
1057 [(set_attr "type" "ssecomi")
1059 (if_then_else (match_operand:SF 1 "" "")
1061 (const_string "DF")))
1062 (set_attr "athlon_decode" "vector")])
1064 (define_insn "*cmpfp_iu_387"
1065 [(set (reg:CCFPU FLAGS_REG)
1066 (compare:CCFPU (match_operand 0 "register_operand" "f")
1067 (match_operand 1 "register_operand" "f")))]
1068 "TARGET_80387 && TARGET_CMOVE
1069 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1070 && FLOAT_MODE_P (GET_MODE (operands[0]))
1071 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1072 "* return output_fp_compare (insn, operands, 1, 1);"
1073 [(set_attr "type" "fcmp")
1075 (cond [(match_operand:SF 1 "" "")
1077 (match_operand:DF 1 "" "")
1080 (const_string "XF")))
1081 (set_attr "athlon_decode" "vector")])
1083 ;; Move instructions.
1085 ;; General case of fullword move.
1087 (define_expand "movsi"
1088 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1089 (match_operand:SI 1 "general_operand" ""))]
1091 "ix86_expand_move (SImode, operands); DONE;")
1093 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1096 ;; %%% We don't use a post-inc memory reference because x86 is not a
1097 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1098 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1099 ;; targets without our curiosities, and it is just as easy to represent
1100 ;; this differently.
1102 (define_insn "*pushsi2"
1103 [(set (match_operand:SI 0 "push_operand" "=<")
1104 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1107 [(set_attr "type" "push")
1108 (set_attr "mode" "SI")])
1110 ;; For 64BIT abi we always round up to 8 bytes.
1111 (define_insn "*pushsi2_rex64"
1112 [(set (match_operand:SI 0 "push_operand" "=X")
1113 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1116 [(set_attr "type" "push")
1117 (set_attr "mode" "SI")])
1119 (define_insn "*pushsi2_prologue"
1120 [(set (match_operand:SI 0 "push_operand" "=<")
1121 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1122 (clobber (mem:BLK (scratch)))]
1125 [(set_attr "type" "push")
1126 (set_attr "mode" "SI")])
1128 (define_insn "*popsi1_epilogue"
1129 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1130 (mem:SI (reg:SI SP_REG)))
1131 (set (reg:SI SP_REG)
1132 (plus:SI (reg:SI SP_REG) (const_int 4)))
1133 (clobber (mem:BLK (scratch)))]
1136 [(set_attr "type" "pop")
1137 (set_attr "mode" "SI")])
1139 (define_insn "popsi1"
1140 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1141 (mem:SI (reg:SI SP_REG)))
1142 (set (reg:SI SP_REG)
1143 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1146 [(set_attr "type" "pop")
1147 (set_attr "mode" "SI")])
1149 (define_insn "*movsi_xor"
1150 [(set (match_operand:SI 0 "register_operand" "=r")
1151 (match_operand:SI 1 "const0_operand" "i"))
1152 (clobber (reg:CC FLAGS_REG))]
1153 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1154 "xor{l}\t{%0, %0|%0, %0}"
1155 [(set_attr "type" "alu1")
1156 (set_attr "mode" "SI")
1157 (set_attr "length_immediate" "0")])
1159 (define_insn "*movsi_or"
1160 [(set (match_operand:SI 0 "register_operand" "=r")
1161 (match_operand:SI 1 "immediate_operand" "i"))
1162 (clobber (reg:CC FLAGS_REG))]
1164 && operands[1] == constm1_rtx
1165 && (TARGET_PENTIUM || optimize_size)"
1167 operands[1] = constm1_rtx;
1168 return "or{l}\t{%1, %0|%0, %1}";
1170 [(set_attr "type" "alu1")
1171 (set_attr "mode" "SI")
1172 (set_attr "length_immediate" "1")])
1174 (define_insn "*movsi_1"
1175 [(set (match_operand:SI 0 "nonimmediate_operand"
1176 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1177 (match_operand:SI 1 "general_operand"
1178 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1179 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1181 switch (get_attr_type (insn))
1184 if (get_attr_mode (insn) == MODE_TI)
1185 return "pxor\t%0, %0";
1186 return "xorps\t%0, %0";
1189 switch (get_attr_mode (insn))
1192 return "movdqa\t{%1, %0|%0, %1}";
1194 return "movaps\t{%1, %0|%0, %1}";
1196 return "movd\t{%1, %0|%0, %1}";
1198 return "movss\t{%1, %0|%0, %1}";
1204 return "pxor\t%0, %0";
1207 if (get_attr_mode (insn) == MODE_DI)
1208 return "movq\t{%1, %0|%0, %1}";
1209 return "movd\t{%1, %0|%0, %1}";
1212 return "lea{l}\t{%1, %0|%0, %1}";
1215 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1216 return "mov{l}\t{%1, %0|%0, %1}";
1220 (cond [(eq_attr "alternative" "2")
1221 (const_string "mmxadd")
1222 (eq_attr "alternative" "3,4,5")
1223 (const_string "mmxmov")
1224 (eq_attr "alternative" "6")
1225 (const_string "sselog1")
1226 (eq_attr "alternative" "7,8,9,10,11")
1227 (const_string "ssemov")
1228 (match_operand:DI 1 "pic_32bit_operand" "")
1229 (const_string "lea")
1231 (const_string "imov")))
1233 (cond [(eq_attr "alternative" "2,3")
1235 (eq_attr "alternative" "6,7")
1237 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1238 (const_string "V4SF")
1239 (const_string "TI"))
1240 (and (eq_attr "alternative" "8,9,10,11")
1241 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1244 (const_string "SI")))])
1246 ;; Stores and loads of ax to arbitrary constant address.
1247 ;; We fake an second form of instruction to force reload to load address
1248 ;; into register when rax is not available
1249 (define_insn "*movabssi_1_rex64"
1250 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1251 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1252 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1254 movabs{l}\t{%1, %P0|%P0, %1}
1255 mov{l}\t{%1, %a0|%a0, %1}"
1256 [(set_attr "type" "imov")
1257 (set_attr "modrm" "0,*")
1258 (set_attr "length_address" "8,0")
1259 (set_attr "length_immediate" "0,*")
1260 (set_attr "memory" "store")
1261 (set_attr "mode" "SI")])
1263 (define_insn "*movabssi_2_rex64"
1264 [(set (match_operand:SI 0 "register_operand" "=a,r")
1265 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1266 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1268 movabs{l}\t{%P1, %0|%0, %P1}
1269 mov{l}\t{%a1, %0|%0, %a1}"
1270 [(set_attr "type" "imov")
1271 (set_attr "modrm" "0,*")
1272 (set_attr "length_address" "8,0")
1273 (set_attr "length_immediate" "0")
1274 (set_attr "memory" "load")
1275 (set_attr "mode" "SI")])
1277 (define_insn "*swapsi"
1278 [(set (match_operand:SI 0 "register_operand" "+r")
1279 (match_operand:SI 1 "register_operand" "+r"))
1284 [(set_attr "type" "imov")
1285 (set_attr "mode" "SI")
1286 (set_attr "pent_pair" "np")
1287 (set_attr "athlon_decode" "vector")])
1289 (define_expand "movhi"
1290 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1291 (match_operand:HI 1 "general_operand" ""))]
1293 "ix86_expand_move (HImode, operands); DONE;")
1295 (define_insn "*pushhi2"
1296 [(set (match_operand:HI 0 "push_operand" "=X")
1297 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1300 [(set_attr "type" "push")
1301 (set_attr "mode" "SI")])
1303 ;; For 64BIT abi we always round up to 8 bytes.
1304 (define_insn "*pushhi2_rex64"
1305 [(set (match_operand:HI 0 "push_operand" "=X")
1306 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1309 [(set_attr "type" "push")
1310 (set_attr "mode" "DI")])
1312 (define_insn "*movhi_1"
1313 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1314 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1315 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1317 switch (get_attr_type (insn))
1320 /* movzwl is faster than movw on p2 due to partial word stalls,
1321 though not as fast as an aligned movl. */
1322 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1324 if (get_attr_mode (insn) == MODE_SI)
1325 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1327 return "mov{w}\t{%1, %0|%0, %1}";
1331 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1332 (const_string "imov")
1333 (and (eq_attr "alternative" "0")
1334 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1336 (eq (symbol_ref "TARGET_HIMODE_MATH")
1338 (const_string "imov")
1339 (and (eq_attr "alternative" "1,2")
1340 (match_operand:HI 1 "aligned_operand" ""))
1341 (const_string "imov")
1342 (and (ne (symbol_ref "TARGET_MOVX")
1344 (eq_attr "alternative" "0,2"))
1345 (const_string "imovx")
1347 (const_string "imov")))
1349 (cond [(eq_attr "type" "imovx")
1351 (and (eq_attr "alternative" "1,2")
1352 (match_operand:HI 1 "aligned_operand" ""))
1354 (and (eq_attr "alternative" "0")
1355 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1357 (eq (symbol_ref "TARGET_HIMODE_MATH")
1361 (const_string "HI")))])
1363 ;; Stores and loads of ax to arbitrary constant address.
1364 ;; We fake an second form of instruction to force reload to load address
1365 ;; into register when rax is not available
1366 (define_insn "*movabshi_1_rex64"
1367 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1368 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1369 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1371 movabs{w}\t{%1, %P0|%P0, %1}
1372 mov{w}\t{%1, %a0|%a0, %1}"
1373 [(set_attr "type" "imov")
1374 (set_attr "modrm" "0,*")
1375 (set_attr "length_address" "8,0")
1376 (set_attr "length_immediate" "0,*")
1377 (set_attr "memory" "store")
1378 (set_attr "mode" "HI")])
1380 (define_insn "*movabshi_2_rex64"
1381 [(set (match_operand:HI 0 "register_operand" "=a,r")
1382 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1383 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1385 movabs{w}\t{%P1, %0|%0, %P1}
1386 mov{w}\t{%a1, %0|%0, %a1}"
1387 [(set_attr "type" "imov")
1388 (set_attr "modrm" "0,*")
1389 (set_attr "length_address" "8,0")
1390 (set_attr "length_immediate" "0")
1391 (set_attr "memory" "load")
1392 (set_attr "mode" "HI")])
1394 (define_insn "*swaphi_1"
1395 [(set (match_operand:HI 0 "register_operand" "+r")
1396 (match_operand:HI 1 "register_operand" "+r"))
1399 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1401 [(set_attr "type" "imov")
1402 (set_attr "mode" "SI")
1403 (set_attr "pent_pair" "np")
1404 (set_attr "athlon_decode" "vector")])
1406 (define_insn "*swaphi_2"
1407 [(set (match_operand:HI 0 "register_operand" "+r")
1408 (match_operand:HI 1 "register_operand" "+r"))
1411 "TARGET_PARTIAL_REG_STALL"
1413 [(set_attr "type" "imov")
1414 (set_attr "mode" "HI")
1415 (set_attr "pent_pair" "np")
1416 (set_attr "athlon_decode" "vector")])
1418 (define_expand "movstricthi"
1419 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1420 (match_operand:HI 1 "general_operand" ""))]
1421 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1423 /* Don't generate memory->memory moves, go through a register */
1424 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1425 operands[1] = force_reg (HImode, operands[1]);
1428 (define_insn "*movstricthi_1"
1429 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1430 (match_operand:HI 1 "general_operand" "rn,m"))]
1431 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1432 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1433 "mov{w}\t{%1, %0|%0, %1}"
1434 [(set_attr "type" "imov")
1435 (set_attr "mode" "HI")])
1437 (define_insn "*movstricthi_xor"
1438 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1439 (match_operand:HI 1 "const0_operand" "i"))
1440 (clobber (reg:CC FLAGS_REG))]
1442 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1443 "xor{w}\t{%0, %0|%0, %0}"
1444 [(set_attr "type" "alu1")
1445 (set_attr "mode" "HI")
1446 (set_attr "length_immediate" "0")])
1448 (define_expand "movqi"
1449 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1450 (match_operand:QI 1 "general_operand" ""))]
1452 "ix86_expand_move (QImode, operands); DONE;")
1454 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1455 ;; "push a byte". But actually we use pushl, which has the effect
1456 ;; of rounding the amount pushed up to a word.
1458 (define_insn "*pushqi2"
1459 [(set (match_operand:QI 0 "push_operand" "=X")
1460 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1463 [(set_attr "type" "push")
1464 (set_attr "mode" "SI")])
1466 ;; For 64BIT abi we always round up to 8 bytes.
1467 (define_insn "*pushqi2_rex64"
1468 [(set (match_operand:QI 0 "push_operand" "=X")
1469 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1472 [(set_attr "type" "push")
1473 (set_attr "mode" "DI")])
1475 ;; Situation is quite tricky about when to choose full sized (SImode) move
1476 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1477 ;; partial register dependency machines (such as AMD Athlon), where QImode
1478 ;; moves issue extra dependency and for partial register stalls machines
1479 ;; that don't use QImode patterns (and QImode move cause stall on the next
1482 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1483 ;; register stall machines with, where we use QImode instructions, since
1484 ;; partial register stall can be caused there. Then we use movzx.
1485 (define_insn "*movqi_1"
1486 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1487 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1488 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1490 switch (get_attr_type (insn))
1493 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1494 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1496 if (get_attr_mode (insn) == MODE_SI)
1497 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1499 return "mov{b}\t{%1, %0|%0, %1}";
1503 (cond [(and (eq_attr "alternative" "5")
1504 (not (match_operand:QI 1 "aligned_operand" "")))
1505 (const_string "imovx")
1506 (ne (symbol_ref "optimize_size") (const_int 0))
1507 (const_string "imov")
1508 (and (eq_attr "alternative" "3")
1509 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1511 (eq (symbol_ref "TARGET_QIMODE_MATH")
1513 (const_string "imov")
1514 (eq_attr "alternative" "3,5")
1515 (const_string "imovx")
1516 (and (ne (symbol_ref "TARGET_MOVX")
1518 (eq_attr "alternative" "2"))
1519 (const_string "imovx")
1521 (const_string "imov")))
1523 (cond [(eq_attr "alternative" "3,4,5")
1525 (eq_attr "alternative" "6")
1527 (eq_attr "type" "imovx")
1529 (and (eq_attr "type" "imov")
1530 (and (eq_attr "alternative" "0,1")
1531 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1533 (and (eq (symbol_ref "optimize_size")
1535 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1538 ;; Avoid partial register stalls when not using QImode arithmetic
1539 (and (eq_attr "type" "imov")
1540 (and (eq_attr "alternative" "0,1")
1541 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1543 (eq (symbol_ref "TARGET_QIMODE_MATH")
1547 (const_string "QI")))])
1549 (define_expand "reload_outqi"
1550 [(parallel [(match_operand:QI 0 "" "=m")
1551 (match_operand:QI 1 "register_operand" "r")
1552 (match_operand:QI 2 "register_operand" "=&q")])]
1556 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1558 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1559 if (! q_regs_operand (op1, QImode))
1561 emit_insn (gen_movqi (op2, op1));
1564 emit_insn (gen_movqi (op0, op1));
1568 (define_insn "*swapqi_1"
1569 [(set (match_operand:QI 0 "register_operand" "+r")
1570 (match_operand:QI 1 "register_operand" "+r"))
1573 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1575 [(set_attr "type" "imov")
1576 (set_attr "mode" "SI")
1577 (set_attr "pent_pair" "np")
1578 (set_attr "athlon_decode" "vector")])
1580 (define_insn "*swapqi_2"
1581 [(set (match_operand:QI 0 "register_operand" "+q")
1582 (match_operand:QI 1 "register_operand" "+q"))
1585 "TARGET_PARTIAL_REG_STALL"
1587 [(set_attr "type" "imov")
1588 (set_attr "mode" "QI")
1589 (set_attr "pent_pair" "np")
1590 (set_attr "athlon_decode" "vector")])
1592 (define_expand "movstrictqi"
1593 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1594 (match_operand:QI 1 "general_operand" ""))]
1595 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1597 /* Don't generate memory->memory moves, go through a register. */
1598 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1599 operands[1] = force_reg (QImode, operands[1]);
1602 (define_insn "*movstrictqi_1"
1603 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1604 (match_operand:QI 1 "general_operand" "*qn,m"))]
1605 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1606 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1607 "mov{b}\t{%1, %0|%0, %1}"
1608 [(set_attr "type" "imov")
1609 (set_attr "mode" "QI")])
1611 (define_insn "*movstrictqi_xor"
1612 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1613 (match_operand:QI 1 "const0_operand" "i"))
1614 (clobber (reg:CC FLAGS_REG))]
1615 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1616 "xor{b}\t{%0, %0|%0, %0}"
1617 [(set_attr "type" "alu1")
1618 (set_attr "mode" "QI")
1619 (set_attr "length_immediate" "0")])
1621 (define_insn "*movsi_extv_1"
1622 [(set (match_operand:SI 0 "register_operand" "=R")
1623 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1627 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1628 [(set_attr "type" "imovx")
1629 (set_attr "mode" "SI")])
1631 (define_insn "*movhi_extv_1"
1632 [(set (match_operand:HI 0 "register_operand" "=R")
1633 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1637 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1638 [(set_attr "type" "imovx")
1639 (set_attr "mode" "SI")])
1641 (define_insn "*movqi_extv_1"
1642 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1643 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1648 switch (get_attr_type (insn))
1651 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1653 return "mov{b}\t{%h1, %0|%0, %h1}";
1657 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1658 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1659 (ne (symbol_ref "TARGET_MOVX")
1661 (const_string "imovx")
1662 (const_string "imov")))
1664 (if_then_else (eq_attr "type" "imovx")
1666 (const_string "QI")))])
1668 (define_insn "*movqi_extv_1_rex64"
1669 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1670 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1675 switch (get_attr_type (insn))
1678 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1680 return "mov{b}\t{%h1, %0|%0, %h1}";
1684 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1685 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1686 (ne (symbol_ref "TARGET_MOVX")
1688 (const_string "imovx")
1689 (const_string "imov")))
1691 (if_then_else (eq_attr "type" "imovx")
1693 (const_string "QI")))])
1695 ;; Stores and loads of ax to arbitrary constant address.
1696 ;; We fake an second form of instruction to force reload to load address
1697 ;; into register when rax is not available
1698 (define_insn "*movabsqi_1_rex64"
1699 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1700 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1701 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1703 movabs{b}\t{%1, %P0|%P0, %1}
1704 mov{b}\t{%1, %a0|%a0, %1}"
1705 [(set_attr "type" "imov")
1706 (set_attr "modrm" "0,*")
1707 (set_attr "length_address" "8,0")
1708 (set_attr "length_immediate" "0,*")
1709 (set_attr "memory" "store")
1710 (set_attr "mode" "QI")])
1712 (define_insn "*movabsqi_2_rex64"
1713 [(set (match_operand:QI 0 "register_operand" "=a,r")
1714 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1715 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1717 movabs{b}\t{%P1, %0|%0, %P1}
1718 mov{b}\t{%a1, %0|%0, %a1}"
1719 [(set_attr "type" "imov")
1720 (set_attr "modrm" "0,*")
1721 (set_attr "length_address" "8,0")
1722 (set_attr "length_immediate" "0")
1723 (set_attr "memory" "load")
1724 (set_attr "mode" "QI")])
1726 (define_insn "*movdi_extzv_1"
1727 [(set (match_operand:DI 0 "register_operand" "=R")
1728 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1732 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1733 [(set_attr "type" "imovx")
1734 (set_attr "mode" "DI")])
1736 (define_insn "*movsi_extzv_1"
1737 [(set (match_operand:SI 0 "register_operand" "=R")
1738 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1742 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1743 [(set_attr "type" "imovx")
1744 (set_attr "mode" "SI")])
1746 (define_insn "*movqi_extzv_2"
1747 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1748 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1753 switch (get_attr_type (insn))
1756 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1758 return "mov{b}\t{%h1, %0|%0, %h1}";
1762 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1763 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1764 (ne (symbol_ref "TARGET_MOVX")
1766 (const_string "imovx")
1767 (const_string "imov")))
1769 (if_then_else (eq_attr "type" "imovx")
1771 (const_string "QI")))])
1773 (define_insn "*movqi_extzv_2_rex64"
1774 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1775 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1780 switch (get_attr_type (insn))
1783 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1785 return "mov{b}\t{%h1, %0|%0, %h1}";
1789 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1790 (ne (symbol_ref "TARGET_MOVX")
1792 (const_string "imovx")
1793 (const_string "imov")))
1795 (if_then_else (eq_attr "type" "imovx")
1797 (const_string "QI")))])
1799 (define_insn "movsi_insv_1"
1800 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1803 (match_operand:SI 1 "general_operand" "Qmn"))]
1805 "mov{b}\t{%b1, %h0|%h0, %b1}"
1806 [(set_attr "type" "imov")
1807 (set_attr "mode" "QI")])
1809 (define_insn "*movsi_insv_1_rex64"
1810 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1813 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1815 "mov{b}\t{%b1, %h0|%h0, %b1}"
1816 [(set_attr "type" "imov")
1817 (set_attr "mode" "QI")])
1819 (define_insn "movdi_insv_1_rex64"
1820 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1823 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1825 "mov{b}\t{%b1, %h0|%h0, %b1}"
1826 [(set_attr "type" "imov")
1827 (set_attr "mode" "QI")])
1829 (define_insn "*movqi_insv_2"
1830 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1833 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1836 "mov{b}\t{%h1, %h0|%h0, %h1}"
1837 [(set_attr "type" "imov")
1838 (set_attr "mode" "QI")])
1840 (define_expand "movdi"
1841 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1842 (match_operand:DI 1 "general_operand" ""))]
1844 "ix86_expand_move (DImode, operands); DONE;")
1846 (define_insn "*pushdi"
1847 [(set (match_operand:DI 0 "push_operand" "=<")
1848 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1852 (define_insn "*pushdi2_rex64"
1853 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1854 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1859 [(set_attr "type" "push,multi")
1860 (set_attr "mode" "DI")])
1862 ;; Convert impossible pushes of immediate to existing instructions.
1863 ;; First try to get scratch register and go through it. In case this
1864 ;; fails, push sign extended lower part first and then overwrite
1865 ;; upper part by 32bit move.
1867 [(match_scratch:DI 2 "r")
1868 (set (match_operand:DI 0 "push_operand" "")
1869 (match_operand:DI 1 "immediate_operand" ""))]
1870 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1871 && !x86_64_immediate_operand (operands[1], DImode)"
1872 [(set (match_dup 2) (match_dup 1))
1873 (set (match_dup 0) (match_dup 2))]
1876 ;; We need to define this as both peepholer and splitter for case
1877 ;; peephole2 pass is not run.
1878 ;; "&& 1" is needed to keep it from matching the previous pattern.
1880 [(set (match_operand:DI 0 "push_operand" "")
1881 (match_operand:DI 1 "immediate_operand" ""))]
1882 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1883 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1884 [(set (match_dup 0) (match_dup 1))
1885 (set (match_dup 2) (match_dup 3))]
1886 "split_di (operands + 1, 1, operands + 2, operands + 3);
1887 operands[1] = gen_lowpart (DImode, operands[2]);
1888 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1893 [(set (match_operand:DI 0 "push_operand" "")
1894 (match_operand:DI 1 "immediate_operand" ""))]
1895 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1896 ? flow2_completed : reload_completed)
1897 && !symbolic_operand (operands[1], DImode)
1898 && !x86_64_immediate_operand (operands[1], DImode)"
1899 [(set (match_dup 0) (match_dup 1))
1900 (set (match_dup 2) (match_dup 3))]
1901 "split_di (operands + 1, 1, operands + 2, operands + 3);
1902 operands[1] = gen_lowpart (DImode, operands[2]);
1903 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1907 (define_insn "*pushdi2_prologue_rex64"
1908 [(set (match_operand:DI 0 "push_operand" "=<")
1909 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1910 (clobber (mem:BLK (scratch)))]
1913 [(set_attr "type" "push")
1914 (set_attr "mode" "DI")])
1916 (define_insn "*popdi1_epilogue_rex64"
1917 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1918 (mem:DI (reg:DI SP_REG)))
1919 (set (reg:DI SP_REG)
1920 (plus:DI (reg:DI SP_REG) (const_int 8)))
1921 (clobber (mem:BLK (scratch)))]
1924 [(set_attr "type" "pop")
1925 (set_attr "mode" "DI")])
1927 (define_insn "popdi1"
1928 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1929 (mem:DI (reg:DI SP_REG)))
1930 (set (reg:DI SP_REG)
1931 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1934 [(set_attr "type" "pop")
1935 (set_attr "mode" "DI")])
1937 (define_insn "*movdi_xor_rex64"
1938 [(set (match_operand:DI 0 "register_operand" "=r")
1939 (match_operand:DI 1 "const0_operand" "i"))
1940 (clobber (reg:CC FLAGS_REG))]
1941 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1942 && reload_completed"
1943 "xor{l}\t{%k0, %k0|%k0, %k0}"
1944 [(set_attr "type" "alu1")
1945 (set_attr "mode" "SI")
1946 (set_attr "length_immediate" "0")])
1948 (define_insn "*movdi_or_rex64"
1949 [(set (match_operand:DI 0 "register_operand" "=r")
1950 (match_operand:DI 1 "const_int_operand" "i"))
1951 (clobber (reg:CC FLAGS_REG))]
1952 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1954 && operands[1] == constm1_rtx"
1956 operands[1] = constm1_rtx;
1957 return "or{q}\t{%1, %0|%0, %1}";
1959 [(set_attr "type" "alu1")
1960 (set_attr "mode" "DI")
1961 (set_attr "length_immediate" "1")])
1963 (define_insn "*movdi_2"
1964 [(set (match_operand:DI 0 "nonimmediate_operand"
1965 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1966 (match_operand:DI 1 "general_operand"
1967 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1968 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1973 movq\t{%1, %0|%0, %1}
1974 movq\t{%1, %0|%0, %1}
1976 movq\t{%1, %0|%0, %1}
1977 movdqa\t{%1, %0|%0, %1}
1978 movq\t{%1, %0|%0, %1}
1980 movlps\t{%1, %0|%0, %1}
1981 movaps\t{%1, %0|%0, %1}
1982 movlps\t{%1, %0|%0, %1}"
1983 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1984 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1987 [(set (match_operand:DI 0 "push_operand" "")
1988 (match_operand:DI 1 "general_operand" ""))]
1989 "!TARGET_64BIT && reload_completed
1990 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1992 "ix86_split_long_move (operands); DONE;")
1994 ;; %%% This multiword shite has got to go.
1996 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1997 (match_operand:DI 1 "general_operand" ""))]
1998 "!TARGET_64BIT && reload_completed
1999 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2000 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2002 "ix86_split_long_move (operands); DONE;")
2004 (define_insn "*movdi_1_rex64"
2005 [(set (match_operand:DI 0 "nonimmediate_operand"
2006 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2007 (match_operand:DI 1 "general_operand"
2008 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2009 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2011 switch (get_attr_type (insn))
2014 if (which_alternative == 13)
2015 return "movq2dq\t{%1, %0|%0, %1}";
2017 return "movdq2q\t{%1, %0|%0, %1}";
2019 if (get_attr_mode (insn) == MODE_TI)
2020 return "movdqa\t{%1, %0|%0, %1}";
2023 /* Moves from and into integer register is done using movd opcode with
2025 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2026 return "movd\t{%1, %0|%0, %1}";
2027 return "movq\t{%1, %0|%0, %1}";
2030 return "pxor\t%0, %0";
2034 return "lea{q}\t{%a1, %0|%0, %a1}";
2036 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2037 if (get_attr_mode (insn) == MODE_SI)
2038 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2039 else if (which_alternative == 2)
2040 return "movabs{q}\t{%1, %0|%0, %1}";
2042 return "mov{q}\t{%1, %0|%0, %1}";
2046 (cond [(eq_attr "alternative" "5")
2047 (const_string "mmxadd")
2048 (eq_attr "alternative" "6,7,8")
2049 (const_string "mmxmov")
2050 (eq_attr "alternative" "9")
2051 (const_string "sselog1")
2052 (eq_attr "alternative" "10,11,12")
2053 (const_string "ssemov")
2054 (eq_attr "alternative" "13,14")
2055 (const_string "ssecvt")
2056 (eq_attr "alternative" "4")
2057 (const_string "multi")
2058 (match_operand:DI 1 "pic_32bit_operand" "")
2059 (const_string "lea")
2061 (const_string "imov")))
2062 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2063 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2064 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2066 ;; Stores and loads of ax to arbitrary constant address.
2067 ;; We fake an second form of instruction to force reload to load address
2068 ;; into register when rax is not available
2069 (define_insn "*movabsdi_1_rex64"
2070 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2071 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2072 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2074 movabs{q}\t{%1, %P0|%P0, %1}
2075 mov{q}\t{%1, %a0|%a0, %1}"
2076 [(set_attr "type" "imov")
2077 (set_attr "modrm" "0,*")
2078 (set_attr "length_address" "8,0")
2079 (set_attr "length_immediate" "0,*")
2080 (set_attr "memory" "store")
2081 (set_attr "mode" "DI")])
2083 (define_insn "*movabsdi_2_rex64"
2084 [(set (match_operand:DI 0 "register_operand" "=a,r")
2085 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2086 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2088 movabs{q}\t{%P1, %0|%0, %P1}
2089 mov{q}\t{%a1, %0|%0, %a1}"
2090 [(set_attr "type" "imov")
2091 (set_attr "modrm" "0,*")
2092 (set_attr "length_address" "8,0")
2093 (set_attr "length_immediate" "0")
2094 (set_attr "memory" "load")
2095 (set_attr "mode" "DI")])
2097 ;; Convert impossible stores of immediate to existing instructions.
2098 ;; First try to get scratch register and go through it. In case this
2099 ;; fails, move by 32bit parts.
2101 [(match_scratch:DI 2 "r")
2102 (set (match_operand:DI 0 "memory_operand" "")
2103 (match_operand:DI 1 "immediate_operand" ""))]
2104 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2105 && !x86_64_immediate_operand (operands[1], DImode)"
2106 [(set (match_dup 2) (match_dup 1))
2107 (set (match_dup 0) (match_dup 2))]
2110 ;; We need to define this as both peepholer and splitter for case
2111 ;; peephole2 pass is not run.
2112 ;; "&& 1" is needed to keep it from matching the previous pattern.
2114 [(set (match_operand:DI 0 "memory_operand" "")
2115 (match_operand:DI 1 "immediate_operand" ""))]
2116 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2117 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2118 [(set (match_dup 2) (match_dup 3))
2119 (set (match_dup 4) (match_dup 5))]
2120 "split_di (operands, 2, operands + 2, operands + 4);")
2123 [(set (match_operand:DI 0 "memory_operand" "")
2124 (match_operand:DI 1 "immediate_operand" ""))]
2125 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2126 ? flow2_completed : reload_completed)
2127 && !symbolic_operand (operands[1], DImode)
2128 && !x86_64_immediate_operand (operands[1], DImode)"
2129 [(set (match_dup 2) (match_dup 3))
2130 (set (match_dup 4) (match_dup 5))]
2131 "split_di (operands, 2, operands + 2, operands + 4);")
2133 (define_insn "*swapdi_rex64"
2134 [(set (match_operand:DI 0 "register_operand" "+r")
2135 (match_operand:DI 1 "register_operand" "+r"))
2140 [(set_attr "type" "imov")
2141 (set_attr "mode" "DI")
2142 (set_attr "pent_pair" "np")
2143 (set_attr "athlon_decode" "vector")])
2145 (define_expand "movti"
2146 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2147 (match_operand:TI 1 "nonimmediate_operand" ""))]
2148 "TARGET_SSE || TARGET_64BIT"
2151 ix86_expand_move (TImode, operands);
2153 ix86_expand_vector_move (TImode, operands);
2157 (define_insn "*movti_internal"
2158 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2159 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2160 "TARGET_SSE && !TARGET_64BIT
2161 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2163 switch (which_alternative)
2166 if (get_attr_mode (insn) == MODE_V4SF)
2167 return "xorps\t%0, %0";
2169 return "pxor\t%0, %0";
2172 if (get_attr_mode (insn) == MODE_V4SF)
2173 return "movaps\t{%1, %0|%0, %1}";
2175 return "movdqa\t{%1, %0|%0, %1}";
2180 [(set_attr "type" "sselog1,ssemov,ssemov")
2182 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2183 (ne (symbol_ref "optimize_size") (const_int 0)))
2184 (const_string "V4SF")
2185 (and (eq_attr "alternative" "2")
2186 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2188 (const_string "V4SF")]
2189 (const_string "TI")))])
2191 (define_insn "*movti_rex64"
2192 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2193 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2195 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2197 switch (which_alternative)
2203 if (get_attr_mode (insn) == MODE_V4SF)
2204 return "xorps\t%0, %0";
2206 return "pxor\t%0, %0";
2209 if (get_attr_mode (insn) == MODE_V4SF)
2210 return "movaps\t{%1, %0|%0, %1}";
2212 return "movdqa\t{%1, %0|%0, %1}";
2217 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2219 (cond [(eq_attr "alternative" "2,3")
2221 (ne (symbol_ref "optimize_size")
2223 (const_string "V4SF")
2224 (const_string "TI"))
2225 (eq_attr "alternative" "4")
2227 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2229 (ne (symbol_ref "optimize_size")
2231 (const_string "V4SF")
2232 (const_string "TI"))]
2233 (const_string "DI")))])
2236 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2237 (match_operand:TI 1 "general_operand" ""))]
2238 "reload_completed && !SSE_REG_P (operands[0])
2239 && !SSE_REG_P (operands[1])"
2241 "ix86_split_long_move (operands); DONE;")
2243 (define_expand "movsf"
2244 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2245 (match_operand:SF 1 "general_operand" ""))]
2247 "ix86_expand_move (SFmode, operands); DONE;")
2249 (define_insn "*pushsf"
2250 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2251 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2254 /* Anything else should be already split before reg-stack. */
2255 gcc_assert (which_alternative == 1);
2256 return "push{l}\t%1";
2258 [(set_attr "type" "multi,push,multi")
2259 (set_attr "unit" "i387,*,*")
2260 (set_attr "mode" "SF,SI,SF")])
2262 (define_insn "*pushsf_rex64"
2263 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2264 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2267 /* Anything else should be already split before reg-stack. */
2268 gcc_assert (which_alternative == 1);
2269 return "push{q}\t%q1";
2271 [(set_attr "type" "multi,push,multi")
2272 (set_attr "unit" "i387,*,*")
2273 (set_attr "mode" "SF,DI,SF")])
2276 [(set (match_operand:SF 0 "push_operand" "")
2277 (match_operand:SF 1 "memory_operand" ""))]
2279 && GET_CODE (operands[1]) == MEM
2280 && constant_pool_reference_p (operands[1])"
2283 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2286 ;; %%% Kill this when call knows how to work this out.
2288 [(set (match_operand:SF 0 "push_operand" "")
2289 (match_operand:SF 1 "any_fp_register_operand" ""))]
2291 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2292 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2295 [(set (match_operand:SF 0 "push_operand" "")
2296 (match_operand:SF 1 "any_fp_register_operand" ""))]
2298 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2299 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2301 (define_insn "*movsf_1"
2302 [(set (match_operand:SF 0 "nonimmediate_operand"
2303 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2304 (match_operand:SF 1 "general_operand"
2305 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2306 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2307 && (reload_in_progress || reload_completed
2308 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2309 || (!TARGET_SSE_MATH && optimize_size
2310 && standard_80387_constant_p (operands[1]))
2311 || GET_CODE (operands[1]) != CONST_DOUBLE
2312 || memory_operand (operands[0], SFmode))"
2314 switch (which_alternative)
2317 return output_387_reg_move (insn, operands);
2320 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2321 return "fstp%z0\t%y0";
2323 return "fst%z0\t%y0";
2326 return standard_80387_constant_opcode (operands[1]);
2330 return "mov{l}\t{%1, %0|%0, %1}";
2332 if (get_attr_mode (insn) == MODE_TI)
2333 return "pxor\t%0, %0";
2335 return "xorps\t%0, %0";
2337 if (get_attr_mode (insn) == MODE_V4SF)
2338 return "movaps\t{%1, %0|%0, %1}";
2340 return "movss\t{%1, %0|%0, %1}";
2343 return "movss\t{%1, %0|%0, %1}";
2347 return "movd\t{%1, %0|%0, %1}";
2350 return "movq\t{%1, %0|%0, %1}";
2356 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2358 (cond [(eq_attr "alternative" "3,4,9,10")
2360 (eq_attr "alternative" "5")
2362 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2364 (ne (symbol_ref "TARGET_SSE2")
2366 (eq (symbol_ref "optimize_size")
2369 (const_string "V4SF"))
2370 /* For architectures resolving dependencies on
2371 whole SSE registers use APS move to break dependency
2372 chains, otherwise use short move to avoid extra work.
2374 Do the same for architectures resolving dependencies on
2375 the parts. While in DF mode it is better to always handle
2376 just register parts, the SF mode is different due to lack
2377 of instructions to load just part of the register. It is
2378 better to maintain the whole registers in single format
2379 to avoid problems on using packed logical operations. */
2380 (eq_attr "alternative" "6")
2382 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2384 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2386 (const_string "V4SF")
2387 (const_string "SF"))
2388 (eq_attr "alternative" "11")
2389 (const_string "DI")]
2390 (const_string "SF")))])
2392 (define_insn "*swapsf"
2393 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2394 (match_operand:SF 1 "fp_register_operand" "+f"))
2397 "reload_completed || TARGET_80387"
2399 if (STACK_TOP_P (operands[0]))
2404 [(set_attr "type" "fxch")
2405 (set_attr "mode" "SF")])
2407 (define_expand "movdf"
2408 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2409 (match_operand:DF 1 "general_operand" ""))]
2411 "ix86_expand_move (DFmode, operands); DONE;")
2413 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2414 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2415 ;; On the average, pushdf using integers can be still shorter. Allow this
2416 ;; pattern for optimize_size too.
2418 (define_insn "*pushdf_nointeger"
2419 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2420 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2421 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2423 /* This insn should be already split before reg-stack. */
2426 [(set_attr "type" "multi")
2427 (set_attr "unit" "i387,*,*,*")
2428 (set_attr "mode" "DF,SI,SI,DF")])
2430 (define_insn "*pushdf_integer"
2431 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2432 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2433 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2435 /* This insn should be already split before reg-stack. */
2438 [(set_attr "type" "multi")
2439 (set_attr "unit" "i387,*,*")
2440 (set_attr "mode" "DF,SI,DF")])
2442 ;; %%% Kill this when call knows how to work this out.
2444 [(set (match_operand:DF 0 "push_operand" "")
2445 (match_operand:DF 1 "any_fp_register_operand" ""))]
2446 "!TARGET_64BIT && reload_completed"
2447 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2448 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2452 [(set (match_operand:DF 0 "push_operand" "")
2453 (match_operand:DF 1 "any_fp_register_operand" ""))]
2454 "TARGET_64BIT && reload_completed"
2455 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2456 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2460 [(set (match_operand:DF 0 "push_operand" "")
2461 (match_operand:DF 1 "general_operand" ""))]
2464 "ix86_split_long_move (operands); DONE;")
2466 ;; Moving is usually shorter when only FP registers are used. This separate
2467 ;; movdf pattern avoids the use of integer registers for FP operations
2468 ;; when optimizing for size.
2470 (define_insn "*movdf_nointeger"
2471 [(set (match_operand:DF 0 "nonimmediate_operand"
2472 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2473 (match_operand:DF 1 "general_operand"
2474 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2475 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2476 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2477 && (reload_in_progress || reload_completed
2478 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2479 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2480 && standard_80387_constant_p (operands[1]))
2481 || GET_CODE (operands[1]) != CONST_DOUBLE
2482 || memory_operand (operands[0], DFmode))"
2484 switch (which_alternative)
2487 return output_387_reg_move (insn, operands);
2490 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2491 return "fstp%z0\t%y0";
2493 return "fst%z0\t%y0";
2496 return standard_80387_constant_opcode (operands[1]);
2502 switch (get_attr_mode (insn))
2505 return "xorps\t%0, %0";
2507 return "xorpd\t%0, %0";
2509 return "pxor\t%0, %0";
2516 switch (get_attr_mode (insn))
2519 return "movaps\t{%1, %0|%0, %1}";
2521 return "movapd\t{%1, %0|%0, %1}";
2523 return "movdqa\t{%1, %0|%0, %1}";
2525 return "movq\t{%1, %0|%0, %1}";
2527 return "movsd\t{%1, %0|%0, %1}";
2529 return "movlpd\t{%1, %0|%0, %1}";
2531 return "movlps\t{%1, %0|%0, %1}";
2540 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2542 (cond [(eq_attr "alternative" "0,1,2")
2544 (eq_attr "alternative" "3,4")
2547 /* For SSE1, we have many fewer alternatives. */
2548 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2549 (cond [(eq_attr "alternative" "5,6")
2550 (const_string "V4SF")
2552 (const_string "V2SF"))
2554 /* xorps is one byte shorter. */
2555 (eq_attr "alternative" "5")
2556 (cond [(ne (symbol_ref "optimize_size")
2558 (const_string "V4SF")
2559 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2563 (const_string "V2DF"))
2565 /* For architectures resolving dependencies on
2566 whole SSE registers use APD move to break dependency
2567 chains, otherwise use short move to avoid extra work.
2569 movaps encodes one byte shorter. */
2570 (eq_attr "alternative" "6")
2572 [(ne (symbol_ref "optimize_size")
2574 (const_string "V4SF")
2575 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2577 (const_string "V2DF")
2579 (const_string "DF"))
2580 /* For architectures resolving dependencies on register
2581 parts we may avoid extra work to zero out upper part
2583 (eq_attr "alternative" "7")
2585 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2587 (const_string "V1DF")
2588 (const_string "DF"))
2590 (const_string "DF")))])
2592 (define_insn "*movdf_integer"
2593 [(set (match_operand:DF 0 "nonimmediate_operand"
2594 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2595 (match_operand:DF 1 "general_operand"
2596 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2597 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2598 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2599 && (reload_in_progress || reload_completed
2600 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2601 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2602 && standard_80387_constant_p (operands[1]))
2603 || GET_CODE (operands[1]) != CONST_DOUBLE
2604 || memory_operand (operands[0], DFmode))"
2606 switch (which_alternative)
2609 return output_387_reg_move (insn, operands);
2612 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2613 return "fstp%z0\t%y0";
2615 return "fst%z0\t%y0";
2618 return standard_80387_constant_opcode (operands[1]);
2625 switch (get_attr_mode (insn))
2628 return "xorps\t%0, %0";
2630 return "xorpd\t%0, %0";
2632 return "pxor\t%0, %0";
2639 switch (get_attr_mode (insn))
2642 return "movaps\t{%1, %0|%0, %1}";
2644 return "movapd\t{%1, %0|%0, %1}";
2646 return "movdqa\t{%1, %0|%0, %1}";
2648 return "movq\t{%1, %0|%0, %1}";
2650 return "movsd\t{%1, %0|%0, %1}";
2652 return "movlpd\t{%1, %0|%0, %1}";
2654 return "movlps\t{%1, %0|%0, %1}";
2663 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2665 (cond [(eq_attr "alternative" "0,1,2")
2667 (eq_attr "alternative" "3,4")
2670 /* For SSE1, we have many fewer alternatives. */
2671 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2672 (cond [(eq_attr "alternative" "5,6")
2673 (const_string "V4SF")
2675 (const_string "V2SF"))
2677 /* xorps is one byte shorter. */
2678 (eq_attr "alternative" "5")
2679 (cond [(ne (symbol_ref "optimize_size")
2681 (const_string "V4SF")
2682 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2686 (const_string "V2DF"))
2688 /* For architectures resolving dependencies on
2689 whole SSE registers use APD move to break dependency
2690 chains, otherwise use short move to avoid extra work.
2692 movaps encodes one byte shorter. */
2693 (eq_attr "alternative" "6")
2695 [(ne (symbol_ref "optimize_size")
2697 (const_string "V4SF")
2698 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2700 (const_string "V2DF")
2702 (const_string "DF"))
2703 /* For architectures resolving dependencies on register
2704 parts we may avoid extra work to zero out upper part
2706 (eq_attr "alternative" "7")
2708 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2710 (const_string "V1DF")
2711 (const_string "DF"))
2713 (const_string "DF")))])
2716 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2717 (match_operand:DF 1 "general_operand" ""))]
2719 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2720 && ! (ANY_FP_REG_P (operands[0]) ||
2721 (GET_CODE (operands[0]) == SUBREG
2722 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2723 && ! (ANY_FP_REG_P (operands[1]) ||
2724 (GET_CODE (operands[1]) == SUBREG
2725 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2727 "ix86_split_long_move (operands); DONE;")
2729 (define_insn "*swapdf"
2730 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2731 (match_operand:DF 1 "fp_register_operand" "+f"))
2734 "reload_completed || TARGET_80387"
2736 if (STACK_TOP_P (operands[0]))
2741 [(set_attr "type" "fxch")
2742 (set_attr "mode" "DF")])
2744 (define_expand "movxf"
2745 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2746 (match_operand:XF 1 "general_operand" ""))]
2748 "ix86_expand_move (XFmode, operands); DONE;")
2750 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2751 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2752 ;; Pushing using integer instructions is longer except for constants
2753 ;; and direct memory references.
2754 ;; (assuming that any given constant is pushed only once, but this ought to be
2755 ;; handled elsewhere).
2757 (define_insn "*pushxf_nointeger"
2758 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2759 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2762 /* This insn should be already split before reg-stack. */
2765 [(set_attr "type" "multi")
2766 (set_attr "unit" "i387,*,*")
2767 (set_attr "mode" "XF,SI,SI")])
2769 (define_insn "*pushxf_integer"
2770 [(set (match_operand:XF 0 "push_operand" "=<,<")
2771 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2774 /* This insn should be already split before reg-stack. */
2777 [(set_attr "type" "multi")
2778 (set_attr "unit" "i387,*")
2779 (set_attr "mode" "XF,SI")])
2782 [(set (match_operand 0 "push_operand" "")
2783 (match_operand 1 "general_operand" ""))]
2785 && (GET_MODE (operands[0]) == XFmode
2786 || GET_MODE (operands[0]) == DFmode)
2787 && !ANY_FP_REG_P (operands[1])"
2789 "ix86_split_long_move (operands); DONE;")
2792 [(set (match_operand:XF 0 "push_operand" "")
2793 (match_operand:XF 1 "any_fp_register_operand" ""))]
2795 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2796 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2797 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2800 [(set (match_operand:XF 0 "push_operand" "")
2801 (match_operand:XF 1 "any_fp_register_operand" ""))]
2803 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2804 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2805 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2807 ;; Do not use integer registers when optimizing for size
2808 (define_insn "*movxf_nointeger"
2809 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2810 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2812 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2813 && (reload_in_progress || reload_completed
2814 || (optimize_size && standard_80387_constant_p (operands[1]))
2815 || GET_CODE (operands[1]) != CONST_DOUBLE
2816 || memory_operand (operands[0], XFmode))"
2818 switch (which_alternative)
2821 return output_387_reg_move (insn, operands);
2824 /* There is no non-popping store to memory for XFmode. So if
2825 we need one, follow the store with a load. */
2826 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2827 return "fstp%z0\t%y0\;fld%z0\t%y0";
2829 return "fstp%z0\t%y0";
2832 return standard_80387_constant_opcode (operands[1]);
2840 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2841 (set_attr "mode" "XF,XF,XF,SI,SI")])
2843 (define_insn "*movxf_integer"
2844 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2845 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2847 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2848 && (reload_in_progress || reload_completed
2849 || (optimize_size && standard_80387_constant_p (operands[1]))
2850 || GET_CODE (operands[1]) != CONST_DOUBLE
2851 || memory_operand (operands[0], XFmode))"
2853 switch (which_alternative)
2856 return output_387_reg_move (insn, operands);
2859 /* There is no non-popping store to memory for XFmode. So if
2860 we need one, follow the store with a load. */
2861 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2862 return "fstp%z0\t%y0\;fld%z0\t%y0";
2864 return "fstp%z0\t%y0";
2867 return standard_80387_constant_opcode (operands[1]);
2876 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2877 (set_attr "mode" "XF,XF,XF,SI,SI")])
2880 [(set (match_operand 0 "nonimmediate_operand" "")
2881 (match_operand 1 "general_operand" ""))]
2883 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2884 && GET_MODE (operands[0]) == XFmode
2885 && ! (ANY_FP_REG_P (operands[0]) ||
2886 (GET_CODE (operands[0]) == SUBREG
2887 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2888 && ! (ANY_FP_REG_P (operands[1]) ||
2889 (GET_CODE (operands[1]) == SUBREG
2890 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2892 "ix86_split_long_move (operands); DONE;")
2895 [(set (match_operand 0 "register_operand" "")
2896 (match_operand 1 "memory_operand" ""))]
2898 && GET_CODE (operands[1]) == MEM
2899 && (GET_MODE (operands[0]) == XFmode
2900 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2901 && constant_pool_reference_p (operands[1])"
2902 [(set (match_dup 0) (match_dup 1))]
2904 rtx c = avoid_constant_pool_reference (operands[1]);
2905 rtx r = operands[0];
2907 if (GET_CODE (r) == SUBREG)
2912 if (!standard_sse_constant_p (c))
2915 else if (FP_REG_P (r))
2917 if (!standard_80387_constant_p (c))
2920 else if (MMX_REG_P (r))
2927 [(set (match_operand 0 "register_operand" "")
2928 (float_extend (match_operand 1 "memory_operand" "")))]
2930 && GET_CODE (operands[1]) == MEM
2931 && (GET_MODE (operands[0]) == XFmode
2932 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2933 && constant_pool_reference_p (operands[1])"
2934 [(set (match_dup 0) (match_dup 1))]
2936 rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
2937 rtx r = operands[0];
2939 if (GET_CODE (r) == SUBREG)
2944 if (!standard_sse_constant_p (c))
2947 else if (FP_REG_P (r))
2949 if (!standard_80387_constant_p (c))
2952 else if (MMX_REG_P (r))
2958 (define_insn "swapxf"
2959 [(set (match_operand:XF 0 "register_operand" "+f")
2960 (match_operand:XF 1 "register_operand" "+f"))
2965 if (STACK_TOP_P (operands[0]))
2970 [(set_attr "type" "fxch")
2971 (set_attr "mode" "XF")])
2973 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2975 [(set (match_operand:X87MODEF 0 "register_operand" "")
2976 (match_operand:X87MODEF 1 "immediate_operand" ""))]
2977 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2978 && (standard_80387_constant_p (operands[1]) == 8
2979 || standard_80387_constant_p (operands[1]) == 9)"
2980 [(set (match_dup 0)(match_dup 1))
2982 (neg:X87MODEF (match_dup 0)))]
2986 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2987 if (real_isnegzero (&r))
2988 operands[1] = CONST0_RTX (<MODE>mode);
2990 operands[1] = CONST1_RTX (<MODE>mode);
2993 (define_expand "movtf"
2994 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2995 (match_operand:TF 1 "nonimmediate_operand" ""))]
2998 ix86_expand_move (TFmode, operands);
3002 (define_insn "*movtf_internal"
3003 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3004 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3006 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3008 switch (which_alternative)
3014 if (get_attr_mode (insn) == MODE_V4SF)
3015 return "xorps\t%0, %0";
3017 return "pxor\t%0, %0";
3020 if (get_attr_mode (insn) == MODE_V4SF)
3021 return "movaps\t{%1, %0|%0, %1}";
3023 return "movdqa\t{%1, %0|%0, %1}";
3028 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3030 (cond [(eq_attr "alternative" "2,3")
3032 (ne (symbol_ref "optimize_size")
3034 (const_string "V4SF")
3035 (const_string "TI"))
3036 (eq_attr "alternative" "4")
3038 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3040 (ne (symbol_ref "optimize_size")
3042 (const_string "V4SF")
3043 (const_string "TI"))]
3044 (const_string "DI")))])
3047 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3048 (match_operand:TF 1 "general_operand" ""))]
3049 "reload_completed && !SSE_REG_P (operands[0])
3050 && !SSE_REG_P (operands[1])"
3052 "ix86_split_long_move (operands); DONE;")
3054 ;; Zero extension instructions
3056 (define_expand "zero_extendhisi2"
3057 [(set (match_operand:SI 0 "register_operand" "")
3058 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3061 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3063 operands[1] = force_reg (HImode, operands[1]);
3064 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3069 (define_insn "zero_extendhisi2_and"
3070 [(set (match_operand:SI 0 "register_operand" "=r")
3071 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3072 (clobber (reg:CC FLAGS_REG))]
3073 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3075 [(set_attr "type" "alu1")
3076 (set_attr "mode" "SI")])
3079 [(set (match_operand:SI 0 "register_operand" "")
3080 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3081 (clobber (reg:CC FLAGS_REG))]
3082 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3083 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3084 (clobber (reg:CC FLAGS_REG))])]
3087 (define_insn "*zero_extendhisi2_movzwl"
3088 [(set (match_operand:SI 0 "register_operand" "=r")
3089 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3090 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3091 "movz{wl|x}\t{%1, %0|%0, %1}"
3092 [(set_attr "type" "imovx")
3093 (set_attr "mode" "SI")])
3095 (define_expand "zero_extendqihi2"
3097 [(set (match_operand:HI 0 "register_operand" "")
3098 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3099 (clobber (reg:CC FLAGS_REG))])]
3103 (define_insn "*zero_extendqihi2_and"
3104 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3105 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3106 (clobber (reg:CC FLAGS_REG))]
3107 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3109 [(set_attr "type" "alu1")
3110 (set_attr "mode" "HI")])
3112 (define_insn "*zero_extendqihi2_movzbw_and"
3113 [(set (match_operand:HI 0 "register_operand" "=r,r")
3114 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3115 (clobber (reg:CC FLAGS_REG))]
3116 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3118 [(set_attr "type" "imovx,alu1")
3119 (set_attr "mode" "HI")])
3121 ; zero extend to SImode here to avoid partial register stalls
3122 (define_insn "*zero_extendqihi2_movzbl"
3123 [(set (match_operand:HI 0 "register_operand" "=r")
3124 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3125 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3126 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3127 [(set_attr "type" "imovx")
3128 (set_attr "mode" "SI")])
3130 ;; For the movzbw case strip only the clobber
3132 [(set (match_operand:HI 0 "register_operand" "")
3133 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3134 (clobber (reg:CC FLAGS_REG))]
3136 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3137 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3138 [(set (match_operand:HI 0 "register_operand" "")
3139 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3141 ;; When source and destination does not overlap, clear destination
3142 ;; first and then do the movb
3144 [(set (match_operand:HI 0 "register_operand" "")
3145 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3146 (clobber (reg:CC FLAGS_REG))]
3148 && ANY_QI_REG_P (operands[0])
3149 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3150 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3151 [(set (match_dup 0) (const_int 0))
3152 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3153 "operands[2] = gen_lowpart (QImode, operands[0]);")
3155 ;; Rest is handled by single and.
3157 [(set (match_operand:HI 0 "register_operand" "")
3158 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3159 (clobber (reg:CC FLAGS_REG))]
3161 && true_regnum (operands[0]) == true_regnum (operands[1])"
3162 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3163 (clobber (reg:CC FLAGS_REG))])]
3166 (define_expand "zero_extendqisi2"
3168 [(set (match_operand:SI 0 "register_operand" "")
3169 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3170 (clobber (reg:CC FLAGS_REG))])]
3174 (define_insn "*zero_extendqisi2_and"
3175 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3176 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3177 (clobber (reg:CC FLAGS_REG))]
3178 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3180 [(set_attr "type" "alu1")
3181 (set_attr "mode" "SI")])
3183 (define_insn "*zero_extendqisi2_movzbw_and"
3184 [(set (match_operand:SI 0 "register_operand" "=r,r")
3185 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3186 (clobber (reg:CC FLAGS_REG))]
3187 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3189 [(set_attr "type" "imovx,alu1")
3190 (set_attr "mode" "SI")])
3192 (define_insn "*zero_extendqisi2_movzbw"
3193 [(set (match_operand:SI 0 "register_operand" "=r")
3194 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3195 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3196 "movz{bl|x}\t{%1, %0|%0, %1}"
3197 [(set_attr "type" "imovx")
3198 (set_attr "mode" "SI")])
3200 ;; For the movzbl case strip only the clobber
3202 [(set (match_operand:SI 0 "register_operand" "")
3203 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3204 (clobber (reg:CC FLAGS_REG))]
3206 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3207 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3209 (zero_extend:SI (match_dup 1)))])
3211 ;; When source and destination does not overlap, clear destination
3212 ;; first and then do the movb
3214 [(set (match_operand:SI 0 "register_operand" "")
3215 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3216 (clobber (reg:CC FLAGS_REG))]
3218 && ANY_QI_REG_P (operands[0])
3219 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3220 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3221 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3222 [(set (match_dup 0) (const_int 0))
3223 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3224 "operands[2] = gen_lowpart (QImode, operands[0]);")
3226 ;; Rest is handled by single and.
3228 [(set (match_operand:SI 0 "register_operand" "")
3229 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3230 (clobber (reg:CC FLAGS_REG))]
3232 && true_regnum (operands[0]) == true_regnum (operands[1])"
3233 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3234 (clobber (reg:CC FLAGS_REG))])]
3237 ;; %%% Kill me once multi-word ops are sane.
3238 (define_expand "zero_extendsidi2"
3239 [(set (match_operand:DI 0 "register_operand" "=r")
3240 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3244 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3249 (define_insn "zero_extendsidi2_32"
3250 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3251 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3252 (clobber (reg:CC FLAGS_REG))]
3258 movd\t{%1, %0|%0, %1}
3259 movd\t{%1, %0|%0, %1}"
3260 [(set_attr "mode" "SI,SI,SI,DI,TI")
3261 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3263 (define_insn "zero_extendsidi2_rex64"
3264 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3265 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3268 mov\t{%k1, %k0|%k0, %k1}
3270 movd\t{%1, %0|%0, %1}
3271 movd\t{%1, %0|%0, %1}"
3272 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3273 (set_attr "mode" "SI,DI,SI,SI")])
3276 [(set (match_operand:DI 0 "memory_operand" "")
3277 (zero_extend:DI (match_dup 0)))]
3279 [(set (match_dup 4) (const_int 0))]
3280 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3283 [(set (match_operand:DI 0 "register_operand" "")
3284 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3285 (clobber (reg:CC FLAGS_REG))]
3286 "!TARGET_64BIT && reload_completed
3287 && true_regnum (operands[0]) == true_regnum (operands[1])"
3288 [(set (match_dup 4) (const_int 0))]
3289 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3292 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3293 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3294 (clobber (reg:CC FLAGS_REG))]
3295 "!TARGET_64BIT && reload_completed
3296 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3297 [(set (match_dup 3) (match_dup 1))
3298 (set (match_dup 4) (const_int 0))]
3299 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3301 (define_insn "zero_extendhidi2"
3302 [(set (match_operand:DI 0 "register_operand" "=r")
3303 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3305 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3306 [(set_attr "type" "imovx")
3307 (set_attr "mode" "DI")])
3309 (define_insn "zero_extendqidi2"
3310 [(set (match_operand:DI 0 "register_operand" "=r")
3311 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3313 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3314 [(set_attr "type" "imovx")
3315 (set_attr "mode" "DI")])
3317 ;; Sign extension instructions
3319 (define_expand "extendsidi2"
3320 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3321 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3322 (clobber (reg:CC FLAGS_REG))
3323 (clobber (match_scratch:SI 2 ""))])]
3328 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3333 (define_insn "*extendsidi2_1"
3334 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3335 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3336 (clobber (reg:CC FLAGS_REG))
3337 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3341 (define_insn "extendsidi2_rex64"
3342 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3343 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3347 movs{lq|x}\t{%1,%0|%0, %1}"
3348 [(set_attr "type" "imovx")
3349 (set_attr "mode" "DI")
3350 (set_attr "prefix_0f" "0")
3351 (set_attr "modrm" "0,1")])
3353 (define_insn "extendhidi2"
3354 [(set (match_operand:DI 0 "register_operand" "=r")
3355 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3357 "movs{wq|x}\t{%1,%0|%0, %1}"
3358 [(set_attr "type" "imovx")
3359 (set_attr "mode" "DI")])
3361 (define_insn "extendqidi2"
3362 [(set (match_operand:DI 0 "register_operand" "=r")
3363 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3365 "movs{bq|x}\t{%1,%0|%0, %1}"
3366 [(set_attr "type" "imovx")
3367 (set_attr "mode" "DI")])
3369 ;; Extend to memory case when source register does die.
3371 [(set (match_operand:DI 0 "memory_operand" "")
3372 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3373 (clobber (reg:CC FLAGS_REG))
3374 (clobber (match_operand:SI 2 "register_operand" ""))]
3376 && dead_or_set_p (insn, operands[1])
3377 && !reg_mentioned_p (operands[1], operands[0]))"
3378 [(set (match_dup 3) (match_dup 1))
3379 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3380 (clobber (reg:CC FLAGS_REG))])
3381 (set (match_dup 4) (match_dup 1))]
3382 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3384 ;; Extend to memory case when source register does not die.
3386 [(set (match_operand:DI 0 "memory_operand" "")
3387 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3388 (clobber (reg:CC FLAGS_REG))
3389 (clobber (match_operand:SI 2 "register_operand" ""))]
3393 split_di (&operands[0], 1, &operands[3], &operands[4]);
3395 emit_move_insn (operands[3], operands[1]);
3397 /* Generate a cltd if possible and doing so it profitable. */
3398 if (true_regnum (operands[1]) == 0
3399 && true_regnum (operands[2]) == 1
3400 && (optimize_size || TARGET_USE_CLTD))
3402 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3406 emit_move_insn (operands[2], operands[1]);
3407 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3409 emit_move_insn (operands[4], operands[2]);
3413 ;; Extend to register case. Optimize case where source and destination
3414 ;; registers match and cases where we can use cltd.
3416 [(set (match_operand:DI 0 "register_operand" "")
3417 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3418 (clobber (reg:CC FLAGS_REG))
3419 (clobber (match_scratch:SI 2 ""))]
3423 split_di (&operands[0], 1, &operands[3], &operands[4]);
3425 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3426 emit_move_insn (operands[3], operands[1]);
3428 /* Generate a cltd if possible and doing so it profitable. */
3429 if (true_regnum (operands[3]) == 0
3430 && (optimize_size || TARGET_USE_CLTD))
3432 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3436 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3437 emit_move_insn (operands[4], operands[1]);
3439 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3443 (define_insn "extendhisi2"
3444 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3445 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3448 switch (get_attr_prefix_0f (insn))
3451 return "{cwtl|cwde}";
3453 return "movs{wl|x}\t{%1,%0|%0, %1}";
3456 [(set_attr "type" "imovx")
3457 (set_attr "mode" "SI")
3458 (set (attr "prefix_0f")
3459 ;; movsx is short decodable while cwtl is vector decoded.
3460 (if_then_else (and (eq_attr "cpu" "!k6")
3461 (eq_attr "alternative" "0"))
3463 (const_string "1")))
3465 (if_then_else (eq_attr "prefix_0f" "0")
3467 (const_string "1")))])
3469 (define_insn "*extendhisi2_zext"
3470 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3472 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3475 switch (get_attr_prefix_0f (insn))
3478 return "{cwtl|cwde}";
3480 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3483 [(set_attr "type" "imovx")
3484 (set_attr "mode" "SI")
3485 (set (attr "prefix_0f")
3486 ;; movsx is short decodable while cwtl is vector decoded.
3487 (if_then_else (and (eq_attr "cpu" "!k6")
3488 (eq_attr "alternative" "0"))
3490 (const_string "1")))
3492 (if_then_else (eq_attr "prefix_0f" "0")
3494 (const_string "1")))])
3496 (define_insn "extendqihi2"
3497 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3498 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3501 switch (get_attr_prefix_0f (insn))
3504 return "{cbtw|cbw}";
3506 return "movs{bw|x}\t{%1,%0|%0, %1}";
3509 [(set_attr "type" "imovx")
3510 (set_attr "mode" "HI")
3511 (set (attr "prefix_0f")
3512 ;; movsx is short decodable while cwtl is vector decoded.
3513 (if_then_else (and (eq_attr "cpu" "!k6")
3514 (eq_attr "alternative" "0"))
3516 (const_string "1")))
3518 (if_then_else (eq_attr "prefix_0f" "0")
3520 (const_string "1")))])
3522 (define_insn "extendqisi2"
3523 [(set (match_operand:SI 0 "register_operand" "=r")
3524 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3526 "movs{bl|x}\t{%1,%0|%0, %1}"
3527 [(set_attr "type" "imovx")
3528 (set_attr "mode" "SI")])
3530 (define_insn "*extendqisi2_zext"
3531 [(set (match_operand:DI 0 "register_operand" "=r")
3533 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3535 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3536 [(set_attr "type" "imovx")
3537 (set_attr "mode" "SI")])
3539 ;; Conversions between float and double.
3541 ;; These are all no-ops in the model used for the 80387. So just
3544 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3545 (define_insn "*dummy_extendsfdf2"
3546 [(set (match_operand:DF 0 "push_operand" "=<")
3547 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3552 [(set (match_operand:DF 0 "push_operand" "")
3553 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3555 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3556 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3559 [(set (match_operand:DF 0 "push_operand" "")
3560 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3562 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3563 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3565 (define_insn "*dummy_extendsfxf2"
3566 [(set (match_operand:XF 0 "push_operand" "=<")
3567 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3572 [(set (match_operand:XF 0 "push_operand" "")
3573 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3575 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3576 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3577 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3580 [(set (match_operand:XF 0 "push_operand" "")
3581 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3583 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3584 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3585 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3588 [(set (match_operand:XF 0 "push_operand" "")
3589 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3591 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3592 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3593 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3596 [(set (match_operand:XF 0 "push_operand" "")
3597 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3599 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3600 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3601 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3603 (define_expand "extendsfdf2"
3604 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3605 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3606 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3608 /* ??? Needed for compress_float_constant since all fp constants
3609 are LEGITIMATE_CONSTANT_P. */
3610 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3612 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3613 && standard_80387_constant_p (operands[1]) > 0)
3615 operands[1] = simplify_const_unary_operation
3616 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3617 emit_move_insn_1 (operands[0], operands[1]);
3620 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3624 (define_insn "*extendsfdf2_mixed"
3625 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3626 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3627 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3629 switch (which_alternative)
3632 return output_387_reg_move (insn, operands);
3635 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3636 return "fstp%z0\t%y0";
3638 return "fst%z0\t%y0";
3641 return "cvtss2sd\t{%1, %0|%0, %1}";
3647 [(set_attr "type" "fmov,fmov,ssecvt")
3648 (set_attr "mode" "SF,XF,DF")])
3650 (define_insn "*extendsfdf2_sse"
3651 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3652 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3653 "TARGET_SSE2 && TARGET_SSE_MATH"
3654 "cvtss2sd\t{%1, %0|%0, %1}"
3655 [(set_attr "type" "ssecvt")
3656 (set_attr "mode" "DF")])
3658 (define_insn "*extendsfdf2_i387"
3659 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3660 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3663 switch (which_alternative)
3666 return output_387_reg_move (insn, operands);
3669 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3670 return "fstp%z0\t%y0";
3672 return "fst%z0\t%y0";
3678 [(set_attr "type" "fmov")
3679 (set_attr "mode" "SF,XF")])
3681 (define_expand "extendsfxf2"
3682 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3683 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3686 /* ??? Needed for compress_float_constant since all fp constants
3687 are LEGITIMATE_CONSTANT_P. */
3688 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3690 if (standard_80387_constant_p (operands[1]) > 0)
3692 operands[1] = simplify_const_unary_operation
3693 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3694 emit_move_insn_1 (operands[0], operands[1]);
3697 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3701 (define_insn "*extendsfxf2_i387"
3702 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3703 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3706 switch (which_alternative)
3709 return output_387_reg_move (insn, operands);
3712 /* There is no non-popping store to memory for XFmode. So if
3713 we need one, follow the store with a load. */
3714 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3715 return "fstp%z0\t%y0";
3717 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3723 [(set_attr "type" "fmov")
3724 (set_attr "mode" "SF,XF")])
3726 (define_expand "extenddfxf2"
3727 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3728 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3731 /* ??? Needed for compress_float_constant since all fp constants
3732 are LEGITIMATE_CONSTANT_P. */
3733 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3735 if (standard_80387_constant_p (operands[1]) > 0)
3737 operands[1] = simplify_const_unary_operation
3738 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3739 emit_move_insn_1 (operands[0], operands[1]);
3742 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3746 (define_insn "*extenddfxf2_i387"
3747 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3748 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3751 switch (which_alternative)
3754 return output_387_reg_move (insn, operands);
3757 /* There is no non-popping store to memory for XFmode. So if
3758 we need one, follow the store with a load. */
3759 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3760 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3762 return "fstp%z0\t%y0";
3768 [(set_attr "type" "fmov")
3769 (set_attr "mode" "DF,XF")])
3771 ;; %%% This seems bad bad news.
3772 ;; This cannot output into an f-reg because there is no way to be sure
3773 ;; of truncating in that case. Otherwise this is just like a simple move
3774 ;; insn. So we pretend we can output to a reg in order to get better
3775 ;; register preferencing, but we really use a stack slot.
3777 ;; Conversion from DFmode to SFmode.
3779 (define_expand "truncdfsf2"
3780 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3782 (match_operand:DF 1 "nonimmediate_operand" "")))]
3783 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3785 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3787 else if (flag_unsafe_math_optimizations)
3791 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3792 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3797 (define_expand "truncdfsf2_with_temp"
3798 [(parallel [(set (match_operand:SF 0 "" "")
3799 (float_truncate:SF (match_operand:DF 1 "" "")))
3800 (clobber (match_operand:SF 2 "" ""))])]
3803 (define_insn "*truncdfsf_fast_mixed"
3804 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3806 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3807 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3809 switch (which_alternative)
3812 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3813 return "fstp%z0\t%y0";
3815 return "fst%z0\t%y0";
3817 return output_387_reg_move (insn, operands);
3819 return "cvtsd2ss\t{%1, %0|%0, %1}";
3824 [(set_attr "type" "fmov,fmov,ssecvt")
3825 (set_attr "mode" "SF")])
3827 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3828 ;; because nothing we do here is unsafe.
3829 (define_insn "*truncdfsf_fast_sse"
3830 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3832 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3833 "TARGET_SSE2 && TARGET_SSE_MATH"
3834 "cvtsd2ss\t{%1, %0|%0, %1}"
3835 [(set_attr "type" "ssecvt")
3836 (set_attr "mode" "SF")])
3838 (define_insn "*truncdfsf_fast_i387"
3839 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3841 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3842 "TARGET_80387 && flag_unsafe_math_optimizations"
3843 "* return output_387_reg_move (insn, operands);"
3844 [(set_attr "type" "fmov")
3845 (set_attr "mode" "SF")])
3847 (define_insn "*truncdfsf_mixed"
3848 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3850 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3851 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3852 "TARGET_MIX_SSE_I387"
3854 switch (which_alternative)
3857 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3858 return "fstp%z0\t%y0";
3860 return "fst%z0\t%y0";
3864 return "cvtsd2ss\t{%1, %0|%0, %1}";
3869 [(set_attr "type" "fmov,multi,ssecvt")
3870 (set_attr "unit" "*,i387,*")
3871 (set_attr "mode" "SF")])
3873 (define_insn "*truncdfsf_i387"
3874 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3876 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3877 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3880 switch (which_alternative)
3883 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3884 return "fstp%z0\t%y0";
3886 return "fst%z0\t%y0";
3893 [(set_attr "type" "fmov,multi")
3894 (set_attr "unit" "*,i387")
3895 (set_attr "mode" "SF")])
3897 (define_insn "*truncdfsf2_i387_1"
3898 [(set (match_operand:SF 0 "memory_operand" "=m")
3900 (match_operand:DF 1 "register_operand" "f")))]
3902 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3903 && !TARGET_MIX_SSE_I387"
3905 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3906 return "fstp%z0\t%y0";
3908 return "fst%z0\t%y0";
3910 [(set_attr "type" "fmov")
3911 (set_attr "mode" "SF")])
3914 [(set (match_operand:SF 0 "register_operand" "")
3916 (match_operand:DF 1 "fp_register_operand" "")))
3917 (clobber (match_operand 2 "" ""))]
3919 [(set (match_dup 2) (match_dup 1))
3920 (set (match_dup 0) (match_dup 2))]
3922 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3925 ;; Conversion from XFmode to SFmode.
3927 (define_expand "truncxfsf2"
3928 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3930 (match_operand:XF 1 "register_operand" "")))
3931 (clobber (match_dup 2))])]
3934 if (flag_unsafe_math_optimizations)
3936 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3937 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3938 if (reg != operands[0])
3939 emit_move_insn (operands[0], reg);
3943 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3946 (define_insn "*truncxfsf2_mixed"
3947 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3949 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3950 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3953 gcc_assert (!which_alternative);
3954 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3955 return "fstp%z0\t%y0";
3957 return "fst%z0\t%y0";
3959 [(set_attr "type" "fmov,multi,multi,multi")
3960 (set_attr "unit" "*,i387,i387,i387")
3961 (set_attr "mode" "SF")])
3963 (define_insn "truncxfsf2_i387_noop"
3964 [(set (match_operand:SF 0 "register_operand" "=f")
3965 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3966 "TARGET_80387 && flag_unsafe_math_optimizations"
3967 "* return output_387_reg_move (insn, operands);"
3968 [(set_attr "type" "fmov")
3969 (set_attr "mode" "SF")])
3971 (define_insn "*truncxfsf2_i387"
3972 [(set (match_operand:SF 0 "memory_operand" "=m")
3974 (match_operand:XF 1 "register_operand" "f")))]
3977 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3978 return "fstp%z0\t%y0";
3980 return "fst%z0\t%y0";
3982 [(set_attr "type" "fmov")
3983 (set_attr "mode" "SF")])
3986 [(set (match_operand:SF 0 "register_operand" "")
3988 (match_operand:XF 1 "register_operand" "")))
3989 (clobber (match_operand:SF 2 "memory_operand" ""))]
3990 "TARGET_80387 && reload_completed"
3991 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3992 (set (match_dup 0) (match_dup 2))]
3996 [(set (match_operand:SF 0 "memory_operand" "")
3998 (match_operand:XF 1 "register_operand" "")))
3999 (clobber (match_operand:SF 2 "memory_operand" ""))]
4001 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4004 ;; Conversion from XFmode to DFmode.
4006 (define_expand "truncxfdf2"
4007 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4009 (match_operand:XF 1 "register_operand" "")))
4010 (clobber (match_dup 2))])]
4013 if (flag_unsafe_math_optimizations)
4015 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4016 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4017 if (reg != operands[0])
4018 emit_move_insn (operands[0], reg);
4022 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4025 (define_insn "*truncxfdf2_mixed"
4026 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4028 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4029 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4032 gcc_assert (!which_alternative);
4033 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4034 return "fstp%z0\t%y0";
4036 return "fst%z0\t%y0";
4038 [(set_attr "type" "fmov,multi,multi,multi")
4039 (set_attr "unit" "*,i387,i387,i387")
4040 (set_attr "mode" "DF")])
4042 (define_insn "truncxfdf2_i387_noop"
4043 [(set (match_operand:DF 0 "register_operand" "=f")
4044 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4045 "TARGET_80387 && flag_unsafe_math_optimizations"
4046 "* return output_387_reg_move (insn, operands);"
4047 [(set_attr "type" "fmov")
4048 (set_attr "mode" "DF")])
4050 (define_insn "*truncxfdf2_i387"
4051 [(set (match_operand:DF 0 "memory_operand" "=m")
4053 (match_operand:XF 1 "register_operand" "f")))]
4056 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4057 return "fstp%z0\t%y0";
4059 return "fst%z0\t%y0";
4061 [(set_attr "type" "fmov")
4062 (set_attr "mode" "DF")])
4065 [(set (match_operand:DF 0 "register_operand" "")
4067 (match_operand:XF 1 "register_operand" "")))
4068 (clobber (match_operand:DF 2 "memory_operand" ""))]
4069 "TARGET_80387 && reload_completed"
4070 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4071 (set (match_dup 0) (match_dup 2))]
4075 [(set (match_operand:DF 0 "memory_operand" "")
4077 (match_operand:XF 1 "register_operand" "")))
4078 (clobber (match_operand:DF 2 "memory_operand" ""))]
4080 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4083 ;; Signed conversion to DImode.
4085 (define_expand "fix_truncxfdi2"
4086 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4087 (fix:DI (match_operand:XF 1 "register_operand" "")))
4088 (clobber (reg:CC FLAGS_REG))])]
4093 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4098 (define_expand "fix_trunc<mode>di2"
4099 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4100 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4101 (clobber (reg:CC FLAGS_REG))])]
4102 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4105 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4107 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4110 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4112 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4113 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4114 if (out != operands[0])
4115 emit_move_insn (operands[0], out);
4120 ;; Signed conversion to SImode.
4122 (define_expand "fix_truncxfsi2"
4123 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4124 (fix:SI (match_operand:XF 1 "register_operand" "")))
4125 (clobber (reg:CC FLAGS_REG))])]
4130 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4135 (define_expand "fix_trunc<mode>si2"
4136 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4137 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4138 (clobber (reg:CC FLAGS_REG))])]
4139 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4142 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4144 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4147 if (SSE_FLOAT_MODE_P (<MODE>mode))
4149 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4150 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4151 if (out != operands[0])
4152 emit_move_insn (operands[0], out);
4157 ;; Signed conversion to HImode.
4159 (define_expand "fix_trunc<mode>hi2"
4160 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4161 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4162 (clobber (reg:CC FLAGS_REG))])]
4164 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4168 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4173 ;; When SSE is available, it is always faster to use it!
4174 (define_insn "fix_truncsfdi_sse"
4175 [(set (match_operand:DI 0 "register_operand" "=r,r")
4176 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4177 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4178 "cvttss2si{q}\t{%1, %0|%0, %1}"
4179 [(set_attr "type" "sseicvt")
4180 (set_attr "mode" "SF")
4181 (set_attr "athlon_decode" "double,vector")])
4183 (define_insn "fix_truncdfdi_sse"
4184 [(set (match_operand:DI 0 "register_operand" "=r,r")
4185 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4186 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4187 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4188 [(set_attr "type" "sseicvt")
4189 (set_attr "mode" "DF")
4190 (set_attr "athlon_decode" "double,vector")])
4192 (define_insn "fix_truncsfsi_sse"
4193 [(set (match_operand:SI 0 "register_operand" "=r,r")
4194 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4195 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4196 "cvttss2si\t{%1, %0|%0, %1}"
4197 [(set_attr "type" "sseicvt")
4198 (set_attr "mode" "DF")
4199 (set_attr "athlon_decode" "double,vector")])
4201 (define_insn "fix_truncdfsi_sse"
4202 [(set (match_operand:SI 0 "register_operand" "=r,r")
4203 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4204 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4205 "cvttsd2si\t{%1, %0|%0, %1}"
4206 [(set_attr "type" "sseicvt")
4207 (set_attr "mode" "DF")
4208 (set_attr "athlon_decode" "double,vector")])
4210 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4212 [(set (match_operand:DF 0 "register_operand" "")
4213 (match_operand:DF 1 "memory_operand" ""))
4214 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4215 (fix:SSEMODEI24 (match_dup 0)))]
4217 && peep2_reg_dead_p (2, operands[0])"
4218 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4222 [(set (match_operand:SF 0 "register_operand" "")
4223 (match_operand:SF 1 "memory_operand" ""))
4224 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4225 (fix:SSEMODEI24 (match_dup 0)))]
4227 && peep2_reg_dead_p (2, operands[0])"
4228 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4231 ;; Avoid vector decoded forms of the instruction.
4233 [(match_scratch:DF 2 "Y")
4234 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4235 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4236 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4237 [(set (match_dup 2) (match_dup 1))
4238 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4242 [(match_scratch:SF 2 "x")
4243 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4244 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4245 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4246 [(set (match_dup 2) (match_dup 1))
4247 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4250 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4251 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4252 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4254 && FLOAT_MODE_P (GET_MODE (operands[1]))
4255 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4256 && (TARGET_64BIT || <MODE>mode != DImode))
4258 && !(reload_completed || reload_in_progress)"
4263 if (memory_operand (operands[0], VOIDmode))
4264 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4267 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4268 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4274 [(set_attr "type" "fisttp")
4275 (set_attr "mode" "<MODE>")])
4277 (define_insn "fix_trunc<mode>_i387_fisttp"
4278 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4279 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4280 (clobber (match_scratch:XF 2 "=&1f"))]
4282 && FLOAT_MODE_P (GET_MODE (operands[1]))
4283 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4284 && (TARGET_64BIT || <MODE>mode != DImode))
4285 && TARGET_SSE_MATH)"
4286 "* return output_fix_trunc (insn, operands, 1);"
4287 [(set_attr "type" "fisttp")
4288 (set_attr "mode" "<MODE>")])
4290 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4291 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4292 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4293 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4294 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4296 && FLOAT_MODE_P (GET_MODE (operands[1]))
4297 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4298 && (TARGET_64BIT || <MODE>mode != DImode))
4299 && TARGET_SSE_MATH)"
4301 [(set_attr "type" "fisttp")
4302 (set_attr "mode" "<MODE>")])
4305 [(set (match_operand:X87MODEI 0 "register_operand" "")
4306 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4307 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4308 (clobber (match_scratch 3 ""))]
4310 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4311 (clobber (match_dup 3))])
4312 (set (match_dup 0) (match_dup 2))]
4316 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4317 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4318 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4319 (clobber (match_scratch 3 ""))]
4321 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4322 (clobber (match_dup 3))])]
4325 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4326 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4327 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4328 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4329 ;; function in i386.c.
4330 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4331 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4332 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4333 (clobber (reg:CC FLAGS_REG))]
4334 "TARGET_80387 && !TARGET_FISTTP
4335 && FLOAT_MODE_P (GET_MODE (operands[1]))
4336 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4337 && (TARGET_64BIT || <MODE>mode != DImode))
4338 && !(reload_completed || reload_in_progress)"
4343 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4345 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4346 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4347 if (memory_operand (operands[0], VOIDmode))
4348 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4349 operands[2], operands[3]));
4352 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4353 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4354 operands[2], operands[3],
4359 [(set_attr "type" "fistp")
4360 (set_attr "i387_cw" "trunc")
4361 (set_attr "mode" "<MODE>")])
4363 (define_insn "fix_truncdi_i387"
4364 [(set (match_operand:DI 0 "memory_operand" "=m")
4365 (fix:DI (match_operand 1 "register_operand" "f")))
4366 (use (match_operand:HI 2 "memory_operand" "m"))
4367 (use (match_operand:HI 3 "memory_operand" "m"))
4368 (clobber (match_scratch:XF 4 "=&1f"))]
4369 "TARGET_80387 && !TARGET_FISTTP
4370 && FLOAT_MODE_P (GET_MODE (operands[1]))
4371 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4372 "* return output_fix_trunc (insn, operands, 0);"
4373 [(set_attr "type" "fistp")
4374 (set_attr "i387_cw" "trunc")
4375 (set_attr "mode" "DI")])
4377 (define_insn "fix_truncdi_i387_with_temp"
4378 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4379 (fix:DI (match_operand 1 "register_operand" "f,f")))
4380 (use (match_operand:HI 2 "memory_operand" "m,m"))
4381 (use (match_operand:HI 3 "memory_operand" "m,m"))
4382 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4383 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4384 "TARGET_80387 && !TARGET_FISTTP
4385 && FLOAT_MODE_P (GET_MODE (operands[1]))
4386 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4388 [(set_attr "type" "fistp")
4389 (set_attr "i387_cw" "trunc")
4390 (set_attr "mode" "DI")])
4393 [(set (match_operand:DI 0 "register_operand" "")
4394 (fix:DI (match_operand 1 "register_operand" "")))
4395 (use (match_operand:HI 2 "memory_operand" ""))
4396 (use (match_operand:HI 3 "memory_operand" ""))
4397 (clobber (match_operand:DI 4 "memory_operand" ""))
4398 (clobber (match_scratch 5 ""))]
4400 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4403 (clobber (match_dup 5))])
4404 (set (match_dup 0) (match_dup 4))]
4408 [(set (match_operand:DI 0 "memory_operand" "")
4409 (fix:DI (match_operand 1 "register_operand" "")))
4410 (use (match_operand:HI 2 "memory_operand" ""))
4411 (use (match_operand:HI 3 "memory_operand" ""))
4412 (clobber (match_operand:DI 4 "memory_operand" ""))
4413 (clobber (match_scratch 5 ""))]
4415 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4418 (clobber (match_dup 5))])]
4421 (define_insn "fix_trunc<mode>_i387"
4422 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4423 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4424 (use (match_operand:HI 2 "memory_operand" "m"))
4425 (use (match_operand:HI 3 "memory_operand" "m"))]
4426 "TARGET_80387 && !TARGET_FISTTP
4427 && FLOAT_MODE_P (GET_MODE (operands[1]))
4428 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4429 "* return output_fix_trunc (insn, operands, 0);"
4430 [(set_attr "type" "fistp")
4431 (set_attr "i387_cw" "trunc")
4432 (set_attr "mode" "<MODE>")])
4434 (define_insn "fix_trunc<mode>_i387_with_temp"
4435 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4436 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4437 (use (match_operand:HI 2 "memory_operand" "m,m"))
4438 (use (match_operand:HI 3 "memory_operand" "m,m"))
4439 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4440 "TARGET_80387 && !TARGET_FISTTP
4441 && FLOAT_MODE_P (GET_MODE (operands[1]))
4442 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4444 [(set_attr "type" "fistp")
4445 (set_attr "i387_cw" "trunc")
4446 (set_attr "mode" "<MODE>")])
4449 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4450 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4451 (use (match_operand:HI 2 "memory_operand" ""))
4452 (use (match_operand:HI 3 "memory_operand" ""))
4453 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4455 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4457 (use (match_dup 3))])
4458 (set (match_dup 0) (match_dup 4))]
4462 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4463 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4464 (use (match_operand:HI 2 "memory_operand" ""))
4465 (use (match_operand:HI 3 "memory_operand" ""))
4466 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4468 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4470 (use (match_dup 3))])]
4473 (define_insn "x86_fnstcw_1"
4474 [(set (match_operand:HI 0 "memory_operand" "=m")
4475 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4478 [(set_attr "length" "2")
4479 (set_attr "mode" "HI")
4480 (set_attr "unit" "i387")])
4482 (define_insn "x86_fldcw_1"
4483 [(set (reg:HI FPCR_REG)
4484 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4487 [(set_attr "length" "2")
4488 (set_attr "mode" "HI")
4489 (set_attr "unit" "i387")
4490 (set_attr "athlon_decode" "vector")])
4492 ;; Conversion between fixed point and floating point.
4494 ;; Even though we only accept memory inputs, the backend _really_
4495 ;; wants to be able to do this between registers.
4497 (define_expand "floathisf2"
4498 [(set (match_operand:SF 0 "register_operand" "")
4499 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4500 "TARGET_80387 || TARGET_SSE_MATH"
4502 if (TARGET_SSE_MATH)
4504 emit_insn (gen_floatsisf2 (operands[0],
4505 convert_to_mode (SImode, operands[1], 0)));
4510 (define_insn "*floathisf2_i387"
4511 [(set (match_operand:SF 0 "register_operand" "=f,f")
4512 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4513 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4517 [(set_attr "type" "fmov,multi")
4518 (set_attr "mode" "SF")
4519 (set_attr "unit" "*,i387")
4520 (set_attr "fp_int_src" "true")])
4522 (define_expand "floatsisf2"
4523 [(set (match_operand:SF 0 "register_operand" "")
4524 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4525 "TARGET_80387 || TARGET_SSE_MATH"
4528 (define_insn "*floatsisf2_mixed"
4529 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4530 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4531 "TARGET_MIX_SSE_I387"
4535 cvtsi2ss\t{%1, %0|%0, %1}
4536 cvtsi2ss\t{%1, %0|%0, %1}"
4537 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4538 (set_attr "mode" "SF")
4539 (set_attr "unit" "*,i387,*,*")
4540 (set_attr "athlon_decode" "*,*,vector,double")
4541 (set_attr "fp_int_src" "true")])
4543 (define_insn "*floatsisf2_sse"
4544 [(set (match_operand:SF 0 "register_operand" "=x,x")
4545 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4547 "cvtsi2ss\t{%1, %0|%0, %1}"
4548 [(set_attr "type" "sseicvt")
4549 (set_attr "mode" "SF")
4550 (set_attr "athlon_decode" "vector,double")
4551 (set_attr "fp_int_src" "true")])
4553 (define_insn "*floatsisf2_i387"
4554 [(set (match_operand:SF 0 "register_operand" "=f,f")
4555 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4560 [(set_attr "type" "fmov,multi")
4561 (set_attr "mode" "SF")
4562 (set_attr "unit" "*,i387")
4563 (set_attr "fp_int_src" "true")])
4565 (define_expand "floatdisf2"
4566 [(set (match_operand:SF 0 "register_operand" "")
4567 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4568 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4571 (define_insn "*floatdisf2_mixed"
4572 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4573 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4574 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4578 cvtsi2ss{q}\t{%1, %0|%0, %1}
4579 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4580 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4581 (set_attr "mode" "SF")
4582 (set_attr "unit" "*,i387,*,*")
4583 (set_attr "athlon_decode" "*,*,vector,double")
4584 (set_attr "fp_int_src" "true")])
4586 (define_insn "*floatdisf2_sse"
4587 [(set (match_operand:SF 0 "register_operand" "=x,x")
4588 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4589 "TARGET_64BIT && TARGET_SSE_MATH"
4590 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4591 [(set_attr "type" "sseicvt")
4592 (set_attr "mode" "SF")
4593 (set_attr "athlon_decode" "vector,double")
4594 (set_attr "fp_int_src" "true")])
4596 (define_insn "*floatdisf2_i387"
4597 [(set (match_operand:SF 0 "register_operand" "=f,f")
4598 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4603 [(set_attr "type" "fmov,multi")
4604 (set_attr "mode" "SF")
4605 (set_attr "unit" "*,i387")
4606 (set_attr "fp_int_src" "true")])
4608 (define_expand "floathidf2"
4609 [(set (match_operand:DF 0 "register_operand" "")
4610 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4611 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4613 if (TARGET_SSE2 && TARGET_SSE_MATH)
4615 emit_insn (gen_floatsidf2 (operands[0],
4616 convert_to_mode (SImode, operands[1], 0)));
4621 (define_insn "*floathidf2_i387"
4622 [(set (match_operand:DF 0 "register_operand" "=f,f")
4623 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4624 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4628 [(set_attr "type" "fmov,multi")
4629 (set_attr "mode" "DF")
4630 (set_attr "unit" "*,i387")
4631 (set_attr "fp_int_src" "true")])
4633 (define_expand "floatsidf2"
4634 [(set (match_operand:DF 0 "register_operand" "")
4635 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4636 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4639 (define_insn "*floatsidf2_mixed"
4640 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4641 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4642 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4646 cvtsi2sd\t{%1, %0|%0, %1}
4647 cvtsi2sd\t{%1, %0|%0, %1}"
4648 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4649 (set_attr "mode" "DF")
4650 (set_attr "unit" "*,i387,*,*")
4651 (set_attr "athlon_decode" "*,*,double,direct")
4652 (set_attr "fp_int_src" "true")])
4654 (define_insn "*floatsidf2_sse"
4655 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4656 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4657 "TARGET_SSE2 && TARGET_SSE_MATH"
4658 "cvtsi2sd\t{%1, %0|%0, %1}"
4659 [(set_attr "type" "sseicvt")
4660 (set_attr "mode" "DF")
4661 (set_attr "athlon_decode" "double,direct")
4662 (set_attr "fp_int_src" "true")])
4664 (define_insn "*floatsidf2_i387"
4665 [(set (match_operand:DF 0 "register_operand" "=f,f")
4666 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4671 [(set_attr "type" "fmov,multi")
4672 (set_attr "mode" "DF")
4673 (set_attr "unit" "*,i387")
4674 (set_attr "fp_int_src" "true")])
4676 (define_expand "floatdidf2"
4677 [(set (match_operand:DF 0 "register_operand" "")
4678 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4679 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4682 (define_insn "*floatdidf2_mixed"
4683 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4684 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4685 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4689 cvtsi2sd{q}\t{%1, %0|%0, %1}
4690 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4691 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4692 (set_attr "mode" "DF")
4693 (set_attr "unit" "*,i387,*,*")
4694 (set_attr "athlon_decode" "*,*,double,direct")
4695 (set_attr "fp_int_src" "true")])
4697 (define_insn "*floatdidf2_sse"
4698 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4699 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4700 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4701 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4702 [(set_attr "type" "sseicvt")
4703 (set_attr "mode" "DF")
4704 (set_attr "athlon_decode" "double,direct")
4705 (set_attr "fp_int_src" "true")])
4707 (define_insn "*floatdidf2_i387"
4708 [(set (match_operand:DF 0 "register_operand" "=f,f")
4709 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4714 [(set_attr "type" "fmov,multi")
4715 (set_attr "mode" "DF")
4716 (set_attr "unit" "*,i387")
4717 (set_attr "fp_int_src" "true")])
4719 (define_insn "floathixf2"
4720 [(set (match_operand:XF 0 "register_operand" "=f,f")
4721 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4726 [(set_attr "type" "fmov,multi")
4727 (set_attr "mode" "XF")
4728 (set_attr "unit" "*,i387")
4729 (set_attr "fp_int_src" "true")])
4731 (define_insn "floatsixf2"
4732 [(set (match_operand:XF 0 "register_operand" "=f,f")
4733 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4738 [(set_attr "type" "fmov,multi")
4739 (set_attr "mode" "XF")
4740 (set_attr "unit" "*,i387")
4741 (set_attr "fp_int_src" "true")])
4743 (define_insn "floatdixf2"
4744 [(set (match_operand:XF 0 "register_operand" "=f,f")
4745 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4750 [(set_attr "type" "fmov,multi")
4751 (set_attr "mode" "XF")
4752 (set_attr "unit" "*,i387")
4753 (set_attr "fp_int_src" "true")])
4755 ;; %%% Kill these when reload knows how to do it.
4757 [(set (match_operand 0 "fp_register_operand" "")
4758 (float (match_operand 1 "register_operand" "")))]
4761 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4764 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4765 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4766 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4767 ix86_free_from_memory (GET_MODE (operands[1]));
4771 (define_expand "floatunssisf2"
4772 [(use (match_operand:SF 0 "register_operand" ""))
4773 (use (match_operand:SI 1 "register_operand" ""))]
4774 "!TARGET_64BIT && TARGET_SSE_MATH"
4775 "x86_emit_floatuns (operands); DONE;")
4777 (define_expand "floatunsdisf2"
4778 [(use (match_operand:SF 0 "register_operand" ""))
4779 (use (match_operand:DI 1 "register_operand" ""))]
4780 "TARGET_64BIT && TARGET_SSE_MATH"
4781 "x86_emit_floatuns (operands); DONE;")
4783 (define_expand "floatunsdidf2"
4784 [(use (match_operand:DF 0 "register_operand" ""))
4785 (use (match_operand:DI 1 "register_operand" ""))]
4786 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4787 "x86_emit_floatuns (operands); DONE;")
4789 ;; SSE extract/set expanders
4794 ;; %%% splits for addditi3
4796 (define_expand "addti3"
4797 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4798 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4799 (match_operand:TI 2 "x86_64_general_operand" "")))
4800 (clobber (reg:CC FLAGS_REG))]
4802 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4804 (define_insn "*addti3_1"
4805 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4806 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4807 (match_operand:TI 2 "general_operand" "roiF,riF")))
4808 (clobber (reg:CC FLAGS_REG))]
4809 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4813 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4814 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4815 (match_operand:TI 2 "general_operand" "")))
4816 (clobber (reg:CC FLAGS_REG))]
4817 "TARGET_64BIT && reload_completed"
4818 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4820 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4821 (parallel [(set (match_dup 3)
4822 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4825 (clobber (reg:CC FLAGS_REG))])]
4826 "split_ti (operands+0, 1, operands+0, operands+3);
4827 split_ti (operands+1, 1, operands+1, operands+4);
4828 split_ti (operands+2, 1, operands+2, operands+5);")
4830 ;; %%% splits for addsidi3
4831 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4832 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4833 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4835 (define_expand "adddi3"
4836 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4837 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4838 (match_operand:DI 2 "x86_64_general_operand" "")))
4839 (clobber (reg:CC FLAGS_REG))]
4841 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4843 (define_insn "*adddi3_1"
4844 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4845 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4846 (match_operand:DI 2 "general_operand" "roiF,riF")))
4847 (clobber (reg:CC FLAGS_REG))]
4848 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4852 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4853 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4854 (match_operand:DI 2 "general_operand" "")))
4855 (clobber (reg:CC FLAGS_REG))]
4856 "!TARGET_64BIT && reload_completed"
4857 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4859 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4860 (parallel [(set (match_dup 3)
4861 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4864 (clobber (reg:CC FLAGS_REG))])]
4865 "split_di (operands+0, 1, operands+0, operands+3);
4866 split_di (operands+1, 1, operands+1, operands+4);
4867 split_di (operands+2, 1, operands+2, operands+5);")
4869 (define_insn "adddi3_carry_rex64"
4870 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4871 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4872 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4873 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4874 (clobber (reg:CC FLAGS_REG))]
4875 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4876 "adc{q}\t{%2, %0|%0, %2}"
4877 [(set_attr "type" "alu")
4878 (set_attr "pent_pair" "pu")
4879 (set_attr "mode" "DI")])
4881 (define_insn "*adddi3_cc_rex64"
4882 [(set (reg:CC FLAGS_REG)
4883 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4884 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4886 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4887 (plus:DI (match_dup 1) (match_dup 2)))]
4888 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4889 "add{q}\t{%2, %0|%0, %2}"
4890 [(set_attr "type" "alu")
4891 (set_attr "mode" "DI")])
4893 (define_insn "addqi3_carry"
4894 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4895 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4896 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4897 (match_operand:QI 2 "general_operand" "qi,qm")))
4898 (clobber (reg:CC FLAGS_REG))]
4899 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4900 "adc{b}\t{%2, %0|%0, %2}"
4901 [(set_attr "type" "alu")
4902 (set_attr "pent_pair" "pu")
4903 (set_attr "mode" "QI")])
4905 (define_insn "addhi3_carry"
4906 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4907 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4908 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4909 (match_operand:HI 2 "general_operand" "ri,rm")))
4910 (clobber (reg:CC FLAGS_REG))]
4911 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4912 "adc{w}\t{%2, %0|%0, %2}"
4913 [(set_attr "type" "alu")
4914 (set_attr "pent_pair" "pu")
4915 (set_attr "mode" "HI")])
4917 (define_insn "addsi3_carry"
4918 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4919 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4920 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4921 (match_operand:SI 2 "general_operand" "ri,rm")))
4922 (clobber (reg:CC FLAGS_REG))]
4923 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4924 "adc{l}\t{%2, %0|%0, %2}"
4925 [(set_attr "type" "alu")
4926 (set_attr "pent_pair" "pu")
4927 (set_attr "mode" "SI")])
4929 (define_insn "*addsi3_carry_zext"
4930 [(set (match_operand:DI 0 "register_operand" "=r")
4932 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4933 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4934 (match_operand:SI 2 "general_operand" "rim"))))
4935 (clobber (reg:CC FLAGS_REG))]
4936 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4937 "adc{l}\t{%2, %k0|%k0, %2}"
4938 [(set_attr "type" "alu")
4939 (set_attr "pent_pair" "pu")
4940 (set_attr "mode" "SI")])
4942 (define_insn "*addsi3_cc"
4943 [(set (reg:CC FLAGS_REG)
4944 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4945 (match_operand:SI 2 "general_operand" "ri,rm")]
4947 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4948 (plus:SI (match_dup 1) (match_dup 2)))]
4949 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4950 "add{l}\t{%2, %0|%0, %2}"
4951 [(set_attr "type" "alu")
4952 (set_attr "mode" "SI")])
4954 (define_insn "addqi3_cc"
4955 [(set (reg:CC FLAGS_REG)
4956 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4957 (match_operand:QI 2 "general_operand" "qi,qm")]
4959 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4960 (plus:QI (match_dup 1) (match_dup 2)))]
4961 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4962 "add{b}\t{%2, %0|%0, %2}"
4963 [(set_attr "type" "alu")
4964 (set_attr "mode" "QI")])
4966 (define_expand "addsi3"
4967 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4968 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4969 (match_operand:SI 2 "general_operand" "")))
4970 (clobber (reg:CC FLAGS_REG))])]
4972 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4974 (define_insn "*lea_1"
4975 [(set (match_operand:SI 0 "register_operand" "=r")
4976 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4978 "lea{l}\t{%a1, %0|%0, %a1}"
4979 [(set_attr "type" "lea")
4980 (set_attr "mode" "SI")])
4982 (define_insn "*lea_1_rex64"
4983 [(set (match_operand:SI 0 "register_operand" "=r")
4984 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4986 "lea{l}\t{%a1, %0|%0, %a1}"
4987 [(set_attr "type" "lea")
4988 (set_attr "mode" "SI")])
4990 (define_insn "*lea_1_zext"
4991 [(set (match_operand:DI 0 "register_operand" "=r")
4993 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4995 "lea{l}\t{%a1, %k0|%k0, %a1}"
4996 [(set_attr "type" "lea")
4997 (set_attr "mode" "SI")])
4999 (define_insn "*lea_2_rex64"
5000 [(set (match_operand:DI 0 "register_operand" "=r")
5001 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5003 "lea{q}\t{%a1, %0|%0, %a1}"
5004 [(set_attr "type" "lea")
5005 (set_attr "mode" "DI")])
5007 ;; The lea patterns for non-Pmodes needs to be matched by several
5008 ;; insns converted to real lea by splitters.
5010 (define_insn_and_split "*lea_general_1"
5011 [(set (match_operand 0 "register_operand" "=r")
5012 (plus (plus (match_operand 1 "index_register_operand" "l")
5013 (match_operand 2 "register_operand" "r"))
5014 (match_operand 3 "immediate_operand" "i")))]
5015 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5016 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5017 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5018 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5019 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5020 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5021 || GET_MODE (operands[3]) == VOIDmode)"
5023 "&& reload_completed"
5027 operands[0] = gen_lowpart (SImode, operands[0]);
5028 operands[1] = gen_lowpart (Pmode, operands[1]);
5029 operands[2] = gen_lowpart (Pmode, operands[2]);
5030 operands[3] = gen_lowpart (Pmode, operands[3]);
5031 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5033 if (Pmode != SImode)
5034 pat = gen_rtx_SUBREG (SImode, pat, 0);
5035 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5038 [(set_attr "type" "lea")
5039 (set_attr "mode" "SI")])
5041 (define_insn_and_split "*lea_general_1_zext"
5042 [(set (match_operand:DI 0 "register_operand" "=r")
5044 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5045 (match_operand:SI 2 "register_operand" "r"))
5046 (match_operand:SI 3 "immediate_operand" "i"))))]
5049 "&& reload_completed"
5051 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5053 (match_dup 3)) 0)))]
5055 operands[1] = gen_lowpart (Pmode, operands[1]);
5056 operands[2] = gen_lowpart (Pmode, operands[2]);
5057 operands[3] = gen_lowpart (Pmode, operands[3]);
5059 [(set_attr "type" "lea")
5060 (set_attr "mode" "SI")])
5062 (define_insn_and_split "*lea_general_2"
5063 [(set (match_operand 0 "register_operand" "=r")
5064 (plus (mult (match_operand 1 "index_register_operand" "l")
5065 (match_operand 2 "const248_operand" "i"))
5066 (match_operand 3 "nonmemory_operand" "ri")))]
5067 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5068 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5069 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5070 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5071 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5072 || GET_MODE (operands[3]) == VOIDmode)"
5074 "&& reload_completed"
5078 operands[0] = gen_lowpart (SImode, operands[0]);
5079 operands[1] = gen_lowpart (Pmode, operands[1]);
5080 operands[3] = gen_lowpart (Pmode, operands[3]);
5081 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5083 if (Pmode != SImode)
5084 pat = gen_rtx_SUBREG (SImode, pat, 0);
5085 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5088 [(set_attr "type" "lea")
5089 (set_attr "mode" "SI")])
5091 (define_insn_and_split "*lea_general_2_zext"
5092 [(set (match_operand:DI 0 "register_operand" "=r")
5094 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5095 (match_operand:SI 2 "const248_operand" "n"))
5096 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5099 "&& reload_completed"
5101 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5103 (match_dup 3)) 0)))]
5105 operands[1] = gen_lowpart (Pmode, operands[1]);
5106 operands[3] = gen_lowpart (Pmode, operands[3]);
5108 [(set_attr "type" "lea")
5109 (set_attr "mode" "SI")])
5111 (define_insn_and_split "*lea_general_3"
5112 [(set (match_operand 0 "register_operand" "=r")
5113 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5114 (match_operand 2 "const248_operand" "i"))
5115 (match_operand 3 "register_operand" "r"))
5116 (match_operand 4 "immediate_operand" "i")))]
5117 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5118 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5119 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5120 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5121 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5123 "&& reload_completed"
5127 operands[0] = gen_lowpart (SImode, operands[0]);
5128 operands[1] = gen_lowpart (Pmode, operands[1]);
5129 operands[3] = gen_lowpart (Pmode, operands[3]);
5130 operands[4] = gen_lowpart (Pmode, operands[4]);
5131 pat = gen_rtx_PLUS (Pmode,
5132 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5136 if (Pmode != SImode)
5137 pat = gen_rtx_SUBREG (SImode, pat, 0);
5138 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5141 [(set_attr "type" "lea")
5142 (set_attr "mode" "SI")])
5144 (define_insn_and_split "*lea_general_3_zext"
5145 [(set (match_operand:DI 0 "register_operand" "=r")
5147 (plus:SI (plus:SI (mult:SI
5148 (match_operand:SI 1 "index_register_operand" "l")
5149 (match_operand:SI 2 "const248_operand" "n"))
5150 (match_operand:SI 3 "register_operand" "r"))
5151 (match_operand:SI 4 "immediate_operand" "i"))))]
5154 "&& reload_completed"
5156 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5159 (match_dup 4)) 0)))]
5161 operands[1] = gen_lowpart (Pmode, operands[1]);
5162 operands[3] = gen_lowpart (Pmode, operands[3]);
5163 operands[4] = gen_lowpart (Pmode, operands[4]);
5165 [(set_attr "type" "lea")
5166 (set_attr "mode" "SI")])
5168 (define_insn "*adddi_1_rex64"
5169 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5170 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5171 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5172 (clobber (reg:CC FLAGS_REG))]
5173 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5175 switch (get_attr_type (insn))
5178 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5179 return "lea{q}\t{%a2, %0|%0, %a2}";
5182 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5183 if (operands[2] == const1_rtx)
5184 return "inc{q}\t%0";
5187 gcc_assert (operands[2] == constm1_rtx);
5188 return "dec{q}\t%0";
5192 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5194 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5195 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5196 if (GET_CODE (operands[2]) == CONST_INT
5197 /* Avoid overflows. */
5198 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5199 && (INTVAL (operands[2]) == 128
5200 || (INTVAL (operands[2]) < 0
5201 && INTVAL (operands[2]) != -128)))
5203 operands[2] = GEN_INT (-INTVAL (operands[2]));
5204 return "sub{q}\t{%2, %0|%0, %2}";
5206 return "add{q}\t{%2, %0|%0, %2}";
5210 (cond [(eq_attr "alternative" "2")
5211 (const_string "lea")
5212 ; Current assemblers are broken and do not allow @GOTOFF in
5213 ; ought but a memory context.
5214 (match_operand:DI 2 "pic_symbolic_operand" "")
5215 (const_string "lea")
5216 (match_operand:DI 2 "incdec_operand" "")
5217 (const_string "incdec")
5219 (const_string "alu")))
5220 (set_attr "mode" "DI")])
5222 ;; Convert lea to the lea pattern to avoid flags dependency.
5224 [(set (match_operand:DI 0 "register_operand" "")
5225 (plus:DI (match_operand:DI 1 "register_operand" "")
5226 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5227 (clobber (reg:CC FLAGS_REG))]
5228 "TARGET_64BIT && reload_completed
5229 && true_regnum (operands[0]) != true_regnum (operands[1])"
5231 (plus:DI (match_dup 1)
5235 (define_insn "*adddi_2_rex64"
5236 [(set (reg FLAGS_REG)
5238 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5239 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5241 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5242 (plus:DI (match_dup 1) (match_dup 2)))]
5243 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5244 && ix86_binary_operator_ok (PLUS, DImode, operands)
5245 /* Current assemblers are broken and do not allow @GOTOFF in
5246 ought but a memory context. */
5247 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5249 switch (get_attr_type (insn))
5252 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5253 if (operands[2] == const1_rtx)
5254 return "inc{q}\t%0";
5257 gcc_assert (operands[2] == constm1_rtx);
5258 return "dec{q}\t%0";
5262 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5263 /* ???? We ought to handle there the 32bit case too
5264 - do we need new constraint? */
5265 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5266 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5267 if (GET_CODE (operands[2]) == CONST_INT
5268 /* Avoid overflows. */
5269 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5270 && (INTVAL (operands[2]) == 128
5271 || (INTVAL (operands[2]) < 0
5272 && INTVAL (operands[2]) != -128)))
5274 operands[2] = GEN_INT (-INTVAL (operands[2]));
5275 return "sub{q}\t{%2, %0|%0, %2}";
5277 return "add{q}\t{%2, %0|%0, %2}";
5281 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5282 (const_string "incdec")
5283 (const_string "alu")))
5284 (set_attr "mode" "DI")])
5286 (define_insn "*adddi_3_rex64"
5287 [(set (reg FLAGS_REG)
5288 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5289 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5290 (clobber (match_scratch:DI 0 "=r"))]
5292 && ix86_match_ccmode (insn, CCZmode)
5293 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5294 /* Current assemblers are broken and do not allow @GOTOFF in
5295 ought but a memory context. */
5296 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5298 switch (get_attr_type (insn))
5301 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5302 if (operands[2] == const1_rtx)
5303 return "inc{q}\t%0";
5306 gcc_assert (operands[2] == constm1_rtx);
5307 return "dec{q}\t%0";
5311 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5312 /* ???? We ought to handle there the 32bit case too
5313 - do we need new constraint? */
5314 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5315 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5316 if (GET_CODE (operands[2]) == CONST_INT
5317 /* Avoid overflows. */
5318 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5319 && (INTVAL (operands[2]) == 128
5320 || (INTVAL (operands[2]) < 0
5321 && INTVAL (operands[2]) != -128)))
5323 operands[2] = GEN_INT (-INTVAL (operands[2]));
5324 return "sub{q}\t{%2, %0|%0, %2}";
5326 return "add{q}\t{%2, %0|%0, %2}";
5330 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5331 (const_string "incdec")
5332 (const_string "alu")))
5333 (set_attr "mode" "DI")])
5335 ; For comparisons against 1, -1 and 128, we may generate better code
5336 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5337 ; is matched then. We can't accept general immediate, because for
5338 ; case of overflows, the result is messed up.
5339 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5341 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5342 ; only for comparisons not depending on it.
5343 (define_insn "*adddi_4_rex64"
5344 [(set (reg FLAGS_REG)
5345 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5346 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5347 (clobber (match_scratch:DI 0 "=rm"))]
5349 && ix86_match_ccmode (insn, CCGCmode)"
5351 switch (get_attr_type (insn))
5354 if (operands[2] == constm1_rtx)
5355 return "inc{q}\t%0";
5358 gcc_assert (operands[2] == const1_rtx);
5359 return "dec{q}\t%0";
5363 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5364 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5365 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5366 if ((INTVAL (operands[2]) == -128
5367 || (INTVAL (operands[2]) > 0
5368 && INTVAL (operands[2]) != 128))
5369 /* Avoid overflows. */
5370 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5371 return "sub{q}\t{%2, %0|%0, %2}";
5372 operands[2] = GEN_INT (-INTVAL (operands[2]));
5373 return "add{q}\t{%2, %0|%0, %2}";
5377 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5378 (const_string "incdec")
5379 (const_string "alu")))
5380 (set_attr "mode" "DI")])
5382 (define_insn "*adddi_5_rex64"
5383 [(set (reg FLAGS_REG)
5385 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5386 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5388 (clobber (match_scratch:DI 0 "=r"))]
5390 && ix86_match_ccmode (insn, CCGOCmode)
5391 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5392 /* Current assemblers are broken and do not allow @GOTOFF in
5393 ought but a memory context. */
5394 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5396 switch (get_attr_type (insn))
5399 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5400 if (operands[2] == const1_rtx)
5401 return "inc{q}\t%0";
5404 gcc_assert (operands[2] == constm1_rtx);
5405 return "dec{q}\t%0";
5409 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5410 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5411 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5412 if (GET_CODE (operands[2]) == CONST_INT
5413 /* Avoid overflows. */
5414 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5415 && (INTVAL (operands[2]) == 128
5416 || (INTVAL (operands[2]) < 0
5417 && INTVAL (operands[2]) != -128)))
5419 operands[2] = GEN_INT (-INTVAL (operands[2]));
5420 return "sub{q}\t{%2, %0|%0, %2}";
5422 return "add{q}\t{%2, %0|%0, %2}";
5426 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5427 (const_string "incdec")
5428 (const_string "alu")))
5429 (set_attr "mode" "DI")])
5432 (define_insn "*addsi_1"
5433 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5434 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5435 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5436 (clobber (reg:CC FLAGS_REG))]
5437 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5439 switch (get_attr_type (insn))
5442 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5443 return "lea{l}\t{%a2, %0|%0, %a2}";
5446 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5447 if (operands[2] == const1_rtx)
5448 return "inc{l}\t%0";
5451 gcc_assert (operands[2] == constm1_rtx);
5452 return "dec{l}\t%0";
5456 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5458 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5459 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5460 if (GET_CODE (operands[2]) == CONST_INT
5461 && (INTVAL (operands[2]) == 128
5462 || (INTVAL (operands[2]) < 0
5463 && INTVAL (operands[2]) != -128)))
5465 operands[2] = GEN_INT (-INTVAL (operands[2]));
5466 return "sub{l}\t{%2, %0|%0, %2}";
5468 return "add{l}\t{%2, %0|%0, %2}";
5472 (cond [(eq_attr "alternative" "2")
5473 (const_string "lea")
5474 ; Current assemblers are broken and do not allow @GOTOFF in
5475 ; ought but a memory context.
5476 (match_operand:SI 2 "pic_symbolic_operand" "")
5477 (const_string "lea")
5478 (match_operand:SI 2 "incdec_operand" "")
5479 (const_string "incdec")
5481 (const_string "alu")))
5482 (set_attr "mode" "SI")])
5484 ;; Convert lea to the lea pattern to avoid flags dependency.
5486 [(set (match_operand 0 "register_operand" "")
5487 (plus (match_operand 1 "register_operand" "")
5488 (match_operand 2 "nonmemory_operand" "")))
5489 (clobber (reg:CC FLAGS_REG))]
5491 && true_regnum (operands[0]) != true_regnum (operands[1])"
5495 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5496 may confuse gen_lowpart. */
5497 if (GET_MODE (operands[0]) != Pmode)
5499 operands[1] = gen_lowpart (Pmode, operands[1]);
5500 operands[2] = gen_lowpart (Pmode, operands[2]);
5502 operands[0] = gen_lowpart (SImode, operands[0]);
5503 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5504 if (Pmode != SImode)
5505 pat = gen_rtx_SUBREG (SImode, pat, 0);
5506 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5510 ;; It may seem that nonimmediate operand is proper one for operand 1.
5511 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5512 ;; we take care in ix86_binary_operator_ok to not allow two memory
5513 ;; operands so proper swapping will be done in reload. This allow
5514 ;; patterns constructed from addsi_1 to match.
5515 (define_insn "addsi_1_zext"
5516 [(set (match_operand:DI 0 "register_operand" "=r,r")
5518 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5519 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5520 (clobber (reg:CC FLAGS_REG))]
5521 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5523 switch (get_attr_type (insn))
5526 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5527 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5530 if (operands[2] == const1_rtx)
5531 return "inc{l}\t%k0";
5534 gcc_assert (operands[2] == constm1_rtx);
5535 return "dec{l}\t%k0";
5539 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5540 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5541 if (GET_CODE (operands[2]) == CONST_INT
5542 && (INTVAL (operands[2]) == 128
5543 || (INTVAL (operands[2]) < 0
5544 && INTVAL (operands[2]) != -128)))
5546 operands[2] = GEN_INT (-INTVAL (operands[2]));
5547 return "sub{l}\t{%2, %k0|%k0, %2}";
5549 return "add{l}\t{%2, %k0|%k0, %2}";
5553 (cond [(eq_attr "alternative" "1")
5554 (const_string "lea")
5555 ; Current assemblers are broken and do not allow @GOTOFF in
5556 ; ought but a memory context.
5557 (match_operand:SI 2 "pic_symbolic_operand" "")
5558 (const_string "lea")
5559 (match_operand:SI 2 "incdec_operand" "")
5560 (const_string "incdec")
5562 (const_string "alu")))
5563 (set_attr "mode" "SI")])
5565 ;; Convert lea to the lea pattern to avoid flags dependency.
5567 [(set (match_operand:DI 0 "register_operand" "")
5569 (plus:SI (match_operand:SI 1 "register_operand" "")
5570 (match_operand:SI 2 "nonmemory_operand" ""))))
5571 (clobber (reg:CC FLAGS_REG))]
5572 "TARGET_64BIT && reload_completed
5573 && true_regnum (operands[0]) != true_regnum (operands[1])"
5575 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5577 operands[1] = gen_lowpart (Pmode, operands[1]);
5578 operands[2] = gen_lowpart (Pmode, operands[2]);
5581 (define_insn "*addsi_2"
5582 [(set (reg FLAGS_REG)
5584 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5585 (match_operand:SI 2 "general_operand" "rmni,rni"))
5587 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5588 (plus:SI (match_dup 1) (match_dup 2)))]
5589 "ix86_match_ccmode (insn, CCGOCmode)
5590 && ix86_binary_operator_ok (PLUS, SImode, operands)
5591 /* Current assemblers are broken and do not allow @GOTOFF in
5592 ought but a memory context. */
5593 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5595 switch (get_attr_type (insn))
5598 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5599 if (operands[2] == const1_rtx)
5600 return "inc{l}\t%0";
5603 gcc_assert (operands[2] == constm1_rtx);
5604 return "dec{l}\t%0";
5608 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5609 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5610 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5611 if (GET_CODE (operands[2]) == CONST_INT
5612 && (INTVAL (operands[2]) == 128
5613 || (INTVAL (operands[2]) < 0
5614 && INTVAL (operands[2]) != -128)))
5616 operands[2] = GEN_INT (-INTVAL (operands[2]));
5617 return "sub{l}\t{%2, %0|%0, %2}";
5619 return "add{l}\t{%2, %0|%0, %2}";
5623 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5624 (const_string "incdec")
5625 (const_string "alu")))
5626 (set_attr "mode" "SI")])
5628 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5629 (define_insn "*addsi_2_zext"
5630 [(set (reg FLAGS_REG)
5632 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5633 (match_operand:SI 2 "general_operand" "rmni"))
5635 (set (match_operand:DI 0 "register_operand" "=r")
5636 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5637 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5638 && ix86_binary_operator_ok (PLUS, SImode, operands)
5639 /* Current assemblers are broken and do not allow @GOTOFF in
5640 ought but a memory context. */
5641 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5643 switch (get_attr_type (insn))
5646 if (operands[2] == const1_rtx)
5647 return "inc{l}\t%k0";
5650 gcc_assert (operands[2] == constm1_rtx);
5651 return "dec{l}\t%k0";
5655 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5656 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5657 if (GET_CODE (operands[2]) == CONST_INT
5658 && (INTVAL (operands[2]) == 128
5659 || (INTVAL (operands[2]) < 0
5660 && INTVAL (operands[2]) != -128)))
5662 operands[2] = GEN_INT (-INTVAL (operands[2]));
5663 return "sub{l}\t{%2, %k0|%k0, %2}";
5665 return "add{l}\t{%2, %k0|%k0, %2}";
5669 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5670 (const_string "incdec")
5671 (const_string "alu")))
5672 (set_attr "mode" "SI")])
5674 (define_insn "*addsi_3"
5675 [(set (reg FLAGS_REG)
5676 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5677 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5678 (clobber (match_scratch:SI 0 "=r"))]
5679 "ix86_match_ccmode (insn, CCZmode)
5680 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5681 /* Current assemblers are broken and do not allow @GOTOFF in
5682 ought but a memory context. */
5683 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5685 switch (get_attr_type (insn))
5688 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689 if (operands[2] == const1_rtx)
5690 return "inc{l}\t%0";
5693 gcc_assert (operands[2] == constm1_rtx);
5694 return "dec{l}\t%0";
5698 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5699 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5700 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5701 if (GET_CODE (operands[2]) == CONST_INT
5702 && (INTVAL (operands[2]) == 128
5703 || (INTVAL (operands[2]) < 0
5704 && INTVAL (operands[2]) != -128)))
5706 operands[2] = GEN_INT (-INTVAL (operands[2]));
5707 return "sub{l}\t{%2, %0|%0, %2}";
5709 return "add{l}\t{%2, %0|%0, %2}";
5713 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5714 (const_string "incdec")
5715 (const_string "alu")))
5716 (set_attr "mode" "SI")])
5718 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5719 (define_insn "*addsi_3_zext"
5720 [(set (reg FLAGS_REG)
5721 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5722 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5723 (set (match_operand:DI 0 "register_operand" "=r")
5724 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5725 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5726 && ix86_binary_operator_ok (PLUS, SImode, operands)
5727 /* Current assemblers are broken and do not allow @GOTOFF in
5728 ought but a memory context. */
5729 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5731 switch (get_attr_type (insn))
5734 if (operands[2] == const1_rtx)
5735 return "inc{l}\t%k0";
5738 gcc_assert (operands[2] == constm1_rtx);
5739 return "dec{l}\t%k0";
5743 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5744 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5745 if (GET_CODE (operands[2]) == CONST_INT
5746 && (INTVAL (operands[2]) == 128
5747 || (INTVAL (operands[2]) < 0
5748 && INTVAL (operands[2]) != -128)))
5750 operands[2] = GEN_INT (-INTVAL (operands[2]));
5751 return "sub{l}\t{%2, %k0|%k0, %2}";
5753 return "add{l}\t{%2, %k0|%k0, %2}";
5757 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5758 (const_string "incdec")
5759 (const_string "alu")))
5760 (set_attr "mode" "SI")])
5762 ; For comparisons against 1, -1 and 128, we may generate better code
5763 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5764 ; is matched then. We can't accept general immediate, because for
5765 ; case of overflows, the result is messed up.
5766 ; This pattern also don't hold of 0x80000000, since the value overflows
5768 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5769 ; only for comparisons not depending on it.
5770 (define_insn "*addsi_4"
5771 [(set (reg FLAGS_REG)
5772 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5773 (match_operand:SI 2 "const_int_operand" "n")))
5774 (clobber (match_scratch:SI 0 "=rm"))]
5775 "ix86_match_ccmode (insn, CCGCmode)
5776 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5778 switch (get_attr_type (insn))
5781 if (operands[2] == constm1_rtx)
5782 return "inc{l}\t%0";
5785 gcc_assert (operands[2] == const1_rtx);
5786 return "dec{l}\t%0";
5790 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5791 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5792 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5793 if ((INTVAL (operands[2]) == -128
5794 || (INTVAL (operands[2]) > 0
5795 && INTVAL (operands[2]) != 128)))
5796 return "sub{l}\t{%2, %0|%0, %2}";
5797 operands[2] = GEN_INT (-INTVAL (operands[2]));
5798 return "add{l}\t{%2, %0|%0, %2}";
5802 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5803 (const_string "incdec")
5804 (const_string "alu")))
5805 (set_attr "mode" "SI")])
5807 (define_insn "*addsi_5"
5808 [(set (reg FLAGS_REG)
5810 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5811 (match_operand:SI 2 "general_operand" "rmni"))
5813 (clobber (match_scratch:SI 0 "=r"))]
5814 "ix86_match_ccmode (insn, CCGOCmode)
5815 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5816 /* Current assemblers are broken and do not allow @GOTOFF in
5817 ought but a memory context. */
5818 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5820 switch (get_attr_type (insn))
5823 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5824 if (operands[2] == const1_rtx)
5825 return "inc{l}\t%0";
5828 gcc_assert (operands[2] == constm1_rtx);
5829 return "dec{l}\t%0";
5833 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5834 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5835 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5836 if (GET_CODE (operands[2]) == CONST_INT
5837 && (INTVAL (operands[2]) == 128
5838 || (INTVAL (operands[2]) < 0
5839 && INTVAL (operands[2]) != -128)))
5841 operands[2] = GEN_INT (-INTVAL (operands[2]));
5842 return "sub{l}\t{%2, %0|%0, %2}";
5844 return "add{l}\t{%2, %0|%0, %2}";
5848 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5849 (const_string "incdec")
5850 (const_string "alu")))
5851 (set_attr "mode" "SI")])
5853 (define_expand "addhi3"
5854 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5855 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5856 (match_operand:HI 2 "general_operand" "")))
5857 (clobber (reg:CC FLAGS_REG))])]
5858 "TARGET_HIMODE_MATH"
5859 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5861 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5862 ;; type optimizations enabled by define-splits. This is not important
5863 ;; for PII, and in fact harmful because of partial register stalls.
5865 (define_insn "*addhi_1_lea"
5866 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5867 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5868 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5869 (clobber (reg:CC FLAGS_REG))]
5870 "!TARGET_PARTIAL_REG_STALL
5871 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5873 switch (get_attr_type (insn))
5878 if (operands[2] == const1_rtx)
5879 return "inc{w}\t%0";
5882 gcc_assert (operands[2] == constm1_rtx);
5883 return "dec{w}\t%0";
5887 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5888 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5889 if (GET_CODE (operands[2]) == CONST_INT
5890 && (INTVAL (operands[2]) == 128
5891 || (INTVAL (operands[2]) < 0
5892 && INTVAL (operands[2]) != -128)))
5894 operands[2] = GEN_INT (-INTVAL (operands[2]));
5895 return "sub{w}\t{%2, %0|%0, %2}";
5897 return "add{w}\t{%2, %0|%0, %2}";
5901 (if_then_else (eq_attr "alternative" "2")
5902 (const_string "lea")
5903 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5904 (const_string "incdec")
5905 (const_string "alu"))))
5906 (set_attr "mode" "HI,HI,SI")])
5908 (define_insn "*addhi_1"
5909 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5910 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5911 (match_operand:HI 2 "general_operand" "ri,rm")))
5912 (clobber (reg:CC FLAGS_REG))]
5913 "TARGET_PARTIAL_REG_STALL
5914 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5916 switch (get_attr_type (insn))
5919 if (operands[2] == const1_rtx)
5920 return "inc{w}\t%0";
5923 gcc_assert (operands[2] == constm1_rtx);
5924 return "dec{w}\t%0";
5928 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5929 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5930 if (GET_CODE (operands[2]) == CONST_INT
5931 && (INTVAL (operands[2]) == 128
5932 || (INTVAL (operands[2]) < 0
5933 && INTVAL (operands[2]) != -128)))
5935 operands[2] = GEN_INT (-INTVAL (operands[2]));
5936 return "sub{w}\t{%2, %0|%0, %2}";
5938 return "add{w}\t{%2, %0|%0, %2}";
5942 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5943 (const_string "incdec")
5944 (const_string "alu")))
5945 (set_attr "mode" "HI")])
5947 (define_insn "*addhi_2"
5948 [(set (reg FLAGS_REG)
5950 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5951 (match_operand:HI 2 "general_operand" "rmni,rni"))
5953 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5954 (plus:HI (match_dup 1) (match_dup 2)))]
5955 "ix86_match_ccmode (insn, CCGOCmode)
5956 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5958 switch (get_attr_type (insn))
5961 if (operands[2] == const1_rtx)
5962 return "inc{w}\t%0";
5965 gcc_assert (operands[2] == constm1_rtx);
5966 return "dec{w}\t%0";
5970 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5971 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5972 if (GET_CODE (operands[2]) == CONST_INT
5973 && (INTVAL (operands[2]) == 128
5974 || (INTVAL (operands[2]) < 0
5975 && INTVAL (operands[2]) != -128)))
5977 operands[2] = GEN_INT (-INTVAL (operands[2]));
5978 return "sub{w}\t{%2, %0|%0, %2}";
5980 return "add{w}\t{%2, %0|%0, %2}";
5984 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5985 (const_string "incdec")
5986 (const_string "alu")))
5987 (set_attr "mode" "HI")])
5989 (define_insn "*addhi_3"
5990 [(set (reg FLAGS_REG)
5991 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5992 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5993 (clobber (match_scratch:HI 0 "=r"))]
5994 "ix86_match_ccmode (insn, CCZmode)
5995 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5997 switch (get_attr_type (insn))
6000 if (operands[2] == const1_rtx)
6001 return "inc{w}\t%0";
6004 gcc_assert (operands[2] == constm1_rtx);
6005 return "dec{w}\t%0";
6009 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6010 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6011 if (GET_CODE (operands[2]) == CONST_INT
6012 && (INTVAL (operands[2]) == 128
6013 || (INTVAL (operands[2]) < 0
6014 && INTVAL (operands[2]) != -128)))
6016 operands[2] = GEN_INT (-INTVAL (operands[2]));
6017 return "sub{w}\t{%2, %0|%0, %2}";
6019 return "add{w}\t{%2, %0|%0, %2}";
6023 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6024 (const_string "incdec")
6025 (const_string "alu")))
6026 (set_attr "mode" "HI")])
6028 ; See comments above addsi_4 for details.
6029 (define_insn "*addhi_4"
6030 [(set (reg FLAGS_REG)
6031 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6032 (match_operand:HI 2 "const_int_operand" "n")))
6033 (clobber (match_scratch:HI 0 "=rm"))]
6034 "ix86_match_ccmode (insn, CCGCmode)
6035 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6037 switch (get_attr_type (insn))
6040 if (operands[2] == constm1_rtx)
6041 return "inc{w}\t%0";
6044 gcc_assert (operands[2] == const1_rtx);
6045 return "dec{w}\t%0";
6049 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6050 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6051 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6052 if ((INTVAL (operands[2]) == -128
6053 || (INTVAL (operands[2]) > 0
6054 && INTVAL (operands[2]) != 128)))
6055 return "sub{w}\t{%2, %0|%0, %2}";
6056 operands[2] = GEN_INT (-INTVAL (operands[2]));
6057 return "add{w}\t{%2, %0|%0, %2}";
6061 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6062 (const_string "incdec")
6063 (const_string "alu")))
6064 (set_attr "mode" "SI")])
6067 (define_insn "*addhi_5"
6068 [(set (reg FLAGS_REG)
6070 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6071 (match_operand:HI 2 "general_operand" "rmni"))
6073 (clobber (match_scratch:HI 0 "=r"))]
6074 "ix86_match_ccmode (insn, CCGOCmode)
6075 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6077 switch (get_attr_type (insn))
6080 if (operands[2] == const1_rtx)
6081 return "inc{w}\t%0";
6084 gcc_assert (operands[2] == constm1_rtx);
6085 return "dec{w}\t%0";
6089 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6090 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6091 if (GET_CODE (operands[2]) == CONST_INT
6092 && (INTVAL (operands[2]) == 128
6093 || (INTVAL (operands[2]) < 0
6094 && INTVAL (operands[2]) != -128)))
6096 operands[2] = GEN_INT (-INTVAL (operands[2]));
6097 return "sub{w}\t{%2, %0|%0, %2}";
6099 return "add{w}\t{%2, %0|%0, %2}";
6103 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6104 (const_string "incdec")
6105 (const_string "alu")))
6106 (set_attr "mode" "HI")])
6108 (define_expand "addqi3"
6109 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6110 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6111 (match_operand:QI 2 "general_operand" "")))
6112 (clobber (reg:CC FLAGS_REG))])]
6113 "TARGET_QIMODE_MATH"
6114 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6116 ;; %%% Potential partial reg stall on alternative 2. What to do?
6117 (define_insn "*addqi_1_lea"
6118 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6119 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6120 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6121 (clobber (reg:CC FLAGS_REG))]
6122 "!TARGET_PARTIAL_REG_STALL
6123 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6125 int widen = (which_alternative == 2);
6126 switch (get_attr_type (insn))
6131 if (operands[2] == const1_rtx)
6132 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6135 gcc_assert (operands[2] == constm1_rtx);
6136 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6140 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6141 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6142 if (GET_CODE (operands[2]) == CONST_INT
6143 && (INTVAL (operands[2]) == 128
6144 || (INTVAL (operands[2]) < 0
6145 && INTVAL (operands[2]) != -128)))
6147 operands[2] = GEN_INT (-INTVAL (operands[2]));
6149 return "sub{l}\t{%2, %k0|%k0, %2}";
6151 return "sub{b}\t{%2, %0|%0, %2}";
6154 return "add{l}\t{%k2, %k0|%k0, %k2}";
6156 return "add{b}\t{%2, %0|%0, %2}";
6160 (if_then_else (eq_attr "alternative" "3")
6161 (const_string "lea")
6162 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6163 (const_string "incdec")
6164 (const_string "alu"))))
6165 (set_attr "mode" "QI,QI,SI,SI")])
6167 (define_insn "*addqi_1"
6168 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6169 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6170 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6171 (clobber (reg:CC FLAGS_REG))]
6172 "TARGET_PARTIAL_REG_STALL
6173 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6175 int widen = (which_alternative == 2);
6176 switch (get_attr_type (insn))
6179 if (operands[2] == const1_rtx)
6180 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6183 gcc_assert (operands[2] == constm1_rtx);
6184 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6188 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6189 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6190 if (GET_CODE (operands[2]) == CONST_INT
6191 && (INTVAL (operands[2]) == 128
6192 || (INTVAL (operands[2]) < 0
6193 && INTVAL (operands[2]) != -128)))
6195 operands[2] = GEN_INT (-INTVAL (operands[2]));
6197 return "sub{l}\t{%2, %k0|%k0, %2}";
6199 return "sub{b}\t{%2, %0|%0, %2}";
6202 return "add{l}\t{%k2, %k0|%k0, %k2}";
6204 return "add{b}\t{%2, %0|%0, %2}";
6208 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6209 (const_string "incdec")
6210 (const_string "alu")))
6211 (set_attr "mode" "QI,QI,SI")])
6213 (define_insn "*addqi_1_slp"
6214 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6215 (plus:QI (match_dup 0)
6216 (match_operand:QI 1 "general_operand" "qn,qnm")))
6217 (clobber (reg:CC FLAGS_REG))]
6218 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6219 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6221 switch (get_attr_type (insn))
6224 if (operands[1] == const1_rtx)
6225 return "inc{b}\t%0";
6228 gcc_assert (operands[1] == constm1_rtx);
6229 return "dec{b}\t%0";
6233 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6234 if (GET_CODE (operands[1]) == CONST_INT
6235 && INTVAL (operands[1]) < 0)
6237 operands[1] = GEN_INT (-INTVAL (operands[1]));
6238 return "sub{b}\t{%1, %0|%0, %1}";
6240 return "add{b}\t{%1, %0|%0, %1}";
6244 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6245 (const_string "incdec")
6246 (const_string "alu1")))
6247 (set (attr "memory")
6248 (if_then_else (match_operand 1 "memory_operand" "")
6249 (const_string "load")
6250 (const_string "none")))
6251 (set_attr "mode" "QI")])
6253 (define_insn "*addqi_2"
6254 [(set (reg FLAGS_REG)
6256 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6257 (match_operand:QI 2 "general_operand" "qmni,qni"))
6259 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6260 (plus:QI (match_dup 1) (match_dup 2)))]
6261 "ix86_match_ccmode (insn, CCGOCmode)
6262 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6264 switch (get_attr_type (insn))
6267 if (operands[2] == const1_rtx)
6268 return "inc{b}\t%0";
6271 gcc_assert (operands[2] == constm1_rtx
6272 || (GET_CODE (operands[2]) == CONST_INT
6273 && INTVAL (operands[2]) == 255));
6274 return "dec{b}\t%0";
6278 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6279 if (GET_CODE (operands[2]) == CONST_INT
6280 && INTVAL (operands[2]) < 0)
6282 operands[2] = GEN_INT (-INTVAL (operands[2]));
6283 return "sub{b}\t{%2, %0|%0, %2}";
6285 return "add{b}\t{%2, %0|%0, %2}";
6289 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6290 (const_string "incdec")
6291 (const_string "alu")))
6292 (set_attr "mode" "QI")])
6294 (define_insn "*addqi_3"
6295 [(set (reg FLAGS_REG)
6296 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6297 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6298 (clobber (match_scratch:QI 0 "=q"))]
6299 "ix86_match_ccmode (insn, CCZmode)
6300 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6302 switch (get_attr_type (insn))
6305 if (operands[2] == const1_rtx)
6306 return "inc{b}\t%0";
6309 gcc_assert (operands[2] == constm1_rtx
6310 || (GET_CODE (operands[2]) == CONST_INT
6311 && INTVAL (operands[2]) == 255));
6312 return "dec{b}\t%0";
6316 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6317 if (GET_CODE (operands[2]) == CONST_INT
6318 && INTVAL (operands[2]) < 0)
6320 operands[2] = GEN_INT (-INTVAL (operands[2]));
6321 return "sub{b}\t{%2, %0|%0, %2}";
6323 return "add{b}\t{%2, %0|%0, %2}";
6327 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6328 (const_string "incdec")
6329 (const_string "alu")))
6330 (set_attr "mode" "QI")])
6332 ; See comments above addsi_4 for details.
6333 (define_insn "*addqi_4"
6334 [(set (reg FLAGS_REG)
6335 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6336 (match_operand:QI 2 "const_int_operand" "n")))
6337 (clobber (match_scratch:QI 0 "=qm"))]
6338 "ix86_match_ccmode (insn, CCGCmode)
6339 && (INTVAL (operands[2]) & 0xff) != 0x80"
6341 switch (get_attr_type (insn))
6344 if (operands[2] == constm1_rtx
6345 || (GET_CODE (operands[2]) == CONST_INT
6346 && INTVAL (operands[2]) == 255))
6347 return "inc{b}\t%0";
6350 gcc_assert (operands[2] == const1_rtx);
6351 return "dec{b}\t%0";
6355 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6356 if (INTVAL (operands[2]) < 0)
6358 operands[2] = GEN_INT (-INTVAL (operands[2]));
6359 return "add{b}\t{%2, %0|%0, %2}";
6361 return "sub{b}\t{%2, %0|%0, %2}";
6365 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6366 (const_string "incdec")
6367 (const_string "alu")))
6368 (set_attr "mode" "QI")])
6371 (define_insn "*addqi_5"
6372 [(set (reg FLAGS_REG)
6374 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6375 (match_operand:QI 2 "general_operand" "qmni"))
6377 (clobber (match_scratch:QI 0 "=q"))]
6378 "ix86_match_ccmode (insn, CCGOCmode)
6379 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6381 switch (get_attr_type (insn))
6384 if (operands[2] == const1_rtx)
6385 return "inc{b}\t%0";
6388 gcc_assert (operands[2] == constm1_rtx
6389 || (GET_CODE (operands[2]) == CONST_INT
6390 && INTVAL (operands[2]) == 255));
6391 return "dec{b}\t%0";
6395 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6396 if (GET_CODE (operands[2]) == CONST_INT
6397 && INTVAL (operands[2]) < 0)
6399 operands[2] = GEN_INT (-INTVAL (operands[2]));
6400 return "sub{b}\t{%2, %0|%0, %2}";
6402 return "add{b}\t{%2, %0|%0, %2}";
6406 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6407 (const_string "incdec")
6408 (const_string "alu")))
6409 (set_attr "mode" "QI")])
6412 (define_insn "addqi_ext_1"
6413 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6418 (match_operand 1 "ext_register_operand" "0")
6421 (match_operand:QI 2 "general_operand" "Qmn")))
6422 (clobber (reg:CC FLAGS_REG))]
6425 switch (get_attr_type (insn))
6428 if (operands[2] == const1_rtx)
6429 return "inc{b}\t%h0";
6432 gcc_assert (operands[2] == constm1_rtx
6433 || (GET_CODE (operands[2]) == CONST_INT
6434 && INTVAL (operands[2]) == 255));
6435 return "dec{b}\t%h0";
6439 return "add{b}\t{%2, %h0|%h0, %2}";
6443 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6444 (const_string "incdec")
6445 (const_string "alu")))
6446 (set_attr "mode" "QI")])
6448 (define_insn "*addqi_ext_1_rex64"
6449 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6454 (match_operand 1 "ext_register_operand" "0")
6457 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6458 (clobber (reg:CC FLAGS_REG))]
6461 switch (get_attr_type (insn))
6464 if (operands[2] == const1_rtx)
6465 return "inc{b}\t%h0";
6468 gcc_assert (operands[2] == constm1_rtx
6469 || (GET_CODE (operands[2]) == CONST_INT
6470 && INTVAL (operands[2]) == 255));
6471 return "dec{b}\t%h0";
6475 return "add{b}\t{%2, %h0|%h0, %2}";
6479 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6480 (const_string "incdec")
6481 (const_string "alu")))
6482 (set_attr "mode" "QI")])
6484 (define_insn "*addqi_ext_2"
6485 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6490 (match_operand 1 "ext_register_operand" "%0")
6494 (match_operand 2 "ext_register_operand" "Q")
6497 (clobber (reg:CC FLAGS_REG))]
6499 "add{b}\t{%h2, %h0|%h0, %h2}"
6500 [(set_attr "type" "alu")
6501 (set_attr "mode" "QI")])
6503 ;; The patterns that match these are at the end of this file.
6505 (define_expand "addxf3"
6506 [(set (match_operand:XF 0 "register_operand" "")
6507 (plus:XF (match_operand:XF 1 "register_operand" "")
6508 (match_operand:XF 2 "register_operand" "")))]
6512 (define_expand "adddf3"
6513 [(set (match_operand:DF 0 "register_operand" "")
6514 (plus:DF (match_operand:DF 1 "register_operand" "")
6515 (match_operand:DF 2 "nonimmediate_operand" "")))]
6516 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6519 (define_expand "addsf3"
6520 [(set (match_operand:SF 0 "register_operand" "")
6521 (plus:SF (match_operand:SF 1 "register_operand" "")
6522 (match_operand:SF 2 "nonimmediate_operand" "")))]
6523 "TARGET_80387 || TARGET_SSE_MATH"
6526 ;; Subtract instructions
6528 ;; %%% splits for subditi3
6530 (define_expand "subti3"
6531 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6532 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6533 (match_operand:TI 2 "x86_64_general_operand" "")))
6534 (clobber (reg:CC FLAGS_REG))])]
6536 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6538 (define_insn "*subti3_1"
6539 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6540 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6541 (match_operand:TI 2 "general_operand" "roiF,riF")))
6542 (clobber (reg:CC FLAGS_REG))]
6543 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6547 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6548 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6549 (match_operand:TI 2 "general_operand" "")))
6550 (clobber (reg:CC FLAGS_REG))]
6551 "TARGET_64BIT && reload_completed"
6552 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6553 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6554 (parallel [(set (match_dup 3)
6555 (minus:DI (match_dup 4)
6556 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6558 (clobber (reg:CC FLAGS_REG))])]
6559 "split_ti (operands+0, 1, operands+0, operands+3);
6560 split_ti (operands+1, 1, operands+1, operands+4);
6561 split_ti (operands+2, 1, operands+2, operands+5);")
6563 ;; %%% splits for subsidi3
6565 (define_expand "subdi3"
6566 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6567 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6568 (match_operand:DI 2 "x86_64_general_operand" "")))
6569 (clobber (reg:CC FLAGS_REG))])]
6571 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6573 (define_insn "*subdi3_1"
6574 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6575 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6576 (match_operand:DI 2 "general_operand" "roiF,riF")))
6577 (clobber (reg:CC FLAGS_REG))]
6578 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6582 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6583 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6584 (match_operand:DI 2 "general_operand" "")))
6585 (clobber (reg:CC FLAGS_REG))]
6586 "!TARGET_64BIT && reload_completed"
6587 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6588 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6589 (parallel [(set (match_dup 3)
6590 (minus:SI (match_dup 4)
6591 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6593 (clobber (reg:CC FLAGS_REG))])]
6594 "split_di (operands+0, 1, operands+0, operands+3);
6595 split_di (operands+1, 1, operands+1, operands+4);
6596 split_di (operands+2, 1, operands+2, operands+5);")
6598 (define_insn "subdi3_carry_rex64"
6599 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6600 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6601 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6602 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6603 (clobber (reg:CC FLAGS_REG))]
6604 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6605 "sbb{q}\t{%2, %0|%0, %2}"
6606 [(set_attr "type" "alu")
6607 (set_attr "pent_pair" "pu")
6608 (set_attr "mode" "DI")])
6610 (define_insn "*subdi_1_rex64"
6611 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6612 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6613 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6614 (clobber (reg:CC FLAGS_REG))]
6615 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6616 "sub{q}\t{%2, %0|%0, %2}"
6617 [(set_attr "type" "alu")
6618 (set_attr "mode" "DI")])
6620 (define_insn "*subdi_2_rex64"
6621 [(set (reg FLAGS_REG)
6623 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6624 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6626 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6627 (minus:DI (match_dup 1) (match_dup 2)))]
6628 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6629 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6630 "sub{q}\t{%2, %0|%0, %2}"
6631 [(set_attr "type" "alu")
6632 (set_attr "mode" "DI")])
6634 (define_insn "*subdi_3_rex63"
6635 [(set (reg FLAGS_REG)
6636 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6637 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6638 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6639 (minus:DI (match_dup 1) (match_dup 2)))]
6640 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6641 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6642 "sub{q}\t{%2, %0|%0, %2}"
6643 [(set_attr "type" "alu")
6644 (set_attr "mode" "DI")])
6646 (define_insn "subqi3_carry"
6647 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6648 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6649 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6650 (match_operand:QI 2 "general_operand" "qi,qm"))))
6651 (clobber (reg:CC FLAGS_REG))]
6652 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6653 "sbb{b}\t{%2, %0|%0, %2}"
6654 [(set_attr "type" "alu")
6655 (set_attr "pent_pair" "pu")
6656 (set_attr "mode" "QI")])
6658 (define_insn "subhi3_carry"
6659 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6660 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6661 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6662 (match_operand:HI 2 "general_operand" "ri,rm"))))
6663 (clobber (reg:CC FLAGS_REG))]
6664 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6665 "sbb{w}\t{%2, %0|%0, %2}"
6666 [(set_attr "type" "alu")
6667 (set_attr "pent_pair" "pu")
6668 (set_attr "mode" "HI")])
6670 (define_insn "subsi3_carry"
6671 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6672 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6674 (match_operand:SI 2 "general_operand" "ri,rm"))))
6675 (clobber (reg:CC FLAGS_REG))]
6676 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6677 "sbb{l}\t{%2, %0|%0, %2}"
6678 [(set_attr "type" "alu")
6679 (set_attr "pent_pair" "pu")
6680 (set_attr "mode" "SI")])
6682 (define_insn "subsi3_carry_zext"
6683 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6685 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6686 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6687 (match_operand:SI 2 "general_operand" "ri,rm")))))
6688 (clobber (reg:CC FLAGS_REG))]
6689 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6690 "sbb{l}\t{%2, %k0|%k0, %2}"
6691 [(set_attr "type" "alu")
6692 (set_attr "pent_pair" "pu")
6693 (set_attr "mode" "SI")])
6695 (define_expand "subsi3"
6696 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6697 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6698 (match_operand:SI 2 "general_operand" "")))
6699 (clobber (reg:CC FLAGS_REG))])]
6701 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6703 (define_insn "*subsi_1"
6704 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6705 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6706 (match_operand:SI 2 "general_operand" "ri,rm")))
6707 (clobber (reg:CC FLAGS_REG))]
6708 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6709 "sub{l}\t{%2, %0|%0, %2}"
6710 [(set_attr "type" "alu")
6711 (set_attr "mode" "SI")])
6713 (define_insn "*subsi_1_zext"
6714 [(set (match_operand:DI 0 "register_operand" "=r")
6716 (minus:SI (match_operand:SI 1 "register_operand" "0")
6717 (match_operand:SI 2 "general_operand" "rim"))))
6718 (clobber (reg:CC FLAGS_REG))]
6719 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6720 "sub{l}\t{%2, %k0|%k0, %2}"
6721 [(set_attr "type" "alu")
6722 (set_attr "mode" "SI")])
6724 (define_insn "*subsi_2"
6725 [(set (reg FLAGS_REG)
6727 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6728 (match_operand:SI 2 "general_operand" "ri,rm"))
6730 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6731 (minus:SI (match_dup 1) (match_dup 2)))]
6732 "ix86_match_ccmode (insn, CCGOCmode)
6733 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6734 "sub{l}\t{%2, %0|%0, %2}"
6735 [(set_attr "type" "alu")
6736 (set_attr "mode" "SI")])
6738 (define_insn "*subsi_2_zext"
6739 [(set (reg FLAGS_REG)
6741 (minus:SI (match_operand:SI 1 "register_operand" "0")
6742 (match_operand:SI 2 "general_operand" "rim"))
6744 (set (match_operand:DI 0 "register_operand" "=r")
6746 (minus:SI (match_dup 1)
6748 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6749 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6750 "sub{l}\t{%2, %k0|%k0, %2}"
6751 [(set_attr "type" "alu")
6752 (set_attr "mode" "SI")])
6754 (define_insn "*subsi_3"
6755 [(set (reg FLAGS_REG)
6756 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6757 (match_operand:SI 2 "general_operand" "ri,rm")))
6758 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6759 (minus:SI (match_dup 1) (match_dup 2)))]
6760 "ix86_match_ccmode (insn, CCmode)
6761 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6762 "sub{l}\t{%2, %0|%0, %2}"
6763 [(set_attr "type" "alu")
6764 (set_attr "mode" "SI")])
6766 (define_insn "*subsi_3_zext"
6767 [(set (reg FLAGS_REG)
6768 (compare (match_operand:SI 1 "register_operand" "0")
6769 (match_operand:SI 2 "general_operand" "rim")))
6770 (set (match_operand:DI 0 "register_operand" "=r")
6772 (minus:SI (match_dup 1)
6774 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6775 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6776 "sub{l}\t{%2, %1|%1, %2}"
6777 [(set_attr "type" "alu")
6778 (set_attr "mode" "DI")])
6780 (define_expand "subhi3"
6781 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6782 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6783 (match_operand:HI 2 "general_operand" "")))
6784 (clobber (reg:CC FLAGS_REG))])]
6785 "TARGET_HIMODE_MATH"
6786 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6788 (define_insn "*subhi_1"
6789 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6790 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6791 (match_operand:HI 2 "general_operand" "ri,rm")))
6792 (clobber (reg:CC FLAGS_REG))]
6793 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6794 "sub{w}\t{%2, %0|%0, %2}"
6795 [(set_attr "type" "alu")
6796 (set_attr "mode" "HI")])
6798 (define_insn "*subhi_2"
6799 [(set (reg FLAGS_REG)
6801 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6802 (match_operand:HI 2 "general_operand" "ri,rm"))
6804 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6805 (minus:HI (match_dup 1) (match_dup 2)))]
6806 "ix86_match_ccmode (insn, CCGOCmode)
6807 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6808 "sub{w}\t{%2, %0|%0, %2}"
6809 [(set_attr "type" "alu")
6810 (set_attr "mode" "HI")])
6812 (define_insn "*subhi_3"
6813 [(set (reg FLAGS_REG)
6814 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6815 (match_operand:HI 2 "general_operand" "ri,rm")))
6816 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6817 (minus:HI (match_dup 1) (match_dup 2)))]
6818 "ix86_match_ccmode (insn, CCmode)
6819 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6820 "sub{w}\t{%2, %0|%0, %2}"
6821 [(set_attr "type" "alu")
6822 (set_attr "mode" "HI")])
6824 (define_expand "subqi3"
6825 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6826 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6827 (match_operand:QI 2 "general_operand" "")))
6828 (clobber (reg:CC FLAGS_REG))])]
6829 "TARGET_QIMODE_MATH"
6830 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6832 (define_insn "*subqi_1"
6833 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6834 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6835 (match_operand:QI 2 "general_operand" "qn,qmn")))
6836 (clobber (reg:CC FLAGS_REG))]
6837 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6838 "sub{b}\t{%2, %0|%0, %2}"
6839 [(set_attr "type" "alu")
6840 (set_attr "mode" "QI")])
6842 (define_insn "*subqi_1_slp"
6843 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6844 (minus:QI (match_dup 0)
6845 (match_operand:QI 1 "general_operand" "qn,qmn")))
6846 (clobber (reg:CC FLAGS_REG))]
6847 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6848 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6849 "sub{b}\t{%1, %0|%0, %1}"
6850 [(set_attr "type" "alu1")
6851 (set_attr "mode" "QI")])
6853 (define_insn "*subqi_2"
6854 [(set (reg FLAGS_REG)
6856 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6857 (match_operand:QI 2 "general_operand" "qi,qm"))
6859 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6860 (minus:HI (match_dup 1) (match_dup 2)))]
6861 "ix86_match_ccmode (insn, CCGOCmode)
6862 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6863 "sub{b}\t{%2, %0|%0, %2}"
6864 [(set_attr "type" "alu")
6865 (set_attr "mode" "QI")])
6867 (define_insn "*subqi_3"
6868 [(set (reg FLAGS_REG)
6869 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6870 (match_operand:QI 2 "general_operand" "qi,qm")))
6871 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6872 (minus:HI (match_dup 1) (match_dup 2)))]
6873 "ix86_match_ccmode (insn, CCmode)
6874 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6875 "sub{b}\t{%2, %0|%0, %2}"
6876 [(set_attr "type" "alu")
6877 (set_attr "mode" "QI")])
6879 ;; The patterns that match these are at the end of this file.
6881 (define_expand "subxf3"
6882 [(set (match_operand:XF 0 "register_operand" "")
6883 (minus:XF (match_operand:XF 1 "register_operand" "")
6884 (match_operand:XF 2 "register_operand" "")))]
6888 (define_expand "subdf3"
6889 [(set (match_operand:DF 0 "register_operand" "")
6890 (minus:DF (match_operand:DF 1 "register_operand" "")
6891 (match_operand:DF 2 "nonimmediate_operand" "")))]
6892 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6895 (define_expand "subsf3"
6896 [(set (match_operand:SF 0 "register_operand" "")
6897 (minus:SF (match_operand:SF 1 "register_operand" "")
6898 (match_operand:SF 2 "nonimmediate_operand" "")))]
6899 "TARGET_80387 || TARGET_SSE_MATH"
6902 ;; Multiply instructions
6904 (define_expand "muldi3"
6905 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6906 (mult:DI (match_operand:DI 1 "register_operand" "")
6907 (match_operand:DI 2 "x86_64_general_operand" "")))
6908 (clobber (reg:CC FLAGS_REG))])]
6912 (define_insn "*muldi3_1_rex64"
6913 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6914 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6915 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6916 (clobber (reg:CC FLAGS_REG))]
6918 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6920 imul{q}\t{%2, %1, %0|%0, %1, %2}
6921 imul{q}\t{%2, %1, %0|%0, %1, %2}
6922 imul{q}\t{%2, %0|%0, %2}"
6923 [(set_attr "type" "imul")
6924 (set_attr "prefix_0f" "0,0,1")
6925 (set (attr "athlon_decode")
6926 (cond [(eq_attr "cpu" "athlon")
6927 (const_string "vector")
6928 (eq_attr "alternative" "1")
6929 (const_string "vector")
6930 (and (eq_attr "alternative" "2")
6931 (match_operand 1 "memory_operand" ""))
6932 (const_string "vector")]
6933 (const_string "direct")))
6934 (set_attr "mode" "DI")])
6936 (define_expand "mulsi3"
6937 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6938 (mult:SI (match_operand:SI 1 "register_operand" "")
6939 (match_operand:SI 2 "general_operand" "")))
6940 (clobber (reg:CC FLAGS_REG))])]
6944 (define_insn "*mulsi3_1"
6945 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6946 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6947 (match_operand:SI 2 "general_operand" "K,i,mr")))
6948 (clobber (reg:CC FLAGS_REG))]
6949 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6951 imul{l}\t{%2, %1, %0|%0, %1, %2}
6952 imul{l}\t{%2, %1, %0|%0, %1, %2}
6953 imul{l}\t{%2, %0|%0, %2}"
6954 [(set_attr "type" "imul")
6955 (set_attr "prefix_0f" "0,0,1")
6956 (set (attr "athlon_decode")
6957 (cond [(eq_attr "cpu" "athlon")
6958 (const_string "vector")
6959 (eq_attr "alternative" "1")
6960 (const_string "vector")
6961 (and (eq_attr "alternative" "2")
6962 (match_operand 1 "memory_operand" ""))
6963 (const_string "vector")]
6964 (const_string "direct")))
6965 (set_attr "mode" "SI")])
6967 (define_insn "*mulsi3_1_zext"
6968 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6970 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6971 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6972 (clobber (reg:CC FLAGS_REG))]
6974 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6976 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6977 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6978 imul{l}\t{%2, %k0|%k0, %2}"
6979 [(set_attr "type" "imul")
6980 (set_attr "prefix_0f" "0,0,1")
6981 (set (attr "athlon_decode")
6982 (cond [(eq_attr "cpu" "athlon")
6983 (const_string "vector")
6984 (eq_attr "alternative" "1")
6985 (const_string "vector")
6986 (and (eq_attr "alternative" "2")
6987 (match_operand 1 "memory_operand" ""))
6988 (const_string "vector")]
6989 (const_string "direct")))
6990 (set_attr "mode" "SI")])
6992 (define_expand "mulhi3"
6993 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6994 (mult:HI (match_operand:HI 1 "register_operand" "")
6995 (match_operand:HI 2 "general_operand" "")))
6996 (clobber (reg:CC FLAGS_REG))])]
6997 "TARGET_HIMODE_MATH"
7000 (define_insn "*mulhi3_1"
7001 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7002 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7003 (match_operand:HI 2 "general_operand" "K,i,mr")))
7004 (clobber (reg:CC FLAGS_REG))]
7005 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7007 imul{w}\t{%2, %1, %0|%0, %1, %2}
7008 imul{w}\t{%2, %1, %0|%0, %1, %2}
7009 imul{w}\t{%2, %0|%0, %2}"
7010 [(set_attr "type" "imul")
7011 (set_attr "prefix_0f" "0,0,1")
7012 (set (attr "athlon_decode")
7013 (cond [(eq_attr "cpu" "athlon")
7014 (const_string "vector")
7015 (eq_attr "alternative" "1,2")
7016 (const_string "vector")]
7017 (const_string "direct")))
7018 (set_attr "mode" "HI")])
7020 (define_expand "mulqi3"
7021 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7022 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7023 (match_operand:QI 2 "register_operand" "")))
7024 (clobber (reg:CC FLAGS_REG))])]
7025 "TARGET_QIMODE_MATH"
7028 (define_insn "*mulqi3_1"
7029 [(set (match_operand:QI 0 "register_operand" "=a")
7030 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7031 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7032 (clobber (reg:CC FLAGS_REG))]
7034 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7036 [(set_attr "type" "imul")
7037 (set_attr "length_immediate" "0")
7038 (set (attr "athlon_decode")
7039 (if_then_else (eq_attr "cpu" "athlon")
7040 (const_string "vector")
7041 (const_string "direct")))
7042 (set_attr "mode" "QI")])
7044 (define_expand "umulqihi3"
7045 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7046 (mult:HI (zero_extend:HI
7047 (match_operand:QI 1 "nonimmediate_operand" ""))
7049 (match_operand:QI 2 "register_operand" ""))))
7050 (clobber (reg:CC FLAGS_REG))])]
7051 "TARGET_QIMODE_MATH"
7054 (define_insn "*umulqihi3_1"
7055 [(set (match_operand:HI 0 "register_operand" "=a")
7056 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7057 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7058 (clobber (reg:CC FLAGS_REG))]
7060 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7062 [(set_attr "type" "imul")
7063 (set_attr "length_immediate" "0")
7064 (set (attr "athlon_decode")
7065 (if_then_else (eq_attr "cpu" "athlon")
7066 (const_string "vector")
7067 (const_string "direct")))
7068 (set_attr "mode" "QI")])
7070 (define_expand "mulqihi3"
7071 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7072 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7073 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7074 (clobber (reg:CC FLAGS_REG))])]
7075 "TARGET_QIMODE_MATH"
7078 (define_insn "*mulqihi3_insn"
7079 [(set (match_operand:HI 0 "register_operand" "=a")
7080 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7081 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7082 (clobber (reg:CC FLAGS_REG))]
7084 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7086 [(set_attr "type" "imul")
7087 (set_attr "length_immediate" "0")
7088 (set (attr "athlon_decode")
7089 (if_then_else (eq_attr "cpu" "athlon")
7090 (const_string "vector")
7091 (const_string "direct")))
7092 (set_attr "mode" "QI")])
7094 (define_expand "umulditi3"
7095 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7096 (mult:TI (zero_extend:TI
7097 (match_operand:DI 1 "nonimmediate_operand" ""))
7099 (match_operand:DI 2 "register_operand" ""))))
7100 (clobber (reg:CC FLAGS_REG))])]
7104 (define_insn "*umulditi3_insn"
7105 [(set (match_operand:TI 0 "register_operand" "=A")
7106 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7107 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7108 (clobber (reg:CC FLAGS_REG))]
7110 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7112 [(set_attr "type" "imul")
7113 (set_attr "length_immediate" "0")
7114 (set (attr "athlon_decode")
7115 (if_then_else (eq_attr "cpu" "athlon")
7116 (const_string "vector")
7117 (const_string "double")))
7118 (set_attr "mode" "DI")])
7120 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7121 (define_expand "umulsidi3"
7122 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7123 (mult:DI (zero_extend:DI
7124 (match_operand:SI 1 "nonimmediate_operand" ""))
7126 (match_operand:SI 2 "register_operand" ""))))
7127 (clobber (reg:CC FLAGS_REG))])]
7131 (define_insn "*umulsidi3_insn"
7132 [(set (match_operand:DI 0 "register_operand" "=A")
7133 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7134 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7135 (clobber (reg:CC FLAGS_REG))]
7137 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7139 [(set_attr "type" "imul")
7140 (set_attr "length_immediate" "0")
7141 (set (attr "athlon_decode")
7142 (if_then_else (eq_attr "cpu" "athlon")
7143 (const_string "vector")
7144 (const_string "double")))
7145 (set_attr "mode" "SI")])
7147 (define_expand "mulditi3"
7148 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7149 (mult:TI (sign_extend:TI
7150 (match_operand:DI 1 "nonimmediate_operand" ""))
7152 (match_operand:DI 2 "register_operand" ""))))
7153 (clobber (reg:CC FLAGS_REG))])]
7157 (define_insn "*mulditi3_insn"
7158 [(set (match_operand:TI 0 "register_operand" "=A")
7159 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7160 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7161 (clobber (reg:CC FLAGS_REG))]
7163 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7165 [(set_attr "type" "imul")
7166 (set_attr "length_immediate" "0")
7167 (set (attr "athlon_decode")
7168 (if_then_else (eq_attr "cpu" "athlon")
7169 (const_string "vector")
7170 (const_string "double")))
7171 (set_attr "mode" "DI")])
7173 (define_expand "mulsidi3"
7174 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7175 (mult:DI (sign_extend:DI
7176 (match_operand:SI 1 "nonimmediate_operand" ""))
7178 (match_operand:SI 2 "register_operand" ""))))
7179 (clobber (reg:CC FLAGS_REG))])]
7183 (define_insn "*mulsidi3_insn"
7184 [(set (match_operand:DI 0 "register_operand" "=A")
7185 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7186 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7187 (clobber (reg:CC FLAGS_REG))]
7189 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7191 [(set_attr "type" "imul")
7192 (set_attr "length_immediate" "0")
7193 (set (attr "athlon_decode")
7194 (if_then_else (eq_attr "cpu" "athlon")
7195 (const_string "vector")
7196 (const_string "double")))
7197 (set_attr "mode" "SI")])
7199 (define_expand "umuldi3_highpart"
7200 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7203 (mult:TI (zero_extend:TI
7204 (match_operand:DI 1 "nonimmediate_operand" ""))
7206 (match_operand:DI 2 "register_operand" "")))
7208 (clobber (match_scratch:DI 3 ""))
7209 (clobber (reg:CC FLAGS_REG))])]
7213 (define_insn "*umuldi3_highpart_rex64"
7214 [(set (match_operand:DI 0 "register_operand" "=d")
7217 (mult:TI (zero_extend:TI
7218 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7220 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7222 (clobber (match_scratch:DI 3 "=1"))
7223 (clobber (reg:CC FLAGS_REG))]
7225 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7227 [(set_attr "type" "imul")
7228 (set_attr "length_immediate" "0")
7229 (set (attr "athlon_decode")
7230 (if_then_else (eq_attr "cpu" "athlon")
7231 (const_string "vector")
7232 (const_string "double")))
7233 (set_attr "mode" "DI")])
7235 (define_expand "umulsi3_highpart"
7236 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7239 (mult:DI (zero_extend:DI
7240 (match_operand:SI 1 "nonimmediate_operand" ""))
7242 (match_operand:SI 2 "register_operand" "")))
7244 (clobber (match_scratch:SI 3 ""))
7245 (clobber (reg:CC FLAGS_REG))])]
7249 (define_insn "*umulsi3_highpart_insn"
7250 [(set (match_operand:SI 0 "register_operand" "=d")
7253 (mult:DI (zero_extend:DI
7254 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7256 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7258 (clobber (match_scratch:SI 3 "=1"))
7259 (clobber (reg:CC FLAGS_REG))]
7260 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7262 [(set_attr "type" "imul")
7263 (set_attr "length_immediate" "0")
7264 (set (attr "athlon_decode")
7265 (if_then_else (eq_attr "cpu" "athlon")
7266 (const_string "vector")
7267 (const_string "double")))
7268 (set_attr "mode" "SI")])
7270 (define_insn "*umulsi3_highpart_zext"
7271 [(set (match_operand:DI 0 "register_operand" "=d")
7272 (zero_extend:DI (truncate:SI
7274 (mult:DI (zero_extend:DI
7275 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7277 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7279 (clobber (match_scratch:SI 3 "=1"))
7280 (clobber (reg:CC FLAGS_REG))]
7282 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7284 [(set_attr "type" "imul")
7285 (set_attr "length_immediate" "0")
7286 (set (attr "athlon_decode")
7287 (if_then_else (eq_attr "cpu" "athlon")
7288 (const_string "vector")
7289 (const_string "double")))
7290 (set_attr "mode" "SI")])
7292 (define_expand "smuldi3_highpart"
7293 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7296 (mult:TI (sign_extend:TI
7297 (match_operand:DI 1 "nonimmediate_operand" ""))
7299 (match_operand:DI 2 "register_operand" "")))
7301 (clobber (match_scratch:DI 3 ""))
7302 (clobber (reg:CC FLAGS_REG))])]
7306 (define_insn "*smuldi3_highpart_rex64"
7307 [(set (match_operand:DI 0 "register_operand" "=d")
7310 (mult:TI (sign_extend:TI
7311 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7313 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7315 (clobber (match_scratch:DI 3 "=1"))
7316 (clobber (reg:CC FLAGS_REG))]
7318 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7320 [(set_attr "type" "imul")
7321 (set (attr "athlon_decode")
7322 (if_then_else (eq_attr "cpu" "athlon")
7323 (const_string "vector")
7324 (const_string "double")))
7325 (set_attr "mode" "DI")])
7327 (define_expand "smulsi3_highpart"
7328 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7331 (mult:DI (sign_extend:DI
7332 (match_operand:SI 1 "nonimmediate_operand" ""))
7334 (match_operand:SI 2 "register_operand" "")))
7336 (clobber (match_scratch:SI 3 ""))
7337 (clobber (reg:CC FLAGS_REG))])]
7341 (define_insn "*smulsi3_highpart_insn"
7342 [(set (match_operand:SI 0 "register_operand" "=d")
7345 (mult:DI (sign_extend:DI
7346 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7348 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7350 (clobber (match_scratch:SI 3 "=1"))
7351 (clobber (reg:CC FLAGS_REG))]
7352 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7354 [(set_attr "type" "imul")
7355 (set (attr "athlon_decode")
7356 (if_then_else (eq_attr "cpu" "athlon")
7357 (const_string "vector")
7358 (const_string "double")))
7359 (set_attr "mode" "SI")])
7361 (define_insn "*smulsi3_highpart_zext"
7362 [(set (match_operand:DI 0 "register_operand" "=d")
7363 (zero_extend:DI (truncate:SI
7365 (mult:DI (sign_extend:DI
7366 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7368 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7370 (clobber (match_scratch:SI 3 "=1"))
7371 (clobber (reg:CC FLAGS_REG))]
7373 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7375 [(set_attr "type" "imul")
7376 (set (attr "athlon_decode")
7377 (if_then_else (eq_attr "cpu" "athlon")
7378 (const_string "vector")
7379 (const_string "double")))
7380 (set_attr "mode" "SI")])
7382 ;; The patterns that match these are at the end of this file.
7384 (define_expand "mulxf3"
7385 [(set (match_operand:XF 0 "register_operand" "")
7386 (mult:XF (match_operand:XF 1 "register_operand" "")
7387 (match_operand:XF 2 "register_operand" "")))]
7391 (define_expand "muldf3"
7392 [(set (match_operand:DF 0 "register_operand" "")
7393 (mult:DF (match_operand:DF 1 "register_operand" "")
7394 (match_operand:DF 2 "nonimmediate_operand" "")))]
7395 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7398 (define_expand "mulsf3"
7399 [(set (match_operand:SF 0 "register_operand" "")
7400 (mult:SF (match_operand:SF 1 "register_operand" "")
7401 (match_operand:SF 2 "nonimmediate_operand" "")))]
7402 "TARGET_80387 || TARGET_SSE_MATH"
7405 ;; Divide instructions
7407 (define_insn "divqi3"
7408 [(set (match_operand:QI 0 "register_operand" "=a")
7409 (div:QI (match_operand:HI 1 "register_operand" "0")
7410 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7411 (clobber (reg:CC FLAGS_REG))]
7412 "TARGET_QIMODE_MATH"
7414 [(set_attr "type" "idiv")
7415 (set_attr "mode" "QI")])
7417 (define_insn "udivqi3"
7418 [(set (match_operand:QI 0 "register_operand" "=a")
7419 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7420 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7421 (clobber (reg:CC FLAGS_REG))]
7422 "TARGET_QIMODE_MATH"
7424 [(set_attr "type" "idiv")
7425 (set_attr "mode" "QI")])
7427 ;; The patterns that match these are at the end of this file.
7429 (define_expand "divxf3"
7430 [(set (match_operand:XF 0 "register_operand" "")
7431 (div:XF (match_operand:XF 1 "register_operand" "")
7432 (match_operand:XF 2 "register_operand" "")))]
7436 (define_expand "divdf3"
7437 [(set (match_operand:DF 0 "register_operand" "")
7438 (div:DF (match_operand:DF 1 "register_operand" "")
7439 (match_operand:DF 2 "nonimmediate_operand" "")))]
7440 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7443 (define_expand "divsf3"
7444 [(set (match_operand:SF 0 "register_operand" "")
7445 (div:SF (match_operand:SF 1 "register_operand" "")
7446 (match_operand:SF 2 "nonimmediate_operand" "")))]
7447 "TARGET_80387 || TARGET_SSE_MATH"
7450 ;; Remainder instructions.
7452 (define_expand "divmoddi4"
7453 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7454 (div:DI (match_operand:DI 1 "register_operand" "")
7455 (match_operand:DI 2 "nonimmediate_operand" "")))
7456 (set (match_operand:DI 3 "register_operand" "")
7457 (mod:DI (match_dup 1) (match_dup 2)))
7458 (clobber (reg:CC FLAGS_REG))])]
7462 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7463 ;; Penalize eax case slightly because it results in worse scheduling
7465 (define_insn "*divmoddi4_nocltd_rex64"
7466 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7467 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7468 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7469 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7470 (mod:DI (match_dup 2) (match_dup 3)))
7471 (clobber (reg:CC FLAGS_REG))]
7472 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7474 [(set_attr "type" "multi")])
7476 (define_insn "*divmoddi4_cltd_rex64"
7477 [(set (match_operand:DI 0 "register_operand" "=a")
7478 (div:DI (match_operand:DI 2 "register_operand" "a")
7479 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7480 (set (match_operand:DI 1 "register_operand" "=&d")
7481 (mod:DI (match_dup 2) (match_dup 3)))
7482 (clobber (reg:CC FLAGS_REG))]
7483 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7485 [(set_attr "type" "multi")])
7487 (define_insn "*divmoddi_noext_rex64"
7488 [(set (match_operand:DI 0 "register_operand" "=a")
7489 (div:DI (match_operand:DI 1 "register_operand" "0")
7490 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7491 (set (match_operand:DI 3 "register_operand" "=d")
7492 (mod:DI (match_dup 1) (match_dup 2)))
7493 (use (match_operand:DI 4 "register_operand" "3"))
7494 (clobber (reg:CC FLAGS_REG))]
7497 [(set_attr "type" "idiv")
7498 (set_attr "mode" "DI")])
7501 [(set (match_operand:DI 0 "register_operand" "")
7502 (div:DI (match_operand:DI 1 "register_operand" "")
7503 (match_operand:DI 2 "nonimmediate_operand" "")))
7504 (set (match_operand:DI 3 "register_operand" "")
7505 (mod:DI (match_dup 1) (match_dup 2)))
7506 (clobber (reg:CC FLAGS_REG))]
7507 "TARGET_64BIT && reload_completed"
7508 [(parallel [(set (match_dup 3)
7509 (ashiftrt:DI (match_dup 4) (const_int 63)))
7510 (clobber (reg:CC FLAGS_REG))])
7511 (parallel [(set (match_dup 0)
7512 (div:DI (reg:DI 0) (match_dup 2)))
7514 (mod:DI (reg:DI 0) (match_dup 2)))
7516 (clobber (reg:CC FLAGS_REG))])]
7518 /* Avoid use of cltd in favor of a mov+shift. */
7519 if (!TARGET_USE_CLTD && !optimize_size)
7521 if (true_regnum (operands[1]))
7522 emit_move_insn (operands[0], operands[1]);
7524 emit_move_insn (operands[3], operands[1]);
7525 operands[4] = operands[3];
7529 gcc_assert (!true_regnum (operands[1]));
7530 operands[4] = operands[1];
7535 (define_expand "divmodsi4"
7536 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7537 (div:SI (match_operand:SI 1 "register_operand" "")
7538 (match_operand:SI 2 "nonimmediate_operand" "")))
7539 (set (match_operand:SI 3 "register_operand" "")
7540 (mod:SI (match_dup 1) (match_dup 2)))
7541 (clobber (reg:CC FLAGS_REG))])]
7545 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7546 ;; Penalize eax case slightly because it results in worse scheduling
7548 (define_insn "*divmodsi4_nocltd"
7549 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7550 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7551 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7552 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7553 (mod:SI (match_dup 2) (match_dup 3)))
7554 (clobber (reg:CC FLAGS_REG))]
7555 "!optimize_size && !TARGET_USE_CLTD"
7557 [(set_attr "type" "multi")])
7559 (define_insn "*divmodsi4_cltd"
7560 [(set (match_operand:SI 0 "register_operand" "=a")
7561 (div:SI (match_operand:SI 2 "register_operand" "a")
7562 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7563 (set (match_operand:SI 1 "register_operand" "=&d")
7564 (mod:SI (match_dup 2) (match_dup 3)))
7565 (clobber (reg:CC FLAGS_REG))]
7566 "optimize_size || TARGET_USE_CLTD"
7568 [(set_attr "type" "multi")])
7570 (define_insn "*divmodsi_noext"
7571 [(set (match_operand:SI 0 "register_operand" "=a")
7572 (div:SI (match_operand:SI 1 "register_operand" "0")
7573 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7574 (set (match_operand:SI 3 "register_operand" "=d")
7575 (mod:SI (match_dup 1) (match_dup 2)))
7576 (use (match_operand:SI 4 "register_operand" "3"))
7577 (clobber (reg:CC FLAGS_REG))]
7580 [(set_attr "type" "idiv")
7581 (set_attr "mode" "SI")])
7584 [(set (match_operand:SI 0 "register_operand" "")
7585 (div:SI (match_operand:SI 1 "register_operand" "")
7586 (match_operand:SI 2 "nonimmediate_operand" "")))
7587 (set (match_operand:SI 3 "register_operand" "")
7588 (mod:SI (match_dup 1) (match_dup 2)))
7589 (clobber (reg:CC FLAGS_REG))]
7591 [(parallel [(set (match_dup 3)
7592 (ashiftrt:SI (match_dup 4) (const_int 31)))
7593 (clobber (reg:CC FLAGS_REG))])
7594 (parallel [(set (match_dup 0)
7595 (div:SI (reg:SI 0) (match_dup 2)))
7597 (mod:SI (reg:SI 0) (match_dup 2)))
7599 (clobber (reg:CC FLAGS_REG))])]
7601 /* Avoid use of cltd in favor of a mov+shift. */
7602 if (!TARGET_USE_CLTD && !optimize_size)
7604 if (true_regnum (operands[1]))
7605 emit_move_insn (operands[0], operands[1]);
7607 emit_move_insn (operands[3], operands[1]);
7608 operands[4] = operands[3];
7612 gcc_assert (!true_regnum (operands[1]));
7613 operands[4] = operands[1];
7617 (define_insn "divmodhi4"
7618 [(set (match_operand:HI 0 "register_operand" "=a")
7619 (div:HI (match_operand:HI 1 "register_operand" "0")
7620 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7621 (set (match_operand:HI 3 "register_operand" "=&d")
7622 (mod:HI (match_dup 1) (match_dup 2)))
7623 (clobber (reg:CC FLAGS_REG))]
7624 "TARGET_HIMODE_MATH"
7626 [(set_attr "type" "multi")
7627 (set_attr "length_immediate" "0")
7628 (set_attr "mode" "SI")])
7630 (define_insn "udivmoddi4"
7631 [(set (match_operand:DI 0 "register_operand" "=a")
7632 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7633 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7634 (set (match_operand:DI 3 "register_operand" "=&d")
7635 (umod:DI (match_dup 1) (match_dup 2)))
7636 (clobber (reg:CC FLAGS_REG))]
7638 "xor{q}\t%3, %3\;div{q}\t%2"
7639 [(set_attr "type" "multi")
7640 (set_attr "length_immediate" "0")
7641 (set_attr "mode" "DI")])
7643 (define_insn "*udivmoddi4_noext"
7644 [(set (match_operand:DI 0 "register_operand" "=a")
7645 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7646 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7647 (set (match_operand:DI 3 "register_operand" "=d")
7648 (umod:DI (match_dup 1) (match_dup 2)))
7650 (clobber (reg:CC FLAGS_REG))]
7653 [(set_attr "type" "idiv")
7654 (set_attr "mode" "DI")])
7657 [(set (match_operand:DI 0 "register_operand" "")
7658 (udiv:DI (match_operand:DI 1 "register_operand" "")
7659 (match_operand:DI 2 "nonimmediate_operand" "")))
7660 (set (match_operand:DI 3 "register_operand" "")
7661 (umod:DI (match_dup 1) (match_dup 2)))
7662 (clobber (reg:CC FLAGS_REG))]
7663 "TARGET_64BIT && reload_completed"
7664 [(set (match_dup 3) (const_int 0))
7665 (parallel [(set (match_dup 0)
7666 (udiv:DI (match_dup 1) (match_dup 2)))
7668 (umod:DI (match_dup 1) (match_dup 2)))
7670 (clobber (reg:CC FLAGS_REG))])]
7673 (define_insn "udivmodsi4"
7674 [(set (match_operand:SI 0 "register_operand" "=a")
7675 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7676 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7677 (set (match_operand:SI 3 "register_operand" "=&d")
7678 (umod:SI (match_dup 1) (match_dup 2)))
7679 (clobber (reg:CC FLAGS_REG))]
7681 "xor{l}\t%3, %3\;div{l}\t%2"
7682 [(set_attr "type" "multi")
7683 (set_attr "length_immediate" "0")
7684 (set_attr "mode" "SI")])
7686 (define_insn "*udivmodsi4_noext"
7687 [(set (match_operand:SI 0 "register_operand" "=a")
7688 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7689 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7690 (set (match_operand:SI 3 "register_operand" "=d")
7691 (umod:SI (match_dup 1) (match_dup 2)))
7693 (clobber (reg:CC FLAGS_REG))]
7696 [(set_attr "type" "idiv")
7697 (set_attr "mode" "SI")])
7700 [(set (match_operand:SI 0 "register_operand" "")
7701 (udiv:SI (match_operand:SI 1 "register_operand" "")
7702 (match_operand:SI 2 "nonimmediate_operand" "")))
7703 (set (match_operand:SI 3 "register_operand" "")
7704 (umod:SI (match_dup 1) (match_dup 2)))
7705 (clobber (reg:CC FLAGS_REG))]
7707 [(set (match_dup 3) (const_int 0))
7708 (parallel [(set (match_dup 0)
7709 (udiv:SI (match_dup 1) (match_dup 2)))
7711 (umod:SI (match_dup 1) (match_dup 2)))
7713 (clobber (reg:CC FLAGS_REG))])]
7716 (define_expand "udivmodhi4"
7717 [(set (match_dup 4) (const_int 0))
7718 (parallel [(set (match_operand:HI 0 "register_operand" "")
7719 (udiv:HI (match_operand:HI 1 "register_operand" "")
7720 (match_operand:HI 2 "nonimmediate_operand" "")))
7721 (set (match_operand:HI 3 "register_operand" "")
7722 (umod:HI (match_dup 1) (match_dup 2)))
7724 (clobber (reg:CC FLAGS_REG))])]
7725 "TARGET_HIMODE_MATH"
7726 "operands[4] = gen_reg_rtx (HImode);")
7728 (define_insn "*udivmodhi_noext"
7729 [(set (match_operand:HI 0 "register_operand" "=a")
7730 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7731 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7732 (set (match_operand:HI 3 "register_operand" "=d")
7733 (umod:HI (match_dup 1) (match_dup 2)))
7734 (use (match_operand:HI 4 "register_operand" "3"))
7735 (clobber (reg:CC FLAGS_REG))]
7738 [(set_attr "type" "idiv")
7739 (set_attr "mode" "HI")])
7741 ;; We cannot use div/idiv for double division, because it causes
7742 ;; "division by zero" on the overflow and that's not what we expect
7743 ;; from truncate. Because true (non truncating) double division is
7744 ;; never generated, we can't create this insn anyway.
7747 ; [(set (match_operand:SI 0 "register_operand" "=a")
7749 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7751 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7752 ; (set (match_operand:SI 3 "register_operand" "=d")
7754 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7755 ; (clobber (reg:CC FLAGS_REG))]
7757 ; "div{l}\t{%2, %0|%0, %2}"
7758 ; [(set_attr "type" "idiv")])
7760 ;;- Logical AND instructions
7762 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7763 ;; Note that this excludes ah.
7765 (define_insn "*testdi_1_rex64"
7766 [(set (reg FLAGS_REG)
7768 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7769 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7771 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7772 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7774 test{l}\t{%k1, %k0|%k0, %k1}
7775 test{l}\t{%k1, %k0|%k0, %k1}
7776 test{q}\t{%1, %0|%0, %1}
7777 test{q}\t{%1, %0|%0, %1}
7778 test{q}\t{%1, %0|%0, %1}"
7779 [(set_attr "type" "test")
7780 (set_attr "modrm" "0,1,0,1,1")
7781 (set_attr "mode" "SI,SI,DI,DI,DI")
7782 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7784 (define_insn "testsi_1"
7785 [(set (reg FLAGS_REG)
7787 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7788 (match_operand:SI 1 "general_operand" "in,in,rin"))
7790 "ix86_match_ccmode (insn, CCNOmode)
7791 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7792 "test{l}\t{%1, %0|%0, %1}"
7793 [(set_attr "type" "test")
7794 (set_attr "modrm" "0,1,1")
7795 (set_attr "mode" "SI")
7796 (set_attr "pent_pair" "uv,np,uv")])
7798 (define_expand "testsi_ccno_1"
7799 [(set (reg:CCNO FLAGS_REG)
7801 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7802 (match_operand:SI 1 "nonmemory_operand" ""))
7807 (define_insn "*testhi_1"
7808 [(set (reg FLAGS_REG)
7809 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7810 (match_operand:HI 1 "general_operand" "n,n,rn"))
7812 "ix86_match_ccmode (insn, CCNOmode)
7813 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7814 "test{w}\t{%1, %0|%0, %1}"
7815 [(set_attr "type" "test")
7816 (set_attr "modrm" "0,1,1")
7817 (set_attr "mode" "HI")
7818 (set_attr "pent_pair" "uv,np,uv")])
7820 (define_expand "testqi_ccz_1"
7821 [(set (reg:CCZ FLAGS_REG)
7822 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7823 (match_operand:QI 1 "nonmemory_operand" ""))
7828 (define_insn "*testqi_1_maybe_si"
7829 [(set (reg FLAGS_REG)
7832 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7833 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7835 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7836 && ix86_match_ccmode (insn,
7837 GET_CODE (operands[1]) == CONST_INT
7838 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7840 if (which_alternative == 3)
7842 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7843 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7844 return "test{l}\t{%1, %k0|%k0, %1}";
7846 return "test{b}\t{%1, %0|%0, %1}";
7848 [(set_attr "type" "test")
7849 (set_attr "modrm" "0,1,1,1")
7850 (set_attr "mode" "QI,QI,QI,SI")
7851 (set_attr "pent_pair" "uv,np,uv,np")])
7853 (define_insn "*testqi_1"
7854 [(set (reg FLAGS_REG)
7857 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7858 (match_operand:QI 1 "general_operand" "n,n,qn"))
7860 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7861 && ix86_match_ccmode (insn, CCNOmode)"
7862 "test{b}\t{%1, %0|%0, %1}"
7863 [(set_attr "type" "test")
7864 (set_attr "modrm" "0,1,1")
7865 (set_attr "mode" "QI")
7866 (set_attr "pent_pair" "uv,np,uv")])
7868 (define_expand "testqi_ext_ccno_0"
7869 [(set (reg:CCNO FLAGS_REG)
7873 (match_operand 0 "ext_register_operand" "")
7876 (match_operand 1 "const_int_operand" ""))
7881 (define_insn "*testqi_ext_0"
7882 [(set (reg FLAGS_REG)
7886 (match_operand 0 "ext_register_operand" "Q")
7889 (match_operand 1 "const_int_operand" "n"))
7891 "ix86_match_ccmode (insn, CCNOmode)"
7892 "test{b}\t{%1, %h0|%h0, %1}"
7893 [(set_attr "type" "test")
7894 (set_attr "mode" "QI")
7895 (set_attr "length_immediate" "1")
7896 (set_attr "pent_pair" "np")])
7898 (define_insn "*testqi_ext_1"
7899 [(set (reg FLAGS_REG)
7903 (match_operand 0 "ext_register_operand" "Q")
7907 (match_operand:QI 1 "general_operand" "Qm")))
7909 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7910 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7911 "test{b}\t{%1, %h0|%h0, %1}"
7912 [(set_attr "type" "test")
7913 (set_attr "mode" "QI")])
7915 (define_insn "*testqi_ext_1_rex64"
7916 [(set (reg FLAGS_REG)
7920 (match_operand 0 "ext_register_operand" "Q")
7924 (match_operand:QI 1 "register_operand" "Q")))
7926 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7927 "test{b}\t{%1, %h0|%h0, %1}"
7928 [(set_attr "type" "test")
7929 (set_attr "mode" "QI")])
7931 (define_insn "*testqi_ext_2"
7932 [(set (reg FLAGS_REG)
7936 (match_operand 0 "ext_register_operand" "Q")
7940 (match_operand 1 "ext_register_operand" "Q")
7944 "ix86_match_ccmode (insn, CCNOmode)"
7945 "test{b}\t{%h1, %h0|%h0, %h1}"
7946 [(set_attr "type" "test")
7947 (set_attr "mode" "QI")])
7949 ;; Combine likes to form bit extractions for some tests. Humor it.
7950 (define_insn "*testqi_ext_3"
7951 [(set (reg FLAGS_REG)
7952 (compare (zero_extract:SI
7953 (match_operand 0 "nonimmediate_operand" "rm")
7954 (match_operand:SI 1 "const_int_operand" "")
7955 (match_operand:SI 2 "const_int_operand" ""))
7957 "ix86_match_ccmode (insn, CCNOmode)
7958 && INTVAL (operands[1]) > 0
7959 && INTVAL (operands[2]) >= 0
7960 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7961 && (GET_MODE (operands[0]) == SImode
7962 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7963 || GET_MODE (operands[0]) == HImode
7964 || GET_MODE (operands[0]) == QImode)"
7967 (define_insn "*testqi_ext_3_rex64"
7968 [(set (reg FLAGS_REG)
7969 (compare (zero_extract:DI
7970 (match_operand 0 "nonimmediate_operand" "rm")
7971 (match_operand:DI 1 "const_int_operand" "")
7972 (match_operand:DI 2 "const_int_operand" ""))
7975 && ix86_match_ccmode (insn, CCNOmode)
7976 && INTVAL (operands[1]) > 0
7977 && INTVAL (operands[2]) >= 0
7978 /* Ensure that resulting mask is zero or sign extended operand. */
7979 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7980 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7981 && INTVAL (operands[1]) > 32))
7982 && (GET_MODE (operands[0]) == SImode
7983 || GET_MODE (operands[0]) == DImode
7984 || GET_MODE (operands[0]) == HImode
7985 || GET_MODE (operands[0]) == QImode)"
7989 [(set (match_operand 0 "flags_reg_operand" "")
7990 (match_operator 1 "compare_operator"
7992 (match_operand 2 "nonimmediate_operand" "")
7993 (match_operand 3 "const_int_operand" "")
7994 (match_operand 4 "const_int_operand" ""))
7996 "ix86_match_ccmode (insn, CCNOmode)"
7997 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7999 rtx val = operands[2];
8000 HOST_WIDE_INT len = INTVAL (operands[3]);
8001 HOST_WIDE_INT pos = INTVAL (operands[4]);
8003 enum machine_mode mode, submode;
8005 mode = GET_MODE (val);
8006 if (GET_CODE (val) == MEM)
8008 /* ??? Combine likes to put non-volatile mem extractions in QImode
8009 no matter the size of the test. So find a mode that works. */
8010 if (! MEM_VOLATILE_P (val))
8012 mode = smallest_mode_for_size (pos + len, MODE_INT);
8013 val = adjust_address (val, mode, 0);
8016 else if (GET_CODE (val) == SUBREG
8017 && (submode = GET_MODE (SUBREG_REG (val)),
8018 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8019 && pos + len <= GET_MODE_BITSIZE (submode))
8021 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8023 val = SUBREG_REG (val);
8025 else if (mode == HImode && pos + len <= 8)
8027 /* Small HImode tests can be converted to QImode. */
8029 val = gen_lowpart (QImode, val);
8032 if (len == HOST_BITS_PER_WIDE_INT)
8035 mask = ((HOST_WIDE_INT)1 << len) - 1;
8038 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8041 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8042 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8043 ;; this is relatively important trick.
8044 ;; Do the conversion only post-reload to avoid limiting of the register class
8047 [(set (match_operand 0 "flags_reg_operand" "")
8048 (match_operator 1 "compare_operator"
8049 [(and (match_operand 2 "register_operand" "")
8050 (match_operand 3 "const_int_operand" ""))
8053 && QI_REG_P (operands[2])
8054 && GET_MODE (operands[2]) != QImode
8055 && ((ix86_match_ccmode (insn, CCZmode)
8056 && !(INTVAL (operands[3]) & ~(255 << 8)))
8057 || (ix86_match_ccmode (insn, CCNOmode)
8058 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8061 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8064 "operands[2] = gen_lowpart (SImode, operands[2]);
8065 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8068 [(set (match_operand 0 "flags_reg_operand" "")
8069 (match_operator 1 "compare_operator"
8070 [(and (match_operand 2 "nonimmediate_operand" "")
8071 (match_operand 3 "const_int_operand" ""))
8074 && GET_MODE (operands[2]) != QImode
8075 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8076 && ((ix86_match_ccmode (insn, CCZmode)
8077 && !(INTVAL (operands[3]) & ~255))
8078 || (ix86_match_ccmode (insn, CCNOmode)
8079 && !(INTVAL (operands[3]) & ~127)))"
8081 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8083 "operands[2] = gen_lowpart (QImode, operands[2]);
8084 operands[3] = gen_lowpart (QImode, operands[3]);")
8087 ;; %%% This used to optimize known byte-wide and operations to memory,
8088 ;; and sometimes to QImode registers. If this is considered useful,
8089 ;; it should be done with splitters.
8091 (define_expand "anddi3"
8092 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8093 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8094 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8095 (clobber (reg:CC FLAGS_REG))]
8097 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8099 (define_insn "*anddi_1_rex64"
8100 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8101 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8102 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8103 (clobber (reg:CC FLAGS_REG))]
8104 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8106 switch (get_attr_type (insn))
8110 enum machine_mode mode;
8112 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8113 if (INTVAL (operands[2]) == 0xff)
8117 gcc_assert (INTVAL (operands[2]) == 0xffff);
8121 operands[1] = gen_lowpart (mode, operands[1]);
8123 return "movz{bq|x}\t{%1,%0|%0, %1}";
8125 return "movz{wq|x}\t{%1,%0|%0, %1}";
8129 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8130 if (get_attr_mode (insn) == MODE_SI)
8131 return "and{l}\t{%k2, %k0|%k0, %k2}";
8133 return "and{q}\t{%2, %0|%0, %2}";
8136 [(set_attr "type" "alu,alu,alu,imovx")
8137 (set_attr "length_immediate" "*,*,*,0")
8138 (set_attr "mode" "SI,DI,DI,DI")])
8140 (define_insn "*anddi_2"
8141 [(set (reg FLAGS_REG)
8142 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8143 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8145 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8146 (and:DI (match_dup 1) (match_dup 2)))]
8147 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8148 && ix86_binary_operator_ok (AND, DImode, operands)"
8150 and{l}\t{%k2, %k0|%k0, %k2}
8151 and{q}\t{%2, %0|%0, %2}
8152 and{q}\t{%2, %0|%0, %2}"
8153 [(set_attr "type" "alu")
8154 (set_attr "mode" "SI,DI,DI")])
8156 (define_expand "andsi3"
8157 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8158 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8159 (match_operand:SI 2 "general_operand" "")))
8160 (clobber (reg:CC FLAGS_REG))]
8162 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8164 (define_insn "*andsi_1"
8165 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8166 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8167 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8168 (clobber (reg:CC FLAGS_REG))]
8169 "ix86_binary_operator_ok (AND, SImode, operands)"
8171 switch (get_attr_type (insn))
8175 enum machine_mode mode;
8177 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8178 if (INTVAL (operands[2]) == 0xff)
8182 gcc_assert (INTVAL (operands[2]) == 0xffff);
8186 operands[1] = gen_lowpart (mode, operands[1]);
8188 return "movz{bl|x}\t{%1,%0|%0, %1}";
8190 return "movz{wl|x}\t{%1,%0|%0, %1}";
8194 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8195 return "and{l}\t{%2, %0|%0, %2}";
8198 [(set_attr "type" "alu,alu,imovx")
8199 (set_attr "length_immediate" "*,*,0")
8200 (set_attr "mode" "SI")])
8203 [(set (match_operand 0 "register_operand" "")
8205 (const_int -65536)))
8206 (clobber (reg:CC FLAGS_REG))]
8207 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8208 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8209 "operands[1] = gen_lowpart (HImode, operands[0]);")
8212 [(set (match_operand 0 "ext_register_operand" "")
8215 (clobber (reg:CC FLAGS_REG))]
8216 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8217 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8218 "operands[1] = gen_lowpart (QImode, operands[0]);")
8221 [(set (match_operand 0 "ext_register_operand" "")
8223 (const_int -65281)))
8224 (clobber (reg:CC FLAGS_REG))]
8225 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8226 [(parallel [(set (zero_extract:SI (match_dup 0)
8230 (zero_extract:SI (match_dup 0)
8233 (zero_extract:SI (match_dup 0)
8236 (clobber (reg:CC FLAGS_REG))])]
8237 "operands[0] = gen_lowpart (SImode, operands[0]);")
8239 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8240 (define_insn "*andsi_1_zext"
8241 [(set (match_operand:DI 0 "register_operand" "=r")
8243 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8244 (match_operand:SI 2 "general_operand" "rim"))))
8245 (clobber (reg:CC FLAGS_REG))]
8246 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8247 "and{l}\t{%2, %k0|%k0, %2}"
8248 [(set_attr "type" "alu")
8249 (set_attr "mode" "SI")])
8251 (define_insn "*andsi_2"
8252 [(set (reg FLAGS_REG)
8253 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8254 (match_operand:SI 2 "general_operand" "rim,ri"))
8256 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8257 (and:SI (match_dup 1) (match_dup 2)))]
8258 "ix86_match_ccmode (insn, CCNOmode)
8259 && ix86_binary_operator_ok (AND, SImode, operands)"
8260 "and{l}\t{%2, %0|%0, %2}"
8261 [(set_attr "type" "alu")
8262 (set_attr "mode" "SI")])
8264 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8265 (define_insn "*andsi_2_zext"
8266 [(set (reg FLAGS_REG)
8267 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8268 (match_operand:SI 2 "general_operand" "rim"))
8270 (set (match_operand:DI 0 "register_operand" "=r")
8271 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8272 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8273 && ix86_binary_operator_ok (AND, SImode, operands)"
8274 "and{l}\t{%2, %k0|%k0, %2}"
8275 [(set_attr "type" "alu")
8276 (set_attr "mode" "SI")])
8278 (define_expand "andhi3"
8279 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8280 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8281 (match_operand:HI 2 "general_operand" "")))
8282 (clobber (reg:CC FLAGS_REG))]
8283 "TARGET_HIMODE_MATH"
8284 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8286 (define_insn "*andhi_1"
8287 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8288 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8289 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8290 (clobber (reg:CC FLAGS_REG))]
8291 "ix86_binary_operator_ok (AND, HImode, operands)"
8293 switch (get_attr_type (insn))
8296 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8297 gcc_assert (INTVAL (operands[2]) == 0xff);
8298 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8301 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8303 return "and{w}\t{%2, %0|%0, %2}";
8306 [(set_attr "type" "alu,alu,imovx")
8307 (set_attr "length_immediate" "*,*,0")
8308 (set_attr "mode" "HI,HI,SI")])
8310 (define_insn "*andhi_2"
8311 [(set (reg FLAGS_REG)
8312 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8313 (match_operand:HI 2 "general_operand" "rim,ri"))
8315 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8316 (and:HI (match_dup 1) (match_dup 2)))]
8317 "ix86_match_ccmode (insn, CCNOmode)
8318 && ix86_binary_operator_ok (AND, HImode, operands)"
8319 "and{w}\t{%2, %0|%0, %2}"
8320 [(set_attr "type" "alu")
8321 (set_attr "mode" "HI")])
8323 (define_expand "andqi3"
8324 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8325 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8326 (match_operand:QI 2 "general_operand" "")))
8327 (clobber (reg:CC FLAGS_REG))]
8328 "TARGET_QIMODE_MATH"
8329 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8331 ;; %%% Potential partial reg stall on alternative 2. What to do?
8332 (define_insn "*andqi_1"
8333 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8334 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8335 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8336 (clobber (reg:CC FLAGS_REG))]
8337 "ix86_binary_operator_ok (AND, QImode, operands)"
8339 and{b}\t{%2, %0|%0, %2}
8340 and{b}\t{%2, %0|%0, %2}
8341 and{l}\t{%k2, %k0|%k0, %k2}"
8342 [(set_attr "type" "alu")
8343 (set_attr "mode" "QI,QI,SI")])
8345 (define_insn "*andqi_1_slp"
8346 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8347 (and:QI (match_dup 0)
8348 (match_operand:QI 1 "general_operand" "qi,qmi")))
8349 (clobber (reg:CC FLAGS_REG))]
8350 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8351 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8352 "and{b}\t{%1, %0|%0, %1}"
8353 [(set_attr "type" "alu1")
8354 (set_attr "mode" "QI")])
8356 (define_insn "*andqi_2_maybe_si"
8357 [(set (reg FLAGS_REG)
8359 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8360 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8362 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8363 (and:QI (match_dup 1) (match_dup 2)))]
8364 "ix86_binary_operator_ok (AND, QImode, operands)
8365 && ix86_match_ccmode (insn,
8366 GET_CODE (operands[2]) == CONST_INT
8367 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8369 if (which_alternative == 2)
8371 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8372 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8373 return "and{l}\t{%2, %k0|%k0, %2}";
8375 return "and{b}\t{%2, %0|%0, %2}";
8377 [(set_attr "type" "alu")
8378 (set_attr "mode" "QI,QI,SI")])
8380 (define_insn "*andqi_2"
8381 [(set (reg FLAGS_REG)
8383 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8384 (match_operand:QI 2 "general_operand" "qim,qi"))
8386 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8387 (and:QI (match_dup 1) (match_dup 2)))]
8388 "ix86_match_ccmode (insn, CCNOmode)
8389 && ix86_binary_operator_ok (AND, QImode, operands)"
8390 "and{b}\t{%2, %0|%0, %2}"
8391 [(set_attr "type" "alu")
8392 (set_attr "mode" "QI")])
8394 (define_insn "*andqi_2_slp"
8395 [(set (reg FLAGS_REG)
8397 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8398 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8400 (set (strict_low_part (match_dup 0))
8401 (and:QI (match_dup 0) (match_dup 1)))]
8402 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8403 && ix86_match_ccmode (insn, CCNOmode)
8404 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8405 "and{b}\t{%1, %0|%0, %1}"
8406 [(set_attr "type" "alu1")
8407 (set_attr "mode" "QI")])
8409 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8410 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8411 ;; for a QImode operand, which of course failed.
8413 (define_insn "andqi_ext_0"
8414 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8419 (match_operand 1 "ext_register_operand" "0")
8422 (match_operand 2 "const_int_operand" "n")))
8423 (clobber (reg:CC FLAGS_REG))]
8425 "and{b}\t{%2, %h0|%h0, %2}"
8426 [(set_attr "type" "alu")
8427 (set_attr "length_immediate" "1")
8428 (set_attr "mode" "QI")])
8430 ;; Generated by peephole translating test to and. This shows up
8431 ;; often in fp comparisons.
8433 (define_insn "*andqi_ext_0_cc"
8434 [(set (reg FLAGS_REG)
8438 (match_operand 1 "ext_register_operand" "0")
8441 (match_operand 2 "const_int_operand" "n"))
8443 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8452 "ix86_match_ccmode (insn, CCNOmode)"
8453 "and{b}\t{%2, %h0|%h0, %2}"
8454 [(set_attr "type" "alu")
8455 (set_attr "length_immediate" "1")
8456 (set_attr "mode" "QI")])
8458 (define_insn "*andqi_ext_1"
8459 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8464 (match_operand 1 "ext_register_operand" "0")
8468 (match_operand:QI 2 "general_operand" "Qm"))))
8469 (clobber (reg:CC FLAGS_REG))]
8471 "and{b}\t{%2, %h0|%h0, %2}"
8472 [(set_attr "type" "alu")
8473 (set_attr "length_immediate" "0")
8474 (set_attr "mode" "QI")])
8476 (define_insn "*andqi_ext_1_rex64"
8477 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8482 (match_operand 1 "ext_register_operand" "0")
8486 (match_operand 2 "ext_register_operand" "Q"))))
8487 (clobber (reg:CC FLAGS_REG))]
8489 "and{b}\t{%2, %h0|%h0, %2}"
8490 [(set_attr "type" "alu")
8491 (set_attr "length_immediate" "0")
8492 (set_attr "mode" "QI")])
8494 (define_insn "*andqi_ext_2"
8495 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8500 (match_operand 1 "ext_register_operand" "%0")
8504 (match_operand 2 "ext_register_operand" "Q")
8507 (clobber (reg:CC FLAGS_REG))]
8509 "and{b}\t{%h2, %h0|%h0, %h2}"
8510 [(set_attr "type" "alu")
8511 (set_attr "length_immediate" "0")
8512 (set_attr "mode" "QI")])
8514 ;; Convert wide AND instructions with immediate operand to shorter QImode
8515 ;; equivalents when possible.
8516 ;; Don't do the splitting with memory operands, since it introduces risk
8517 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8518 ;; for size, but that can (should?) be handled by generic code instead.
8520 [(set (match_operand 0 "register_operand" "")
8521 (and (match_operand 1 "register_operand" "")
8522 (match_operand 2 "const_int_operand" "")))
8523 (clobber (reg:CC FLAGS_REG))]
8525 && QI_REG_P (operands[0])
8526 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8527 && !(~INTVAL (operands[2]) & ~(255 << 8))
8528 && GET_MODE (operands[0]) != QImode"
8529 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8530 (and:SI (zero_extract:SI (match_dup 1)
8531 (const_int 8) (const_int 8))
8533 (clobber (reg:CC FLAGS_REG))])]
8534 "operands[0] = gen_lowpart (SImode, operands[0]);
8535 operands[1] = gen_lowpart (SImode, operands[1]);
8536 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8538 ;; Since AND can be encoded with sign extended immediate, this is only
8539 ;; profitable when 7th bit is not set.
8541 [(set (match_operand 0 "register_operand" "")
8542 (and (match_operand 1 "general_operand" "")
8543 (match_operand 2 "const_int_operand" "")))
8544 (clobber (reg:CC FLAGS_REG))]
8546 && ANY_QI_REG_P (operands[0])
8547 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8548 && !(~INTVAL (operands[2]) & ~255)
8549 && !(INTVAL (operands[2]) & 128)
8550 && GET_MODE (operands[0]) != QImode"
8551 [(parallel [(set (strict_low_part (match_dup 0))
8552 (and:QI (match_dup 1)
8554 (clobber (reg:CC FLAGS_REG))])]
8555 "operands[0] = gen_lowpart (QImode, operands[0]);
8556 operands[1] = gen_lowpart (QImode, operands[1]);
8557 operands[2] = gen_lowpart (QImode, operands[2]);")
8559 ;; Logical inclusive OR instructions
8561 ;; %%% This used to optimize known byte-wide and operations to memory.
8562 ;; If this is considered useful, it should be done with splitters.
8564 (define_expand "iordi3"
8565 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8566 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8567 (match_operand:DI 2 "x86_64_general_operand" "")))
8568 (clobber (reg:CC FLAGS_REG))]
8570 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8572 (define_insn "*iordi_1_rex64"
8573 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8574 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8575 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8576 (clobber (reg:CC FLAGS_REG))]
8578 && ix86_binary_operator_ok (IOR, DImode, operands)"
8579 "or{q}\t{%2, %0|%0, %2}"
8580 [(set_attr "type" "alu")
8581 (set_attr "mode" "DI")])
8583 (define_insn "*iordi_2_rex64"
8584 [(set (reg FLAGS_REG)
8585 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8586 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8588 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8589 (ior:DI (match_dup 1) (match_dup 2)))]
8591 && ix86_match_ccmode (insn, CCNOmode)
8592 && ix86_binary_operator_ok (IOR, DImode, operands)"
8593 "or{q}\t{%2, %0|%0, %2}"
8594 [(set_attr "type" "alu")
8595 (set_attr "mode" "DI")])
8597 (define_insn "*iordi_3_rex64"
8598 [(set (reg FLAGS_REG)
8599 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8600 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8602 (clobber (match_scratch:DI 0 "=r"))]
8604 && ix86_match_ccmode (insn, CCNOmode)
8605 && ix86_binary_operator_ok (IOR, DImode, operands)"
8606 "or{q}\t{%2, %0|%0, %2}"
8607 [(set_attr "type" "alu")
8608 (set_attr "mode" "DI")])
8611 (define_expand "iorsi3"
8612 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8613 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8614 (match_operand:SI 2 "general_operand" "")))
8615 (clobber (reg:CC FLAGS_REG))]
8617 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8619 (define_insn "*iorsi_1"
8620 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8621 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8622 (match_operand:SI 2 "general_operand" "ri,rmi")))
8623 (clobber (reg:CC FLAGS_REG))]
8624 "ix86_binary_operator_ok (IOR, SImode, operands)"
8625 "or{l}\t{%2, %0|%0, %2}"
8626 [(set_attr "type" "alu")
8627 (set_attr "mode" "SI")])
8629 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8630 (define_insn "*iorsi_1_zext"
8631 [(set (match_operand:DI 0 "register_operand" "=rm")
8633 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8634 (match_operand:SI 2 "general_operand" "rim"))))
8635 (clobber (reg:CC FLAGS_REG))]
8636 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8637 "or{l}\t{%2, %k0|%k0, %2}"
8638 [(set_attr "type" "alu")
8639 (set_attr "mode" "SI")])
8641 (define_insn "*iorsi_1_zext_imm"
8642 [(set (match_operand:DI 0 "register_operand" "=rm")
8643 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8644 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8645 (clobber (reg:CC FLAGS_REG))]
8647 "or{l}\t{%2, %k0|%k0, %2}"
8648 [(set_attr "type" "alu")
8649 (set_attr "mode" "SI")])
8651 (define_insn "*iorsi_2"
8652 [(set (reg FLAGS_REG)
8653 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8654 (match_operand:SI 2 "general_operand" "rim,ri"))
8656 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8657 (ior:SI (match_dup 1) (match_dup 2)))]
8658 "ix86_match_ccmode (insn, CCNOmode)
8659 && ix86_binary_operator_ok (IOR, SImode, operands)"
8660 "or{l}\t{%2, %0|%0, %2}"
8661 [(set_attr "type" "alu")
8662 (set_attr "mode" "SI")])
8664 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8665 ;; ??? Special case for immediate operand is missing - it is tricky.
8666 (define_insn "*iorsi_2_zext"
8667 [(set (reg FLAGS_REG)
8668 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8669 (match_operand:SI 2 "general_operand" "rim"))
8671 (set (match_operand:DI 0 "register_operand" "=r")
8672 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8673 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8674 && ix86_binary_operator_ok (IOR, SImode, operands)"
8675 "or{l}\t{%2, %k0|%k0, %2}"
8676 [(set_attr "type" "alu")
8677 (set_attr "mode" "SI")])
8679 (define_insn "*iorsi_2_zext_imm"
8680 [(set (reg FLAGS_REG)
8681 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8682 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8684 (set (match_operand:DI 0 "register_operand" "=r")
8685 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8686 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8687 && ix86_binary_operator_ok (IOR, SImode, operands)"
8688 "or{l}\t{%2, %k0|%k0, %2}"
8689 [(set_attr "type" "alu")
8690 (set_attr "mode" "SI")])
8692 (define_insn "*iorsi_3"
8693 [(set (reg FLAGS_REG)
8694 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8695 (match_operand:SI 2 "general_operand" "rim"))
8697 (clobber (match_scratch:SI 0 "=r"))]
8698 "ix86_match_ccmode (insn, CCNOmode)
8699 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8700 "or{l}\t{%2, %0|%0, %2}"
8701 [(set_attr "type" "alu")
8702 (set_attr "mode" "SI")])
8704 (define_expand "iorhi3"
8705 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8706 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8707 (match_operand:HI 2 "general_operand" "")))
8708 (clobber (reg:CC FLAGS_REG))]
8709 "TARGET_HIMODE_MATH"
8710 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8712 (define_insn "*iorhi_1"
8713 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8714 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8715 (match_operand:HI 2 "general_operand" "rmi,ri")))
8716 (clobber (reg:CC FLAGS_REG))]
8717 "ix86_binary_operator_ok (IOR, HImode, operands)"
8718 "or{w}\t{%2, %0|%0, %2}"
8719 [(set_attr "type" "alu")
8720 (set_attr "mode" "HI")])
8722 (define_insn "*iorhi_2"
8723 [(set (reg FLAGS_REG)
8724 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8725 (match_operand:HI 2 "general_operand" "rim,ri"))
8727 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8728 (ior:HI (match_dup 1) (match_dup 2)))]
8729 "ix86_match_ccmode (insn, CCNOmode)
8730 && ix86_binary_operator_ok (IOR, HImode, operands)"
8731 "or{w}\t{%2, %0|%0, %2}"
8732 [(set_attr "type" "alu")
8733 (set_attr "mode" "HI")])
8735 (define_insn "*iorhi_3"
8736 [(set (reg FLAGS_REG)
8737 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8738 (match_operand:HI 2 "general_operand" "rim"))
8740 (clobber (match_scratch:HI 0 "=r"))]
8741 "ix86_match_ccmode (insn, CCNOmode)
8742 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8743 "or{w}\t{%2, %0|%0, %2}"
8744 [(set_attr "type" "alu")
8745 (set_attr "mode" "HI")])
8747 (define_expand "iorqi3"
8748 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8749 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8750 (match_operand:QI 2 "general_operand" "")))
8751 (clobber (reg:CC FLAGS_REG))]
8752 "TARGET_QIMODE_MATH"
8753 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8755 ;; %%% Potential partial reg stall on alternative 2. What to do?
8756 (define_insn "*iorqi_1"
8757 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8758 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8759 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8760 (clobber (reg:CC FLAGS_REG))]
8761 "ix86_binary_operator_ok (IOR, QImode, operands)"
8763 or{b}\t{%2, %0|%0, %2}
8764 or{b}\t{%2, %0|%0, %2}
8765 or{l}\t{%k2, %k0|%k0, %k2}"
8766 [(set_attr "type" "alu")
8767 (set_attr "mode" "QI,QI,SI")])
8769 (define_insn "*iorqi_1_slp"
8770 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8771 (ior:QI (match_dup 0)
8772 (match_operand:QI 1 "general_operand" "qmi,qi")))
8773 (clobber (reg:CC FLAGS_REG))]
8774 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8775 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8776 "or{b}\t{%1, %0|%0, %1}"
8777 [(set_attr "type" "alu1")
8778 (set_attr "mode" "QI")])
8780 (define_insn "*iorqi_2"
8781 [(set (reg FLAGS_REG)
8782 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8783 (match_operand:QI 2 "general_operand" "qim,qi"))
8785 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8786 (ior:QI (match_dup 1) (match_dup 2)))]
8787 "ix86_match_ccmode (insn, CCNOmode)
8788 && ix86_binary_operator_ok (IOR, QImode, operands)"
8789 "or{b}\t{%2, %0|%0, %2}"
8790 [(set_attr "type" "alu")
8791 (set_attr "mode" "QI")])
8793 (define_insn "*iorqi_2_slp"
8794 [(set (reg FLAGS_REG)
8795 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8796 (match_operand:QI 1 "general_operand" "qim,qi"))
8798 (set (strict_low_part (match_dup 0))
8799 (ior:QI (match_dup 0) (match_dup 1)))]
8800 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8801 && ix86_match_ccmode (insn, CCNOmode)
8802 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8803 "or{b}\t{%1, %0|%0, %1}"
8804 [(set_attr "type" "alu1")
8805 (set_attr "mode" "QI")])
8807 (define_insn "*iorqi_3"
8808 [(set (reg FLAGS_REG)
8809 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8810 (match_operand:QI 2 "general_operand" "qim"))
8812 (clobber (match_scratch:QI 0 "=q"))]
8813 "ix86_match_ccmode (insn, CCNOmode)
8814 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8815 "or{b}\t{%2, %0|%0, %2}"
8816 [(set_attr "type" "alu")
8817 (set_attr "mode" "QI")])
8819 (define_insn "iorqi_ext_0"
8820 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8825 (match_operand 1 "ext_register_operand" "0")
8828 (match_operand 2 "const_int_operand" "n")))
8829 (clobber (reg:CC FLAGS_REG))]
8830 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8831 "or{b}\t{%2, %h0|%h0, %2}"
8832 [(set_attr "type" "alu")
8833 (set_attr "length_immediate" "1")
8834 (set_attr "mode" "QI")])
8836 (define_insn "*iorqi_ext_1"
8837 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8842 (match_operand 1 "ext_register_operand" "0")
8846 (match_operand:QI 2 "general_operand" "Qm"))))
8847 (clobber (reg:CC FLAGS_REG))]
8849 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8850 "or{b}\t{%2, %h0|%h0, %2}"
8851 [(set_attr "type" "alu")
8852 (set_attr "length_immediate" "0")
8853 (set_attr "mode" "QI")])
8855 (define_insn "*iorqi_ext_1_rex64"
8856 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8861 (match_operand 1 "ext_register_operand" "0")
8865 (match_operand 2 "ext_register_operand" "Q"))))
8866 (clobber (reg:CC FLAGS_REG))]
8868 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8869 "or{b}\t{%2, %h0|%h0, %2}"
8870 [(set_attr "type" "alu")
8871 (set_attr "length_immediate" "0")
8872 (set_attr "mode" "QI")])
8874 (define_insn "*iorqi_ext_2"
8875 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8879 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8882 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8885 (clobber (reg:CC FLAGS_REG))]
8886 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8887 "ior{b}\t{%h2, %h0|%h0, %h2}"
8888 [(set_attr "type" "alu")
8889 (set_attr "length_immediate" "0")
8890 (set_attr "mode" "QI")])
8893 [(set (match_operand 0 "register_operand" "")
8894 (ior (match_operand 1 "register_operand" "")
8895 (match_operand 2 "const_int_operand" "")))
8896 (clobber (reg:CC FLAGS_REG))]
8898 && QI_REG_P (operands[0])
8899 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8900 && !(INTVAL (operands[2]) & ~(255 << 8))
8901 && GET_MODE (operands[0]) != QImode"
8902 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8903 (ior:SI (zero_extract:SI (match_dup 1)
8904 (const_int 8) (const_int 8))
8906 (clobber (reg:CC FLAGS_REG))])]
8907 "operands[0] = gen_lowpart (SImode, operands[0]);
8908 operands[1] = gen_lowpart (SImode, operands[1]);
8909 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8911 ;; Since OR can be encoded with sign extended immediate, this is only
8912 ;; profitable when 7th bit is set.
8914 [(set (match_operand 0 "register_operand" "")
8915 (ior (match_operand 1 "general_operand" "")
8916 (match_operand 2 "const_int_operand" "")))
8917 (clobber (reg:CC FLAGS_REG))]
8919 && ANY_QI_REG_P (operands[0])
8920 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8921 && !(INTVAL (operands[2]) & ~255)
8922 && (INTVAL (operands[2]) & 128)
8923 && GET_MODE (operands[0]) != QImode"
8924 [(parallel [(set (strict_low_part (match_dup 0))
8925 (ior:QI (match_dup 1)
8927 (clobber (reg:CC FLAGS_REG))])]
8928 "operands[0] = gen_lowpart (QImode, operands[0]);
8929 operands[1] = gen_lowpart (QImode, operands[1]);
8930 operands[2] = gen_lowpart (QImode, operands[2]);")
8932 ;; Logical XOR instructions
8934 ;; %%% This used to optimize known byte-wide and operations to memory.
8935 ;; If this is considered useful, it should be done with splitters.
8937 (define_expand "xordi3"
8938 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8939 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8940 (match_operand:DI 2 "x86_64_general_operand" "")))
8941 (clobber (reg:CC FLAGS_REG))]
8943 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8945 (define_insn "*xordi_1_rex64"
8946 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8947 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8948 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8949 (clobber (reg:CC FLAGS_REG))]
8951 && ix86_binary_operator_ok (XOR, DImode, operands)"
8953 xor{q}\t{%2, %0|%0, %2}
8954 xor{q}\t{%2, %0|%0, %2}"
8955 [(set_attr "type" "alu")
8956 (set_attr "mode" "DI,DI")])
8958 (define_insn "*xordi_2_rex64"
8959 [(set (reg FLAGS_REG)
8960 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8961 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8963 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8964 (xor:DI (match_dup 1) (match_dup 2)))]
8966 && ix86_match_ccmode (insn, CCNOmode)
8967 && ix86_binary_operator_ok (XOR, DImode, operands)"
8969 xor{q}\t{%2, %0|%0, %2}
8970 xor{q}\t{%2, %0|%0, %2}"
8971 [(set_attr "type" "alu")
8972 (set_attr "mode" "DI,DI")])
8974 (define_insn "*xordi_3_rex64"
8975 [(set (reg FLAGS_REG)
8976 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8977 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8979 (clobber (match_scratch:DI 0 "=r"))]
8981 && ix86_match_ccmode (insn, CCNOmode)
8982 && ix86_binary_operator_ok (XOR, DImode, operands)"
8983 "xor{q}\t{%2, %0|%0, %2}"
8984 [(set_attr "type" "alu")
8985 (set_attr "mode" "DI")])
8987 (define_expand "xorsi3"
8988 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8989 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8990 (match_operand:SI 2 "general_operand" "")))
8991 (clobber (reg:CC FLAGS_REG))]
8993 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8995 (define_insn "*xorsi_1"
8996 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8997 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8998 (match_operand:SI 2 "general_operand" "ri,rm")))
8999 (clobber (reg:CC FLAGS_REG))]
9000 "ix86_binary_operator_ok (XOR, SImode, operands)"
9001 "xor{l}\t{%2, %0|%0, %2}"
9002 [(set_attr "type" "alu")
9003 (set_attr "mode" "SI")])
9005 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9006 ;; Add speccase for immediates
9007 (define_insn "*xorsi_1_zext"
9008 [(set (match_operand:DI 0 "register_operand" "=r")
9010 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9011 (match_operand:SI 2 "general_operand" "rim"))))
9012 (clobber (reg:CC FLAGS_REG))]
9013 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9014 "xor{l}\t{%2, %k0|%k0, %2}"
9015 [(set_attr "type" "alu")
9016 (set_attr "mode" "SI")])
9018 (define_insn "*xorsi_1_zext_imm"
9019 [(set (match_operand:DI 0 "register_operand" "=r")
9020 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9021 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9022 (clobber (reg:CC FLAGS_REG))]
9023 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9024 "xor{l}\t{%2, %k0|%k0, %2}"
9025 [(set_attr "type" "alu")
9026 (set_attr "mode" "SI")])
9028 (define_insn "*xorsi_2"
9029 [(set (reg FLAGS_REG)
9030 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9031 (match_operand:SI 2 "general_operand" "rim,ri"))
9033 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9034 (xor:SI (match_dup 1) (match_dup 2)))]
9035 "ix86_match_ccmode (insn, CCNOmode)
9036 && ix86_binary_operator_ok (XOR, SImode, operands)"
9037 "xor{l}\t{%2, %0|%0, %2}"
9038 [(set_attr "type" "alu")
9039 (set_attr "mode" "SI")])
9041 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9042 ;; ??? Special case for immediate operand is missing - it is tricky.
9043 (define_insn "*xorsi_2_zext"
9044 [(set (reg FLAGS_REG)
9045 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9046 (match_operand:SI 2 "general_operand" "rim"))
9048 (set (match_operand:DI 0 "register_operand" "=r")
9049 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9050 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9051 && ix86_binary_operator_ok (XOR, SImode, operands)"
9052 "xor{l}\t{%2, %k0|%k0, %2}"
9053 [(set_attr "type" "alu")
9054 (set_attr "mode" "SI")])
9056 (define_insn "*xorsi_2_zext_imm"
9057 [(set (reg FLAGS_REG)
9058 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9059 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9061 (set (match_operand:DI 0 "register_operand" "=r")
9062 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9063 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9064 && ix86_binary_operator_ok (XOR, SImode, operands)"
9065 "xor{l}\t{%2, %k0|%k0, %2}"
9066 [(set_attr "type" "alu")
9067 (set_attr "mode" "SI")])
9069 (define_insn "*xorsi_3"
9070 [(set (reg FLAGS_REG)
9071 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9072 (match_operand:SI 2 "general_operand" "rim"))
9074 (clobber (match_scratch:SI 0 "=r"))]
9075 "ix86_match_ccmode (insn, CCNOmode)
9076 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9077 "xor{l}\t{%2, %0|%0, %2}"
9078 [(set_attr "type" "alu")
9079 (set_attr "mode" "SI")])
9081 (define_expand "xorhi3"
9082 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9083 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9084 (match_operand:HI 2 "general_operand" "")))
9085 (clobber (reg:CC FLAGS_REG))]
9086 "TARGET_HIMODE_MATH"
9087 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9089 (define_insn "*xorhi_1"
9090 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9091 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9092 (match_operand:HI 2 "general_operand" "rmi,ri")))
9093 (clobber (reg:CC FLAGS_REG))]
9094 "ix86_binary_operator_ok (XOR, HImode, operands)"
9095 "xor{w}\t{%2, %0|%0, %2}"
9096 [(set_attr "type" "alu")
9097 (set_attr "mode" "HI")])
9099 (define_insn "*xorhi_2"
9100 [(set (reg FLAGS_REG)
9101 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9102 (match_operand:HI 2 "general_operand" "rim,ri"))
9104 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9105 (xor:HI (match_dup 1) (match_dup 2)))]
9106 "ix86_match_ccmode (insn, CCNOmode)
9107 && ix86_binary_operator_ok (XOR, HImode, operands)"
9108 "xor{w}\t{%2, %0|%0, %2}"
9109 [(set_attr "type" "alu")
9110 (set_attr "mode" "HI")])
9112 (define_insn "*xorhi_3"
9113 [(set (reg FLAGS_REG)
9114 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9115 (match_operand:HI 2 "general_operand" "rim"))
9117 (clobber (match_scratch:HI 0 "=r"))]
9118 "ix86_match_ccmode (insn, CCNOmode)
9119 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9120 "xor{w}\t{%2, %0|%0, %2}"
9121 [(set_attr "type" "alu")
9122 (set_attr "mode" "HI")])
9124 (define_expand "xorqi3"
9125 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9126 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9127 (match_operand:QI 2 "general_operand" "")))
9128 (clobber (reg:CC FLAGS_REG))]
9129 "TARGET_QIMODE_MATH"
9130 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9132 ;; %%% Potential partial reg stall on alternative 2. What to do?
9133 (define_insn "*xorqi_1"
9134 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9135 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9136 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9137 (clobber (reg:CC FLAGS_REG))]
9138 "ix86_binary_operator_ok (XOR, QImode, operands)"
9140 xor{b}\t{%2, %0|%0, %2}
9141 xor{b}\t{%2, %0|%0, %2}
9142 xor{l}\t{%k2, %k0|%k0, %k2}"
9143 [(set_attr "type" "alu")
9144 (set_attr "mode" "QI,QI,SI")])
9146 (define_insn "*xorqi_1_slp"
9147 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9148 (xor:QI (match_dup 0)
9149 (match_operand:QI 1 "general_operand" "qi,qmi")))
9150 (clobber (reg:CC FLAGS_REG))]
9151 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9152 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9153 "xor{b}\t{%1, %0|%0, %1}"
9154 [(set_attr "type" "alu1")
9155 (set_attr "mode" "QI")])
9157 (define_insn "xorqi_ext_0"
9158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9163 (match_operand 1 "ext_register_operand" "0")
9166 (match_operand 2 "const_int_operand" "n")))
9167 (clobber (reg:CC FLAGS_REG))]
9168 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9169 "xor{b}\t{%2, %h0|%h0, %2}"
9170 [(set_attr "type" "alu")
9171 (set_attr "length_immediate" "1")
9172 (set_attr "mode" "QI")])
9174 (define_insn "*xorqi_ext_1"
9175 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9180 (match_operand 1 "ext_register_operand" "0")
9184 (match_operand:QI 2 "general_operand" "Qm"))))
9185 (clobber (reg:CC FLAGS_REG))]
9187 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9188 "xor{b}\t{%2, %h0|%h0, %2}"
9189 [(set_attr "type" "alu")
9190 (set_attr "length_immediate" "0")
9191 (set_attr "mode" "QI")])
9193 (define_insn "*xorqi_ext_1_rex64"
9194 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9199 (match_operand 1 "ext_register_operand" "0")
9203 (match_operand 2 "ext_register_operand" "Q"))))
9204 (clobber (reg:CC FLAGS_REG))]
9206 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9207 "xor{b}\t{%2, %h0|%h0, %2}"
9208 [(set_attr "type" "alu")
9209 (set_attr "length_immediate" "0")
9210 (set_attr "mode" "QI")])
9212 (define_insn "*xorqi_ext_2"
9213 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9217 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9220 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9223 (clobber (reg:CC FLAGS_REG))]
9224 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9225 "xor{b}\t{%h2, %h0|%h0, %h2}"
9226 [(set_attr "type" "alu")
9227 (set_attr "length_immediate" "0")
9228 (set_attr "mode" "QI")])
9230 (define_insn "*xorqi_cc_1"
9231 [(set (reg FLAGS_REG)
9233 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9234 (match_operand:QI 2 "general_operand" "qim,qi"))
9236 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9237 (xor:QI (match_dup 1) (match_dup 2)))]
9238 "ix86_match_ccmode (insn, CCNOmode)
9239 && ix86_binary_operator_ok (XOR, QImode, operands)"
9240 "xor{b}\t{%2, %0|%0, %2}"
9241 [(set_attr "type" "alu")
9242 (set_attr "mode" "QI")])
9244 (define_insn "*xorqi_2_slp"
9245 [(set (reg FLAGS_REG)
9246 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9247 (match_operand:QI 1 "general_operand" "qim,qi"))
9249 (set (strict_low_part (match_dup 0))
9250 (xor:QI (match_dup 0) (match_dup 1)))]
9251 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9252 && ix86_match_ccmode (insn, CCNOmode)
9253 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9254 "xor{b}\t{%1, %0|%0, %1}"
9255 [(set_attr "type" "alu1")
9256 (set_attr "mode" "QI")])
9258 (define_insn "*xorqi_cc_2"
9259 [(set (reg FLAGS_REG)
9261 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9262 (match_operand:QI 2 "general_operand" "qim"))
9264 (clobber (match_scratch:QI 0 "=q"))]
9265 "ix86_match_ccmode (insn, CCNOmode)
9266 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9267 "xor{b}\t{%2, %0|%0, %2}"
9268 [(set_attr "type" "alu")
9269 (set_attr "mode" "QI")])
9271 (define_insn "*xorqi_cc_ext_1"
9272 [(set (reg FLAGS_REG)
9276 (match_operand 1 "ext_register_operand" "0")
9279 (match_operand:QI 2 "general_operand" "qmn"))
9281 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9285 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9287 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9288 "xor{b}\t{%2, %h0|%h0, %2}"
9289 [(set_attr "type" "alu")
9290 (set_attr "mode" "QI")])
9292 (define_insn "*xorqi_cc_ext_1_rex64"
9293 [(set (reg FLAGS_REG)
9297 (match_operand 1 "ext_register_operand" "0")
9300 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9302 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9306 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9308 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9309 "xor{b}\t{%2, %h0|%h0, %2}"
9310 [(set_attr "type" "alu")
9311 (set_attr "mode" "QI")])
9313 (define_expand "xorqi_cc_ext_1"
9315 (set (reg:CCNO FLAGS_REG)
9319 (match_operand 1 "ext_register_operand" "")
9322 (match_operand:QI 2 "general_operand" ""))
9324 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9328 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9334 [(set (match_operand 0 "register_operand" "")
9335 (xor (match_operand 1 "register_operand" "")
9336 (match_operand 2 "const_int_operand" "")))
9337 (clobber (reg:CC FLAGS_REG))]
9339 && QI_REG_P (operands[0])
9340 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9341 && !(INTVAL (operands[2]) & ~(255 << 8))
9342 && GET_MODE (operands[0]) != QImode"
9343 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9344 (xor:SI (zero_extract:SI (match_dup 1)
9345 (const_int 8) (const_int 8))
9347 (clobber (reg:CC FLAGS_REG))])]
9348 "operands[0] = gen_lowpart (SImode, operands[0]);
9349 operands[1] = gen_lowpart (SImode, operands[1]);
9350 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9352 ;; Since XOR can be encoded with sign extended immediate, this is only
9353 ;; profitable when 7th bit is set.
9355 [(set (match_operand 0 "register_operand" "")
9356 (xor (match_operand 1 "general_operand" "")
9357 (match_operand 2 "const_int_operand" "")))
9358 (clobber (reg:CC FLAGS_REG))]
9360 && ANY_QI_REG_P (operands[0])
9361 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9362 && !(INTVAL (operands[2]) & ~255)
9363 && (INTVAL (operands[2]) & 128)
9364 && GET_MODE (operands[0]) != QImode"
9365 [(parallel [(set (strict_low_part (match_dup 0))
9366 (xor:QI (match_dup 1)
9368 (clobber (reg:CC FLAGS_REG))])]
9369 "operands[0] = gen_lowpart (QImode, operands[0]);
9370 operands[1] = gen_lowpart (QImode, operands[1]);
9371 operands[2] = gen_lowpart (QImode, operands[2]);")
9373 ;; Negation instructions
9375 (define_expand "negti2"
9376 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9377 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9378 (clobber (reg:CC FLAGS_REG))])]
9380 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9382 (define_insn "*negti2_1"
9383 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9384 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9385 (clobber (reg:CC FLAGS_REG))]
9387 && ix86_unary_operator_ok (NEG, TImode, operands)"
9391 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9392 (neg:TI (match_operand:TI 1 "general_operand" "")))
9393 (clobber (reg:CC FLAGS_REG))]
9394 "TARGET_64BIT && reload_completed"
9396 [(set (reg:CCZ FLAGS_REG)
9397 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9398 (set (match_dup 0) (neg:DI (match_dup 2)))])
9401 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9404 (clobber (reg:CC FLAGS_REG))])
9407 (neg:DI (match_dup 1)))
9408 (clobber (reg:CC FLAGS_REG))])]
9409 "split_ti (operands+1, 1, operands+2, operands+3);
9410 split_ti (operands+0, 1, operands+0, operands+1);")
9412 (define_expand "negdi2"
9413 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9414 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9415 (clobber (reg:CC FLAGS_REG))])]
9417 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9419 (define_insn "*negdi2_1"
9420 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9421 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9422 (clobber (reg:CC FLAGS_REG))]
9424 && ix86_unary_operator_ok (NEG, DImode, operands)"
9428 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9429 (neg:DI (match_operand:DI 1 "general_operand" "")))
9430 (clobber (reg:CC FLAGS_REG))]
9431 "!TARGET_64BIT && reload_completed"
9433 [(set (reg:CCZ FLAGS_REG)
9434 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9435 (set (match_dup 0) (neg:SI (match_dup 2)))])
9438 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9441 (clobber (reg:CC FLAGS_REG))])
9444 (neg:SI (match_dup 1)))
9445 (clobber (reg:CC FLAGS_REG))])]
9446 "split_di (operands+1, 1, operands+2, operands+3);
9447 split_di (operands+0, 1, operands+0, operands+1);")
9449 (define_insn "*negdi2_1_rex64"
9450 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9451 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9452 (clobber (reg:CC FLAGS_REG))]
9453 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9455 [(set_attr "type" "negnot")
9456 (set_attr "mode" "DI")])
9458 ;; The problem with neg is that it does not perform (compare x 0),
9459 ;; it really performs (compare 0 x), which leaves us with the zero
9460 ;; flag being the only useful item.
9462 (define_insn "*negdi2_cmpz_rex64"
9463 [(set (reg:CCZ FLAGS_REG)
9464 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9466 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9467 (neg:DI (match_dup 1)))]
9468 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9470 [(set_attr "type" "negnot")
9471 (set_attr "mode" "DI")])
9474 (define_expand "negsi2"
9475 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9476 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9477 (clobber (reg:CC FLAGS_REG))])]
9479 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9481 (define_insn "*negsi2_1"
9482 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9483 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9484 (clobber (reg:CC FLAGS_REG))]
9485 "ix86_unary_operator_ok (NEG, SImode, operands)"
9487 [(set_attr "type" "negnot")
9488 (set_attr "mode" "SI")])
9490 ;; Combine is quite creative about this pattern.
9491 (define_insn "*negsi2_1_zext"
9492 [(set (match_operand:DI 0 "register_operand" "=r")
9493 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9496 (clobber (reg:CC FLAGS_REG))]
9497 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9499 [(set_attr "type" "negnot")
9500 (set_attr "mode" "SI")])
9502 ;; The problem with neg is that it does not perform (compare x 0),
9503 ;; it really performs (compare 0 x), which leaves us with the zero
9504 ;; flag being the only useful item.
9506 (define_insn "*negsi2_cmpz"
9507 [(set (reg:CCZ FLAGS_REG)
9508 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9510 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9511 (neg:SI (match_dup 1)))]
9512 "ix86_unary_operator_ok (NEG, SImode, operands)"
9514 [(set_attr "type" "negnot")
9515 (set_attr "mode" "SI")])
9517 (define_insn "*negsi2_cmpz_zext"
9518 [(set (reg:CCZ FLAGS_REG)
9519 (compare:CCZ (lshiftrt:DI
9521 (match_operand:DI 1 "register_operand" "0")
9525 (set (match_operand:DI 0 "register_operand" "=r")
9526 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9529 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9531 [(set_attr "type" "negnot")
9532 (set_attr "mode" "SI")])
9534 (define_expand "neghi2"
9535 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9536 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9537 (clobber (reg:CC FLAGS_REG))])]
9538 "TARGET_HIMODE_MATH"
9539 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9541 (define_insn "*neghi2_1"
9542 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9543 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9544 (clobber (reg:CC FLAGS_REG))]
9545 "ix86_unary_operator_ok (NEG, HImode, operands)"
9547 [(set_attr "type" "negnot")
9548 (set_attr "mode" "HI")])
9550 (define_insn "*neghi2_cmpz"
9551 [(set (reg:CCZ FLAGS_REG)
9552 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9554 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9555 (neg:HI (match_dup 1)))]
9556 "ix86_unary_operator_ok (NEG, HImode, operands)"
9558 [(set_attr "type" "negnot")
9559 (set_attr "mode" "HI")])
9561 (define_expand "negqi2"
9562 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9563 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9564 (clobber (reg:CC FLAGS_REG))])]
9565 "TARGET_QIMODE_MATH"
9566 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9568 (define_insn "*negqi2_1"
9569 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9570 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9571 (clobber (reg:CC FLAGS_REG))]
9572 "ix86_unary_operator_ok (NEG, QImode, operands)"
9574 [(set_attr "type" "negnot")
9575 (set_attr "mode" "QI")])
9577 (define_insn "*negqi2_cmpz"
9578 [(set (reg:CCZ FLAGS_REG)
9579 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9581 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9582 (neg:QI (match_dup 1)))]
9583 "ix86_unary_operator_ok (NEG, QImode, operands)"
9585 [(set_attr "type" "negnot")
9586 (set_attr "mode" "QI")])
9588 ;; Changing of sign for FP values is doable using integer unit too.
9590 (define_expand "negsf2"
9591 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9592 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9593 "TARGET_80387 || TARGET_SSE_MATH"
9594 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9596 (define_expand "abssf2"
9597 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9598 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9599 "TARGET_80387 || TARGET_SSE_MATH"
9600 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9602 (define_insn "*absnegsf2_mixed"
9603 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9604 (match_operator:SF 3 "absneg_operator"
9605 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9606 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9607 (clobber (reg:CC FLAGS_REG))]
9608 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9609 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9612 (define_insn "*absnegsf2_sse"
9613 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9614 (match_operator:SF 3 "absneg_operator"
9615 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9616 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9617 (clobber (reg:CC FLAGS_REG))]
9619 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9622 (define_insn "*absnegsf2_i387"
9623 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9624 (match_operator:SF 3 "absneg_operator"
9625 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9626 (use (match_operand 2 "" ""))
9627 (clobber (reg:CC FLAGS_REG))]
9628 "TARGET_80387 && !TARGET_SSE_MATH
9629 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9632 (define_expand "copysignsf3"
9633 [(match_operand:SF 0 "register_operand" "")
9634 (match_operand:SF 1 "nonmemory_operand" "")
9635 (match_operand:SF 2 "register_operand" "")]
9638 ix86_expand_copysign (operands);
9642 (define_insn_and_split "copysignsf3_const"
9643 [(set (match_operand:SF 0 "register_operand" "=x")
9645 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9646 (match_operand:SF 2 "register_operand" "0")
9647 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9651 "&& reload_completed"
9654 ix86_split_copysign_const (operands);
9658 (define_insn "copysignsf3_var"
9659 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9661 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9662 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9663 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9664 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9666 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9671 [(set (match_operand:SF 0 "register_operand" "")
9673 [(match_operand:SF 2 "register_operand" "")
9674 (match_operand:SF 3 "register_operand" "")
9675 (match_operand:V4SF 4 "" "")
9676 (match_operand:V4SF 5 "" "")]
9678 (clobber (match_scratch:V4SF 1 ""))]
9679 "TARGET_SSE_MATH && reload_completed"
9682 ix86_split_copysign_var (operands);
9686 (define_expand "negdf2"
9687 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9688 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9689 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9690 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9692 (define_expand "absdf2"
9693 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9694 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9695 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9696 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9698 (define_insn "*absnegdf2_mixed"
9699 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9700 (match_operator:DF 3 "absneg_operator"
9701 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9702 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9703 (clobber (reg:CC FLAGS_REG))]
9704 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9705 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9708 (define_insn "*absnegdf2_sse"
9709 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9710 (match_operator:DF 3 "absneg_operator"
9711 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9712 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9713 (clobber (reg:CC FLAGS_REG))]
9714 "TARGET_SSE2 && TARGET_SSE_MATH
9715 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9718 (define_insn "*absnegdf2_i387"
9719 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9720 (match_operator:DF 3 "absneg_operator"
9721 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9722 (use (match_operand 2 "" ""))
9723 (clobber (reg:CC FLAGS_REG))]
9724 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9725 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9728 (define_expand "copysigndf3"
9729 [(match_operand:DF 0 "register_operand" "")
9730 (match_operand:DF 1 "nonmemory_operand" "")
9731 (match_operand:DF 2 "register_operand" "")]
9732 "TARGET_SSE2 && TARGET_SSE_MATH"
9734 ix86_expand_copysign (operands);
9738 (define_insn_and_split "copysigndf3_const"
9739 [(set (match_operand:DF 0 "register_operand" "=x")
9741 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9742 (match_operand:DF 2 "register_operand" "0")
9743 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9745 "TARGET_SSE2 && TARGET_SSE_MATH"
9747 "&& reload_completed"
9750 ix86_split_copysign_const (operands);
9754 (define_insn "copysigndf3_var"
9755 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9757 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9758 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9759 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9760 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9762 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9763 "TARGET_SSE2 && TARGET_SSE_MATH"
9767 [(set (match_operand:DF 0 "register_operand" "")
9769 [(match_operand:DF 2 "register_operand" "")
9770 (match_operand:DF 3 "register_operand" "")
9771 (match_operand:V2DF 4 "" "")
9772 (match_operand:V2DF 5 "" "")]
9774 (clobber (match_scratch:V2DF 1 ""))]
9775 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9778 ix86_split_copysign_var (operands);
9782 (define_expand "negxf2"
9783 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9784 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9786 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9788 (define_expand "absxf2"
9789 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9790 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9792 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9794 (define_insn "*absnegxf2_i387"
9795 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9796 (match_operator:XF 3 "absneg_operator"
9797 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9798 (use (match_operand 2 "" ""))
9799 (clobber (reg:CC FLAGS_REG))]
9801 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9804 ;; Splitters for fp abs and neg.
9807 [(set (match_operand 0 "fp_register_operand" "")
9808 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9809 (use (match_operand 2 "" ""))
9810 (clobber (reg:CC FLAGS_REG))]
9812 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9815 [(set (match_operand 0 "register_operand" "")
9816 (match_operator 3 "absneg_operator"
9817 [(match_operand 1 "register_operand" "")]))
9818 (use (match_operand 2 "nonimmediate_operand" ""))
9819 (clobber (reg:CC FLAGS_REG))]
9820 "reload_completed && SSE_REG_P (operands[0])"
9821 [(set (match_dup 0) (match_dup 3))]
9823 enum machine_mode mode = GET_MODE (operands[0]);
9824 enum machine_mode vmode = GET_MODE (operands[2]);
9827 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9828 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9829 if (operands_match_p (operands[0], operands[2]))
9832 operands[1] = operands[2];
9835 if (GET_CODE (operands[3]) == ABS)
9836 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9838 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9843 [(set (match_operand:SF 0 "register_operand" "")
9844 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9845 (use (match_operand:V4SF 2 "" ""))
9846 (clobber (reg:CC FLAGS_REG))]
9848 [(parallel [(set (match_dup 0) (match_dup 1))
9849 (clobber (reg:CC FLAGS_REG))])]
9852 operands[0] = gen_lowpart (SImode, operands[0]);
9853 if (GET_CODE (operands[1]) == ABS)
9855 tmp = gen_int_mode (0x7fffffff, SImode);
9856 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9860 tmp = gen_int_mode (0x80000000, SImode);
9861 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9867 [(set (match_operand:DF 0 "register_operand" "")
9868 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9869 (use (match_operand 2 "" ""))
9870 (clobber (reg:CC FLAGS_REG))]
9872 [(parallel [(set (match_dup 0) (match_dup 1))
9873 (clobber (reg:CC FLAGS_REG))])]
9878 tmp = gen_lowpart (DImode, operands[0]);
9879 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9882 if (GET_CODE (operands[1]) == ABS)
9885 tmp = gen_rtx_NOT (DImode, tmp);
9889 operands[0] = gen_highpart (SImode, operands[0]);
9890 if (GET_CODE (operands[1]) == ABS)
9892 tmp = gen_int_mode (0x7fffffff, SImode);
9893 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9897 tmp = gen_int_mode (0x80000000, SImode);
9898 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9905 [(set (match_operand:XF 0 "register_operand" "")
9906 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9907 (use (match_operand 2 "" ""))
9908 (clobber (reg:CC FLAGS_REG))]
9910 [(parallel [(set (match_dup 0) (match_dup 1))
9911 (clobber (reg:CC FLAGS_REG))])]
9914 operands[0] = gen_rtx_REG (SImode,
9915 true_regnum (operands[0])
9916 + (TARGET_64BIT ? 1 : 2));
9917 if (GET_CODE (operands[1]) == ABS)
9919 tmp = GEN_INT (0x7fff);
9920 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9924 tmp = GEN_INT (0x8000);
9925 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9931 [(set (match_operand 0 "memory_operand" "")
9932 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9933 (use (match_operand 2 "" ""))
9934 (clobber (reg:CC FLAGS_REG))]
9936 [(parallel [(set (match_dup 0) (match_dup 1))
9937 (clobber (reg:CC FLAGS_REG))])]
9939 enum machine_mode mode = GET_MODE (operands[0]);
9940 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9943 operands[0] = adjust_address (operands[0], QImode, size - 1);
9944 if (GET_CODE (operands[1]) == ABS)
9946 tmp = gen_int_mode (0x7f, QImode);
9947 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9951 tmp = gen_int_mode (0x80, QImode);
9952 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9957 ;; Conditionalize these after reload. If they match before reload, we
9958 ;; lose the clobber and ability to use integer instructions.
9960 (define_insn "*negsf2_1"
9961 [(set (match_operand:SF 0 "register_operand" "=f")
9962 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9963 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9965 [(set_attr "type" "fsgn")
9966 (set_attr "mode" "SF")])
9968 (define_insn "*negdf2_1"
9969 [(set (match_operand:DF 0 "register_operand" "=f")
9970 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9971 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9973 [(set_attr "type" "fsgn")
9974 (set_attr "mode" "DF")])
9976 (define_insn "*negxf2_1"
9977 [(set (match_operand:XF 0 "register_operand" "=f")
9978 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9981 [(set_attr "type" "fsgn")
9982 (set_attr "mode" "XF")])
9984 (define_insn "*abssf2_1"
9985 [(set (match_operand:SF 0 "register_operand" "=f")
9986 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9987 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9989 [(set_attr "type" "fsgn")
9990 (set_attr "mode" "SF")])
9992 (define_insn "*absdf2_1"
9993 [(set (match_operand:DF 0 "register_operand" "=f")
9994 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9995 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9997 [(set_attr "type" "fsgn")
9998 (set_attr "mode" "DF")])
10000 (define_insn "*absxf2_1"
10001 [(set (match_operand:XF 0 "register_operand" "=f")
10002 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10005 [(set_attr "type" "fsgn")
10006 (set_attr "mode" "DF")])
10008 (define_insn "*negextendsfdf2"
10009 [(set (match_operand:DF 0 "register_operand" "=f")
10010 (neg:DF (float_extend:DF
10011 (match_operand:SF 1 "register_operand" "0"))))]
10012 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10014 [(set_attr "type" "fsgn")
10015 (set_attr "mode" "DF")])
10017 (define_insn "*negextenddfxf2"
10018 [(set (match_operand:XF 0 "register_operand" "=f")
10019 (neg:XF (float_extend:XF
10020 (match_operand:DF 1 "register_operand" "0"))))]
10023 [(set_attr "type" "fsgn")
10024 (set_attr "mode" "XF")])
10026 (define_insn "*negextendsfxf2"
10027 [(set (match_operand:XF 0 "register_operand" "=f")
10028 (neg:XF (float_extend:XF
10029 (match_operand:SF 1 "register_operand" "0"))))]
10032 [(set_attr "type" "fsgn")
10033 (set_attr "mode" "XF")])
10035 (define_insn "*absextendsfdf2"
10036 [(set (match_operand:DF 0 "register_operand" "=f")
10037 (abs:DF (float_extend:DF
10038 (match_operand:SF 1 "register_operand" "0"))))]
10039 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10041 [(set_attr "type" "fsgn")
10042 (set_attr "mode" "DF")])
10044 (define_insn "*absextenddfxf2"
10045 [(set (match_operand:XF 0 "register_operand" "=f")
10046 (abs:XF (float_extend:XF
10047 (match_operand:DF 1 "register_operand" "0"))))]
10050 [(set_attr "type" "fsgn")
10051 (set_attr "mode" "XF")])
10053 (define_insn "*absextendsfxf2"
10054 [(set (match_operand:XF 0 "register_operand" "=f")
10055 (abs:XF (float_extend:XF
10056 (match_operand:SF 1 "register_operand" "0"))))]
10059 [(set_attr "type" "fsgn")
10060 (set_attr "mode" "XF")])
10062 ;; One complement instructions
10064 (define_expand "one_cmpldi2"
10065 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10066 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10068 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10070 (define_insn "*one_cmpldi2_1_rex64"
10071 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10072 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10073 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10075 [(set_attr "type" "negnot")
10076 (set_attr "mode" "DI")])
10078 (define_insn "*one_cmpldi2_2_rex64"
10079 [(set (reg FLAGS_REG)
10080 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10082 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10083 (not:DI (match_dup 1)))]
10084 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10085 && ix86_unary_operator_ok (NOT, DImode, operands)"
10087 [(set_attr "type" "alu1")
10088 (set_attr "mode" "DI")])
10091 [(set (match_operand 0 "flags_reg_operand" "")
10092 (match_operator 2 "compare_operator"
10093 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10095 (set (match_operand:DI 1 "nonimmediate_operand" "")
10096 (not:DI (match_dup 3)))]
10097 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10098 [(parallel [(set (match_dup 0)
10100 [(xor:DI (match_dup 3) (const_int -1))
10103 (xor:DI (match_dup 3) (const_int -1)))])]
10106 (define_expand "one_cmplsi2"
10107 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10108 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10110 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10112 (define_insn "*one_cmplsi2_1"
10113 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10114 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10115 "ix86_unary_operator_ok (NOT, SImode, operands)"
10117 [(set_attr "type" "negnot")
10118 (set_attr "mode" "SI")])
10120 ;; ??? Currently never generated - xor is used instead.
10121 (define_insn "*one_cmplsi2_1_zext"
10122 [(set (match_operand:DI 0 "register_operand" "=r")
10123 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10124 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10126 [(set_attr "type" "negnot")
10127 (set_attr "mode" "SI")])
10129 (define_insn "*one_cmplsi2_2"
10130 [(set (reg FLAGS_REG)
10131 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10133 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10134 (not:SI (match_dup 1)))]
10135 "ix86_match_ccmode (insn, CCNOmode)
10136 && ix86_unary_operator_ok (NOT, SImode, operands)"
10138 [(set_attr "type" "alu1")
10139 (set_attr "mode" "SI")])
10142 [(set (match_operand 0 "flags_reg_operand" "")
10143 (match_operator 2 "compare_operator"
10144 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10146 (set (match_operand:SI 1 "nonimmediate_operand" "")
10147 (not:SI (match_dup 3)))]
10148 "ix86_match_ccmode (insn, CCNOmode)"
10149 [(parallel [(set (match_dup 0)
10150 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10153 (xor:SI (match_dup 3) (const_int -1)))])]
10156 ;; ??? Currently never generated - xor is used instead.
10157 (define_insn "*one_cmplsi2_2_zext"
10158 [(set (reg FLAGS_REG)
10159 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10161 (set (match_operand:DI 0 "register_operand" "=r")
10162 (zero_extend:DI (not:SI (match_dup 1))))]
10163 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10164 && ix86_unary_operator_ok (NOT, SImode, operands)"
10166 [(set_attr "type" "alu1")
10167 (set_attr "mode" "SI")])
10170 [(set (match_operand 0 "flags_reg_operand" "")
10171 (match_operator 2 "compare_operator"
10172 [(not:SI (match_operand:SI 3 "register_operand" ""))
10174 (set (match_operand:DI 1 "register_operand" "")
10175 (zero_extend:DI (not:SI (match_dup 3))))]
10176 "ix86_match_ccmode (insn, CCNOmode)"
10177 [(parallel [(set (match_dup 0)
10178 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10181 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10184 (define_expand "one_cmplhi2"
10185 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10186 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10187 "TARGET_HIMODE_MATH"
10188 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10190 (define_insn "*one_cmplhi2_1"
10191 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10192 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10193 "ix86_unary_operator_ok (NOT, HImode, operands)"
10195 [(set_attr "type" "negnot")
10196 (set_attr "mode" "HI")])
10198 (define_insn "*one_cmplhi2_2"
10199 [(set (reg FLAGS_REG)
10200 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10202 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10203 (not:HI (match_dup 1)))]
10204 "ix86_match_ccmode (insn, CCNOmode)
10205 && ix86_unary_operator_ok (NEG, HImode, operands)"
10207 [(set_attr "type" "alu1")
10208 (set_attr "mode" "HI")])
10211 [(set (match_operand 0 "flags_reg_operand" "")
10212 (match_operator 2 "compare_operator"
10213 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10215 (set (match_operand:HI 1 "nonimmediate_operand" "")
10216 (not:HI (match_dup 3)))]
10217 "ix86_match_ccmode (insn, CCNOmode)"
10218 [(parallel [(set (match_dup 0)
10219 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10222 (xor:HI (match_dup 3) (const_int -1)))])]
10225 ;; %%% Potential partial reg stall on alternative 1. What to do?
10226 (define_expand "one_cmplqi2"
10227 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10228 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10229 "TARGET_QIMODE_MATH"
10230 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10232 (define_insn "*one_cmplqi2_1"
10233 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10234 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10235 "ix86_unary_operator_ok (NOT, QImode, operands)"
10239 [(set_attr "type" "negnot")
10240 (set_attr "mode" "QI,SI")])
10242 (define_insn "*one_cmplqi2_2"
10243 [(set (reg FLAGS_REG)
10244 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10246 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10247 (not:QI (match_dup 1)))]
10248 "ix86_match_ccmode (insn, CCNOmode)
10249 && ix86_unary_operator_ok (NOT, QImode, operands)"
10251 [(set_attr "type" "alu1")
10252 (set_attr "mode" "QI")])
10255 [(set (match_operand 0 "flags_reg_operand" "")
10256 (match_operator 2 "compare_operator"
10257 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10259 (set (match_operand:QI 1 "nonimmediate_operand" "")
10260 (not:QI (match_dup 3)))]
10261 "ix86_match_ccmode (insn, CCNOmode)"
10262 [(parallel [(set (match_dup 0)
10263 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10266 (xor:QI (match_dup 3) (const_int -1)))])]
10269 ;; Arithmetic shift instructions
10271 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10272 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10273 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10274 ;; from the assembler input.
10276 ;; This instruction shifts the target reg/mem as usual, but instead of
10277 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10278 ;; is a left shift double, bits are taken from the high order bits of
10279 ;; reg, else if the insn is a shift right double, bits are taken from the
10280 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10281 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10283 ;; Since sh[lr]d does not change the `reg' operand, that is done
10284 ;; separately, making all shifts emit pairs of shift double and normal
10285 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10286 ;; support a 63 bit shift, each shift where the count is in a reg expands
10287 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10289 ;; If the shift count is a constant, we need never emit more than one
10290 ;; shift pair, instead using moves and sign extension for counts greater
10293 (define_expand "ashlti3"
10294 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10295 (ashift:TI (match_operand:TI 1 "register_operand" "")
10296 (match_operand:QI 2 "nonmemory_operand" "")))
10297 (clobber (reg:CC FLAGS_REG))])]
10300 if (! immediate_operand (operands[2], QImode))
10302 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10305 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10309 (define_insn "ashlti3_1"
10310 [(set (match_operand:TI 0 "register_operand" "=r")
10311 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10312 (match_operand:QI 2 "register_operand" "c")))
10313 (clobber (match_scratch:DI 3 "=&r"))
10314 (clobber (reg:CC FLAGS_REG))]
10317 [(set_attr "type" "multi")])
10319 (define_insn "*ashlti3_2"
10320 [(set (match_operand:TI 0 "register_operand" "=r")
10321 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10322 (match_operand:QI 2 "immediate_operand" "O")))
10323 (clobber (reg:CC FLAGS_REG))]
10326 [(set_attr "type" "multi")])
10329 [(set (match_operand:TI 0 "register_operand" "")
10330 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10331 (match_operand:QI 2 "register_operand" "")))
10332 (clobber (match_scratch:DI 3 ""))
10333 (clobber (reg:CC FLAGS_REG))]
10334 "TARGET_64BIT && reload_completed"
10336 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10339 [(set (match_operand:TI 0 "register_operand" "")
10340 (ashift:TI (match_operand:TI 1 "register_operand" "")
10341 (match_operand:QI 2 "immediate_operand" "")))
10342 (clobber (reg:CC FLAGS_REG))]
10343 "TARGET_64BIT && reload_completed"
10345 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10347 (define_insn "x86_64_shld"
10348 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10349 (ior:DI (ashift:DI (match_dup 0)
10350 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10351 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10352 (minus:QI (const_int 64) (match_dup 2)))))
10353 (clobber (reg:CC FLAGS_REG))]
10356 shld{q}\t{%2, %1, %0|%0, %1, %2}
10357 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10358 [(set_attr "type" "ishift")
10359 (set_attr "prefix_0f" "1")
10360 (set_attr "mode" "DI")
10361 (set_attr "athlon_decode" "vector")])
10363 (define_expand "x86_64_shift_adj"
10364 [(set (reg:CCZ FLAGS_REG)
10365 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10368 (set (match_operand:DI 0 "register_operand" "")
10369 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10370 (match_operand:DI 1 "register_operand" "")
10373 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10374 (match_operand:DI 3 "register_operand" "r")
10379 (define_expand "ashldi3"
10380 [(set (match_operand:DI 0 "shiftdi_operand" "")
10381 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10382 (match_operand:QI 2 "nonmemory_operand" "")))]
10384 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10386 (define_insn "*ashldi3_1_rex64"
10387 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10388 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10389 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10390 (clobber (reg:CC FLAGS_REG))]
10391 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10393 switch (get_attr_type (insn))
10396 gcc_assert (operands[2] == const1_rtx);
10397 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10398 return "add{q}\t{%0, %0|%0, %0}";
10401 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10402 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10403 operands[1] = gen_rtx_MULT (DImode, operands[1],
10404 GEN_INT (1 << INTVAL (operands[2])));
10405 return "lea{q}\t{%a1, %0|%0, %a1}";
10408 if (REG_P (operands[2]))
10409 return "sal{q}\t{%b2, %0|%0, %b2}";
10410 else if (operands[2] == const1_rtx
10411 && (TARGET_SHIFT1 || optimize_size))
10412 return "sal{q}\t%0";
10414 return "sal{q}\t{%2, %0|%0, %2}";
10417 [(set (attr "type")
10418 (cond [(eq_attr "alternative" "1")
10419 (const_string "lea")
10420 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10422 (match_operand 0 "register_operand" ""))
10423 (match_operand 2 "const1_operand" ""))
10424 (const_string "alu")
10426 (const_string "ishift")))
10427 (set_attr "mode" "DI")])
10429 ;; Convert lea to the lea pattern to avoid flags dependency.
10431 [(set (match_operand:DI 0 "register_operand" "")
10432 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10433 (match_operand:QI 2 "immediate_operand" "")))
10434 (clobber (reg:CC FLAGS_REG))]
10435 "TARGET_64BIT && reload_completed
10436 && true_regnum (operands[0]) != true_regnum (operands[1])"
10437 [(set (match_dup 0)
10438 (mult:DI (match_dup 1)
10440 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10442 ;; This pattern can't accept a variable shift count, since shifts by
10443 ;; zero don't affect the flags. We assume that shifts by constant
10444 ;; zero are optimized away.
10445 (define_insn "*ashldi3_cmp_rex64"
10446 [(set (reg FLAGS_REG)
10448 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10449 (match_operand:QI 2 "immediate_operand" "e"))
10451 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10452 (ashift:DI (match_dup 1) (match_dup 2)))]
10453 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10454 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10456 || !TARGET_PARTIAL_FLAG_REG_STALL
10457 || (operands[2] == const1_rtx
10459 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10461 switch (get_attr_type (insn))
10464 gcc_assert (operands[2] == const1_rtx);
10465 return "add{q}\t{%0, %0|%0, %0}";
10468 if (REG_P (operands[2]))
10469 return "sal{q}\t{%b2, %0|%0, %b2}";
10470 else if (operands[2] == const1_rtx
10471 && (TARGET_SHIFT1 || optimize_size))
10472 return "sal{q}\t%0";
10474 return "sal{q}\t{%2, %0|%0, %2}";
10477 [(set (attr "type")
10478 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10480 (match_operand 0 "register_operand" ""))
10481 (match_operand 2 "const1_operand" ""))
10482 (const_string "alu")
10484 (const_string "ishift")))
10485 (set_attr "mode" "DI")])
10487 (define_insn "*ashldi3_cconly_rex64"
10488 [(set (reg FLAGS_REG)
10490 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10491 (match_operand:QI 2 "immediate_operand" "e"))
10493 (clobber (match_scratch:DI 0 "=r"))]
10494 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10495 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10497 || !TARGET_PARTIAL_FLAG_REG_STALL
10498 || (operands[2] == const1_rtx
10500 || TARGET_DOUBLE_WITH_ADD)))"
10502 switch (get_attr_type (insn))
10505 gcc_assert (operands[2] == const1_rtx);
10506 return "add{q}\t{%0, %0|%0, %0}";
10509 if (REG_P (operands[2]))
10510 return "sal{q}\t{%b2, %0|%0, %b2}";
10511 else if (operands[2] == const1_rtx
10512 && (TARGET_SHIFT1 || optimize_size))
10513 return "sal{q}\t%0";
10515 return "sal{q}\t{%2, %0|%0, %2}";
10518 [(set (attr "type")
10519 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10521 (match_operand 0 "register_operand" ""))
10522 (match_operand 2 "const1_operand" ""))
10523 (const_string "alu")
10525 (const_string "ishift")))
10526 (set_attr "mode" "DI")])
10528 (define_insn "*ashldi3_1"
10529 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10530 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10531 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10532 (clobber (reg:CC FLAGS_REG))]
10535 [(set_attr "type" "multi")])
10537 ;; By default we don't ask for a scratch register, because when DImode
10538 ;; values are manipulated, registers are already at a premium. But if
10539 ;; we have one handy, we won't turn it away.
10541 [(match_scratch:SI 3 "r")
10542 (parallel [(set (match_operand:DI 0 "register_operand" "")
10543 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10544 (match_operand:QI 2 "nonmemory_operand" "")))
10545 (clobber (reg:CC FLAGS_REG))])
10547 "!TARGET_64BIT && TARGET_CMOVE"
10549 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10552 [(set (match_operand:DI 0 "register_operand" "")
10553 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10554 (match_operand:QI 2 "nonmemory_operand" "")))
10555 (clobber (reg:CC FLAGS_REG))]
10556 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10557 ? flow2_completed : reload_completed)"
10559 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10561 (define_insn "x86_shld_1"
10562 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10563 (ior:SI (ashift:SI (match_dup 0)
10564 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10565 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10566 (minus:QI (const_int 32) (match_dup 2)))))
10567 (clobber (reg:CC FLAGS_REG))]
10570 shld{l}\t{%2, %1, %0|%0, %1, %2}
10571 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10572 [(set_attr "type" "ishift")
10573 (set_attr "prefix_0f" "1")
10574 (set_attr "mode" "SI")
10575 (set_attr "pent_pair" "np")
10576 (set_attr "athlon_decode" "vector")])
10578 (define_expand "x86_shift_adj_1"
10579 [(set (reg:CCZ FLAGS_REG)
10580 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10583 (set (match_operand:SI 0 "register_operand" "")
10584 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10585 (match_operand:SI 1 "register_operand" "")
10588 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10589 (match_operand:SI 3 "register_operand" "r")
10594 (define_expand "x86_shift_adj_2"
10595 [(use (match_operand:SI 0 "register_operand" ""))
10596 (use (match_operand:SI 1 "register_operand" ""))
10597 (use (match_operand:QI 2 "register_operand" ""))]
10600 rtx label = gen_label_rtx ();
10603 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10605 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10606 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10607 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10608 gen_rtx_LABEL_REF (VOIDmode, label),
10610 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10611 JUMP_LABEL (tmp) = label;
10613 emit_move_insn (operands[0], operands[1]);
10614 ix86_expand_clear (operands[1]);
10616 emit_label (label);
10617 LABEL_NUSES (label) = 1;
10622 (define_expand "ashlsi3"
10623 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10624 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10625 (match_operand:QI 2 "nonmemory_operand" "")))
10626 (clobber (reg:CC FLAGS_REG))]
10628 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10630 (define_insn "*ashlsi3_1"
10631 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10632 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10633 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10634 (clobber (reg:CC FLAGS_REG))]
10635 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10637 switch (get_attr_type (insn))
10640 gcc_assert (operands[2] == const1_rtx);
10641 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10642 return "add{l}\t{%0, %0|%0, %0}";
10648 if (REG_P (operands[2]))
10649 return "sal{l}\t{%b2, %0|%0, %b2}";
10650 else if (operands[2] == const1_rtx
10651 && (TARGET_SHIFT1 || optimize_size))
10652 return "sal{l}\t%0";
10654 return "sal{l}\t{%2, %0|%0, %2}";
10657 [(set (attr "type")
10658 (cond [(eq_attr "alternative" "1")
10659 (const_string "lea")
10660 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10662 (match_operand 0 "register_operand" ""))
10663 (match_operand 2 "const1_operand" ""))
10664 (const_string "alu")
10666 (const_string "ishift")))
10667 (set_attr "mode" "SI")])
10669 ;; Convert lea to the lea pattern to avoid flags dependency.
10671 [(set (match_operand 0 "register_operand" "")
10672 (ashift (match_operand 1 "index_register_operand" "")
10673 (match_operand:QI 2 "const_int_operand" "")))
10674 (clobber (reg:CC FLAGS_REG))]
10676 && true_regnum (operands[0]) != true_regnum (operands[1])
10677 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10681 enum machine_mode mode = GET_MODE (operands[0]);
10683 if (GET_MODE_SIZE (mode) < 4)
10684 operands[0] = gen_lowpart (SImode, operands[0]);
10686 operands[1] = gen_lowpart (Pmode, operands[1]);
10687 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10689 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10690 if (Pmode != SImode)
10691 pat = gen_rtx_SUBREG (SImode, pat, 0);
10692 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10696 ;; Rare case of shifting RSP is handled by generating move and shift
10698 [(set (match_operand 0 "register_operand" "")
10699 (ashift (match_operand 1 "register_operand" "")
10700 (match_operand:QI 2 "const_int_operand" "")))
10701 (clobber (reg:CC FLAGS_REG))]
10703 && true_regnum (operands[0]) != true_regnum (operands[1])"
10707 emit_move_insn (operands[0], operands[1]);
10708 pat = gen_rtx_SET (VOIDmode, operands[0],
10709 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10710 operands[0], operands[2]));
10711 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10712 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10716 (define_insn "*ashlsi3_1_zext"
10717 [(set (match_operand:DI 0 "register_operand" "=r,r")
10718 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10719 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10720 (clobber (reg:CC FLAGS_REG))]
10721 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10723 switch (get_attr_type (insn))
10726 gcc_assert (operands[2] == const1_rtx);
10727 return "add{l}\t{%k0, %k0|%k0, %k0}";
10733 if (REG_P (operands[2]))
10734 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10735 else if (operands[2] == const1_rtx
10736 && (TARGET_SHIFT1 || optimize_size))
10737 return "sal{l}\t%k0";
10739 return "sal{l}\t{%2, %k0|%k0, %2}";
10742 [(set (attr "type")
10743 (cond [(eq_attr "alternative" "1")
10744 (const_string "lea")
10745 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10747 (match_operand 2 "const1_operand" ""))
10748 (const_string "alu")
10750 (const_string "ishift")))
10751 (set_attr "mode" "SI")])
10753 ;; Convert lea to the lea pattern to avoid flags dependency.
10755 [(set (match_operand:DI 0 "register_operand" "")
10756 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10757 (match_operand:QI 2 "const_int_operand" ""))))
10758 (clobber (reg:CC FLAGS_REG))]
10759 "TARGET_64BIT && reload_completed
10760 && true_regnum (operands[0]) != true_regnum (operands[1])"
10761 [(set (match_dup 0) (zero_extend:DI
10762 (subreg:SI (mult:SI (match_dup 1)
10763 (match_dup 2)) 0)))]
10765 operands[1] = gen_lowpart (Pmode, operands[1]);
10766 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10769 ;; This pattern can't accept a variable shift count, since shifts by
10770 ;; zero don't affect the flags. We assume that shifts by constant
10771 ;; zero are optimized away.
10772 (define_insn "*ashlsi3_cmp"
10773 [(set (reg FLAGS_REG)
10775 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10776 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10778 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10779 (ashift:SI (match_dup 1) (match_dup 2)))]
10780 "ix86_match_ccmode (insn, CCGOCmode)
10781 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10783 || !TARGET_PARTIAL_FLAG_REG_STALL
10784 || (operands[2] == const1_rtx
10786 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10788 switch (get_attr_type (insn))
10791 gcc_assert (operands[2] == const1_rtx);
10792 return "add{l}\t{%0, %0|%0, %0}";
10795 if (REG_P (operands[2]))
10796 return "sal{l}\t{%b2, %0|%0, %b2}";
10797 else if (operands[2] == const1_rtx
10798 && (TARGET_SHIFT1 || optimize_size))
10799 return "sal{l}\t%0";
10801 return "sal{l}\t{%2, %0|%0, %2}";
10804 [(set (attr "type")
10805 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10807 (match_operand 0 "register_operand" ""))
10808 (match_operand 2 "const1_operand" ""))
10809 (const_string "alu")
10811 (const_string "ishift")))
10812 (set_attr "mode" "SI")])
10814 (define_insn "*ashlsi3_cconly"
10815 [(set (reg FLAGS_REG)
10817 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10818 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10820 (clobber (match_scratch:SI 0 "=r"))]
10821 "ix86_match_ccmode (insn, CCGOCmode)
10822 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10824 || !TARGET_PARTIAL_FLAG_REG_STALL
10825 || (operands[2] == const1_rtx
10827 || TARGET_DOUBLE_WITH_ADD)))"
10829 switch (get_attr_type (insn))
10832 gcc_assert (operands[2] == const1_rtx);
10833 return "add{l}\t{%0, %0|%0, %0}";
10836 if (REG_P (operands[2]))
10837 return "sal{l}\t{%b2, %0|%0, %b2}";
10838 else if (operands[2] == const1_rtx
10839 && (TARGET_SHIFT1 || optimize_size))
10840 return "sal{l}\t%0";
10842 return "sal{l}\t{%2, %0|%0, %2}";
10845 [(set (attr "type")
10846 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10848 (match_operand 0 "register_operand" ""))
10849 (match_operand 2 "const1_operand" ""))
10850 (const_string "alu")
10852 (const_string "ishift")))
10853 (set_attr "mode" "SI")])
10855 (define_insn "*ashlsi3_cmp_zext"
10856 [(set (reg FLAGS_REG)
10858 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10859 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10861 (set (match_operand:DI 0 "register_operand" "=r")
10862 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10863 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10864 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10866 || !TARGET_PARTIAL_FLAG_REG_STALL
10867 || (operands[2] == const1_rtx
10869 || TARGET_DOUBLE_WITH_ADD)))"
10871 switch (get_attr_type (insn))
10874 gcc_assert (operands[2] == const1_rtx);
10875 return "add{l}\t{%k0, %k0|%k0, %k0}";
10878 if (REG_P (operands[2]))
10879 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10880 else if (operands[2] == const1_rtx
10881 && (TARGET_SHIFT1 || optimize_size))
10882 return "sal{l}\t%k0";
10884 return "sal{l}\t{%2, %k0|%k0, %2}";
10887 [(set (attr "type")
10888 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10890 (match_operand 2 "const1_operand" ""))
10891 (const_string "alu")
10893 (const_string "ishift")))
10894 (set_attr "mode" "SI")])
10896 (define_expand "ashlhi3"
10897 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10898 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10899 (match_operand:QI 2 "nonmemory_operand" "")))
10900 (clobber (reg:CC FLAGS_REG))]
10901 "TARGET_HIMODE_MATH"
10902 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10904 (define_insn "*ashlhi3_1_lea"
10905 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10906 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10907 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10908 (clobber (reg:CC FLAGS_REG))]
10909 "!TARGET_PARTIAL_REG_STALL
10910 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10912 switch (get_attr_type (insn))
10917 gcc_assert (operands[2] == const1_rtx);
10918 return "add{w}\t{%0, %0|%0, %0}";
10921 if (REG_P (operands[2]))
10922 return "sal{w}\t{%b2, %0|%0, %b2}";
10923 else if (operands[2] == const1_rtx
10924 && (TARGET_SHIFT1 || optimize_size))
10925 return "sal{w}\t%0";
10927 return "sal{w}\t{%2, %0|%0, %2}";
10930 [(set (attr "type")
10931 (cond [(eq_attr "alternative" "1")
10932 (const_string "lea")
10933 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10935 (match_operand 0 "register_operand" ""))
10936 (match_operand 2 "const1_operand" ""))
10937 (const_string "alu")
10939 (const_string "ishift")))
10940 (set_attr "mode" "HI,SI")])
10942 (define_insn "*ashlhi3_1"
10943 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10944 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10945 (match_operand:QI 2 "nonmemory_operand" "cI")))
10946 (clobber (reg:CC FLAGS_REG))]
10947 "TARGET_PARTIAL_REG_STALL
10948 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10950 switch (get_attr_type (insn))
10953 gcc_assert (operands[2] == const1_rtx);
10954 return "add{w}\t{%0, %0|%0, %0}";
10957 if (REG_P (operands[2]))
10958 return "sal{w}\t{%b2, %0|%0, %b2}";
10959 else if (operands[2] == const1_rtx
10960 && (TARGET_SHIFT1 || optimize_size))
10961 return "sal{w}\t%0";
10963 return "sal{w}\t{%2, %0|%0, %2}";
10966 [(set (attr "type")
10967 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10969 (match_operand 0 "register_operand" ""))
10970 (match_operand 2 "const1_operand" ""))
10971 (const_string "alu")
10973 (const_string "ishift")))
10974 (set_attr "mode" "HI")])
10976 ;; This pattern can't accept a variable shift count, since shifts by
10977 ;; zero don't affect the flags. We assume that shifts by constant
10978 ;; zero are optimized away.
10979 (define_insn "*ashlhi3_cmp"
10980 [(set (reg FLAGS_REG)
10982 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10983 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10985 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10986 (ashift:HI (match_dup 1) (match_dup 2)))]
10987 "ix86_match_ccmode (insn, CCGOCmode)
10988 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10990 || !TARGET_PARTIAL_FLAG_REG_STALL
10991 || (operands[2] == const1_rtx
10993 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10995 switch (get_attr_type (insn))
10998 gcc_assert (operands[2] == const1_rtx);
10999 return "add{w}\t{%0, %0|%0, %0}";
11002 if (REG_P (operands[2]))
11003 return "sal{w}\t{%b2, %0|%0, %b2}";
11004 else if (operands[2] == const1_rtx
11005 && (TARGET_SHIFT1 || optimize_size))
11006 return "sal{w}\t%0";
11008 return "sal{w}\t{%2, %0|%0, %2}";
11011 [(set (attr "type")
11012 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11014 (match_operand 0 "register_operand" ""))
11015 (match_operand 2 "const1_operand" ""))
11016 (const_string "alu")
11018 (const_string "ishift")))
11019 (set_attr "mode" "HI")])
11021 (define_insn "*ashlhi3_cconly"
11022 [(set (reg FLAGS_REG)
11024 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11025 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11027 (clobber (match_scratch:HI 0 "=r"))]
11028 "ix86_match_ccmode (insn, CCGOCmode)
11029 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11031 || !TARGET_PARTIAL_FLAG_REG_STALL
11032 || (operands[2] == const1_rtx
11034 || TARGET_DOUBLE_WITH_ADD)))"
11036 switch (get_attr_type (insn))
11039 gcc_assert (operands[2] == const1_rtx);
11040 return "add{w}\t{%0, %0|%0, %0}";
11043 if (REG_P (operands[2]))
11044 return "sal{w}\t{%b2, %0|%0, %b2}";
11045 else if (operands[2] == const1_rtx
11046 && (TARGET_SHIFT1 || optimize_size))
11047 return "sal{w}\t%0";
11049 return "sal{w}\t{%2, %0|%0, %2}";
11052 [(set (attr "type")
11053 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11055 (match_operand 0 "register_operand" ""))
11056 (match_operand 2 "const1_operand" ""))
11057 (const_string "alu")
11059 (const_string "ishift")))
11060 (set_attr "mode" "HI")])
11062 (define_expand "ashlqi3"
11063 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11064 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11065 (match_operand:QI 2 "nonmemory_operand" "")))
11066 (clobber (reg:CC FLAGS_REG))]
11067 "TARGET_QIMODE_MATH"
11068 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11070 ;; %%% Potential partial reg stall on alternative 2. What to do?
11072 (define_insn "*ashlqi3_1_lea"
11073 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11074 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11075 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11076 (clobber (reg:CC FLAGS_REG))]
11077 "!TARGET_PARTIAL_REG_STALL
11078 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11080 switch (get_attr_type (insn))
11085 gcc_assert (operands[2] == const1_rtx);
11086 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11087 return "add{l}\t{%k0, %k0|%k0, %k0}";
11089 return "add{b}\t{%0, %0|%0, %0}";
11092 if (REG_P (operands[2]))
11094 if (get_attr_mode (insn) == MODE_SI)
11095 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11097 return "sal{b}\t{%b2, %0|%0, %b2}";
11099 else if (operands[2] == const1_rtx
11100 && (TARGET_SHIFT1 || optimize_size))
11102 if (get_attr_mode (insn) == MODE_SI)
11103 return "sal{l}\t%0";
11105 return "sal{b}\t%0";
11109 if (get_attr_mode (insn) == MODE_SI)
11110 return "sal{l}\t{%2, %k0|%k0, %2}";
11112 return "sal{b}\t{%2, %0|%0, %2}";
11116 [(set (attr "type")
11117 (cond [(eq_attr "alternative" "2")
11118 (const_string "lea")
11119 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11121 (match_operand 0 "register_operand" ""))
11122 (match_operand 2 "const1_operand" ""))
11123 (const_string "alu")
11125 (const_string "ishift")))
11126 (set_attr "mode" "QI,SI,SI")])
11128 (define_insn "*ashlqi3_1"
11129 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11130 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11131 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11132 (clobber (reg:CC FLAGS_REG))]
11133 "TARGET_PARTIAL_REG_STALL
11134 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11136 switch (get_attr_type (insn))
11139 gcc_assert (operands[2] == const1_rtx);
11140 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11141 return "add{l}\t{%k0, %k0|%k0, %k0}";
11143 return "add{b}\t{%0, %0|%0, %0}";
11146 if (REG_P (operands[2]))
11148 if (get_attr_mode (insn) == MODE_SI)
11149 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11151 return "sal{b}\t{%b2, %0|%0, %b2}";
11153 else if (operands[2] == const1_rtx
11154 && (TARGET_SHIFT1 || optimize_size))
11156 if (get_attr_mode (insn) == MODE_SI)
11157 return "sal{l}\t%0";
11159 return "sal{b}\t%0";
11163 if (get_attr_mode (insn) == MODE_SI)
11164 return "sal{l}\t{%2, %k0|%k0, %2}";
11166 return "sal{b}\t{%2, %0|%0, %2}";
11170 [(set (attr "type")
11171 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11173 (match_operand 0 "register_operand" ""))
11174 (match_operand 2 "const1_operand" ""))
11175 (const_string "alu")
11177 (const_string "ishift")))
11178 (set_attr "mode" "QI,SI")])
11180 ;; This pattern can't accept a variable shift count, since shifts by
11181 ;; zero don't affect the flags. We assume that shifts by constant
11182 ;; zero are optimized away.
11183 (define_insn "*ashlqi3_cmp"
11184 [(set (reg FLAGS_REG)
11186 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11187 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11189 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11190 (ashift:QI (match_dup 1) (match_dup 2)))]
11191 "ix86_match_ccmode (insn, CCGOCmode)
11192 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11194 || !TARGET_PARTIAL_FLAG_REG_STALL
11195 || (operands[2] == const1_rtx
11197 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11199 switch (get_attr_type (insn))
11202 gcc_assert (operands[2] == const1_rtx);
11203 return "add{b}\t{%0, %0|%0, %0}";
11206 if (REG_P (operands[2]))
11207 return "sal{b}\t{%b2, %0|%0, %b2}";
11208 else if (operands[2] == const1_rtx
11209 && (TARGET_SHIFT1 || optimize_size))
11210 return "sal{b}\t%0";
11212 return "sal{b}\t{%2, %0|%0, %2}";
11215 [(set (attr "type")
11216 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11218 (match_operand 0 "register_operand" ""))
11219 (match_operand 2 "const1_operand" ""))
11220 (const_string "alu")
11222 (const_string "ishift")))
11223 (set_attr "mode" "QI")])
11225 (define_insn "*ashlqi3_cconly"
11226 [(set (reg FLAGS_REG)
11228 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11229 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11231 (clobber (match_scratch:QI 0 "=q"))]
11232 "ix86_match_ccmode (insn, CCGOCmode)
11233 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11235 || !TARGET_PARTIAL_FLAG_REG_STALL
11236 || (operands[2] == const1_rtx
11238 || TARGET_DOUBLE_WITH_ADD)))"
11240 switch (get_attr_type (insn))
11243 gcc_assert (operands[2] == const1_rtx);
11244 return "add{b}\t{%0, %0|%0, %0}";
11247 if (REG_P (operands[2]))
11248 return "sal{b}\t{%b2, %0|%0, %b2}";
11249 else if (operands[2] == const1_rtx
11250 && (TARGET_SHIFT1 || optimize_size))
11251 return "sal{b}\t%0";
11253 return "sal{b}\t{%2, %0|%0, %2}";
11256 [(set (attr "type")
11257 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11259 (match_operand 0 "register_operand" ""))
11260 (match_operand 2 "const1_operand" ""))
11261 (const_string "alu")
11263 (const_string "ishift")))
11264 (set_attr "mode" "QI")])
11266 ;; See comment above `ashldi3' about how this works.
11268 (define_expand "ashrti3"
11269 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11270 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11271 (match_operand:QI 2 "nonmemory_operand" "")))
11272 (clobber (reg:CC FLAGS_REG))])]
11275 if (! immediate_operand (operands[2], QImode))
11277 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11280 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11284 (define_insn "ashrti3_1"
11285 [(set (match_operand:TI 0 "register_operand" "=r")
11286 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11287 (match_operand:QI 2 "register_operand" "c")))
11288 (clobber (match_scratch:DI 3 "=&r"))
11289 (clobber (reg:CC FLAGS_REG))]
11292 [(set_attr "type" "multi")])
11294 (define_insn "*ashrti3_2"
11295 [(set (match_operand:TI 0 "register_operand" "=r")
11296 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11297 (match_operand:QI 2 "immediate_operand" "O")))
11298 (clobber (reg:CC FLAGS_REG))]
11301 [(set_attr "type" "multi")])
11304 [(set (match_operand:TI 0 "register_operand" "")
11305 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11306 (match_operand:QI 2 "register_operand" "")))
11307 (clobber (match_scratch:DI 3 ""))
11308 (clobber (reg:CC FLAGS_REG))]
11309 "TARGET_64BIT && reload_completed"
11311 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11314 [(set (match_operand:TI 0 "register_operand" "")
11315 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11316 (match_operand:QI 2 "immediate_operand" "")))
11317 (clobber (reg:CC FLAGS_REG))]
11318 "TARGET_64BIT && reload_completed"
11320 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11322 (define_insn "x86_64_shrd"
11323 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11324 (ior:DI (ashiftrt:DI (match_dup 0)
11325 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11326 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11327 (minus:QI (const_int 64) (match_dup 2)))))
11328 (clobber (reg:CC FLAGS_REG))]
11331 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11332 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11333 [(set_attr "type" "ishift")
11334 (set_attr "prefix_0f" "1")
11335 (set_attr "mode" "DI")
11336 (set_attr "athlon_decode" "vector")])
11338 (define_expand "ashrdi3"
11339 [(set (match_operand:DI 0 "shiftdi_operand" "")
11340 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11341 (match_operand:QI 2 "nonmemory_operand" "")))]
11343 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11345 (define_insn "*ashrdi3_63_rex64"
11346 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11347 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11348 (match_operand:DI 2 "const_int_operand" "i,i")))
11349 (clobber (reg:CC FLAGS_REG))]
11350 "TARGET_64BIT && INTVAL (operands[2]) == 63
11351 && (TARGET_USE_CLTD || optimize_size)
11352 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11355 sar{q}\t{%2, %0|%0, %2}"
11356 [(set_attr "type" "imovx,ishift")
11357 (set_attr "prefix_0f" "0,*")
11358 (set_attr "length_immediate" "0,*")
11359 (set_attr "modrm" "0,1")
11360 (set_attr "mode" "DI")])
11362 (define_insn "*ashrdi3_1_one_bit_rex64"
11363 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11364 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11365 (match_operand:QI 2 "const1_operand" "")))
11366 (clobber (reg:CC FLAGS_REG))]
11367 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11368 && (TARGET_SHIFT1 || optimize_size)"
11370 [(set_attr "type" "ishift")
11371 (set (attr "length")
11372 (if_then_else (match_operand:DI 0 "register_operand" "")
11374 (const_string "*")))])
11376 (define_insn "*ashrdi3_1_rex64"
11377 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11378 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11379 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11380 (clobber (reg:CC FLAGS_REG))]
11381 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11383 sar{q}\t{%2, %0|%0, %2}
11384 sar{q}\t{%b2, %0|%0, %b2}"
11385 [(set_attr "type" "ishift")
11386 (set_attr "mode" "DI")])
11388 ;; This pattern can't accept a variable shift count, since shifts by
11389 ;; zero don't affect the flags. We assume that shifts by constant
11390 ;; zero are optimized away.
11391 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11392 [(set (reg FLAGS_REG)
11394 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11395 (match_operand:QI 2 "const1_operand" ""))
11397 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11398 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11399 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11400 && (TARGET_SHIFT1 || optimize_size)
11401 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11403 [(set_attr "type" "ishift")
11404 (set (attr "length")
11405 (if_then_else (match_operand:DI 0 "register_operand" "")
11407 (const_string "*")))])
11409 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11410 [(set (reg FLAGS_REG)
11412 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11413 (match_operand:QI 2 "const1_operand" ""))
11415 (clobber (match_scratch:DI 0 "=r"))]
11416 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11417 && (TARGET_SHIFT1 || optimize_size)
11418 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11420 [(set_attr "type" "ishift")
11421 (set_attr "length" "2")])
11423 ;; This pattern can't accept a variable shift count, since shifts by
11424 ;; zero don't affect the flags. We assume that shifts by constant
11425 ;; zero are optimized away.
11426 (define_insn "*ashrdi3_cmp_rex64"
11427 [(set (reg FLAGS_REG)
11429 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11430 (match_operand:QI 2 "const_int_operand" "n"))
11432 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11433 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11434 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11435 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11437 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11438 "sar{q}\t{%2, %0|%0, %2}"
11439 [(set_attr "type" "ishift")
11440 (set_attr "mode" "DI")])
11442 (define_insn "*ashrdi3_cconly_rex64"
11443 [(set (reg FLAGS_REG)
11445 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11446 (match_operand:QI 2 "const_int_operand" "n"))
11448 (clobber (match_scratch:DI 0 "=r"))]
11449 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11450 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11452 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11453 "sar{q}\t{%2, %0|%0, %2}"
11454 [(set_attr "type" "ishift")
11455 (set_attr "mode" "DI")])
11457 (define_insn "*ashrdi3_1"
11458 [(set (match_operand:DI 0 "register_operand" "=r")
11459 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11460 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11461 (clobber (reg:CC FLAGS_REG))]
11464 [(set_attr "type" "multi")])
11466 ;; By default we don't ask for a scratch register, because when DImode
11467 ;; values are manipulated, registers are already at a premium. But if
11468 ;; we have one handy, we won't turn it away.
11470 [(match_scratch:SI 3 "r")
11471 (parallel [(set (match_operand:DI 0 "register_operand" "")
11472 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11473 (match_operand:QI 2 "nonmemory_operand" "")))
11474 (clobber (reg:CC FLAGS_REG))])
11476 "!TARGET_64BIT && TARGET_CMOVE"
11478 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11481 [(set (match_operand:DI 0 "register_operand" "")
11482 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11483 (match_operand:QI 2 "nonmemory_operand" "")))
11484 (clobber (reg:CC FLAGS_REG))]
11485 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11486 ? flow2_completed : reload_completed)"
11488 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11490 (define_insn "x86_shrd_1"
11491 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11492 (ior:SI (ashiftrt:SI (match_dup 0)
11493 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11494 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11495 (minus:QI (const_int 32) (match_dup 2)))))
11496 (clobber (reg:CC FLAGS_REG))]
11499 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11500 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11501 [(set_attr "type" "ishift")
11502 (set_attr "prefix_0f" "1")
11503 (set_attr "pent_pair" "np")
11504 (set_attr "mode" "SI")])
11506 (define_expand "x86_shift_adj_3"
11507 [(use (match_operand:SI 0 "register_operand" ""))
11508 (use (match_operand:SI 1 "register_operand" ""))
11509 (use (match_operand:QI 2 "register_operand" ""))]
11512 rtx label = gen_label_rtx ();
11515 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11517 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11518 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11519 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11520 gen_rtx_LABEL_REF (VOIDmode, label),
11522 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11523 JUMP_LABEL (tmp) = label;
11525 emit_move_insn (operands[0], operands[1]);
11526 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11528 emit_label (label);
11529 LABEL_NUSES (label) = 1;
11534 (define_insn "ashrsi3_31"
11535 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11536 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11537 (match_operand:SI 2 "const_int_operand" "i,i")))
11538 (clobber (reg:CC FLAGS_REG))]
11539 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11540 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11543 sar{l}\t{%2, %0|%0, %2}"
11544 [(set_attr "type" "imovx,ishift")
11545 (set_attr "prefix_0f" "0,*")
11546 (set_attr "length_immediate" "0,*")
11547 (set_attr "modrm" "0,1")
11548 (set_attr "mode" "SI")])
11550 (define_insn "*ashrsi3_31_zext"
11551 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11552 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11553 (match_operand:SI 2 "const_int_operand" "i,i"))))
11554 (clobber (reg:CC FLAGS_REG))]
11555 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11556 && INTVAL (operands[2]) == 31
11557 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11560 sar{l}\t{%2, %k0|%k0, %2}"
11561 [(set_attr "type" "imovx,ishift")
11562 (set_attr "prefix_0f" "0,*")
11563 (set_attr "length_immediate" "0,*")
11564 (set_attr "modrm" "0,1")
11565 (set_attr "mode" "SI")])
11567 (define_expand "ashrsi3"
11568 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11569 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11570 (match_operand:QI 2 "nonmemory_operand" "")))
11571 (clobber (reg:CC FLAGS_REG))]
11573 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11575 (define_insn "*ashrsi3_1_one_bit"
11576 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11577 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11578 (match_operand:QI 2 "const1_operand" "")))
11579 (clobber (reg:CC FLAGS_REG))]
11580 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11581 && (TARGET_SHIFT1 || optimize_size)"
11583 [(set_attr "type" "ishift")
11584 (set (attr "length")
11585 (if_then_else (match_operand:SI 0 "register_operand" "")
11587 (const_string "*")))])
11589 (define_insn "*ashrsi3_1_one_bit_zext"
11590 [(set (match_operand:DI 0 "register_operand" "=r")
11591 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11592 (match_operand:QI 2 "const1_operand" ""))))
11593 (clobber (reg:CC FLAGS_REG))]
11594 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11595 && (TARGET_SHIFT1 || optimize_size)"
11597 [(set_attr "type" "ishift")
11598 (set_attr "length" "2")])
11600 (define_insn "*ashrsi3_1"
11601 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11602 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11603 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11604 (clobber (reg:CC FLAGS_REG))]
11605 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11607 sar{l}\t{%2, %0|%0, %2}
11608 sar{l}\t{%b2, %0|%0, %b2}"
11609 [(set_attr "type" "ishift")
11610 (set_attr "mode" "SI")])
11612 (define_insn "*ashrsi3_1_zext"
11613 [(set (match_operand:DI 0 "register_operand" "=r,r")
11614 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11615 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11616 (clobber (reg:CC FLAGS_REG))]
11617 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11619 sar{l}\t{%2, %k0|%k0, %2}
11620 sar{l}\t{%b2, %k0|%k0, %b2}"
11621 [(set_attr "type" "ishift")
11622 (set_attr "mode" "SI")])
11624 ;; This pattern can't accept a variable shift count, since shifts by
11625 ;; zero don't affect the flags. We assume that shifts by constant
11626 ;; zero are optimized away.
11627 (define_insn "*ashrsi3_one_bit_cmp"
11628 [(set (reg FLAGS_REG)
11630 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11631 (match_operand:QI 2 "const1_operand" ""))
11633 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11634 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11635 "ix86_match_ccmode (insn, CCGOCmode)
11636 && (TARGET_SHIFT1 || optimize_size)
11637 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11639 [(set_attr "type" "ishift")
11640 (set (attr "length")
11641 (if_then_else (match_operand:SI 0 "register_operand" "")
11643 (const_string "*")))])
11645 (define_insn "*ashrsi3_one_bit_cconly"
11646 [(set (reg FLAGS_REG)
11648 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11649 (match_operand:QI 2 "const1_operand" ""))
11651 (clobber (match_scratch:SI 0 "=r"))]
11652 "ix86_match_ccmode (insn, CCGOCmode)
11653 && (TARGET_SHIFT1 || optimize_size)
11654 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11656 [(set_attr "type" "ishift")
11657 (set_attr "length" "2")])
11659 (define_insn "*ashrsi3_one_bit_cmp_zext"
11660 [(set (reg FLAGS_REG)
11662 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11663 (match_operand:QI 2 "const1_operand" ""))
11665 (set (match_operand:DI 0 "register_operand" "=r")
11666 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11667 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11668 && (TARGET_SHIFT1 || optimize_size)
11669 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11671 [(set_attr "type" "ishift")
11672 (set_attr "length" "2")])
11674 ;; This pattern can't accept a variable shift count, since shifts by
11675 ;; zero don't affect the flags. We assume that shifts by constant
11676 ;; zero are optimized away.
11677 (define_insn "*ashrsi3_cmp"
11678 [(set (reg FLAGS_REG)
11680 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11681 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11683 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11684 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11685 "ix86_match_ccmode (insn, CCGOCmode)
11686 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11688 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11689 "sar{l}\t{%2, %0|%0, %2}"
11690 [(set_attr "type" "ishift")
11691 (set_attr "mode" "SI")])
11693 (define_insn "*ashrsi3_cconly"
11694 [(set (reg FLAGS_REG)
11696 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11697 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11699 (clobber (match_scratch:SI 0 "=r"))]
11700 "ix86_match_ccmode (insn, CCGOCmode)
11701 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11703 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11704 "sar{l}\t{%2, %0|%0, %2}"
11705 [(set_attr "type" "ishift")
11706 (set_attr "mode" "SI")])
11708 (define_insn "*ashrsi3_cmp_zext"
11709 [(set (reg FLAGS_REG)
11711 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11712 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11714 (set (match_operand:DI 0 "register_operand" "=r")
11715 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11716 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11717 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11719 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11720 "sar{l}\t{%2, %k0|%k0, %2}"
11721 [(set_attr "type" "ishift")
11722 (set_attr "mode" "SI")])
11724 (define_expand "ashrhi3"
11725 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11726 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11727 (match_operand:QI 2 "nonmemory_operand" "")))
11728 (clobber (reg:CC FLAGS_REG))]
11729 "TARGET_HIMODE_MATH"
11730 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11732 (define_insn "*ashrhi3_1_one_bit"
11733 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11734 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11735 (match_operand:QI 2 "const1_operand" "")))
11736 (clobber (reg:CC FLAGS_REG))]
11737 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11738 && (TARGET_SHIFT1 || optimize_size)"
11740 [(set_attr "type" "ishift")
11741 (set (attr "length")
11742 (if_then_else (match_operand 0 "register_operand" "")
11744 (const_string "*")))])
11746 (define_insn "*ashrhi3_1"
11747 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11748 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11749 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11750 (clobber (reg:CC FLAGS_REG))]
11751 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11753 sar{w}\t{%2, %0|%0, %2}
11754 sar{w}\t{%b2, %0|%0, %b2}"
11755 [(set_attr "type" "ishift")
11756 (set_attr "mode" "HI")])
11758 ;; This pattern can't accept a variable shift count, since shifts by
11759 ;; zero don't affect the flags. We assume that shifts by constant
11760 ;; zero are optimized away.
11761 (define_insn "*ashrhi3_one_bit_cmp"
11762 [(set (reg FLAGS_REG)
11764 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11765 (match_operand:QI 2 "const1_operand" ""))
11767 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11768 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11769 "ix86_match_ccmode (insn, CCGOCmode)
11770 && (TARGET_SHIFT1 || optimize_size)
11771 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11773 [(set_attr "type" "ishift")
11774 (set (attr "length")
11775 (if_then_else (match_operand 0 "register_operand" "")
11777 (const_string "*")))])
11779 (define_insn "*ashrhi3_one_bit_cconly"
11780 [(set (reg FLAGS_REG)
11782 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11783 (match_operand:QI 2 "const1_operand" ""))
11785 (clobber (match_scratch:HI 0 "=r"))]
11786 "ix86_match_ccmode (insn, CCGOCmode)
11787 && (TARGET_SHIFT1 || optimize_size)
11788 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11790 [(set_attr "type" "ishift")
11791 (set_attr "length" "2")])
11793 ;; This pattern can't accept a variable shift count, since shifts by
11794 ;; zero don't affect the flags. We assume that shifts by constant
11795 ;; zero are optimized away.
11796 (define_insn "*ashrhi3_cmp"
11797 [(set (reg FLAGS_REG)
11799 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11800 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11802 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11803 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11804 "ix86_match_ccmode (insn, CCGOCmode)
11805 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11807 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11808 "sar{w}\t{%2, %0|%0, %2}"
11809 [(set_attr "type" "ishift")
11810 (set_attr "mode" "HI")])
11812 (define_insn "*ashrhi3_cconly"
11813 [(set (reg FLAGS_REG)
11815 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11816 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11818 (clobber (match_scratch:HI 0 "=r"))]
11819 "ix86_match_ccmode (insn, CCGOCmode)
11820 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11822 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11823 "sar{w}\t{%2, %0|%0, %2}"
11824 [(set_attr "type" "ishift")
11825 (set_attr "mode" "HI")])
11827 (define_expand "ashrqi3"
11828 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11829 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11830 (match_operand:QI 2 "nonmemory_operand" "")))
11831 (clobber (reg:CC FLAGS_REG))]
11832 "TARGET_QIMODE_MATH"
11833 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11835 (define_insn "*ashrqi3_1_one_bit"
11836 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11837 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11838 (match_operand:QI 2 "const1_operand" "")))
11839 (clobber (reg:CC FLAGS_REG))]
11840 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11841 && (TARGET_SHIFT1 || optimize_size)"
11843 [(set_attr "type" "ishift")
11844 (set (attr "length")
11845 (if_then_else (match_operand 0 "register_operand" "")
11847 (const_string "*")))])
11849 (define_insn "*ashrqi3_1_one_bit_slp"
11850 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11851 (ashiftrt:QI (match_dup 0)
11852 (match_operand:QI 1 "const1_operand" "")))
11853 (clobber (reg:CC FLAGS_REG))]
11854 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11855 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11856 && (TARGET_SHIFT1 || optimize_size)"
11858 [(set_attr "type" "ishift1")
11859 (set (attr "length")
11860 (if_then_else (match_operand 0 "register_operand" "")
11862 (const_string "*")))])
11864 (define_insn "*ashrqi3_1"
11865 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11866 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11867 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11868 (clobber (reg:CC FLAGS_REG))]
11869 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11871 sar{b}\t{%2, %0|%0, %2}
11872 sar{b}\t{%b2, %0|%0, %b2}"
11873 [(set_attr "type" "ishift")
11874 (set_attr "mode" "QI")])
11876 (define_insn "*ashrqi3_1_slp"
11877 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11878 (ashiftrt:QI (match_dup 0)
11879 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11880 (clobber (reg:CC FLAGS_REG))]
11881 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11882 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11884 sar{b}\t{%1, %0|%0, %1}
11885 sar{b}\t{%b1, %0|%0, %b1}"
11886 [(set_attr "type" "ishift1")
11887 (set_attr "mode" "QI")])
11889 ;; This pattern can't accept a variable shift count, since shifts by
11890 ;; zero don't affect the flags. We assume that shifts by constant
11891 ;; zero are optimized away.
11892 (define_insn "*ashrqi3_one_bit_cmp"
11893 [(set (reg FLAGS_REG)
11895 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11896 (match_operand:QI 2 "const1_operand" "I"))
11898 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11899 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11900 "ix86_match_ccmode (insn, CCGOCmode)
11901 && (TARGET_SHIFT1 || optimize_size)
11902 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11904 [(set_attr "type" "ishift")
11905 (set (attr "length")
11906 (if_then_else (match_operand 0 "register_operand" "")
11908 (const_string "*")))])
11910 (define_insn "*ashrqi3_one_bit_cconly"
11911 [(set (reg FLAGS_REG)
11913 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11914 (match_operand:QI 2 "const1_operand" "I"))
11916 (clobber (match_scratch:QI 0 "=q"))]
11917 "ix86_match_ccmode (insn, CCGOCmode)
11918 && (TARGET_SHIFT1 || optimize_size)
11919 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11921 [(set_attr "type" "ishift")
11922 (set_attr "length" "2")])
11924 ;; This pattern can't accept a variable shift count, since shifts by
11925 ;; zero don't affect the flags. We assume that shifts by constant
11926 ;; zero are optimized away.
11927 (define_insn "*ashrqi3_cmp"
11928 [(set (reg FLAGS_REG)
11930 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11931 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11933 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11934 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11935 "ix86_match_ccmode (insn, CCGOCmode)
11936 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11938 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11939 "sar{b}\t{%2, %0|%0, %2}"
11940 [(set_attr "type" "ishift")
11941 (set_attr "mode" "QI")])
11943 (define_insn "*ashrqi3_cconly"
11944 [(set (reg FLAGS_REG)
11946 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11947 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11949 (clobber (match_scratch:QI 0 "=q"))]
11950 "ix86_match_ccmode (insn, CCGOCmode)
11951 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11953 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11954 "sar{b}\t{%2, %0|%0, %2}"
11955 [(set_attr "type" "ishift")
11956 (set_attr "mode" "QI")])
11959 ;; Logical shift instructions
11961 ;; See comment above `ashldi3' about how this works.
11963 (define_expand "lshrti3"
11964 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11965 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11966 (match_operand:QI 2 "nonmemory_operand" "")))
11967 (clobber (reg:CC FLAGS_REG))])]
11970 if (! immediate_operand (operands[2], QImode))
11972 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11975 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11979 (define_insn "lshrti3_1"
11980 [(set (match_operand:TI 0 "register_operand" "=r")
11981 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11982 (match_operand:QI 2 "register_operand" "c")))
11983 (clobber (match_scratch:DI 3 "=&r"))
11984 (clobber (reg:CC FLAGS_REG))]
11987 [(set_attr "type" "multi")])
11989 (define_insn "*lshrti3_2"
11990 [(set (match_operand:TI 0 "register_operand" "=r")
11991 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11992 (match_operand:QI 2 "immediate_operand" "O")))
11993 (clobber (reg:CC FLAGS_REG))]
11996 [(set_attr "type" "multi")])
11999 [(set (match_operand:TI 0 "register_operand" "")
12000 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12001 (match_operand:QI 2 "register_operand" "")))
12002 (clobber (match_scratch:DI 3 ""))
12003 (clobber (reg:CC FLAGS_REG))]
12004 "TARGET_64BIT && reload_completed"
12006 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12009 [(set (match_operand:TI 0 "register_operand" "")
12010 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12011 (match_operand:QI 2 "immediate_operand" "")))
12012 (clobber (reg:CC FLAGS_REG))]
12013 "TARGET_64BIT && reload_completed"
12015 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12017 (define_expand "lshrdi3"
12018 [(set (match_operand:DI 0 "shiftdi_operand" "")
12019 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12020 (match_operand:QI 2 "nonmemory_operand" "")))]
12022 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12024 (define_insn "*lshrdi3_1_one_bit_rex64"
12025 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12026 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12027 (match_operand:QI 2 "const1_operand" "")))
12028 (clobber (reg:CC FLAGS_REG))]
12029 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12030 && (TARGET_SHIFT1 || optimize_size)"
12032 [(set_attr "type" "ishift")
12033 (set (attr "length")
12034 (if_then_else (match_operand:DI 0 "register_operand" "")
12036 (const_string "*")))])
12038 (define_insn "*lshrdi3_1_rex64"
12039 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12040 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12041 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12042 (clobber (reg:CC FLAGS_REG))]
12043 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12045 shr{q}\t{%2, %0|%0, %2}
12046 shr{q}\t{%b2, %0|%0, %b2}"
12047 [(set_attr "type" "ishift")
12048 (set_attr "mode" "DI")])
12050 ;; This pattern can't accept a variable shift count, since shifts by
12051 ;; zero don't affect the flags. We assume that shifts by constant
12052 ;; zero are optimized away.
12053 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12054 [(set (reg FLAGS_REG)
12056 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12057 (match_operand:QI 2 "const1_operand" ""))
12059 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12060 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12061 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12062 && (TARGET_SHIFT1 || optimize_size)
12063 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12065 [(set_attr "type" "ishift")
12066 (set (attr "length")
12067 (if_then_else (match_operand:DI 0 "register_operand" "")
12069 (const_string "*")))])
12071 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12072 [(set (reg FLAGS_REG)
12074 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12075 (match_operand:QI 2 "const1_operand" ""))
12077 (clobber (match_scratch:DI 0 "=r"))]
12078 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12079 && (TARGET_SHIFT1 || optimize_size)
12080 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12082 [(set_attr "type" "ishift")
12083 (set_attr "length" "2")])
12085 ;; This pattern can't accept a variable shift count, since shifts by
12086 ;; zero don't affect the flags. We assume that shifts by constant
12087 ;; zero are optimized away.
12088 (define_insn "*lshrdi3_cmp_rex64"
12089 [(set (reg FLAGS_REG)
12091 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12092 (match_operand:QI 2 "const_int_operand" "e"))
12094 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12095 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12096 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12097 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12099 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12100 "shr{q}\t{%2, %0|%0, %2}"
12101 [(set_attr "type" "ishift")
12102 (set_attr "mode" "DI")])
12104 (define_insn "*lshrdi3_cconly_rex64"
12105 [(set (reg FLAGS_REG)
12107 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12108 (match_operand:QI 2 "const_int_operand" "e"))
12110 (clobber (match_scratch:DI 0 "=r"))]
12111 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12112 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12114 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12115 "shr{q}\t{%2, %0|%0, %2}"
12116 [(set_attr "type" "ishift")
12117 (set_attr "mode" "DI")])
12119 (define_insn "*lshrdi3_1"
12120 [(set (match_operand:DI 0 "register_operand" "=r")
12121 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12122 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12123 (clobber (reg:CC FLAGS_REG))]
12126 [(set_attr "type" "multi")])
12128 ;; By default we don't ask for a scratch register, because when DImode
12129 ;; values are manipulated, registers are already at a premium. But if
12130 ;; we have one handy, we won't turn it away.
12132 [(match_scratch:SI 3 "r")
12133 (parallel [(set (match_operand:DI 0 "register_operand" "")
12134 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12135 (match_operand:QI 2 "nonmemory_operand" "")))
12136 (clobber (reg:CC FLAGS_REG))])
12138 "!TARGET_64BIT && TARGET_CMOVE"
12140 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12143 [(set (match_operand:DI 0 "register_operand" "")
12144 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12145 (match_operand:QI 2 "nonmemory_operand" "")))
12146 (clobber (reg:CC FLAGS_REG))]
12147 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12148 ? flow2_completed : reload_completed)"
12150 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12152 (define_expand "lshrsi3"
12153 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12154 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12155 (match_operand:QI 2 "nonmemory_operand" "")))
12156 (clobber (reg:CC FLAGS_REG))]
12158 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12160 (define_insn "*lshrsi3_1_one_bit"
12161 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12162 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12163 (match_operand:QI 2 "const1_operand" "")))
12164 (clobber (reg:CC FLAGS_REG))]
12165 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12166 && (TARGET_SHIFT1 || optimize_size)"
12168 [(set_attr "type" "ishift")
12169 (set (attr "length")
12170 (if_then_else (match_operand:SI 0 "register_operand" "")
12172 (const_string "*")))])
12174 (define_insn "*lshrsi3_1_one_bit_zext"
12175 [(set (match_operand:DI 0 "register_operand" "=r")
12176 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12177 (match_operand:QI 2 "const1_operand" "")))
12178 (clobber (reg:CC FLAGS_REG))]
12179 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12180 && (TARGET_SHIFT1 || optimize_size)"
12182 [(set_attr "type" "ishift")
12183 (set_attr "length" "2")])
12185 (define_insn "*lshrsi3_1"
12186 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12187 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12188 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12189 (clobber (reg:CC FLAGS_REG))]
12190 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12192 shr{l}\t{%2, %0|%0, %2}
12193 shr{l}\t{%b2, %0|%0, %b2}"
12194 [(set_attr "type" "ishift")
12195 (set_attr "mode" "SI")])
12197 (define_insn "*lshrsi3_1_zext"
12198 [(set (match_operand:DI 0 "register_operand" "=r,r")
12200 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12201 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12202 (clobber (reg:CC FLAGS_REG))]
12203 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12205 shr{l}\t{%2, %k0|%k0, %2}
12206 shr{l}\t{%b2, %k0|%k0, %b2}"
12207 [(set_attr "type" "ishift")
12208 (set_attr "mode" "SI")])
12210 ;; This pattern can't accept a variable shift count, since shifts by
12211 ;; zero don't affect the flags. We assume that shifts by constant
12212 ;; zero are optimized away.
12213 (define_insn "*lshrsi3_one_bit_cmp"
12214 [(set (reg FLAGS_REG)
12216 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12217 (match_operand:QI 2 "const1_operand" ""))
12219 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12220 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12221 "ix86_match_ccmode (insn, CCGOCmode)
12222 && (TARGET_SHIFT1 || optimize_size)
12223 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12225 [(set_attr "type" "ishift")
12226 (set (attr "length")
12227 (if_then_else (match_operand:SI 0 "register_operand" "")
12229 (const_string "*")))])
12231 (define_insn "*lshrsi3_one_bit_cconly"
12232 [(set (reg FLAGS_REG)
12234 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12235 (match_operand:QI 2 "const1_operand" ""))
12237 (clobber (match_scratch:SI 0 "=r"))]
12238 "ix86_match_ccmode (insn, CCGOCmode)
12239 && (TARGET_SHIFT1 || optimize_size)
12240 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12242 [(set_attr "type" "ishift")
12243 (set_attr "length" "2")])
12245 (define_insn "*lshrsi3_cmp_one_bit_zext"
12246 [(set (reg FLAGS_REG)
12248 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12249 (match_operand:QI 2 "const1_operand" ""))
12251 (set (match_operand:DI 0 "register_operand" "=r")
12252 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12253 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12254 && (TARGET_SHIFT1 || optimize_size)
12255 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12257 [(set_attr "type" "ishift")
12258 (set_attr "length" "2")])
12260 ;; This pattern can't accept a variable shift count, since shifts by
12261 ;; zero don't affect the flags. We assume that shifts by constant
12262 ;; zero are optimized away.
12263 (define_insn "*lshrsi3_cmp"
12264 [(set (reg FLAGS_REG)
12266 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12267 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12269 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12270 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12271 "ix86_match_ccmode (insn, CCGOCmode)
12272 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12274 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12275 "shr{l}\t{%2, %0|%0, %2}"
12276 [(set_attr "type" "ishift")
12277 (set_attr "mode" "SI")])
12279 (define_insn "*lshrsi3_cconly"
12280 [(set (reg FLAGS_REG)
12282 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12283 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12285 (clobber (match_scratch:SI 0 "=r"))]
12286 "ix86_match_ccmode (insn, CCGOCmode)
12287 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12289 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12290 "shr{l}\t{%2, %0|%0, %2}"
12291 [(set_attr "type" "ishift")
12292 (set_attr "mode" "SI")])
12294 (define_insn "*lshrsi3_cmp_zext"
12295 [(set (reg FLAGS_REG)
12297 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12298 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12300 (set (match_operand:DI 0 "register_operand" "=r")
12301 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12302 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12303 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12305 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12306 "shr{l}\t{%2, %k0|%k0, %2}"
12307 [(set_attr "type" "ishift")
12308 (set_attr "mode" "SI")])
12310 (define_expand "lshrhi3"
12311 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12312 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12313 (match_operand:QI 2 "nonmemory_operand" "")))
12314 (clobber (reg:CC FLAGS_REG))]
12315 "TARGET_HIMODE_MATH"
12316 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12318 (define_insn "*lshrhi3_1_one_bit"
12319 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12320 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12321 (match_operand:QI 2 "const1_operand" "")))
12322 (clobber (reg:CC FLAGS_REG))]
12323 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12324 && (TARGET_SHIFT1 || optimize_size)"
12326 [(set_attr "type" "ishift")
12327 (set (attr "length")
12328 (if_then_else (match_operand 0 "register_operand" "")
12330 (const_string "*")))])
12332 (define_insn "*lshrhi3_1"
12333 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12334 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12335 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12336 (clobber (reg:CC FLAGS_REG))]
12337 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12339 shr{w}\t{%2, %0|%0, %2}
12340 shr{w}\t{%b2, %0|%0, %b2}"
12341 [(set_attr "type" "ishift")
12342 (set_attr "mode" "HI")])
12344 ;; This pattern can't accept a variable shift count, since shifts by
12345 ;; zero don't affect the flags. We assume that shifts by constant
12346 ;; zero are optimized away.
12347 (define_insn "*lshrhi3_one_bit_cmp"
12348 [(set (reg FLAGS_REG)
12350 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12351 (match_operand:QI 2 "const1_operand" ""))
12353 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12354 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12355 "ix86_match_ccmode (insn, CCGOCmode)
12356 && (TARGET_SHIFT1 || optimize_size)
12357 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12359 [(set_attr "type" "ishift")
12360 (set (attr "length")
12361 (if_then_else (match_operand:SI 0 "register_operand" "")
12363 (const_string "*")))])
12365 (define_insn "*lshrhi3_one_bit_cconly"
12366 [(set (reg FLAGS_REG)
12368 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12369 (match_operand:QI 2 "const1_operand" ""))
12371 (clobber (match_scratch:HI 0 "=r"))]
12372 "ix86_match_ccmode (insn, CCGOCmode)
12373 && (TARGET_SHIFT1 || optimize_size)
12374 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12376 [(set_attr "type" "ishift")
12377 (set_attr "length" "2")])
12379 ;; This pattern can't accept a variable shift count, since shifts by
12380 ;; zero don't affect the flags. We assume that shifts by constant
12381 ;; zero are optimized away.
12382 (define_insn "*lshrhi3_cmp"
12383 [(set (reg FLAGS_REG)
12385 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12386 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12388 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12389 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12390 "ix86_match_ccmode (insn, CCGOCmode)
12391 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12393 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12394 "shr{w}\t{%2, %0|%0, %2}"
12395 [(set_attr "type" "ishift")
12396 (set_attr "mode" "HI")])
12398 (define_insn "*lshrhi3_cconly"
12399 [(set (reg FLAGS_REG)
12401 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12402 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12404 (clobber (match_scratch:HI 0 "=r"))]
12405 "ix86_match_ccmode (insn, CCGOCmode)
12406 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12408 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12409 "shr{w}\t{%2, %0|%0, %2}"
12410 [(set_attr "type" "ishift")
12411 (set_attr "mode" "HI")])
12413 (define_expand "lshrqi3"
12414 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12415 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12416 (match_operand:QI 2 "nonmemory_operand" "")))
12417 (clobber (reg:CC FLAGS_REG))]
12418 "TARGET_QIMODE_MATH"
12419 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12421 (define_insn "*lshrqi3_1_one_bit"
12422 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12423 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12424 (match_operand:QI 2 "const1_operand" "")))
12425 (clobber (reg:CC FLAGS_REG))]
12426 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12427 && (TARGET_SHIFT1 || optimize_size)"
12429 [(set_attr "type" "ishift")
12430 (set (attr "length")
12431 (if_then_else (match_operand 0 "register_operand" "")
12433 (const_string "*")))])
12435 (define_insn "*lshrqi3_1_one_bit_slp"
12436 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12437 (lshiftrt:QI (match_dup 0)
12438 (match_operand:QI 1 "const1_operand" "")))
12439 (clobber (reg:CC FLAGS_REG))]
12440 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12441 && (TARGET_SHIFT1 || optimize_size)"
12443 [(set_attr "type" "ishift1")
12444 (set (attr "length")
12445 (if_then_else (match_operand 0 "register_operand" "")
12447 (const_string "*")))])
12449 (define_insn "*lshrqi3_1"
12450 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12451 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12452 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12453 (clobber (reg:CC FLAGS_REG))]
12454 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12456 shr{b}\t{%2, %0|%0, %2}
12457 shr{b}\t{%b2, %0|%0, %b2}"
12458 [(set_attr "type" "ishift")
12459 (set_attr "mode" "QI")])
12461 (define_insn "*lshrqi3_1_slp"
12462 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12463 (lshiftrt:QI (match_dup 0)
12464 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12465 (clobber (reg:CC FLAGS_REG))]
12466 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12467 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12469 shr{b}\t{%1, %0|%0, %1}
12470 shr{b}\t{%b1, %0|%0, %b1}"
12471 [(set_attr "type" "ishift1")
12472 (set_attr "mode" "QI")])
12474 ;; This pattern can't accept a variable shift count, since shifts by
12475 ;; zero don't affect the flags. We assume that shifts by constant
12476 ;; zero are optimized away.
12477 (define_insn "*lshrqi2_one_bit_cmp"
12478 [(set (reg FLAGS_REG)
12480 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12481 (match_operand:QI 2 "const1_operand" ""))
12483 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12484 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12485 "ix86_match_ccmode (insn, CCGOCmode)
12486 && (TARGET_SHIFT1 || optimize_size)
12487 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12489 [(set_attr "type" "ishift")
12490 (set (attr "length")
12491 (if_then_else (match_operand:SI 0 "register_operand" "")
12493 (const_string "*")))])
12495 (define_insn "*lshrqi2_one_bit_cconly"
12496 [(set (reg FLAGS_REG)
12498 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12499 (match_operand:QI 2 "const1_operand" ""))
12501 (clobber (match_scratch:QI 0 "=q"))]
12502 "ix86_match_ccmode (insn, CCGOCmode)
12503 && (TARGET_SHIFT1 || optimize_size)
12504 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12506 [(set_attr "type" "ishift")
12507 (set_attr "length" "2")])
12509 ;; This pattern can't accept a variable shift count, since shifts by
12510 ;; zero don't affect the flags. We assume that shifts by constant
12511 ;; zero are optimized away.
12512 (define_insn "*lshrqi2_cmp"
12513 [(set (reg FLAGS_REG)
12515 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12516 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12518 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12519 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12520 "ix86_match_ccmode (insn, CCGOCmode)
12521 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12523 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12524 "shr{b}\t{%2, %0|%0, %2}"
12525 [(set_attr "type" "ishift")
12526 (set_attr "mode" "QI")])
12528 (define_insn "*lshrqi2_cconly"
12529 [(set (reg FLAGS_REG)
12531 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12532 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12534 (clobber (match_scratch:QI 0 "=q"))]
12535 "ix86_match_ccmode (insn, CCGOCmode)
12536 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12538 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12539 "shr{b}\t{%2, %0|%0, %2}"
12540 [(set_attr "type" "ishift")
12541 (set_attr "mode" "QI")])
12543 ;; Rotate instructions
12545 (define_expand "rotldi3"
12546 [(set (match_operand:DI 0 "shiftdi_operand" "")
12547 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12548 (match_operand:QI 2 "nonmemory_operand" "")))
12549 (clobber (reg:CC FLAGS_REG))]
12554 ix86_expand_binary_operator (ROTATE, DImode, operands);
12557 if (!const_1_to_31_operand (operands[2], VOIDmode))
12559 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12563 ;; Implement rotation using two double-precision shift instructions
12564 ;; and a scratch register.
12565 (define_insn_and_split "ix86_rotldi3"
12566 [(set (match_operand:DI 0 "register_operand" "=r")
12567 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12568 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12569 (clobber (reg:CC FLAGS_REG))
12570 (clobber (match_scratch:SI 3 "=&r"))]
12573 "&& reload_completed"
12574 [(set (match_dup 3) (match_dup 4))
12576 [(set (match_dup 4)
12577 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12578 (lshiftrt:SI (match_dup 5)
12579 (minus:QI (const_int 32) (match_dup 2)))))
12580 (clobber (reg:CC FLAGS_REG))])
12582 [(set (match_dup 5)
12583 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12584 (lshiftrt:SI (match_dup 3)
12585 (minus:QI (const_int 32) (match_dup 2)))))
12586 (clobber (reg:CC FLAGS_REG))])]
12587 "split_di (operands, 1, operands + 4, operands + 5);")
12589 (define_insn "*rotlsi3_1_one_bit_rex64"
12590 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12591 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12592 (match_operand:QI 2 "const1_operand" "")))
12593 (clobber (reg:CC FLAGS_REG))]
12594 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12595 && (TARGET_SHIFT1 || optimize_size)"
12597 [(set_attr "type" "rotate")
12598 (set (attr "length")
12599 (if_then_else (match_operand:DI 0 "register_operand" "")
12601 (const_string "*")))])
12603 (define_insn "*rotldi3_1_rex64"
12604 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12605 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12606 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12607 (clobber (reg:CC FLAGS_REG))]
12608 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12610 rol{q}\t{%2, %0|%0, %2}
12611 rol{q}\t{%b2, %0|%0, %b2}"
12612 [(set_attr "type" "rotate")
12613 (set_attr "mode" "DI")])
12615 (define_expand "rotlsi3"
12616 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12617 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12618 (match_operand:QI 2 "nonmemory_operand" "")))
12619 (clobber (reg:CC FLAGS_REG))]
12621 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12623 (define_insn "*rotlsi3_1_one_bit"
12624 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12625 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12626 (match_operand:QI 2 "const1_operand" "")))
12627 (clobber (reg:CC FLAGS_REG))]
12628 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12629 && (TARGET_SHIFT1 || optimize_size)"
12631 [(set_attr "type" "rotate")
12632 (set (attr "length")
12633 (if_then_else (match_operand:SI 0 "register_operand" "")
12635 (const_string "*")))])
12637 (define_insn "*rotlsi3_1_one_bit_zext"
12638 [(set (match_operand:DI 0 "register_operand" "=r")
12640 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12641 (match_operand:QI 2 "const1_operand" ""))))
12642 (clobber (reg:CC FLAGS_REG))]
12643 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12644 && (TARGET_SHIFT1 || optimize_size)"
12646 [(set_attr "type" "rotate")
12647 (set_attr "length" "2")])
12649 (define_insn "*rotlsi3_1"
12650 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12651 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12652 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12653 (clobber (reg:CC FLAGS_REG))]
12654 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12656 rol{l}\t{%2, %0|%0, %2}
12657 rol{l}\t{%b2, %0|%0, %b2}"
12658 [(set_attr "type" "rotate")
12659 (set_attr "mode" "SI")])
12661 (define_insn "*rotlsi3_1_zext"
12662 [(set (match_operand:DI 0 "register_operand" "=r,r")
12664 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12665 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12666 (clobber (reg:CC FLAGS_REG))]
12667 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12669 rol{l}\t{%2, %k0|%k0, %2}
12670 rol{l}\t{%b2, %k0|%k0, %b2}"
12671 [(set_attr "type" "rotate")
12672 (set_attr "mode" "SI")])
12674 (define_expand "rotlhi3"
12675 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12676 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12677 (match_operand:QI 2 "nonmemory_operand" "")))
12678 (clobber (reg:CC FLAGS_REG))]
12679 "TARGET_HIMODE_MATH"
12680 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12682 (define_insn "*rotlhi3_1_one_bit"
12683 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12684 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12685 (match_operand:QI 2 "const1_operand" "")))
12686 (clobber (reg:CC FLAGS_REG))]
12687 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12688 && (TARGET_SHIFT1 || optimize_size)"
12690 [(set_attr "type" "rotate")
12691 (set (attr "length")
12692 (if_then_else (match_operand 0 "register_operand" "")
12694 (const_string "*")))])
12696 (define_insn "*rotlhi3_1"
12697 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12698 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12699 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12700 (clobber (reg:CC FLAGS_REG))]
12701 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12703 rol{w}\t{%2, %0|%0, %2}
12704 rol{w}\t{%b2, %0|%0, %b2}"
12705 [(set_attr "type" "rotate")
12706 (set_attr "mode" "HI")])
12708 (define_expand "rotlqi3"
12709 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12710 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12711 (match_operand:QI 2 "nonmemory_operand" "")))
12712 (clobber (reg:CC FLAGS_REG))]
12713 "TARGET_QIMODE_MATH"
12714 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12716 (define_insn "*rotlqi3_1_one_bit_slp"
12717 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12718 (rotate:QI (match_dup 0)
12719 (match_operand:QI 1 "const1_operand" "")))
12720 (clobber (reg:CC FLAGS_REG))]
12721 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12722 && (TARGET_SHIFT1 || optimize_size)"
12724 [(set_attr "type" "rotate1")
12725 (set (attr "length")
12726 (if_then_else (match_operand 0 "register_operand" "")
12728 (const_string "*")))])
12730 (define_insn "*rotlqi3_1_one_bit"
12731 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12732 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12733 (match_operand:QI 2 "const1_operand" "")))
12734 (clobber (reg:CC FLAGS_REG))]
12735 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12736 && (TARGET_SHIFT1 || optimize_size)"
12738 [(set_attr "type" "rotate")
12739 (set (attr "length")
12740 (if_then_else (match_operand 0 "register_operand" "")
12742 (const_string "*")))])
12744 (define_insn "*rotlqi3_1_slp"
12745 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12746 (rotate:QI (match_dup 0)
12747 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12748 (clobber (reg:CC FLAGS_REG))]
12749 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12750 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12752 rol{b}\t{%1, %0|%0, %1}
12753 rol{b}\t{%b1, %0|%0, %b1}"
12754 [(set_attr "type" "rotate1")
12755 (set_attr "mode" "QI")])
12757 (define_insn "*rotlqi3_1"
12758 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12759 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12760 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12761 (clobber (reg:CC FLAGS_REG))]
12762 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12764 rol{b}\t{%2, %0|%0, %2}
12765 rol{b}\t{%b2, %0|%0, %b2}"
12766 [(set_attr "type" "rotate")
12767 (set_attr "mode" "QI")])
12769 (define_expand "rotrdi3"
12770 [(set (match_operand:DI 0 "shiftdi_operand" "")
12771 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12772 (match_operand:QI 2 "nonmemory_operand" "")))
12773 (clobber (reg:CC FLAGS_REG))]
12778 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12781 if (!const_1_to_31_operand (operands[2], VOIDmode))
12783 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12787 ;; Implement rotation using two double-precision shift instructions
12788 ;; and a scratch register.
12789 (define_insn_and_split "ix86_rotrdi3"
12790 [(set (match_operand:DI 0 "register_operand" "=r")
12791 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12792 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12793 (clobber (reg:CC FLAGS_REG))
12794 (clobber (match_scratch:SI 3 "=&r"))]
12797 "&& reload_completed"
12798 [(set (match_dup 3) (match_dup 4))
12800 [(set (match_dup 4)
12801 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12802 (ashift:SI (match_dup 5)
12803 (minus:QI (const_int 32) (match_dup 2)))))
12804 (clobber (reg:CC FLAGS_REG))])
12806 [(set (match_dup 5)
12807 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12808 (ashift:SI (match_dup 3)
12809 (minus:QI (const_int 32) (match_dup 2)))))
12810 (clobber (reg:CC FLAGS_REG))])]
12811 "split_di (operands, 1, operands + 4, operands + 5);")
12813 (define_insn "*rotrdi3_1_one_bit_rex64"
12814 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12815 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12816 (match_operand:QI 2 "const1_operand" "")))
12817 (clobber (reg:CC FLAGS_REG))]
12818 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12819 && (TARGET_SHIFT1 || optimize_size)"
12821 [(set_attr "type" "rotate")
12822 (set (attr "length")
12823 (if_then_else (match_operand:DI 0 "register_operand" "")
12825 (const_string "*")))])
12827 (define_insn "*rotrdi3_1_rex64"
12828 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12829 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12830 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12831 (clobber (reg:CC FLAGS_REG))]
12832 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12834 ror{q}\t{%2, %0|%0, %2}
12835 ror{q}\t{%b2, %0|%0, %b2}"
12836 [(set_attr "type" "rotate")
12837 (set_attr "mode" "DI")])
12839 (define_expand "rotrsi3"
12840 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12841 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12842 (match_operand:QI 2 "nonmemory_operand" "")))
12843 (clobber (reg:CC FLAGS_REG))]
12845 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12847 (define_insn "*rotrsi3_1_one_bit"
12848 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12849 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12850 (match_operand:QI 2 "const1_operand" "")))
12851 (clobber (reg:CC FLAGS_REG))]
12852 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12853 && (TARGET_SHIFT1 || optimize_size)"
12855 [(set_attr "type" "rotate")
12856 (set (attr "length")
12857 (if_then_else (match_operand:SI 0 "register_operand" "")
12859 (const_string "*")))])
12861 (define_insn "*rotrsi3_1_one_bit_zext"
12862 [(set (match_operand:DI 0 "register_operand" "=r")
12864 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12865 (match_operand:QI 2 "const1_operand" ""))))
12866 (clobber (reg:CC FLAGS_REG))]
12867 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12868 && (TARGET_SHIFT1 || optimize_size)"
12870 [(set_attr "type" "rotate")
12871 (set (attr "length")
12872 (if_then_else (match_operand:SI 0 "register_operand" "")
12874 (const_string "*")))])
12876 (define_insn "*rotrsi3_1"
12877 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12878 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12879 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12880 (clobber (reg:CC FLAGS_REG))]
12881 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12883 ror{l}\t{%2, %0|%0, %2}
12884 ror{l}\t{%b2, %0|%0, %b2}"
12885 [(set_attr "type" "rotate")
12886 (set_attr "mode" "SI")])
12888 (define_insn "*rotrsi3_1_zext"
12889 [(set (match_operand:DI 0 "register_operand" "=r,r")
12891 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12892 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12893 (clobber (reg:CC FLAGS_REG))]
12894 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12896 ror{l}\t{%2, %k0|%k0, %2}
12897 ror{l}\t{%b2, %k0|%k0, %b2}"
12898 [(set_attr "type" "rotate")
12899 (set_attr "mode" "SI")])
12901 (define_expand "rotrhi3"
12902 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12903 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12904 (match_operand:QI 2 "nonmemory_operand" "")))
12905 (clobber (reg:CC FLAGS_REG))]
12906 "TARGET_HIMODE_MATH"
12907 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12909 (define_insn "*rotrhi3_one_bit"
12910 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12911 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12912 (match_operand:QI 2 "const1_operand" "")))
12913 (clobber (reg:CC FLAGS_REG))]
12914 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12915 && (TARGET_SHIFT1 || optimize_size)"
12917 [(set_attr "type" "rotate")
12918 (set (attr "length")
12919 (if_then_else (match_operand 0 "register_operand" "")
12921 (const_string "*")))])
12923 (define_insn "*rotrhi3"
12924 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12925 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12926 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12927 (clobber (reg:CC FLAGS_REG))]
12928 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12930 ror{w}\t{%2, %0|%0, %2}
12931 ror{w}\t{%b2, %0|%0, %b2}"
12932 [(set_attr "type" "rotate")
12933 (set_attr "mode" "HI")])
12935 (define_expand "rotrqi3"
12936 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12937 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12938 (match_operand:QI 2 "nonmemory_operand" "")))
12939 (clobber (reg:CC FLAGS_REG))]
12940 "TARGET_QIMODE_MATH"
12941 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12943 (define_insn "*rotrqi3_1_one_bit"
12944 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12945 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12946 (match_operand:QI 2 "const1_operand" "")))
12947 (clobber (reg:CC FLAGS_REG))]
12948 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12949 && (TARGET_SHIFT1 || optimize_size)"
12951 [(set_attr "type" "rotate")
12952 (set (attr "length")
12953 (if_then_else (match_operand 0 "register_operand" "")
12955 (const_string "*")))])
12957 (define_insn "*rotrqi3_1_one_bit_slp"
12958 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12959 (rotatert:QI (match_dup 0)
12960 (match_operand:QI 1 "const1_operand" "")))
12961 (clobber (reg:CC FLAGS_REG))]
12962 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12963 && (TARGET_SHIFT1 || optimize_size)"
12965 [(set_attr "type" "rotate1")
12966 (set (attr "length")
12967 (if_then_else (match_operand 0 "register_operand" "")
12969 (const_string "*")))])
12971 (define_insn "*rotrqi3_1"
12972 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12973 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12974 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12975 (clobber (reg:CC FLAGS_REG))]
12976 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12978 ror{b}\t{%2, %0|%0, %2}
12979 ror{b}\t{%b2, %0|%0, %b2}"
12980 [(set_attr "type" "rotate")
12981 (set_attr "mode" "QI")])
12983 (define_insn "*rotrqi3_1_slp"
12984 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12985 (rotatert:QI (match_dup 0)
12986 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12987 (clobber (reg:CC FLAGS_REG))]
12988 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12989 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12991 ror{b}\t{%1, %0|%0, %1}
12992 ror{b}\t{%b1, %0|%0, %b1}"
12993 [(set_attr "type" "rotate1")
12994 (set_attr "mode" "QI")])
12996 ;; Bit set / bit test instructions
12998 (define_expand "extv"
12999 [(set (match_operand:SI 0 "register_operand" "")
13000 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13001 (match_operand:SI 2 "const8_operand" "")
13002 (match_operand:SI 3 "const8_operand" "")))]
13005 /* Handle extractions from %ah et al. */
13006 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13009 /* From mips.md: extract_bit_field doesn't verify that our source
13010 matches the predicate, so check it again here. */
13011 if (! ext_register_operand (operands[1], VOIDmode))
13015 (define_expand "extzv"
13016 [(set (match_operand:SI 0 "register_operand" "")
13017 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13018 (match_operand:SI 2 "const8_operand" "")
13019 (match_operand:SI 3 "const8_operand" "")))]
13022 /* Handle extractions from %ah et al. */
13023 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13026 /* From mips.md: extract_bit_field doesn't verify that our source
13027 matches the predicate, so check it again here. */
13028 if (! ext_register_operand (operands[1], VOIDmode))
13032 (define_expand "insv"
13033 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13034 (match_operand 1 "const8_operand" "")
13035 (match_operand 2 "const8_operand" ""))
13036 (match_operand 3 "register_operand" ""))]
13039 /* Handle insertions to %ah et al. */
13040 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13043 /* From mips.md: insert_bit_field doesn't verify that our source
13044 matches the predicate, so check it again here. */
13045 if (! ext_register_operand (operands[0], VOIDmode))
13049 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13051 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13056 ;; %%% bts, btr, btc, bt.
13057 ;; In general these instructions are *slow* when applied to memory,
13058 ;; since they enforce atomic operation. When applied to registers,
13059 ;; it depends on the cpu implementation. They're never faster than
13060 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13061 ;; no point. But in 64-bit, we can't hold the relevant immediates
13062 ;; within the instruction itself, so operating on bits in the high
13063 ;; 32-bits of a register becomes easier.
13065 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13066 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13067 ;; negdf respectively, so they can never be disabled entirely.
13069 (define_insn "*btsq"
13070 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13072 (match_operand:DI 1 "const_0_to_63_operand" ""))
13074 (clobber (reg:CC FLAGS_REG))]
13075 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13077 [(set_attr "type" "alu1")])
13079 (define_insn "*btrq"
13080 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13082 (match_operand:DI 1 "const_0_to_63_operand" ""))
13084 (clobber (reg:CC FLAGS_REG))]
13085 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13087 [(set_attr "type" "alu1")])
13089 (define_insn "*btcq"
13090 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13092 (match_operand:DI 1 "const_0_to_63_operand" ""))
13093 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13094 (clobber (reg:CC FLAGS_REG))]
13095 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13097 [(set_attr "type" "alu1")])
13099 ;; Allow Nocona to avoid these instructions if a register is available.
13102 [(match_scratch:DI 2 "r")
13103 (parallel [(set (zero_extract:DI
13104 (match_operand:DI 0 "register_operand" "")
13106 (match_operand:DI 1 "const_0_to_63_operand" ""))
13108 (clobber (reg:CC FLAGS_REG))])]
13109 "TARGET_64BIT && !TARGET_USE_BT"
13112 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13115 if (HOST_BITS_PER_WIDE_INT >= 64)
13116 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13117 else if (i < HOST_BITS_PER_WIDE_INT)
13118 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13120 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13122 op1 = immed_double_const (lo, hi, DImode);
13125 emit_move_insn (operands[2], op1);
13129 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13134 [(match_scratch:DI 2 "r")
13135 (parallel [(set (zero_extract:DI
13136 (match_operand:DI 0 "register_operand" "")
13138 (match_operand:DI 1 "const_0_to_63_operand" ""))
13140 (clobber (reg:CC FLAGS_REG))])]
13141 "TARGET_64BIT && !TARGET_USE_BT"
13144 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13147 if (HOST_BITS_PER_WIDE_INT >= 64)
13148 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13149 else if (i < HOST_BITS_PER_WIDE_INT)
13150 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13152 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13154 op1 = immed_double_const (~lo, ~hi, DImode);
13157 emit_move_insn (operands[2], op1);
13161 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13166 [(match_scratch:DI 2 "r")
13167 (parallel [(set (zero_extract:DI
13168 (match_operand:DI 0 "register_operand" "")
13170 (match_operand:DI 1 "const_0_to_63_operand" ""))
13171 (not:DI (zero_extract:DI
13172 (match_dup 0) (const_int 1) (match_dup 1))))
13173 (clobber (reg:CC FLAGS_REG))])]
13174 "TARGET_64BIT && !TARGET_USE_BT"
13177 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13180 if (HOST_BITS_PER_WIDE_INT >= 64)
13181 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13182 else if (i < HOST_BITS_PER_WIDE_INT)
13183 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13185 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13187 op1 = immed_double_const (lo, hi, DImode);
13190 emit_move_insn (operands[2], op1);
13194 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13198 ;; Store-flag instructions.
13200 ;; For all sCOND expanders, also expand the compare or test insn that
13201 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13203 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13204 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13205 ;; way, which can later delete the movzx if only QImode is needed.
13207 (define_expand "seq"
13208 [(set (match_operand:QI 0 "register_operand" "")
13209 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13211 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13213 (define_expand "sne"
13214 [(set (match_operand:QI 0 "register_operand" "")
13215 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13217 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13219 (define_expand "sgt"
13220 [(set (match_operand:QI 0 "register_operand" "")
13221 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13223 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13225 (define_expand "sgtu"
13226 [(set (match_operand:QI 0 "register_operand" "")
13227 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13229 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13231 (define_expand "slt"
13232 [(set (match_operand:QI 0 "register_operand" "")
13233 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13235 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13237 (define_expand "sltu"
13238 [(set (match_operand:QI 0 "register_operand" "")
13239 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13241 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13243 (define_expand "sge"
13244 [(set (match_operand:QI 0 "register_operand" "")
13245 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13247 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13249 (define_expand "sgeu"
13250 [(set (match_operand:QI 0 "register_operand" "")
13251 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13253 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13255 (define_expand "sle"
13256 [(set (match_operand:QI 0 "register_operand" "")
13257 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13259 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13261 (define_expand "sleu"
13262 [(set (match_operand:QI 0 "register_operand" "")
13263 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13265 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13267 (define_expand "sunordered"
13268 [(set (match_operand:QI 0 "register_operand" "")
13269 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13270 "TARGET_80387 || TARGET_SSE"
13271 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13273 (define_expand "sordered"
13274 [(set (match_operand:QI 0 "register_operand" "")
13275 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13277 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13279 (define_expand "suneq"
13280 [(set (match_operand:QI 0 "register_operand" "")
13281 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13282 "TARGET_80387 || TARGET_SSE"
13283 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13285 (define_expand "sunge"
13286 [(set (match_operand:QI 0 "register_operand" "")
13287 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13288 "TARGET_80387 || TARGET_SSE"
13289 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13291 (define_expand "sungt"
13292 [(set (match_operand:QI 0 "register_operand" "")
13293 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13294 "TARGET_80387 || TARGET_SSE"
13295 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13297 (define_expand "sunle"
13298 [(set (match_operand:QI 0 "register_operand" "")
13299 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13300 "TARGET_80387 || TARGET_SSE"
13301 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13303 (define_expand "sunlt"
13304 [(set (match_operand:QI 0 "register_operand" "")
13305 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13306 "TARGET_80387 || TARGET_SSE"
13307 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13309 (define_expand "sltgt"
13310 [(set (match_operand:QI 0 "register_operand" "")
13311 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13312 "TARGET_80387 || TARGET_SSE"
13313 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13315 (define_insn "*setcc_1"
13316 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13317 (match_operator:QI 1 "ix86_comparison_operator"
13318 [(reg FLAGS_REG) (const_int 0)]))]
13321 [(set_attr "type" "setcc")
13322 (set_attr "mode" "QI")])
13324 (define_insn "*setcc_2"
13325 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13326 (match_operator:QI 1 "ix86_comparison_operator"
13327 [(reg FLAGS_REG) (const_int 0)]))]
13330 [(set_attr "type" "setcc")
13331 (set_attr "mode" "QI")])
13333 ;; In general it is not safe to assume too much about CCmode registers,
13334 ;; so simplify-rtx stops when it sees a second one. Under certain
13335 ;; conditions this is safe on x86, so help combine not create
13342 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13343 (ne:QI (match_operator 1 "ix86_comparison_operator"
13344 [(reg FLAGS_REG) (const_int 0)])
13347 [(set (match_dup 0) (match_dup 1))]
13349 PUT_MODE (operands[1], QImode);
13353 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13354 (ne:QI (match_operator 1 "ix86_comparison_operator"
13355 [(reg FLAGS_REG) (const_int 0)])
13358 [(set (match_dup 0) (match_dup 1))]
13360 PUT_MODE (operands[1], QImode);
13364 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13365 (eq:QI (match_operator 1 "ix86_comparison_operator"
13366 [(reg FLAGS_REG) (const_int 0)])
13369 [(set (match_dup 0) (match_dup 1))]
13371 rtx new_op1 = copy_rtx (operands[1]);
13372 operands[1] = new_op1;
13373 PUT_MODE (new_op1, QImode);
13374 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13375 GET_MODE (XEXP (new_op1, 0))));
13377 /* Make sure that (a) the CCmode we have for the flags is strong
13378 enough for the reversed compare or (b) we have a valid FP compare. */
13379 if (! ix86_comparison_operator (new_op1, VOIDmode))
13384 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13385 (eq:QI (match_operator 1 "ix86_comparison_operator"
13386 [(reg FLAGS_REG) (const_int 0)])
13389 [(set (match_dup 0) (match_dup 1))]
13391 rtx new_op1 = copy_rtx (operands[1]);
13392 operands[1] = new_op1;
13393 PUT_MODE (new_op1, QImode);
13394 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13395 GET_MODE (XEXP (new_op1, 0))));
13397 /* Make sure that (a) the CCmode we have for the flags is strong
13398 enough for the reversed compare or (b) we have a valid FP compare. */
13399 if (! ix86_comparison_operator (new_op1, VOIDmode))
13403 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13404 ;; subsequent logical operations are used to imitate conditional moves.
13405 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13408 (define_insn "*sse_setccsf"
13409 [(set (match_operand:SF 0 "register_operand" "=x")
13410 (match_operator:SF 1 "sse_comparison_operator"
13411 [(match_operand:SF 2 "register_operand" "0")
13412 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13414 "cmp%D1ss\t{%3, %0|%0, %3}"
13415 [(set_attr "type" "ssecmp")
13416 (set_attr "mode" "SF")])
13418 (define_insn "*sse_setccdf"
13419 [(set (match_operand:DF 0 "register_operand" "=Y")
13420 (match_operator:DF 1 "sse_comparison_operator"
13421 [(match_operand:DF 2 "register_operand" "0")
13422 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13424 "cmp%D1sd\t{%3, %0|%0, %3}"
13425 [(set_attr "type" "ssecmp")
13426 (set_attr "mode" "DF")])
13428 ;; Basic conditional jump instructions.
13429 ;; We ignore the overflow flag for signed branch instructions.
13431 ;; For all bCOND expanders, also expand the compare or test insn that
13432 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13434 (define_expand "beq"
13436 (if_then_else (match_dup 1)
13437 (label_ref (match_operand 0 "" ""))
13440 "ix86_expand_branch (EQ, operands[0]); DONE;")
13442 (define_expand "bne"
13444 (if_then_else (match_dup 1)
13445 (label_ref (match_operand 0 "" ""))
13448 "ix86_expand_branch (NE, operands[0]); DONE;")
13450 (define_expand "bgt"
13452 (if_then_else (match_dup 1)
13453 (label_ref (match_operand 0 "" ""))
13456 "ix86_expand_branch (GT, operands[0]); DONE;")
13458 (define_expand "bgtu"
13460 (if_then_else (match_dup 1)
13461 (label_ref (match_operand 0 "" ""))
13464 "ix86_expand_branch (GTU, operands[0]); DONE;")
13466 (define_expand "blt"
13468 (if_then_else (match_dup 1)
13469 (label_ref (match_operand 0 "" ""))
13472 "ix86_expand_branch (LT, operands[0]); DONE;")
13474 (define_expand "bltu"
13476 (if_then_else (match_dup 1)
13477 (label_ref (match_operand 0 "" ""))
13480 "ix86_expand_branch (LTU, operands[0]); DONE;")
13482 (define_expand "bge"
13484 (if_then_else (match_dup 1)
13485 (label_ref (match_operand 0 "" ""))
13488 "ix86_expand_branch (GE, operands[0]); DONE;")
13490 (define_expand "bgeu"
13492 (if_then_else (match_dup 1)
13493 (label_ref (match_operand 0 "" ""))
13496 "ix86_expand_branch (GEU, operands[0]); DONE;")
13498 (define_expand "ble"
13500 (if_then_else (match_dup 1)
13501 (label_ref (match_operand 0 "" ""))
13504 "ix86_expand_branch (LE, operands[0]); DONE;")
13506 (define_expand "bleu"
13508 (if_then_else (match_dup 1)
13509 (label_ref (match_operand 0 "" ""))
13512 "ix86_expand_branch (LEU, operands[0]); DONE;")
13514 (define_expand "bunordered"
13516 (if_then_else (match_dup 1)
13517 (label_ref (match_operand 0 "" ""))
13519 "TARGET_80387 || TARGET_SSE_MATH"
13520 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13522 (define_expand "bordered"
13524 (if_then_else (match_dup 1)
13525 (label_ref (match_operand 0 "" ""))
13527 "TARGET_80387 || TARGET_SSE_MATH"
13528 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13530 (define_expand "buneq"
13532 (if_then_else (match_dup 1)
13533 (label_ref (match_operand 0 "" ""))
13535 "TARGET_80387 || TARGET_SSE_MATH"
13536 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13538 (define_expand "bunge"
13540 (if_then_else (match_dup 1)
13541 (label_ref (match_operand 0 "" ""))
13543 "TARGET_80387 || TARGET_SSE_MATH"
13544 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13546 (define_expand "bungt"
13548 (if_then_else (match_dup 1)
13549 (label_ref (match_operand 0 "" ""))
13551 "TARGET_80387 || TARGET_SSE_MATH"
13552 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13554 (define_expand "bunle"
13556 (if_then_else (match_dup 1)
13557 (label_ref (match_operand 0 "" ""))
13559 "TARGET_80387 || TARGET_SSE_MATH"
13560 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13562 (define_expand "bunlt"
13564 (if_then_else (match_dup 1)
13565 (label_ref (match_operand 0 "" ""))
13567 "TARGET_80387 || TARGET_SSE_MATH"
13568 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13570 (define_expand "bltgt"
13572 (if_then_else (match_dup 1)
13573 (label_ref (match_operand 0 "" ""))
13575 "TARGET_80387 || TARGET_SSE_MATH"
13576 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13578 (define_insn "*jcc_1"
13580 (if_then_else (match_operator 1 "ix86_comparison_operator"
13581 [(reg FLAGS_REG) (const_int 0)])
13582 (label_ref (match_operand 0 "" ""))
13586 [(set_attr "type" "ibr")
13587 (set_attr "modrm" "0")
13588 (set (attr "length")
13589 (if_then_else (and (ge (minus (match_dup 0) (pc))
13591 (lt (minus (match_dup 0) (pc))
13596 (define_insn "*jcc_2"
13598 (if_then_else (match_operator 1 "ix86_comparison_operator"
13599 [(reg FLAGS_REG) (const_int 0)])
13601 (label_ref (match_operand 0 "" ""))))]
13604 [(set_attr "type" "ibr")
13605 (set_attr "modrm" "0")
13606 (set (attr "length")
13607 (if_then_else (and (ge (minus (match_dup 0) (pc))
13609 (lt (minus (match_dup 0) (pc))
13614 ;; In general it is not safe to assume too much about CCmode registers,
13615 ;; so simplify-rtx stops when it sees a second one. Under certain
13616 ;; conditions this is safe on x86, so help combine not create
13624 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13625 [(reg FLAGS_REG) (const_int 0)])
13627 (label_ref (match_operand 1 "" ""))
13631 (if_then_else (match_dup 0)
13632 (label_ref (match_dup 1))
13635 PUT_MODE (operands[0], VOIDmode);
13640 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13641 [(reg FLAGS_REG) (const_int 0)])
13643 (label_ref (match_operand 1 "" ""))
13647 (if_then_else (match_dup 0)
13648 (label_ref (match_dup 1))
13651 rtx new_op0 = copy_rtx (operands[0]);
13652 operands[0] = new_op0;
13653 PUT_MODE (new_op0, VOIDmode);
13654 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13655 GET_MODE (XEXP (new_op0, 0))));
13657 /* Make sure that (a) the CCmode we have for the flags is strong
13658 enough for the reversed compare or (b) we have a valid FP compare. */
13659 if (! ix86_comparison_operator (new_op0, VOIDmode))
13663 ;; Define combination compare-and-branch fp compare instructions to use
13664 ;; during early optimization. Splitting the operation apart early makes
13665 ;; for bad code when we want to reverse the operation.
13667 (define_insn "*fp_jcc_1_mixed"
13669 (if_then_else (match_operator 0 "comparison_operator"
13670 [(match_operand 1 "register_operand" "f,x")
13671 (match_operand 2 "nonimmediate_operand" "f,xm")])
13672 (label_ref (match_operand 3 "" ""))
13674 (clobber (reg:CCFP FPSR_REG))
13675 (clobber (reg:CCFP FLAGS_REG))]
13676 "TARGET_MIX_SSE_I387
13677 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13678 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13679 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13682 (define_insn "*fp_jcc_1_sse"
13684 (if_then_else (match_operator 0 "comparison_operator"
13685 [(match_operand 1 "register_operand" "x")
13686 (match_operand 2 "nonimmediate_operand" "xm")])
13687 (label_ref (match_operand 3 "" ""))
13689 (clobber (reg:CCFP FPSR_REG))
13690 (clobber (reg:CCFP FLAGS_REG))]
13692 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13693 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13694 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13697 (define_insn "*fp_jcc_1_387"
13699 (if_then_else (match_operator 0 "comparison_operator"
13700 [(match_operand 1 "register_operand" "f")
13701 (match_operand 2 "register_operand" "f")])
13702 (label_ref (match_operand 3 "" ""))
13704 (clobber (reg:CCFP FPSR_REG))
13705 (clobber (reg:CCFP FLAGS_REG))]
13706 "TARGET_CMOVE && TARGET_80387
13707 && FLOAT_MODE_P (GET_MODE (operands[1]))
13708 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13709 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13712 (define_insn "*fp_jcc_2_mixed"
13714 (if_then_else (match_operator 0 "comparison_operator"
13715 [(match_operand 1 "register_operand" "f,x")
13716 (match_operand 2 "nonimmediate_operand" "f,xm")])
13718 (label_ref (match_operand 3 "" ""))))
13719 (clobber (reg:CCFP FPSR_REG))
13720 (clobber (reg:CCFP FLAGS_REG))]
13721 "TARGET_MIX_SSE_I387
13722 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13723 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13724 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13727 (define_insn "*fp_jcc_2_sse"
13729 (if_then_else (match_operator 0 "comparison_operator"
13730 [(match_operand 1 "register_operand" "x")
13731 (match_operand 2 "nonimmediate_operand" "xm")])
13733 (label_ref (match_operand 3 "" ""))))
13734 (clobber (reg:CCFP FPSR_REG))
13735 (clobber (reg:CCFP FLAGS_REG))]
13737 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13738 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13739 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13742 (define_insn "*fp_jcc_2_387"
13744 (if_then_else (match_operator 0 "comparison_operator"
13745 [(match_operand 1 "register_operand" "f")
13746 (match_operand 2 "register_operand" "f")])
13748 (label_ref (match_operand 3 "" ""))))
13749 (clobber (reg:CCFP FPSR_REG))
13750 (clobber (reg:CCFP FLAGS_REG))]
13751 "TARGET_CMOVE && TARGET_80387
13752 && FLOAT_MODE_P (GET_MODE (operands[1]))
13753 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13754 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13757 (define_insn "*fp_jcc_3_387"
13759 (if_then_else (match_operator 0 "comparison_operator"
13760 [(match_operand 1 "register_operand" "f")
13761 (match_operand 2 "nonimmediate_operand" "fm")])
13762 (label_ref (match_operand 3 "" ""))
13764 (clobber (reg:CCFP FPSR_REG))
13765 (clobber (reg:CCFP FLAGS_REG))
13766 (clobber (match_scratch:HI 4 "=a"))]
13768 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13769 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13770 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13771 && SELECT_CC_MODE (GET_CODE (operands[0]),
13772 operands[1], operands[2]) == CCFPmode
13773 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13776 (define_insn "*fp_jcc_4_387"
13778 (if_then_else (match_operator 0 "comparison_operator"
13779 [(match_operand 1 "register_operand" "f")
13780 (match_operand 2 "nonimmediate_operand" "fm")])
13782 (label_ref (match_operand 3 "" ""))))
13783 (clobber (reg:CCFP FPSR_REG))
13784 (clobber (reg:CCFP FLAGS_REG))
13785 (clobber (match_scratch:HI 4 "=a"))]
13787 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13788 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13789 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13790 && SELECT_CC_MODE (GET_CODE (operands[0]),
13791 operands[1], operands[2]) == CCFPmode
13792 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13795 (define_insn "*fp_jcc_5_387"
13797 (if_then_else (match_operator 0 "comparison_operator"
13798 [(match_operand 1 "register_operand" "f")
13799 (match_operand 2 "register_operand" "f")])
13800 (label_ref (match_operand 3 "" ""))
13802 (clobber (reg:CCFP FPSR_REG))
13803 (clobber (reg:CCFP FLAGS_REG))
13804 (clobber (match_scratch:HI 4 "=a"))]
13806 && FLOAT_MODE_P (GET_MODE (operands[1]))
13807 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13808 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13811 (define_insn "*fp_jcc_6_387"
13813 (if_then_else (match_operator 0 "comparison_operator"
13814 [(match_operand 1 "register_operand" "f")
13815 (match_operand 2 "register_operand" "f")])
13817 (label_ref (match_operand 3 "" ""))))
13818 (clobber (reg:CCFP FPSR_REG))
13819 (clobber (reg:CCFP FLAGS_REG))
13820 (clobber (match_scratch:HI 4 "=a"))]
13822 && FLOAT_MODE_P (GET_MODE (operands[1]))
13823 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13824 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13827 (define_insn "*fp_jcc_7_387"
13829 (if_then_else (match_operator 0 "comparison_operator"
13830 [(match_operand 1 "register_operand" "f")
13831 (match_operand 2 "const0_operand" "X")])
13832 (label_ref (match_operand 3 "" ""))
13834 (clobber (reg:CCFP FPSR_REG))
13835 (clobber (reg:CCFP FLAGS_REG))
13836 (clobber (match_scratch:HI 4 "=a"))]
13838 && FLOAT_MODE_P (GET_MODE (operands[1]))
13839 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13840 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13841 && SELECT_CC_MODE (GET_CODE (operands[0]),
13842 operands[1], operands[2]) == CCFPmode
13843 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13846 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13847 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13848 ;; with a precedence over other operators and is always put in the first
13849 ;; place. Swap condition and operands to match ficom instruction.
13851 (define_insn "*fp_jcc_8<mode>_387"
13853 (if_then_else (match_operator 0 "comparison_operator"
13854 [(match_operator 1 "float_operator"
13855 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13856 (match_operand 3 "register_operand" "f,f")])
13857 (label_ref (match_operand 4 "" ""))
13859 (clobber (reg:CCFP FPSR_REG))
13860 (clobber (reg:CCFP FLAGS_REG))
13861 (clobber (match_scratch:HI 5 "=a,a"))]
13862 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13863 && FLOAT_MODE_P (GET_MODE (operands[3]))
13864 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13865 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13866 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13867 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13872 (if_then_else (match_operator 0 "comparison_operator"
13873 [(match_operand 1 "register_operand" "")
13874 (match_operand 2 "nonimmediate_operand" "")])
13875 (match_operand 3 "" "")
13876 (match_operand 4 "" "")))
13877 (clobber (reg:CCFP FPSR_REG))
13878 (clobber (reg:CCFP FLAGS_REG))]
13882 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13883 operands[3], operands[4], NULL_RTX, NULL_RTX);
13889 (if_then_else (match_operator 0 "comparison_operator"
13890 [(match_operand 1 "register_operand" "")
13891 (match_operand 2 "general_operand" "")])
13892 (match_operand 3 "" "")
13893 (match_operand 4 "" "")))
13894 (clobber (reg:CCFP FPSR_REG))
13895 (clobber (reg:CCFP FLAGS_REG))
13896 (clobber (match_scratch:HI 5 "=a"))]
13900 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13901 operands[3], operands[4], operands[5], NULL_RTX);
13907 (if_then_else (match_operator 0 "comparison_operator"
13908 [(match_operator 1 "float_operator"
13909 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13910 (match_operand 3 "register_operand" "")])
13911 (match_operand 4 "" "")
13912 (match_operand 5 "" "")))
13913 (clobber (reg:CCFP FPSR_REG))
13914 (clobber (reg:CCFP FLAGS_REG))
13915 (clobber (match_scratch:HI 6 "=a"))]
13919 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13920 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13921 operands[3], operands[7],
13922 operands[4], operands[5], operands[6], NULL_RTX);
13926 ;; %%% Kill this when reload knows how to do it.
13929 (if_then_else (match_operator 0 "comparison_operator"
13930 [(match_operator 1 "float_operator"
13931 [(match_operand:X87MODEI12 2 "register_operand" "")])
13932 (match_operand 3 "register_operand" "")])
13933 (match_operand 4 "" "")
13934 (match_operand 5 "" "")))
13935 (clobber (reg:CCFP FPSR_REG))
13936 (clobber (reg:CCFP FLAGS_REG))
13937 (clobber (match_scratch:HI 6 "=a"))]
13941 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13942 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13943 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13944 operands[3], operands[7],
13945 operands[4], operands[5], operands[6], operands[2]);
13949 ;; Unconditional and other jump instructions
13951 (define_insn "jump"
13953 (label_ref (match_operand 0 "" "")))]
13956 [(set_attr "type" "ibr")
13957 (set (attr "length")
13958 (if_then_else (and (ge (minus (match_dup 0) (pc))
13960 (lt (minus (match_dup 0) (pc))
13964 (set_attr "modrm" "0")])
13966 (define_expand "indirect_jump"
13967 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13971 (define_insn "*indirect_jump"
13972 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13975 [(set_attr "type" "ibr")
13976 (set_attr "length_immediate" "0")])
13978 (define_insn "*indirect_jump_rtx64"
13979 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13982 [(set_attr "type" "ibr")
13983 (set_attr "length_immediate" "0")])
13985 (define_expand "tablejump"
13986 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13987 (use (label_ref (match_operand 1 "" "")))])]
13990 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13991 relative. Convert the relative address to an absolute address. */
13995 enum rtx_code code;
14001 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14003 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14007 op1 = pic_offset_table_rtx;
14012 op0 = pic_offset_table_rtx;
14016 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14021 (define_insn "*tablejump_1"
14022 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14023 (use (label_ref (match_operand 1 "" "")))]
14026 [(set_attr "type" "ibr")
14027 (set_attr "length_immediate" "0")])
14029 (define_insn "*tablejump_1_rtx64"
14030 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14031 (use (label_ref (match_operand 1 "" "")))]
14034 [(set_attr "type" "ibr")
14035 (set_attr "length_immediate" "0")])
14037 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14040 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14041 (set (match_operand:QI 1 "register_operand" "")
14042 (match_operator:QI 2 "ix86_comparison_operator"
14043 [(reg FLAGS_REG) (const_int 0)]))
14044 (set (match_operand 3 "q_regs_operand" "")
14045 (zero_extend (match_dup 1)))]
14046 "(peep2_reg_dead_p (3, operands[1])
14047 || operands_match_p (operands[1], operands[3]))
14048 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14049 [(set (match_dup 4) (match_dup 0))
14050 (set (strict_low_part (match_dup 5))
14053 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14054 operands[5] = gen_lowpart (QImode, operands[3]);
14055 ix86_expand_clear (operands[3]);
14058 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14061 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14062 (set (match_operand:QI 1 "register_operand" "")
14063 (match_operator:QI 2 "ix86_comparison_operator"
14064 [(reg FLAGS_REG) (const_int 0)]))
14065 (parallel [(set (match_operand 3 "q_regs_operand" "")
14066 (zero_extend (match_dup 1)))
14067 (clobber (reg:CC FLAGS_REG))])]
14068 "(peep2_reg_dead_p (3, operands[1])
14069 || operands_match_p (operands[1], operands[3]))
14070 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14071 [(set (match_dup 4) (match_dup 0))
14072 (set (strict_low_part (match_dup 5))
14075 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14076 operands[5] = gen_lowpart (QImode, operands[3]);
14077 ix86_expand_clear (operands[3]);
14080 ;; Call instructions.
14082 ;; The predicates normally associated with named expanders are not properly
14083 ;; checked for calls. This is a bug in the generic code, but it isn't that
14084 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14086 ;; Call subroutine returning no value.
14088 (define_expand "call_pop"
14089 [(parallel [(call (match_operand:QI 0 "" "")
14090 (match_operand:SI 1 "" ""))
14091 (set (reg:SI SP_REG)
14092 (plus:SI (reg:SI SP_REG)
14093 (match_operand:SI 3 "" "")))])]
14096 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14100 (define_insn "*call_pop_0"
14101 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14102 (match_operand:SI 1 "" ""))
14103 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14104 (match_operand:SI 2 "immediate_operand" "")))]
14107 if (SIBLING_CALL_P (insn))
14110 return "call\t%P0";
14112 [(set_attr "type" "call")])
14114 (define_insn "*call_pop_1"
14115 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14116 (match_operand:SI 1 "" ""))
14117 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14118 (match_operand:SI 2 "immediate_operand" "i")))]
14121 if (constant_call_address_operand (operands[0], Pmode))
14123 if (SIBLING_CALL_P (insn))
14126 return "call\t%P0";
14128 if (SIBLING_CALL_P (insn))
14131 return "call\t%A0";
14133 [(set_attr "type" "call")])
14135 (define_expand "call"
14136 [(call (match_operand:QI 0 "" "")
14137 (match_operand 1 "" ""))
14138 (use (match_operand 2 "" ""))]
14141 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14145 (define_expand "sibcall"
14146 [(call (match_operand:QI 0 "" "")
14147 (match_operand 1 "" ""))
14148 (use (match_operand 2 "" ""))]
14151 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14155 (define_insn "*call_0"
14156 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14157 (match_operand 1 "" ""))]
14160 if (SIBLING_CALL_P (insn))
14163 return "call\t%P0";
14165 [(set_attr "type" "call")])
14167 (define_insn "*call_1"
14168 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14169 (match_operand 1 "" ""))]
14170 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14172 if (constant_call_address_operand (operands[0], Pmode))
14173 return "call\t%P0";
14174 return "call\t%A0";
14176 [(set_attr "type" "call")])
14178 (define_insn "*sibcall_1"
14179 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14180 (match_operand 1 "" ""))]
14181 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14183 if (constant_call_address_operand (operands[0], Pmode))
14187 [(set_attr "type" "call")])
14189 (define_insn "*call_1_rex64"
14190 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14191 (match_operand 1 "" ""))]
14192 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14194 if (constant_call_address_operand (operands[0], Pmode))
14195 return "call\t%P0";
14196 return "call\t%A0";
14198 [(set_attr "type" "call")])
14200 (define_insn "*sibcall_1_rex64"
14201 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14202 (match_operand 1 "" ""))]
14203 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14205 [(set_attr "type" "call")])
14207 (define_insn "*sibcall_1_rex64_v"
14208 [(call (mem:QI (reg:DI R11_REG))
14209 (match_operand 0 "" ""))]
14210 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14212 [(set_attr "type" "call")])
14215 ;; Call subroutine, returning value in operand 0
14217 (define_expand "call_value_pop"
14218 [(parallel [(set (match_operand 0 "" "")
14219 (call (match_operand:QI 1 "" "")
14220 (match_operand:SI 2 "" "")))
14221 (set (reg:SI SP_REG)
14222 (plus:SI (reg:SI SP_REG)
14223 (match_operand:SI 4 "" "")))])]
14226 ix86_expand_call (operands[0], operands[1], operands[2],
14227 operands[3], operands[4], 0);
14231 (define_expand "call_value"
14232 [(set (match_operand 0 "" "")
14233 (call (match_operand:QI 1 "" "")
14234 (match_operand:SI 2 "" "")))
14235 (use (match_operand:SI 3 "" ""))]
14236 ;; Operand 2 not used on the i386.
14239 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14243 (define_expand "sibcall_value"
14244 [(set (match_operand 0 "" "")
14245 (call (match_operand:QI 1 "" "")
14246 (match_operand:SI 2 "" "")))
14247 (use (match_operand:SI 3 "" ""))]
14248 ;; Operand 2 not used on the i386.
14251 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14255 ;; Call subroutine returning any type.
14257 (define_expand "untyped_call"
14258 [(parallel [(call (match_operand 0 "" "")
14260 (match_operand 1 "" "")
14261 (match_operand 2 "" "")])]
14266 /* In order to give reg-stack an easier job in validating two
14267 coprocessor registers as containing a possible return value,
14268 simply pretend the untyped call returns a complex long double
14271 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14272 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14273 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14276 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14278 rtx set = XVECEXP (operands[2], 0, i);
14279 emit_move_insn (SET_DEST (set), SET_SRC (set));
14282 /* The optimizer does not know that the call sets the function value
14283 registers we stored in the result block. We avoid problems by
14284 claiming that all hard registers are used and clobbered at this
14286 emit_insn (gen_blockage (const0_rtx));
14291 ;; Prologue and epilogue instructions
14293 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14294 ;; all of memory. This blocks insns from being moved across this point.
14296 (define_insn "blockage"
14297 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14300 [(set_attr "length" "0")])
14302 ;; Insn emitted into the body of a function to return from a function.
14303 ;; This is only done if the function's epilogue is known to be simple.
14304 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14306 (define_expand "return"
14308 "ix86_can_use_return_insn_p ()"
14310 if (current_function_pops_args)
14312 rtx popc = GEN_INT (current_function_pops_args);
14313 emit_jump_insn (gen_return_pop_internal (popc));
14318 (define_insn "return_internal"
14322 [(set_attr "length" "1")
14323 (set_attr "length_immediate" "0")
14324 (set_attr "modrm" "0")])
14326 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14327 ;; instruction Athlon and K8 have.
14329 (define_insn "return_internal_long"
14331 (unspec [(const_int 0)] UNSPEC_REP)]
14334 [(set_attr "length" "1")
14335 (set_attr "length_immediate" "0")
14336 (set_attr "prefix_rep" "1")
14337 (set_attr "modrm" "0")])
14339 (define_insn "return_pop_internal"
14341 (use (match_operand:SI 0 "const_int_operand" ""))]
14344 [(set_attr "length" "3")
14345 (set_attr "length_immediate" "2")
14346 (set_attr "modrm" "0")])
14348 (define_insn "return_indirect_internal"
14350 (use (match_operand:SI 0 "register_operand" "r"))]
14353 [(set_attr "type" "ibr")
14354 (set_attr "length_immediate" "0")])
14360 [(set_attr "length" "1")
14361 (set_attr "length_immediate" "0")
14362 (set_attr "modrm" "0")])
14364 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14365 ;; branch prediction penalty for the third jump in a 16-byte
14368 (define_insn "align"
14369 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14372 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14373 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14375 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14376 The align insn is used to avoid 3 jump instructions in the row to improve
14377 branch prediction and the benefits hardly outweigh the cost of extra 8
14378 nops on the average inserted by full alignment pseudo operation. */
14382 [(set_attr "length" "16")])
14384 (define_expand "prologue"
14387 "ix86_expand_prologue (); DONE;")
14389 (define_insn "set_got"
14390 [(set (match_operand:SI 0 "register_operand" "=r")
14391 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14392 (clobber (reg:CC FLAGS_REG))]
14394 { return output_set_got (operands[0], NULL_RTX); }
14395 [(set_attr "type" "multi")
14396 (set_attr "length" "12")])
14398 (define_insn "set_got_labelled"
14399 [(set (match_operand:SI 0 "register_operand" "=r")
14400 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14402 (clobber (reg:CC FLAGS_REG))]
14404 { return output_set_got (operands[0], operands[1]); }
14405 [(set_attr "type" "multi")
14406 (set_attr "length" "12")])
14408 (define_insn "set_got_rex64"
14409 [(set (match_operand:DI 0 "register_operand" "=r")
14410 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14412 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14413 [(set_attr "type" "lea")
14414 (set_attr "length" "6")])
14416 (define_expand "epilogue"
14419 "ix86_expand_epilogue (1); DONE;")
14421 (define_expand "sibcall_epilogue"
14424 "ix86_expand_epilogue (0); DONE;")
14426 (define_expand "eh_return"
14427 [(use (match_operand 0 "register_operand" ""))]
14430 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14432 /* Tricky bit: we write the address of the handler to which we will
14433 be returning into someone else's stack frame, one word below the
14434 stack address we wish to restore. */
14435 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14436 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14437 tmp = gen_rtx_MEM (Pmode, tmp);
14438 emit_move_insn (tmp, ra);
14440 if (Pmode == SImode)
14441 emit_jump_insn (gen_eh_return_si (sa));
14443 emit_jump_insn (gen_eh_return_di (sa));
14448 (define_insn_and_split "eh_return_si"
14450 (unspec [(match_operand:SI 0 "register_operand" "c")]
14451 UNSPEC_EH_RETURN))]
14456 "ix86_expand_epilogue (2); DONE;")
14458 (define_insn_and_split "eh_return_di"
14460 (unspec [(match_operand:DI 0 "register_operand" "c")]
14461 UNSPEC_EH_RETURN))]
14466 "ix86_expand_epilogue (2); DONE;")
14468 (define_insn "leave"
14469 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14470 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14471 (clobber (mem:BLK (scratch)))]
14474 [(set_attr "type" "leave")])
14476 (define_insn "leave_rex64"
14477 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14478 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14479 (clobber (mem:BLK (scratch)))]
14482 [(set_attr "type" "leave")])
14484 (define_expand "ffssi2"
14486 [(set (match_operand:SI 0 "register_operand" "")
14487 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14488 (clobber (match_scratch:SI 2 ""))
14489 (clobber (reg:CC FLAGS_REG))])]
14493 (define_insn_and_split "*ffs_cmove"
14494 [(set (match_operand:SI 0 "register_operand" "=r")
14495 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14496 (clobber (match_scratch:SI 2 "=&r"))
14497 (clobber (reg:CC FLAGS_REG))]
14500 "&& reload_completed"
14501 [(set (match_dup 2) (const_int -1))
14502 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14503 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14504 (set (match_dup 0) (if_then_else:SI
14505 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14508 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14509 (clobber (reg:CC FLAGS_REG))])]
14512 (define_insn_and_split "*ffs_no_cmove"
14513 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14514 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14515 (clobber (match_scratch:SI 2 "=&q"))
14516 (clobber (reg:CC FLAGS_REG))]
14520 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14521 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14522 (set (strict_low_part (match_dup 3))
14523 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14524 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14525 (clobber (reg:CC FLAGS_REG))])
14526 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14527 (clobber (reg:CC FLAGS_REG))])
14528 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14529 (clobber (reg:CC FLAGS_REG))])]
14531 operands[3] = gen_lowpart (QImode, operands[2]);
14532 ix86_expand_clear (operands[2]);
14535 (define_insn "*ffssi_1"
14536 [(set (reg:CCZ FLAGS_REG)
14537 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14539 (set (match_operand:SI 0 "register_operand" "=r")
14540 (ctz:SI (match_dup 1)))]
14542 "bsf{l}\t{%1, %0|%0, %1}"
14543 [(set_attr "prefix_0f" "1")])
14545 (define_expand "ffsdi2"
14547 [(set (match_operand:DI 0 "register_operand" "")
14548 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14549 (clobber (match_scratch:DI 2 ""))
14550 (clobber (reg:CC FLAGS_REG))])]
14551 "TARGET_64BIT && TARGET_CMOVE"
14554 (define_insn_and_split "*ffs_rex64"
14555 [(set (match_operand:DI 0 "register_operand" "=r")
14556 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14557 (clobber (match_scratch:DI 2 "=&r"))
14558 (clobber (reg:CC FLAGS_REG))]
14559 "TARGET_64BIT && TARGET_CMOVE"
14561 "&& reload_completed"
14562 [(set (match_dup 2) (const_int -1))
14563 (parallel [(set (reg:CCZ FLAGS_REG)
14564 (compare:CCZ (match_dup 1) (const_int 0)))
14565 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14566 (set (match_dup 0) (if_then_else:DI
14567 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14570 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14571 (clobber (reg:CC FLAGS_REG))])]
14574 (define_insn "*ffsdi_1"
14575 [(set (reg:CCZ FLAGS_REG)
14576 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14578 (set (match_operand:DI 0 "register_operand" "=r")
14579 (ctz:DI (match_dup 1)))]
14581 "bsf{q}\t{%1, %0|%0, %1}"
14582 [(set_attr "prefix_0f" "1")])
14584 (define_insn "ctzsi2"
14585 [(set (match_operand:SI 0 "register_operand" "=r")
14586 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14587 (clobber (reg:CC FLAGS_REG))]
14589 "bsf{l}\t{%1, %0|%0, %1}"
14590 [(set_attr "prefix_0f" "1")])
14592 (define_insn "ctzdi2"
14593 [(set (match_operand:DI 0 "register_operand" "=r")
14594 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14595 (clobber (reg:CC FLAGS_REG))]
14597 "bsf{q}\t{%1, %0|%0, %1}"
14598 [(set_attr "prefix_0f" "1")])
14600 (define_expand "clzsi2"
14602 [(set (match_operand:SI 0 "register_operand" "")
14603 (minus:SI (const_int 31)
14604 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14605 (clobber (reg:CC FLAGS_REG))])
14607 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14608 (clobber (reg:CC FLAGS_REG))])]
14612 (define_insn "*bsr"
14613 [(set (match_operand:SI 0 "register_operand" "=r")
14614 (minus:SI (const_int 31)
14615 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14616 (clobber (reg:CC FLAGS_REG))]
14618 "bsr{l}\t{%1, %0|%0, %1}"
14619 [(set_attr "prefix_0f" "1")])
14621 (define_insn "bswapsi2"
14622 [(set (match_operand:SI 0 "register_operand" "=r")
14623 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14624 (clobber (reg:CC FLAGS_REG))]
14627 [(set_attr "prefix_0f" "1")
14628 (set_attr "length" "2")])
14630 (define_insn "bswapdi2"
14631 [(set (match_operand:DI 0 "register_operand" "=r")
14632 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14633 (clobber (reg:CC FLAGS_REG))]
14634 "TARGET_64BIT && TARGET_BSWAP"
14636 [(set_attr "prefix_0f" "1")
14637 (set_attr "length" "3")])
14639 (define_expand "clzdi2"
14641 [(set (match_operand:DI 0 "register_operand" "")
14642 (minus:DI (const_int 63)
14643 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14644 (clobber (reg:CC FLAGS_REG))])
14646 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14647 (clobber (reg:CC FLAGS_REG))])]
14651 (define_insn "*bsr_rex64"
14652 [(set (match_operand:DI 0 "register_operand" "=r")
14653 (minus:DI (const_int 63)
14654 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14655 (clobber (reg:CC FLAGS_REG))]
14657 "bsr{q}\t{%1, %0|%0, %1}"
14658 [(set_attr "prefix_0f" "1")])
14660 ;; Thread-local storage patterns for ELF.
14662 ;; Note that these code sequences must appear exactly as shown
14663 ;; in order to allow linker relaxation.
14665 (define_insn "*tls_global_dynamic_32_gnu"
14666 [(set (match_operand:SI 0 "register_operand" "=a")
14667 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14668 (match_operand:SI 2 "tls_symbolic_operand" "")
14669 (match_operand:SI 3 "call_insn_operand" "")]
14671 (clobber (match_scratch:SI 4 "=d"))
14672 (clobber (match_scratch:SI 5 "=c"))
14673 (clobber (reg:CC FLAGS_REG))]
14674 "!TARGET_64BIT && TARGET_GNU_TLS"
14675 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14676 [(set_attr "type" "multi")
14677 (set_attr "length" "12")])
14679 (define_insn "*tls_global_dynamic_32_sun"
14680 [(set (match_operand:SI 0 "register_operand" "=a")
14681 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14682 (match_operand:SI 2 "tls_symbolic_operand" "")
14683 (match_operand:SI 3 "call_insn_operand" "")]
14685 (clobber (match_scratch:SI 4 "=d"))
14686 (clobber (match_scratch:SI 5 "=c"))
14687 (clobber (reg:CC FLAGS_REG))]
14688 "!TARGET_64BIT && TARGET_SUN_TLS"
14689 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14690 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14691 [(set_attr "type" "multi")
14692 (set_attr "length" "14")])
14694 (define_expand "tls_global_dynamic_32"
14695 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14698 (match_operand:SI 1 "tls_symbolic_operand" "")
14701 (clobber (match_scratch:SI 4 ""))
14702 (clobber (match_scratch:SI 5 ""))
14703 (clobber (reg:CC FLAGS_REG))])]
14707 operands[2] = pic_offset_table_rtx;
14710 operands[2] = gen_reg_rtx (Pmode);
14711 emit_insn (gen_set_got (operands[2]));
14713 if (TARGET_GNU2_TLS)
14715 emit_insn (gen_tls_dynamic_gnu2_32
14716 (operands[0], operands[1], operands[2]));
14719 operands[3] = ix86_tls_get_addr ();
14722 (define_insn "*tls_global_dynamic_64"
14723 [(set (match_operand:DI 0 "register_operand" "=a")
14724 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14725 (match_operand:DI 3 "" "")))
14726 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14729 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14730 [(set_attr "type" "multi")
14731 (set_attr "length" "16")])
14733 (define_expand "tls_global_dynamic_64"
14734 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14735 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14736 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14740 if (TARGET_GNU2_TLS)
14742 emit_insn (gen_tls_dynamic_gnu2_64
14743 (operands[0], operands[1]));
14746 operands[2] = ix86_tls_get_addr ();
14749 (define_insn "*tls_local_dynamic_base_32_gnu"
14750 [(set (match_operand:SI 0 "register_operand" "=a")
14751 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14752 (match_operand:SI 2 "call_insn_operand" "")]
14753 UNSPEC_TLS_LD_BASE))
14754 (clobber (match_scratch:SI 3 "=d"))
14755 (clobber (match_scratch:SI 4 "=c"))
14756 (clobber (reg:CC FLAGS_REG))]
14757 "!TARGET_64BIT && TARGET_GNU_TLS"
14758 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14759 [(set_attr "type" "multi")
14760 (set_attr "length" "11")])
14762 (define_insn "*tls_local_dynamic_base_32_sun"
14763 [(set (match_operand:SI 0 "register_operand" "=a")
14764 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14765 (match_operand:SI 2 "call_insn_operand" "")]
14766 UNSPEC_TLS_LD_BASE))
14767 (clobber (match_scratch:SI 3 "=d"))
14768 (clobber (match_scratch:SI 4 "=c"))
14769 (clobber (reg:CC FLAGS_REG))]
14770 "!TARGET_64BIT && TARGET_SUN_TLS"
14771 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14772 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14773 [(set_attr "type" "multi")
14774 (set_attr "length" "13")])
14776 (define_expand "tls_local_dynamic_base_32"
14777 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14778 (unspec:SI [(match_dup 1) (match_dup 2)]
14779 UNSPEC_TLS_LD_BASE))
14780 (clobber (match_scratch:SI 3 ""))
14781 (clobber (match_scratch:SI 4 ""))
14782 (clobber (reg:CC FLAGS_REG))])]
14786 operands[1] = pic_offset_table_rtx;
14789 operands[1] = gen_reg_rtx (Pmode);
14790 emit_insn (gen_set_got (operands[1]));
14792 if (TARGET_GNU2_TLS)
14794 emit_insn (gen_tls_dynamic_gnu2_32
14795 (operands[0], ix86_tls_module_base (), operands[1]));
14798 operands[2] = ix86_tls_get_addr ();
14801 (define_insn "*tls_local_dynamic_base_64"
14802 [(set (match_operand:DI 0 "register_operand" "=a")
14803 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14804 (match_operand:DI 2 "" "")))
14805 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14807 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14808 [(set_attr "type" "multi")
14809 (set_attr "length" "12")])
14811 (define_expand "tls_local_dynamic_base_64"
14812 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14813 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14814 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14817 if (TARGET_GNU2_TLS)
14819 emit_insn (gen_tls_dynamic_gnu2_64
14820 (operands[0], ix86_tls_module_base ()));
14823 operands[1] = ix86_tls_get_addr ();
14826 ;; Local dynamic of a single variable is a lose. Show combine how
14827 ;; to convert that back to global dynamic.
14829 (define_insn_and_split "*tls_local_dynamic_32_once"
14830 [(set (match_operand:SI 0 "register_operand" "=a")
14831 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14832 (match_operand:SI 2 "call_insn_operand" "")]
14833 UNSPEC_TLS_LD_BASE)
14834 (const:SI (unspec:SI
14835 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14837 (clobber (match_scratch:SI 4 "=d"))
14838 (clobber (match_scratch:SI 5 "=c"))
14839 (clobber (reg:CC FLAGS_REG))]
14843 [(parallel [(set (match_dup 0)
14844 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14846 (clobber (match_dup 4))
14847 (clobber (match_dup 5))
14848 (clobber (reg:CC FLAGS_REG))])]
14851 ;; Load and add the thread base pointer from %gs:0.
14853 (define_insn "*load_tp_si"
14854 [(set (match_operand:SI 0 "register_operand" "=r")
14855 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14857 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14858 [(set_attr "type" "imov")
14859 (set_attr "modrm" "0")
14860 (set_attr "length" "7")
14861 (set_attr "memory" "load")
14862 (set_attr "imm_disp" "false")])
14864 (define_insn "*add_tp_si"
14865 [(set (match_operand:SI 0 "register_operand" "=r")
14866 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14867 (match_operand:SI 1 "register_operand" "0")))
14868 (clobber (reg:CC FLAGS_REG))]
14870 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14871 [(set_attr "type" "alu")
14872 (set_attr "modrm" "0")
14873 (set_attr "length" "7")
14874 (set_attr "memory" "load")
14875 (set_attr "imm_disp" "false")])
14877 (define_insn "*load_tp_di"
14878 [(set (match_operand:DI 0 "register_operand" "=r")
14879 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14881 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14882 [(set_attr "type" "imov")
14883 (set_attr "modrm" "0")
14884 (set_attr "length" "7")
14885 (set_attr "memory" "load")
14886 (set_attr "imm_disp" "false")])
14888 (define_insn "*add_tp_di"
14889 [(set (match_operand:DI 0 "register_operand" "=r")
14890 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14891 (match_operand:DI 1 "register_operand" "0")))
14892 (clobber (reg:CC FLAGS_REG))]
14894 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14895 [(set_attr "type" "alu")
14896 (set_attr "modrm" "0")
14897 (set_attr "length" "7")
14898 (set_attr "memory" "load")
14899 (set_attr "imm_disp" "false")])
14901 ;; GNU2 TLS patterns can be split.
14903 (define_expand "tls_dynamic_gnu2_32"
14904 [(set (match_dup 3)
14905 (plus:SI (match_operand:SI 2 "register_operand" "")
14907 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14910 [(set (match_operand:SI 0 "register_operand" "")
14911 (unspec:SI [(match_dup 1) (match_dup 3)
14912 (match_dup 2) (reg:SI SP_REG)]
14914 (clobber (reg:CC FLAGS_REG))])]
14915 "!TARGET_64BIT && TARGET_GNU2_TLS"
14917 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14918 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14921 (define_insn "*tls_dynamic_lea_32"
14922 [(set (match_operand:SI 0 "register_operand" "=r")
14923 (plus:SI (match_operand:SI 1 "register_operand" "b")
14925 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14926 UNSPEC_TLSDESC))))]
14927 "!TARGET_64BIT && TARGET_GNU2_TLS"
14928 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14929 [(set_attr "type" "lea")
14930 (set_attr "mode" "SI")
14931 (set_attr "length" "6")
14932 (set_attr "length_address" "4")])
14934 (define_insn "*tls_dynamic_call_32"
14935 [(set (match_operand:SI 0 "register_operand" "=a")
14936 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14937 (match_operand:SI 2 "register_operand" "0")
14938 ;; we have to make sure %ebx still points to the GOT
14939 (match_operand:SI 3 "register_operand" "b")
14942 (clobber (reg:CC FLAGS_REG))]
14943 "!TARGET_64BIT && TARGET_GNU2_TLS"
14944 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14945 [(set_attr "type" "call")
14946 (set_attr "length" "2")
14947 (set_attr "length_address" "0")])
14949 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14950 [(set (match_operand:SI 0 "register_operand" "=&a")
14952 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14953 (match_operand:SI 4 "" "")
14954 (match_operand:SI 2 "register_operand" "b")
14957 (const:SI (unspec:SI
14958 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14960 (clobber (reg:CC FLAGS_REG))]
14961 "!TARGET_64BIT && TARGET_GNU2_TLS"
14964 [(set (match_dup 0) (match_dup 5))]
14966 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14967 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14970 (define_expand "tls_dynamic_gnu2_64"
14971 [(set (match_dup 2)
14972 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14975 [(set (match_operand:DI 0 "register_operand" "")
14976 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14978 (clobber (reg:CC FLAGS_REG))])]
14979 "TARGET_64BIT && TARGET_GNU2_TLS"
14981 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14982 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14985 (define_insn "*tls_dynamic_lea_64"
14986 [(set (match_operand:DI 0 "register_operand" "=r")
14987 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14989 "TARGET_64BIT && TARGET_GNU2_TLS"
14990 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14991 [(set_attr "type" "lea")
14992 (set_attr "mode" "DI")
14993 (set_attr "length" "7")
14994 (set_attr "length_address" "4")])
14996 (define_insn "*tls_dynamic_call_64"
14997 [(set (match_operand:DI 0 "register_operand" "=a")
14998 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14999 (match_operand:DI 2 "register_operand" "0")
15002 (clobber (reg:CC FLAGS_REG))]
15003 "TARGET_64BIT && TARGET_GNU2_TLS"
15004 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15005 [(set_attr "type" "call")
15006 (set_attr "length" "2")
15007 (set_attr "length_address" "0")])
15009 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15010 [(set (match_operand:DI 0 "register_operand" "=&a")
15012 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15013 (match_operand:DI 3 "" "")
15016 (const:DI (unspec:DI
15017 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15019 (clobber (reg:CC FLAGS_REG))]
15020 "TARGET_64BIT && TARGET_GNU2_TLS"
15023 [(set (match_dup 0) (match_dup 4))]
15025 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15026 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15031 ;; These patterns match the binary 387 instructions for addM3, subM3,
15032 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15033 ;; SFmode. The first is the normal insn, the second the same insn but
15034 ;; with one operand a conversion, and the third the same insn but with
15035 ;; the other operand a conversion. The conversion may be SFmode or
15036 ;; SImode if the target mode DFmode, but only SImode if the target mode
15039 ;; Gcc is slightly more smart about handling normal two address instructions
15040 ;; so use special patterns for add and mull.
15042 (define_insn "*fop_sf_comm_mixed"
15043 [(set (match_operand:SF 0 "register_operand" "=f,x")
15044 (match_operator:SF 3 "binary_fp_operator"
15045 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15046 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15047 "TARGET_MIX_SSE_I387
15048 && COMMUTATIVE_ARITH_P (operands[3])
15049 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15050 "* return output_387_binary_op (insn, operands);"
15051 [(set (attr "type")
15052 (if_then_else (eq_attr "alternative" "1")
15053 (if_then_else (match_operand:SF 3 "mult_operator" "")
15054 (const_string "ssemul")
15055 (const_string "sseadd"))
15056 (if_then_else (match_operand:SF 3 "mult_operator" "")
15057 (const_string "fmul")
15058 (const_string "fop"))))
15059 (set_attr "mode" "SF")])
15061 (define_insn "*fop_sf_comm_sse"
15062 [(set (match_operand:SF 0 "register_operand" "=x")
15063 (match_operator:SF 3 "binary_fp_operator"
15064 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15065 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15067 && COMMUTATIVE_ARITH_P (operands[3])
15068 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15069 "* return output_387_binary_op (insn, operands);"
15070 [(set (attr "type")
15071 (if_then_else (match_operand:SF 3 "mult_operator" "")
15072 (const_string "ssemul")
15073 (const_string "sseadd")))
15074 (set_attr "mode" "SF")])
15076 (define_insn "*fop_sf_comm_i387"
15077 [(set (match_operand:SF 0 "register_operand" "=f")
15078 (match_operator:SF 3 "binary_fp_operator"
15079 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15080 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15082 && COMMUTATIVE_ARITH_P (operands[3])
15083 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15084 "* return output_387_binary_op (insn, operands);"
15085 [(set (attr "type")
15086 (if_then_else (match_operand:SF 3 "mult_operator" "")
15087 (const_string "fmul")
15088 (const_string "fop")))
15089 (set_attr "mode" "SF")])
15091 (define_insn "*fop_sf_1_mixed"
15092 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15093 (match_operator:SF 3 "binary_fp_operator"
15094 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15095 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15096 "TARGET_MIX_SSE_I387
15097 && !COMMUTATIVE_ARITH_P (operands[3])
15098 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15099 "* return output_387_binary_op (insn, operands);"
15100 [(set (attr "type")
15101 (cond [(and (eq_attr "alternative" "2")
15102 (match_operand:SF 3 "mult_operator" ""))
15103 (const_string "ssemul")
15104 (and (eq_attr "alternative" "2")
15105 (match_operand:SF 3 "div_operator" ""))
15106 (const_string "ssediv")
15107 (eq_attr "alternative" "2")
15108 (const_string "sseadd")
15109 (match_operand:SF 3 "mult_operator" "")
15110 (const_string "fmul")
15111 (match_operand:SF 3 "div_operator" "")
15112 (const_string "fdiv")
15114 (const_string "fop")))
15115 (set_attr "mode" "SF")])
15117 (define_insn "*fop_sf_1_sse"
15118 [(set (match_operand:SF 0 "register_operand" "=x")
15119 (match_operator:SF 3 "binary_fp_operator"
15120 [(match_operand:SF 1 "register_operand" "0")
15121 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15123 && !COMMUTATIVE_ARITH_P (operands[3])"
15124 "* return output_387_binary_op (insn, operands);"
15125 [(set (attr "type")
15126 (cond [(match_operand:SF 3 "mult_operator" "")
15127 (const_string "ssemul")
15128 (match_operand:SF 3 "div_operator" "")
15129 (const_string "ssediv")
15131 (const_string "sseadd")))
15132 (set_attr "mode" "SF")])
15134 ;; This pattern is not fully shadowed by the pattern above.
15135 (define_insn "*fop_sf_1_i387"
15136 [(set (match_operand:SF 0 "register_operand" "=f,f")
15137 (match_operator:SF 3 "binary_fp_operator"
15138 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15139 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15140 "TARGET_80387 && !TARGET_SSE_MATH
15141 && !COMMUTATIVE_ARITH_P (operands[3])
15142 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15143 "* return output_387_binary_op (insn, operands);"
15144 [(set (attr "type")
15145 (cond [(match_operand:SF 3 "mult_operator" "")
15146 (const_string "fmul")
15147 (match_operand:SF 3 "div_operator" "")
15148 (const_string "fdiv")
15150 (const_string "fop")))
15151 (set_attr "mode" "SF")])
15153 ;; ??? Add SSE splitters for these!
15154 (define_insn "*fop_sf_2<mode>_i387"
15155 [(set (match_operand:SF 0 "register_operand" "=f,f")
15156 (match_operator:SF 3 "binary_fp_operator"
15157 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15158 (match_operand:SF 2 "register_operand" "0,0")]))]
15159 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15160 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15161 [(set (attr "type")
15162 (cond [(match_operand:SF 3 "mult_operator" "")
15163 (const_string "fmul")
15164 (match_operand:SF 3 "div_operator" "")
15165 (const_string "fdiv")
15167 (const_string "fop")))
15168 (set_attr "fp_int_src" "true")
15169 (set_attr "mode" "<MODE>")])
15171 (define_insn "*fop_sf_3<mode>_i387"
15172 [(set (match_operand:SF 0 "register_operand" "=f,f")
15173 (match_operator:SF 3 "binary_fp_operator"
15174 [(match_operand:SF 1 "register_operand" "0,0")
15175 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15176 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15177 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15178 [(set (attr "type")
15179 (cond [(match_operand:SF 3 "mult_operator" "")
15180 (const_string "fmul")
15181 (match_operand:SF 3 "div_operator" "")
15182 (const_string "fdiv")
15184 (const_string "fop")))
15185 (set_attr "fp_int_src" "true")
15186 (set_attr "mode" "<MODE>")])
15188 (define_insn "*fop_df_comm_mixed"
15189 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15190 (match_operator:DF 3 "binary_fp_operator"
15191 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15192 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15193 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15194 && COMMUTATIVE_ARITH_P (operands[3])
15195 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15196 "* return output_387_binary_op (insn, operands);"
15197 [(set (attr "type")
15198 (if_then_else (eq_attr "alternative" "1")
15199 (if_then_else (match_operand:DF 3 "mult_operator" "")
15200 (const_string "ssemul")
15201 (const_string "sseadd"))
15202 (if_then_else (match_operand:DF 3 "mult_operator" "")
15203 (const_string "fmul")
15204 (const_string "fop"))))
15205 (set_attr "mode" "DF")])
15207 (define_insn "*fop_df_comm_sse"
15208 [(set (match_operand:DF 0 "register_operand" "=Y")
15209 (match_operator:DF 3 "binary_fp_operator"
15210 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15211 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15212 "TARGET_SSE2 && TARGET_SSE_MATH
15213 && COMMUTATIVE_ARITH_P (operands[3])
15214 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15215 "* return output_387_binary_op (insn, operands);"
15216 [(set (attr "type")
15217 (if_then_else (match_operand:DF 3 "mult_operator" "")
15218 (const_string "ssemul")
15219 (const_string "sseadd")))
15220 (set_attr "mode" "DF")])
15222 (define_insn "*fop_df_comm_i387"
15223 [(set (match_operand:DF 0 "register_operand" "=f")
15224 (match_operator:DF 3 "binary_fp_operator"
15225 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15226 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15228 && COMMUTATIVE_ARITH_P (operands[3])
15229 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15230 "* return output_387_binary_op (insn, operands);"
15231 [(set (attr "type")
15232 (if_then_else (match_operand:DF 3 "mult_operator" "")
15233 (const_string "fmul")
15234 (const_string "fop")))
15235 (set_attr "mode" "DF")])
15237 (define_insn "*fop_df_1_mixed"
15238 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15239 (match_operator:DF 3 "binary_fp_operator"
15240 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15241 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15242 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15243 && !COMMUTATIVE_ARITH_P (operands[3])
15244 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15245 "* return output_387_binary_op (insn, operands);"
15246 [(set (attr "type")
15247 (cond [(and (eq_attr "alternative" "2")
15248 (match_operand:DF 3 "mult_operator" ""))
15249 (const_string "ssemul")
15250 (and (eq_attr "alternative" "2")
15251 (match_operand:DF 3 "div_operator" ""))
15252 (const_string "ssediv")
15253 (eq_attr "alternative" "2")
15254 (const_string "sseadd")
15255 (match_operand:DF 3 "mult_operator" "")
15256 (const_string "fmul")
15257 (match_operand:DF 3 "div_operator" "")
15258 (const_string "fdiv")
15260 (const_string "fop")))
15261 (set_attr "mode" "DF")])
15263 (define_insn "*fop_df_1_sse"
15264 [(set (match_operand:DF 0 "register_operand" "=Y")
15265 (match_operator:DF 3 "binary_fp_operator"
15266 [(match_operand:DF 1 "register_operand" "0")
15267 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15268 "TARGET_SSE2 && TARGET_SSE_MATH
15269 && !COMMUTATIVE_ARITH_P (operands[3])"
15270 "* return output_387_binary_op (insn, operands);"
15271 [(set_attr "mode" "DF")
15273 (cond [(match_operand:DF 3 "mult_operator" "")
15274 (const_string "ssemul")
15275 (match_operand:DF 3 "div_operator" "")
15276 (const_string "ssediv")
15278 (const_string "sseadd")))])
15280 ;; This pattern is not fully shadowed by the pattern above.
15281 (define_insn "*fop_df_1_i387"
15282 [(set (match_operand:DF 0 "register_operand" "=f,f")
15283 (match_operator:DF 3 "binary_fp_operator"
15284 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15285 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15286 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15287 && !COMMUTATIVE_ARITH_P (operands[3])
15288 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15289 "* return output_387_binary_op (insn, operands);"
15290 [(set (attr "type")
15291 (cond [(match_operand:DF 3 "mult_operator" "")
15292 (const_string "fmul")
15293 (match_operand:DF 3 "div_operator" "")
15294 (const_string "fdiv")
15296 (const_string "fop")))
15297 (set_attr "mode" "DF")])
15299 ;; ??? Add SSE splitters for these!
15300 (define_insn "*fop_df_2<mode>_i387"
15301 [(set (match_operand:DF 0 "register_operand" "=f,f")
15302 (match_operator:DF 3 "binary_fp_operator"
15303 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15304 (match_operand:DF 2 "register_operand" "0,0")]))]
15305 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15306 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15307 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15308 [(set (attr "type")
15309 (cond [(match_operand:DF 3 "mult_operator" "")
15310 (const_string "fmul")
15311 (match_operand:DF 3 "div_operator" "")
15312 (const_string "fdiv")
15314 (const_string "fop")))
15315 (set_attr "fp_int_src" "true")
15316 (set_attr "mode" "<MODE>")])
15318 (define_insn "*fop_df_3<mode>_i387"
15319 [(set (match_operand:DF 0 "register_operand" "=f,f")
15320 (match_operator:DF 3 "binary_fp_operator"
15321 [(match_operand:DF 1 "register_operand" "0,0")
15322 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15323 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15324 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15325 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15326 [(set (attr "type")
15327 (cond [(match_operand:DF 3 "mult_operator" "")
15328 (const_string "fmul")
15329 (match_operand:DF 3 "div_operator" "")
15330 (const_string "fdiv")
15332 (const_string "fop")))
15333 (set_attr "fp_int_src" "true")
15334 (set_attr "mode" "<MODE>")])
15336 (define_insn "*fop_df_4_i387"
15337 [(set (match_operand:DF 0 "register_operand" "=f,f")
15338 (match_operator:DF 3 "binary_fp_operator"
15339 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15340 (match_operand:DF 2 "register_operand" "0,f")]))]
15341 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15342 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15343 "* return output_387_binary_op (insn, operands);"
15344 [(set (attr "type")
15345 (cond [(match_operand:DF 3 "mult_operator" "")
15346 (const_string "fmul")
15347 (match_operand:DF 3 "div_operator" "")
15348 (const_string "fdiv")
15350 (const_string "fop")))
15351 (set_attr "mode" "SF")])
15353 (define_insn "*fop_df_5_i387"
15354 [(set (match_operand:DF 0 "register_operand" "=f,f")
15355 (match_operator:DF 3 "binary_fp_operator"
15356 [(match_operand:DF 1 "register_operand" "0,f")
15358 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15359 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15360 "* return output_387_binary_op (insn, operands);"
15361 [(set (attr "type")
15362 (cond [(match_operand:DF 3 "mult_operator" "")
15363 (const_string "fmul")
15364 (match_operand:DF 3 "div_operator" "")
15365 (const_string "fdiv")
15367 (const_string "fop")))
15368 (set_attr "mode" "SF")])
15370 (define_insn "*fop_df_6_i387"
15371 [(set (match_operand:DF 0 "register_operand" "=f,f")
15372 (match_operator:DF 3 "binary_fp_operator"
15374 (match_operand:SF 1 "register_operand" "0,f"))
15376 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15377 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15378 "* return output_387_binary_op (insn, operands);"
15379 [(set (attr "type")
15380 (cond [(match_operand:DF 3 "mult_operator" "")
15381 (const_string "fmul")
15382 (match_operand:DF 3 "div_operator" "")
15383 (const_string "fdiv")
15385 (const_string "fop")))
15386 (set_attr "mode" "SF")])
15388 (define_insn "*fop_xf_comm_i387"
15389 [(set (match_operand:XF 0 "register_operand" "=f")
15390 (match_operator:XF 3 "binary_fp_operator"
15391 [(match_operand:XF 1 "register_operand" "%0")
15392 (match_operand:XF 2 "register_operand" "f")]))]
15394 && COMMUTATIVE_ARITH_P (operands[3])"
15395 "* return output_387_binary_op (insn, operands);"
15396 [(set (attr "type")
15397 (if_then_else (match_operand:XF 3 "mult_operator" "")
15398 (const_string "fmul")
15399 (const_string "fop")))
15400 (set_attr "mode" "XF")])
15402 (define_insn "*fop_xf_1_i387"
15403 [(set (match_operand:XF 0 "register_operand" "=f,f")
15404 (match_operator:XF 3 "binary_fp_operator"
15405 [(match_operand:XF 1 "register_operand" "0,f")
15406 (match_operand:XF 2 "register_operand" "f,0")]))]
15408 && !COMMUTATIVE_ARITH_P (operands[3])"
15409 "* return output_387_binary_op (insn, operands);"
15410 [(set (attr "type")
15411 (cond [(match_operand:XF 3 "mult_operator" "")
15412 (const_string "fmul")
15413 (match_operand:XF 3 "div_operator" "")
15414 (const_string "fdiv")
15416 (const_string "fop")))
15417 (set_attr "mode" "XF")])
15419 (define_insn "*fop_xf_2<mode>_i387"
15420 [(set (match_operand:XF 0 "register_operand" "=f,f")
15421 (match_operator:XF 3 "binary_fp_operator"
15422 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15423 (match_operand:XF 2 "register_operand" "0,0")]))]
15424 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15425 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15426 [(set (attr "type")
15427 (cond [(match_operand:XF 3 "mult_operator" "")
15428 (const_string "fmul")
15429 (match_operand:XF 3 "div_operator" "")
15430 (const_string "fdiv")
15432 (const_string "fop")))
15433 (set_attr "fp_int_src" "true")
15434 (set_attr "mode" "<MODE>")])
15436 (define_insn "*fop_xf_3<mode>_i387"
15437 [(set (match_operand:XF 0 "register_operand" "=f,f")
15438 (match_operator:XF 3 "binary_fp_operator"
15439 [(match_operand:XF 1 "register_operand" "0,0")
15440 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15441 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15442 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15443 [(set (attr "type")
15444 (cond [(match_operand:XF 3 "mult_operator" "")
15445 (const_string "fmul")
15446 (match_operand:XF 3 "div_operator" "")
15447 (const_string "fdiv")
15449 (const_string "fop")))
15450 (set_attr "fp_int_src" "true")
15451 (set_attr "mode" "<MODE>")])
15453 (define_insn "*fop_xf_4_i387"
15454 [(set (match_operand:XF 0 "register_operand" "=f,f")
15455 (match_operator:XF 3 "binary_fp_operator"
15457 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15458 (match_operand:XF 2 "register_operand" "0,f")]))]
15460 "* return output_387_binary_op (insn, operands);"
15461 [(set (attr "type")
15462 (cond [(match_operand:XF 3 "mult_operator" "")
15463 (const_string "fmul")
15464 (match_operand:XF 3 "div_operator" "")
15465 (const_string "fdiv")
15467 (const_string "fop")))
15468 (set_attr "mode" "SF")])
15470 (define_insn "*fop_xf_5_i387"
15471 [(set (match_operand:XF 0 "register_operand" "=f,f")
15472 (match_operator:XF 3 "binary_fp_operator"
15473 [(match_operand:XF 1 "register_operand" "0,f")
15475 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15477 "* return output_387_binary_op (insn, operands);"
15478 [(set (attr "type")
15479 (cond [(match_operand:XF 3 "mult_operator" "")
15480 (const_string "fmul")
15481 (match_operand:XF 3 "div_operator" "")
15482 (const_string "fdiv")
15484 (const_string "fop")))
15485 (set_attr "mode" "SF")])
15487 (define_insn "*fop_xf_6_i387"
15488 [(set (match_operand:XF 0 "register_operand" "=f,f")
15489 (match_operator:XF 3 "binary_fp_operator"
15491 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15493 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15495 "* return output_387_binary_op (insn, operands);"
15496 [(set (attr "type")
15497 (cond [(match_operand:XF 3 "mult_operator" "")
15498 (const_string "fmul")
15499 (match_operand:XF 3 "div_operator" "")
15500 (const_string "fdiv")
15502 (const_string "fop")))
15503 (set_attr "mode" "SF")])
15506 [(set (match_operand 0 "register_operand" "")
15507 (match_operator 3 "binary_fp_operator"
15508 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15509 (match_operand 2 "register_operand" "")]))]
15510 "TARGET_80387 && reload_completed
15511 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15514 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15515 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15516 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15517 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15518 GET_MODE (operands[3]),
15521 ix86_free_from_memory (GET_MODE (operands[1]));
15526 [(set (match_operand 0 "register_operand" "")
15527 (match_operator 3 "binary_fp_operator"
15528 [(match_operand 1 "register_operand" "")
15529 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15530 "TARGET_80387 && reload_completed
15531 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15534 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15535 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15536 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15537 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15538 GET_MODE (operands[3]),
15541 ix86_free_from_memory (GET_MODE (operands[2]));
15545 ;; FPU special functions.
15547 ;; This pattern implements a no-op XFmode truncation for
15548 ;; all fancy i386 XFmode math functions.
15550 (define_insn "truncxf<mode>2_i387_noop_unspec"
15551 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15552 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15553 UNSPEC_TRUNC_NOOP))]
15554 "TARGET_USE_FANCY_MATH_387"
15555 "* return output_387_reg_move (insn, operands);"
15556 [(set_attr "type" "fmov")
15557 (set_attr "mode" "<MODE>")])
15559 (define_insn "sqrtxf2"
15560 [(set (match_operand:XF 0 "register_operand" "=f")
15561 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15562 "TARGET_USE_FANCY_MATH_387"
15564 [(set_attr "type" "fpspc")
15565 (set_attr "mode" "XF")
15566 (set_attr "athlon_decode" "direct")])
15568 (define_insn "sqrt_extend<mode>xf2_i387"
15569 [(set (match_operand:XF 0 "register_operand" "=f")
15572 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15573 "TARGET_USE_FANCY_MATH_387"
15575 [(set_attr "type" "fpspc")
15576 (set_attr "mode" "XF")
15577 (set_attr "athlon_decode" "direct")])
15579 (define_insn "*sqrt<mode>2_sse"
15580 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15582 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15583 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15584 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15585 [(set_attr "type" "sse")
15586 (set_attr "mode" "<MODE>")
15587 (set_attr "athlon_decode" "*")])
15589 (define_expand "sqrt<mode>2"
15590 [(set (match_operand:X87MODEF12 0 "register_operand" "")
15592 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15593 "TARGET_USE_FANCY_MATH_387
15594 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15596 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15598 rtx op0 = gen_reg_rtx (XFmode);
15599 rtx op1 = force_reg (<MODE>mode, operands[1]);
15601 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15602 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15607 (define_insn "fpremxf4_i387"
15608 [(set (match_operand:XF 0 "register_operand" "=f")
15609 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15610 (match_operand:XF 3 "register_operand" "1")]
15612 (set (match_operand:XF 1 "register_operand" "=u")
15613 (unspec:XF [(match_dup 2) (match_dup 3)]
15615 (set (reg:CCFP FPSR_REG)
15616 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15617 "TARGET_USE_FANCY_MATH_387"
15619 [(set_attr "type" "fpspc")
15620 (set_attr "mode" "XF")])
15622 (define_expand "fmodxf3"
15623 [(use (match_operand:XF 0 "register_operand" ""))
15624 (use (match_operand:XF 1 "register_operand" ""))
15625 (use (match_operand:XF 2 "register_operand" ""))]
15626 "TARGET_USE_FANCY_MATH_387"
15628 rtx label = gen_label_rtx ();
15630 emit_label (label);
15632 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15633 operands[1], operands[2]));
15634 ix86_emit_fp_unordered_jump (label);
15636 emit_move_insn (operands[0], operands[1]);
15640 (define_expand "fmod<mode>3"
15641 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15642 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15643 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15644 "TARGET_USE_FANCY_MATH_387"
15646 rtx label = gen_label_rtx ();
15648 rtx op1 = gen_reg_rtx (XFmode);
15649 rtx op2 = gen_reg_rtx (XFmode);
15651 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15652 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15654 emit_label (label);
15655 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15656 ix86_emit_fp_unordered_jump (label);
15658 /* Truncate the result properly for strict SSE math. */
15659 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15660 && !TARGET_MIX_SSE_I387)
15661 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15663 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15668 (define_insn "fprem1xf4_i387"
15669 [(set (match_operand:XF 0 "register_operand" "=f")
15670 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15671 (match_operand:XF 3 "register_operand" "1")]
15673 (set (match_operand:XF 1 "register_operand" "=u")
15674 (unspec:XF [(match_dup 2) (match_dup 3)]
15676 (set (reg:CCFP FPSR_REG)
15677 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15678 "TARGET_USE_FANCY_MATH_387"
15680 [(set_attr "type" "fpspc")
15681 (set_attr "mode" "XF")])
15683 (define_expand "remainderxf3"
15684 [(use (match_operand:XF 0 "register_operand" ""))
15685 (use (match_operand:XF 1 "register_operand" ""))
15686 (use (match_operand:XF 2 "register_operand" ""))]
15687 "TARGET_USE_FANCY_MATH_387"
15689 rtx label = gen_label_rtx ();
15691 emit_label (label);
15693 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15694 operands[1], operands[2]));
15695 ix86_emit_fp_unordered_jump (label);
15697 emit_move_insn (operands[0], operands[1]);
15701 (define_expand "remainder<mode>3"
15702 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15703 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15704 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15705 "TARGET_USE_FANCY_MATH_387"
15707 rtx label = gen_label_rtx ();
15709 rtx op1 = gen_reg_rtx (XFmode);
15710 rtx op2 = gen_reg_rtx (XFmode);
15712 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15713 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15715 emit_label (label);
15717 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15718 ix86_emit_fp_unordered_jump (label);
15720 /* Truncate the result properly for strict SSE math. */
15721 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15722 && !TARGET_MIX_SSE_I387)
15723 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15725 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15730 (define_insn "*sindf2"
15731 [(set (match_operand:DF 0 "register_operand" "=f")
15732 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15733 "TARGET_USE_FANCY_MATH_387
15734 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15735 && flag_unsafe_math_optimizations"
15737 [(set_attr "type" "fpspc")
15738 (set_attr "mode" "DF")])
15740 (define_insn "*sinsf2"
15741 [(set (match_operand:SF 0 "register_operand" "=f")
15742 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15743 "TARGET_USE_FANCY_MATH_387
15744 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15745 && flag_unsafe_math_optimizations"
15747 [(set_attr "type" "fpspc")
15748 (set_attr "mode" "SF")])
15750 (define_insn "*sinextendsfdf2"
15751 [(set (match_operand:DF 0 "register_operand" "=f")
15752 (unspec:DF [(float_extend:DF
15753 (match_operand:SF 1 "register_operand" "0"))]
15755 "TARGET_USE_FANCY_MATH_387
15756 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15757 && flag_unsafe_math_optimizations"
15759 [(set_attr "type" "fpspc")
15760 (set_attr "mode" "DF")])
15762 (define_insn "*sinxf2"
15763 [(set (match_operand:XF 0 "register_operand" "=f")
15764 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15765 "TARGET_USE_FANCY_MATH_387
15766 && flag_unsafe_math_optimizations"
15768 [(set_attr "type" "fpspc")
15769 (set_attr "mode" "XF")])
15771 (define_insn "*cosdf2"
15772 [(set (match_operand:DF 0 "register_operand" "=f")
15773 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15774 "TARGET_USE_FANCY_MATH_387
15775 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15776 && flag_unsafe_math_optimizations"
15778 [(set_attr "type" "fpspc")
15779 (set_attr "mode" "DF")])
15781 (define_insn "*cossf2"
15782 [(set (match_operand:SF 0 "register_operand" "=f")
15783 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15784 "TARGET_USE_FANCY_MATH_387
15785 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15786 && flag_unsafe_math_optimizations"
15788 [(set_attr "type" "fpspc")
15789 (set_attr "mode" "SF")])
15791 (define_insn "*cosextendsfdf2"
15792 [(set (match_operand:DF 0 "register_operand" "=f")
15793 (unspec:DF [(float_extend:DF
15794 (match_operand:SF 1 "register_operand" "0"))]
15796 "TARGET_USE_FANCY_MATH_387
15797 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15798 && flag_unsafe_math_optimizations"
15800 [(set_attr "type" "fpspc")
15801 (set_attr "mode" "DF")])
15803 (define_insn "*cosxf2"
15804 [(set (match_operand:XF 0 "register_operand" "=f")
15805 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15806 "TARGET_USE_FANCY_MATH_387
15807 && flag_unsafe_math_optimizations"
15809 [(set_attr "type" "fpspc")
15810 (set_attr "mode" "XF")])
15812 ;; With sincos pattern defined, sin and cos builtin function will be
15813 ;; expanded to sincos pattern with one of its outputs left unused.
15814 ;; Cse pass will detected, if two sincos patterns can be combined,
15815 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15816 ;; depending on the unused output.
15818 (define_insn "sincosdf3"
15819 [(set (match_operand:DF 0 "register_operand" "=f")
15820 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15821 UNSPEC_SINCOS_COS))
15822 (set (match_operand:DF 1 "register_operand" "=u")
15823 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15824 "TARGET_USE_FANCY_MATH_387
15825 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15826 && flag_unsafe_math_optimizations"
15828 [(set_attr "type" "fpspc")
15829 (set_attr "mode" "DF")])
15832 [(set (match_operand:DF 0 "register_operand" "")
15833 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15834 UNSPEC_SINCOS_COS))
15835 (set (match_operand:DF 1 "register_operand" "")
15836 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15837 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15838 && !reload_completed && !reload_in_progress"
15839 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15843 [(set (match_operand:DF 0 "register_operand" "")
15844 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15845 UNSPEC_SINCOS_COS))
15846 (set (match_operand:DF 1 "register_operand" "")
15847 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15848 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15849 && !reload_completed && !reload_in_progress"
15850 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15853 (define_insn "sincossf3"
15854 [(set (match_operand:SF 0 "register_operand" "=f")
15855 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15856 UNSPEC_SINCOS_COS))
15857 (set (match_operand:SF 1 "register_operand" "=u")
15858 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15859 "TARGET_USE_FANCY_MATH_387
15860 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15861 && flag_unsafe_math_optimizations"
15863 [(set_attr "type" "fpspc")
15864 (set_attr "mode" "SF")])
15867 [(set (match_operand:SF 0 "register_operand" "")
15868 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15869 UNSPEC_SINCOS_COS))
15870 (set (match_operand:SF 1 "register_operand" "")
15871 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15872 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15873 && !reload_completed && !reload_in_progress"
15874 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15878 [(set (match_operand:SF 0 "register_operand" "")
15879 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15880 UNSPEC_SINCOS_COS))
15881 (set (match_operand:SF 1 "register_operand" "")
15882 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15883 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15884 && !reload_completed && !reload_in_progress"
15885 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15888 (define_insn "*sincosextendsfdf3"
15889 [(set (match_operand:DF 0 "register_operand" "=f")
15890 (unspec:DF [(float_extend:DF
15891 (match_operand:SF 2 "register_operand" "0"))]
15892 UNSPEC_SINCOS_COS))
15893 (set (match_operand:DF 1 "register_operand" "=u")
15894 (unspec:DF [(float_extend:DF
15895 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15896 "TARGET_USE_FANCY_MATH_387
15897 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15898 && flag_unsafe_math_optimizations"
15900 [(set_attr "type" "fpspc")
15901 (set_attr "mode" "DF")])
15904 [(set (match_operand:DF 0 "register_operand" "")
15905 (unspec:DF [(float_extend:DF
15906 (match_operand:SF 2 "register_operand" ""))]
15907 UNSPEC_SINCOS_COS))
15908 (set (match_operand:DF 1 "register_operand" "")
15909 (unspec:DF [(float_extend:DF
15910 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15911 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15912 && !reload_completed && !reload_in_progress"
15913 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15914 (match_dup 2))] UNSPEC_SIN))]
15918 [(set (match_operand:DF 0 "register_operand" "")
15919 (unspec:DF [(float_extend:DF
15920 (match_operand:SF 2 "register_operand" ""))]
15921 UNSPEC_SINCOS_COS))
15922 (set (match_operand:DF 1 "register_operand" "")
15923 (unspec:DF [(float_extend:DF
15924 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15925 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15926 && !reload_completed && !reload_in_progress"
15927 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15928 (match_dup 2))] UNSPEC_COS))]
15931 (define_insn "sincosxf3"
15932 [(set (match_operand:XF 0 "register_operand" "=f")
15933 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15934 UNSPEC_SINCOS_COS))
15935 (set (match_operand:XF 1 "register_operand" "=u")
15936 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15937 "TARGET_USE_FANCY_MATH_387
15938 && flag_unsafe_math_optimizations"
15940 [(set_attr "type" "fpspc")
15941 (set_attr "mode" "XF")])
15944 [(set (match_operand:XF 0 "register_operand" "")
15945 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15946 UNSPEC_SINCOS_COS))
15947 (set (match_operand:XF 1 "register_operand" "")
15948 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15949 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15950 && !reload_completed && !reload_in_progress"
15951 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15955 [(set (match_operand:XF 0 "register_operand" "")
15956 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15957 UNSPEC_SINCOS_COS))
15958 (set (match_operand:XF 1 "register_operand" "")
15959 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15960 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15961 && !reload_completed && !reload_in_progress"
15962 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15965 (define_insn "*tandf3_1"
15966 [(set (match_operand:DF 0 "register_operand" "=f")
15967 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15969 (set (match_operand:DF 1 "register_operand" "=u")
15970 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15971 "TARGET_USE_FANCY_MATH_387
15972 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15973 && flag_unsafe_math_optimizations"
15975 [(set_attr "type" "fpspc")
15976 (set_attr "mode" "DF")])
15978 ;; optimize sequence: fptan
15981 ;; into fptan insn.
15984 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15985 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15987 (set (match_operand:DF 1 "register_operand" "")
15988 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15990 (match_operand:DF 3 "immediate_operand" ""))]
15991 "standard_80387_constant_p (operands[3]) == 2"
15992 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15993 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15996 (define_expand "tandf2"
15997 [(parallel [(set (match_dup 2)
15998 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16000 (set (match_operand:DF 0 "register_operand" "")
16001 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16002 "TARGET_USE_FANCY_MATH_387
16003 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16004 && flag_unsafe_math_optimizations"
16006 operands[2] = gen_reg_rtx (DFmode);
16009 (define_insn "*tansf3_1"
16010 [(set (match_operand:SF 0 "register_operand" "=f")
16011 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16013 (set (match_operand:SF 1 "register_operand" "=u")
16014 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16015 "TARGET_USE_FANCY_MATH_387
16016 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16017 && flag_unsafe_math_optimizations"
16019 [(set_attr "type" "fpspc")
16020 (set_attr "mode" "SF")])
16022 ;; optimize sequence: fptan
16025 ;; into fptan insn.
16028 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16029 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16031 (set (match_operand:SF 1 "register_operand" "")
16032 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16034 (match_operand:SF 3 "immediate_operand" ""))]
16035 "standard_80387_constant_p (operands[3]) == 2"
16036 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16037 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16040 (define_expand "tansf2"
16041 [(parallel [(set (match_dup 2)
16042 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16044 (set (match_operand:SF 0 "register_operand" "")
16045 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16046 "TARGET_USE_FANCY_MATH_387
16047 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16048 && flag_unsafe_math_optimizations"
16050 operands[2] = gen_reg_rtx (SFmode);
16053 (define_insn "*tanxf3_1"
16054 [(set (match_operand:XF 0 "register_operand" "=f")
16055 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16057 (set (match_operand:XF 1 "register_operand" "=u")
16058 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16059 "TARGET_USE_FANCY_MATH_387
16060 && flag_unsafe_math_optimizations"
16062 [(set_attr "type" "fpspc")
16063 (set_attr "mode" "XF")])
16065 ;; optimize sequence: fptan
16068 ;; into fptan insn.
16071 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16072 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16074 (set (match_operand:XF 1 "register_operand" "")
16075 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16077 (match_operand:XF 3 "immediate_operand" ""))]
16078 "standard_80387_constant_p (operands[3]) == 2"
16079 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16080 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16083 (define_expand "tanxf2"
16084 [(parallel [(set (match_dup 2)
16085 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16087 (set (match_operand:XF 0 "register_operand" "")
16088 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16089 "TARGET_USE_FANCY_MATH_387
16090 && flag_unsafe_math_optimizations"
16092 operands[2] = gen_reg_rtx (XFmode);
16095 (define_insn "atan2df3_1"
16096 [(set (match_operand:DF 0 "register_operand" "=f")
16097 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16098 (match_operand:DF 1 "register_operand" "u")]
16100 (clobber (match_scratch:DF 3 "=1"))]
16101 "TARGET_USE_FANCY_MATH_387
16102 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16103 && flag_unsafe_math_optimizations"
16105 [(set_attr "type" "fpspc")
16106 (set_attr "mode" "DF")])
16108 (define_expand "atan2df3"
16109 [(use (match_operand:DF 0 "register_operand" ""))
16110 (use (match_operand:DF 2 "register_operand" ""))
16111 (use (match_operand:DF 1 "register_operand" ""))]
16112 "TARGET_USE_FANCY_MATH_387
16113 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16114 && flag_unsafe_math_optimizations"
16116 rtx copy = gen_reg_rtx (DFmode);
16117 emit_move_insn (copy, operands[1]);
16118 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16122 (define_expand "atandf2"
16123 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16124 (unspec:DF [(match_dup 2)
16125 (match_operand:DF 1 "register_operand" "")]
16127 (clobber (match_scratch:DF 3 ""))])]
16128 "TARGET_USE_FANCY_MATH_387
16129 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16130 && flag_unsafe_math_optimizations"
16132 operands[2] = gen_reg_rtx (DFmode);
16133 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16136 (define_insn "atan2sf3_1"
16137 [(set (match_operand:SF 0 "register_operand" "=f")
16138 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16139 (match_operand:SF 1 "register_operand" "u")]
16141 (clobber (match_scratch:SF 3 "=1"))]
16142 "TARGET_USE_FANCY_MATH_387
16143 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16144 && flag_unsafe_math_optimizations"
16146 [(set_attr "type" "fpspc")
16147 (set_attr "mode" "SF")])
16149 (define_expand "atan2sf3"
16150 [(use (match_operand:SF 0 "register_operand" ""))
16151 (use (match_operand:SF 2 "register_operand" ""))
16152 (use (match_operand:SF 1 "register_operand" ""))]
16153 "TARGET_USE_FANCY_MATH_387
16154 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16155 && flag_unsafe_math_optimizations"
16157 rtx copy = gen_reg_rtx (SFmode);
16158 emit_move_insn (copy, operands[1]);
16159 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16163 (define_expand "atansf2"
16164 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16165 (unspec:SF [(match_dup 2)
16166 (match_operand:SF 1 "register_operand" "")]
16168 (clobber (match_scratch:SF 3 ""))])]
16169 "TARGET_USE_FANCY_MATH_387
16170 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16171 && flag_unsafe_math_optimizations"
16173 operands[2] = gen_reg_rtx (SFmode);
16174 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16177 (define_insn "atan2xf3_1"
16178 [(set (match_operand:XF 0 "register_operand" "=f")
16179 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16180 (match_operand:XF 1 "register_operand" "u")]
16182 (clobber (match_scratch:XF 3 "=1"))]
16183 "TARGET_USE_FANCY_MATH_387
16184 && flag_unsafe_math_optimizations"
16186 [(set_attr "type" "fpspc")
16187 (set_attr "mode" "XF")])
16189 (define_expand "atan2xf3"
16190 [(use (match_operand:XF 0 "register_operand" ""))
16191 (use (match_operand:XF 2 "register_operand" ""))
16192 (use (match_operand:XF 1 "register_operand" ""))]
16193 "TARGET_USE_FANCY_MATH_387
16194 && flag_unsafe_math_optimizations"
16196 rtx copy = gen_reg_rtx (XFmode);
16197 emit_move_insn (copy, operands[1]);
16198 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16202 (define_expand "atanxf2"
16203 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16204 (unspec:XF [(match_dup 2)
16205 (match_operand:XF 1 "register_operand" "")]
16207 (clobber (match_scratch:XF 3 ""))])]
16208 "TARGET_USE_FANCY_MATH_387
16209 && flag_unsafe_math_optimizations"
16211 operands[2] = gen_reg_rtx (XFmode);
16212 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16215 (define_expand "asindf2"
16216 [(set (match_dup 2)
16217 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16218 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16219 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16220 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16221 (parallel [(set (match_dup 7)
16222 (unspec:XF [(match_dup 6) (match_dup 2)]
16224 (clobber (match_scratch:XF 8 ""))])
16225 (set (match_operand:DF 0 "register_operand" "")
16226 (float_truncate:DF (match_dup 7)))]
16227 "TARGET_USE_FANCY_MATH_387
16228 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16229 && flag_unsafe_math_optimizations && !optimize_size"
16233 for (i=2; i<8; i++)
16234 operands[i] = gen_reg_rtx (XFmode);
16236 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16239 (define_expand "asinsf2"
16240 [(set (match_dup 2)
16241 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16242 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16243 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16244 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16245 (parallel [(set (match_dup 7)
16246 (unspec:XF [(match_dup 6) (match_dup 2)]
16248 (clobber (match_scratch:XF 8 ""))])
16249 (set (match_operand:SF 0 "register_operand" "")
16250 (float_truncate:SF (match_dup 7)))]
16251 "TARGET_USE_FANCY_MATH_387
16252 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16253 && flag_unsafe_math_optimizations && !optimize_size"
16257 for (i=2; i<8; i++)
16258 operands[i] = gen_reg_rtx (XFmode);
16260 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16263 (define_expand "asinxf2"
16264 [(set (match_dup 2)
16265 (mult:XF (match_operand:XF 1 "register_operand" "")
16267 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16268 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16269 (parallel [(set (match_operand:XF 0 "register_operand" "")
16270 (unspec:XF [(match_dup 5) (match_dup 1)]
16272 (clobber (match_scratch:XF 6 ""))])]
16273 "TARGET_USE_FANCY_MATH_387
16274 && flag_unsafe_math_optimizations && !optimize_size"
16278 for (i=2; i<6; i++)
16279 operands[i] = gen_reg_rtx (XFmode);
16281 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16284 (define_expand "acosdf2"
16285 [(set (match_dup 2)
16286 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16287 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16288 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16289 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16290 (parallel [(set (match_dup 7)
16291 (unspec:XF [(match_dup 2) (match_dup 6)]
16293 (clobber (match_scratch:XF 8 ""))])
16294 (set (match_operand:DF 0 "register_operand" "")
16295 (float_truncate:DF (match_dup 7)))]
16296 "TARGET_USE_FANCY_MATH_387
16297 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16298 && flag_unsafe_math_optimizations && !optimize_size"
16302 for (i=2; i<8; i++)
16303 operands[i] = gen_reg_rtx (XFmode);
16305 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16308 (define_expand "acossf2"
16309 [(set (match_dup 2)
16310 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16311 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16312 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16313 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16314 (parallel [(set (match_dup 7)
16315 (unspec:XF [(match_dup 2) (match_dup 6)]
16317 (clobber (match_scratch:XF 8 ""))])
16318 (set (match_operand:SF 0 "register_operand" "")
16319 (float_truncate:SF (match_dup 7)))]
16320 "TARGET_USE_FANCY_MATH_387
16321 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16322 && flag_unsafe_math_optimizations && !optimize_size"
16326 for (i=2; i<8; i++)
16327 operands[i] = gen_reg_rtx (XFmode);
16329 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16332 (define_expand "acosxf2"
16333 [(set (match_dup 2)
16334 (mult:XF (match_operand:XF 1 "register_operand" "")
16336 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16337 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16338 (parallel [(set (match_operand:XF 0 "register_operand" "")
16339 (unspec:XF [(match_dup 1) (match_dup 5)]
16341 (clobber (match_scratch:XF 6 ""))])]
16342 "TARGET_USE_FANCY_MATH_387
16343 && flag_unsafe_math_optimizations && !optimize_size"
16347 for (i=2; i<6; i++)
16348 operands[i] = gen_reg_rtx (XFmode);
16350 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16353 (define_insn "fyl2x_xf3"
16354 [(set (match_operand:XF 0 "register_operand" "=f")
16355 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16356 (match_operand:XF 1 "register_operand" "u")]
16358 (clobber (match_scratch:XF 3 "=1"))]
16359 "TARGET_USE_FANCY_MATH_387
16360 && flag_unsafe_math_optimizations"
16362 [(set_attr "type" "fpspc")
16363 (set_attr "mode" "XF")])
16365 (define_expand "logsf2"
16366 [(set (match_dup 2)
16367 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16368 (parallel [(set (match_dup 4)
16369 (unspec:XF [(match_dup 2)
16370 (match_dup 3)] UNSPEC_FYL2X))
16371 (clobber (match_scratch:XF 5 ""))])
16372 (set (match_operand:SF 0 "register_operand" "")
16373 (float_truncate:SF (match_dup 4)))]
16374 "TARGET_USE_FANCY_MATH_387
16375 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16376 && flag_unsafe_math_optimizations"
16380 operands[2] = gen_reg_rtx (XFmode);
16381 operands[3] = gen_reg_rtx (XFmode);
16382 operands[4] = gen_reg_rtx (XFmode);
16384 temp = standard_80387_constant_rtx (4); /* fldln2 */
16385 emit_move_insn (operands[3], temp);
16388 (define_expand "logdf2"
16389 [(set (match_dup 2)
16390 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16391 (parallel [(set (match_dup 4)
16392 (unspec:XF [(match_dup 2)
16393 (match_dup 3)] UNSPEC_FYL2X))
16394 (clobber (match_scratch:XF 5 ""))])
16395 (set (match_operand:DF 0 "register_operand" "")
16396 (float_truncate:DF (match_dup 4)))]
16397 "TARGET_USE_FANCY_MATH_387
16398 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16399 && flag_unsafe_math_optimizations"
16403 operands[2] = gen_reg_rtx (XFmode);
16404 operands[3] = gen_reg_rtx (XFmode);
16405 operands[4] = gen_reg_rtx (XFmode);
16407 temp = standard_80387_constant_rtx (4); /* fldln2 */
16408 emit_move_insn (operands[3], temp);
16411 (define_expand "logxf2"
16412 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16413 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16414 (match_dup 2)] UNSPEC_FYL2X))
16415 (clobber (match_scratch:XF 3 ""))])]
16416 "TARGET_USE_FANCY_MATH_387
16417 && flag_unsafe_math_optimizations"
16421 operands[2] = gen_reg_rtx (XFmode);
16422 temp = standard_80387_constant_rtx (4); /* fldln2 */
16423 emit_move_insn (operands[2], temp);
16426 (define_expand "log10sf2"
16427 [(set (match_dup 2)
16428 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16429 (parallel [(set (match_dup 4)
16430 (unspec:XF [(match_dup 2)
16431 (match_dup 3)] UNSPEC_FYL2X))
16432 (clobber (match_scratch:XF 5 ""))])
16433 (set (match_operand:SF 0 "register_operand" "")
16434 (float_truncate:SF (match_dup 4)))]
16435 "TARGET_USE_FANCY_MATH_387
16436 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16437 && flag_unsafe_math_optimizations"
16441 operands[2] = gen_reg_rtx (XFmode);
16442 operands[3] = gen_reg_rtx (XFmode);
16443 operands[4] = gen_reg_rtx (XFmode);
16445 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16446 emit_move_insn (operands[3], temp);
16449 (define_expand "log10df2"
16450 [(set (match_dup 2)
16451 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16452 (parallel [(set (match_dup 4)
16453 (unspec:XF [(match_dup 2)
16454 (match_dup 3)] UNSPEC_FYL2X))
16455 (clobber (match_scratch:XF 5 ""))])
16456 (set (match_operand:DF 0 "register_operand" "")
16457 (float_truncate:DF (match_dup 4)))]
16458 "TARGET_USE_FANCY_MATH_387
16459 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16460 && flag_unsafe_math_optimizations"
16464 operands[2] = gen_reg_rtx (XFmode);
16465 operands[3] = gen_reg_rtx (XFmode);
16466 operands[4] = gen_reg_rtx (XFmode);
16468 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16469 emit_move_insn (operands[3], temp);
16472 (define_expand "log10xf2"
16473 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16474 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16475 (match_dup 2)] UNSPEC_FYL2X))
16476 (clobber (match_scratch:XF 3 ""))])]
16477 "TARGET_USE_FANCY_MATH_387
16478 && flag_unsafe_math_optimizations"
16482 operands[2] = gen_reg_rtx (XFmode);
16483 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16484 emit_move_insn (operands[2], temp);
16487 (define_expand "log2sf2"
16488 [(set (match_dup 2)
16489 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16490 (parallel [(set (match_dup 4)
16491 (unspec:XF [(match_dup 2)
16492 (match_dup 3)] UNSPEC_FYL2X))
16493 (clobber (match_scratch:XF 5 ""))])
16494 (set (match_operand:SF 0 "register_operand" "")
16495 (float_truncate:SF (match_dup 4)))]
16496 "TARGET_USE_FANCY_MATH_387
16497 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16498 && flag_unsafe_math_optimizations"
16500 operands[2] = gen_reg_rtx (XFmode);
16501 operands[3] = gen_reg_rtx (XFmode);
16502 operands[4] = gen_reg_rtx (XFmode);
16504 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16507 (define_expand "log2df2"
16508 [(set (match_dup 2)
16509 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16510 (parallel [(set (match_dup 4)
16511 (unspec:XF [(match_dup 2)
16512 (match_dup 3)] UNSPEC_FYL2X))
16513 (clobber (match_scratch:XF 5 ""))])
16514 (set (match_operand:DF 0 "register_operand" "")
16515 (float_truncate:DF (match_dup 4)))]
16516 "TARGET_USE_FANCY_MATH_387
16517 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16518 && flag_unsafe_math_optimizations"
16520 operands[2] = gen_reg_rtx (XFmode);
16521 operands[3] = gen_reg_rtx (XFmode);
16522 operands[4] = gen_reg_rtx (XFmode);
16524 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16527 (define_expand "log2xf2"
16528 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16529 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16530 (match_dup 2)] UNSPEC_FYL2X))
16531 (clobber (match_scratch:XF 3 ""))])]
16532 "TARGET_USE_FANCY_MATH_387
16533 && flag_unsafe_math_optimizations"
16535 operands[2] = gen_reg_rtx (XFmode);
16536 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16539 (define_insn "fyl2xp1_xf3"
16540 [(set (match_operand:XF 0 "register_operand" "=f")
16541 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16542 (match_operand:XF 1 "register_operand" "u")]
16544 (clobber (match_scratch:XF 3 "=1"))]
16545 "TARGET_USE_FANCY_MATH_387
16546 && flag_unsafe_math_optimizations"
16548 [(set_attr "type" "fpspc")
16549 (set_attr "mode" "XF")])
16551 (define_expand "log1psf2"
16552 [(use (match_operand:SF 0 "register_operand" ""))
16553 (use (match_operand:SF 1 "register_operand" ""))]
16554 "TARGET_USE_FANCY_MATH_387
16555 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16556 && flag_unsafe_math_optimizations && !optimize_size"
16558 rtx op0 = gen_reg_rtx (XFmode);
16559 rtx op1 = gen_reg_rtx (XFmode);
16561 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16562 ix86_emit_i387_log1p (op0, op1);
16563 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16567 (define_expand "log1pdf2"
16568 [(use (match_operand:DF 0 "register_operand" ""))
16569 (use (match_operand:DF 1 "register_operand" ""))]
16570 "TARGET_USE_FANCY_MATH_387
16571 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16572 && flag_unsafe_math_optimizations && !optimize_size"
16574 rtx op0 = gen_reg_rtx (XFmode);
16575 rtx op1 = gen_reg_rtx (XFmode);
16577 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16578 ix86_emit_i387_log1p (op0, op1);
16579 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16583 (define_expand "log1pxf2"
16584 [(use (match_operand:XF 0 "register_operand" ""))
16585 (use (match_operand:XF 1 "register_operand" ""))]
16586 "TARGET_USE_FANCY_MATH_387
16587 && flag_unsafe_math_optimizations && !optimize_size"
16589 ix86_emit_i387_log1p (operands[0], operands[1]);
16593 (define_insn "*fxtractxf3"
16594 [(set (match_operand:XF 0 "register_operand" "=f")
16595 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16596 UNSPEC_XTRACT_FRACT))
16597 (set (match_operand:XF 1 "register_operand" "=u")
16598 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16599 "TARGET_USE_FANCY_MATH_387
16600 && flag_unsafe_math_optimizations"
16602 [(set_attr "type" "fpspc")
16603 (set_attr "mode" "XF")])
16605 (define_expand "logbsf2"
16606 [(set (match_dup 2)
16607 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16608 (parallel [(set (match_dup 3)
16609 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16611 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16612 (set (match_operand:SF 0 "register_operand" "")
16613 (float_truncate:SF (match_dup 4)))]
16614 "TARGET_USE_FANCY_MATH_387
16615 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16616 && flag_unsafe_math_optimizations"
16618 operands[2] = gen_reg_rtx (XFmode);
16619 operands[3] = gen_reg_rtx (XFmode);
16620 operands[4] = gen_reg_rtx (XFmode);
16623 (define_expand "logbdf2"
16624 [(set (match_dup 2)
16625 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16626 (parallel [(set (match_dup 3)
16627 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16629 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16630 (set (match_operand:DF 0 "register_operand" "")
16631 (float_truncate:DF (match_dup 4)))]
16632 "TARGET_USE_FANCY_MATH_387
16633 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16634 && flag_unsafe_math_optimizations"
16636 operands[2] = gen_reg_rtx (XFmode);
16637 operands[3] = gen_reg_rtx (XFmode);
16638 operands[4] = gen_reg_rtx (XFmode);
16641 (define_expand "logbxf2"
16642 [(parallel [(set (match_dup 2)
16643 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16644 UNSPEC_XTRACT_FRACT))
16645 (set (match_operand:XF 0 "register_operand" "")
16646 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16647 "TARGET_USE_FANCY_MATH_387
16648 && flag_unsafe_math_optimizations"
16650 operands[2] = gen_reg_rtx (XFmode);
16653 (define_expand "ilogbsi2"
16654 [(parallel [(set (match_dup 2)
16655 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16656 UNSPEC_XTRACT_FRACT))
16657 (set (match_operand:XF 3 "register_operand" "")
16658 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16659 (parallel [(set (match_operand:SI 0 "register_operand" "")
16660 (fix:SI (match_dup 3)))
16661 (clobber (reg:CC FLAGS_REG))])]
16662 "TARGET_USE_FANCY_MATH_387
16663 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16664 && flag_unsafe_math_optimizations && !optimize_size"
16666 operands[2] = gen_reg_rtx (XFmode);
16667 operands[3] = gen_reg_rtx (XFmode);
16670 (define_insn "*f2xm1xf2"
16671 [(set (match_operand:XF 0 "register_operand" "=f")
16672 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16674 "TARGET_USE_FANCY_MATH_387
16675 && flag_unsafe_math_optimizations"
16677 [(set_attr "type" "fpspc")
16678 (set_attr "mode" "XF")])
16680 (define_insn "*fscalexf4"
16681 [(set (match_operand:XF 0 "register_operand" "=f")
16682 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16683 (match_operand:XF 3 "register_operand" "1")]
16684 UNSPEC_FSCALE_FRACT))
16685 (set (match_operand:XF 1 "register_operand" "=u")
16686 (unspec:XF [(match_dup 2) (match_dup 3)]
16687 UNSPEC_FSCALE_EXP))]
16688 "TARGET_USE_FANCY_MATH_387
16689 && flag_unsafe_math_optimizations"
16691 [(set_attr "type" "fpspc")
16692 (set_attr "mode" "XF")])
16694 (define_expand "expsf2"
16695 [(set (match_dup 2)
16696 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16697 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16698 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16699 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16700 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16701 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16702 (parallel [(set (match_dup 10)
16703 (unspec:XF [(match_dup 9) (match_dup 5)]
16704 UNSPEC_FSCALE_FRACT))
16705 (set (match_dup 11)
16706 (unspec:XF [(match_dup 9) (match_dup 5)]
16707 UNSPEC_FSCALE_EXP))])
16708 (set (match_operand:SF 0 "register_operand" "")
16709 (float_truncate:SF (match_dup 10)))]
16710 "TARGET_USE_FANCY_MATH_387
16711 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16712 && flag_unsafe_math_optimizations && !optimize_size"
16717 for (i=2; i<12; i++)
16718 operands[i] = gen_reg_rtx (XFmode);
16719 temp = standard_80387_constant_rtx (5); /* fldl2e */
16720 emit_move_insn (operands[3], temp);
16721 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16724 (define_expand "expdf2"
16725 [(set (match_dup 2)
16726 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16727 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16728 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16729 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16730 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16731 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16732 (parallel [(set (match_dup 10)
16733 (unspec:XF [(match_dup 9) (match_dup 5)]
16734 UNSPEC_FSCALE_FRACT))
16735 (set (match_dup 11)
16736 (unspec:XF [(match_dup 9) (match_dup 5)]
16737 UNSPEC_FSCALE_EXP))])
16738 (set (match_operand:DF 0 "register_operand" "")
16739 (float_truncate:DF (match_dup 10)))]
16740 "TARGET_USE_FANCY_MATH_387
16741 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16742 && flag_unsafe_math_optimizations && !optimize_size"
16747 for (i=2; i<12; i++)
16748 operands[i] = gen_reg_rtx (XFmode);
16749 temp = standard_80387_constant_rtx (5); /* fldl2e */
16750 emit_move_insn (operands[3], temp);
16751 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16754 (define_expand "expxf2"
16755 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16757 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16758 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16759 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16760 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16761 (parallel [(set (match_operand:XF 0 "register_operand" "")
16762 (unspec:XF [(match_dup 8) (match_dup 4)]
16763 UNSPEC_FSCALE_FRACT))
16765 (unspec:XF [(match_dup 8) (match_dup 4)]
16766 UNSPEC_FSCALE_EXP))])]
16767 "TARGET_USE_FANCY_MATH_387
16768 && flag_unsafe_math_optimizations && !optimize_size"
16773 for (i=2; i<10; i++)
16774 operands[i] = gen_reg_rtx (XFmode);
16775 temp = standard_80387_constant_rtx (5); /* fldl2e */
16776 emit_move_insn (operands[2], temp);
16777 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16780 (define_expand "exp10sf2"
16781 [(set (match_dup 2)
16782 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16783 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16784 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16785 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16786 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16787 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16788 (parallel [(set (match_dup 10)
16789 (unspec:XF [(match_dup 9) (match_dup 5)]
16790 UNSPEC_FSCALE_FRACT))
16791 (set (match_dup 11)
16792 (unspec:XF [(match_dup 9) (match_dup 5)]
16793 UNSPEC_FSCALE_EXP))])
16794 (set (match_operand:SF 0 "register_operand" "")
16795 (float_truncate:SF (match_dup 10)))]
16796 "TARGET_USE_FANCY_MATH_387
16797 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16798 && flag_unsafe_math_optimizations && !optimize_size"
16803 for (i=2; i<12; i++)
16804 operands[i] = gen_reg_rtx (XFmode);
16805 temp = standard_80387_constant_rtx (6); /* fldl2t */
16806 emit_move_insn (operands[3], temp);
16807 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16810 (define_expand "exp10df2"
16811 [(set (match_dup 2)
16812 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16813 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16814 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16815 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16816 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16817 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16818 (parallel [(set (match_dup 10)
16819 (unspec:XF [(match_dup 9) (match_dup 5)]
16820 UNSPEC_FSCALE_FRACT))
16821 (set (match_dup 11)
16822 (unspec:XF [(match_dup 9) (match_dup 5)]
16823 UNSPEC_FSCALE_EXP))])
16824 (set (match_operand:DF 0 "register_operand" "")
16825 (float_truncate:DF (match_dup 10)))]
16826 "TARGET_USE_FANCY_MATH_387
16827 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16828 && flag_unsafe_math_optimizations && !optimize_size"
16833 for (i=2; i<12; i++)
16834 operands[i] = gen_reg_rtx (XFmode);
16835 temp = standard_80387_constant_rtx (6); /* fldl2t */
16836 emit_move_insn (operands[3], temp);
16837 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16840 (define_expand "exp10xf2"
16841 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16843 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16844 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16845 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16846 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16847 (parallel [(set (match_operand:XF 0 "register_operand" "")
16848 (unspec:XF [(match_dup 8) (match_dup 4)]
16849 UNSPEC_FSCALE_FRACT))
16851 (unspec:XF [(match_dup 8) (match_dup 4)]
16852 UNSPEC_FSCALE_EXP))])]
16853 "TARGET_USE_FANCY_MATH_387
16854 && flag_unsafe_math_optimizations && !optimize_size"
16859 for (i=2; i<10; i++)
16860 operands[i] = gen_reg_rtx (XFmode);
16861 temp = standard_80387_constant_rtx (6); /* fldl2t */
16862 emit_move_insn (operands[2], temp);
16863 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16866 (define_expand "exp2sf2"
16867 [(set (match_dup 2)
16868 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16869 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16870 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16871 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16872 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16873 (parallel [(set (match_dup 8)
16874 (unspec:XF [(match_dup 7) (match_dup 3)]
16875 UNSPEC_FSCALE_FRACT))
16877 (unspec:XF [(match_dup 7) (match_dup 3)]
16878 UNSPEC_FSCALE_EXP))])
16879 (set (match_operand:SF 0 "register_operand" "")
16880 (float_truncate:SF (match_dup 8)))]
16881 "TARGET_USE_FANCY_MATH_387
16882 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16883 && flag_unsafe_math_optimizations && !optimize_size"
16887 for (i=2; i<10; i++)
16888 operands[i] = gen_reg_rtx (XFmode);
16889 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16892 (define_expand "exp2df2"
16893 [(set (match_dup 2)
16894 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16895 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16896 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16897 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16898 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16899 (parallel [(set (match_dup 8)
16900 (unspec:XF [(match_dup 7) (match_dup 3)]
16901 UNSPEC_FSCALE_FRACT))
16903 (unspec:XF [(match_dup 7) (match_dup 3)]
16904 UNSPEC_FSCALE_EXP))])
16905 (set (match_operand:DF 0 "register_operand" "")
16906 (float_truncate:DF (match_dup 8)))]
16907 "TARGET_USE_FANCY_MATH_387
16908 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16909 && flag_unsafe_math_optimizations && !optimize_size"
16913 for (i=2; i<10; i++)
16914 operands[i] = gen_reg_rtx (XFmode);
16915 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16918 (define_expand "exp2xf2"
16919 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16920 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16921 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16922 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16923 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16924 (parallel [(set (match_operand:XF 0 "register_operand" "")
16925 (unspec:XF [(match_dup 7) (match_dup 3)]
16926 UNSPEC_FSCALE_FRACT))
16928 (unspec:XF [(match_dup 7) (match_dup 3)]
16929 UNSPEC_FSCALE_EXP))])]
16930 "TARGET_USE_FANCY_MATH_387
16931 && flag_unsafe_math_optimizations && !optimize_size"
16935 for (i=2; i<9; i++)
16936 operands[i] = gen_reg_rtx (XFmode);
16937 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16940 (define_expand "expm1df2"
16941 [(set (match_dup 2)
16942 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16943 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16944 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16945 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16946 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16947 (parallel [(set (match_dup 8)
16948 (unspec:XF [(match_dup 7) (match_dup 5)]
16949 UNSPEC_FSCALE_FRACT))
16951 (unspec:XF [(match_dup 7) (match_dup 5)]
16952 UNSPEC_FSCALE_EXP))])
16953 (parallel [(set (match_dup 11)
16954 (unspec:XF [(match_dup 10) (match_dup 9)]
16955 UNSPEC_FSCALE_FRACT))
16956 (set (match_dup 12)
16957 (unspec:XF [(match_dup 10) (match_dup 9)]
16958 UNSPEC_FSCALE_EXP))])
16959 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16960 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16961 (set (match_operand:DF 0 "register_operand" "")
16962 (float_truncate:DF (match_dup 14)))]
16963 "TARGET_USE_FANCY_MATH_387
16964 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16965 && flag_unsafe_math_optimizations && !optimize_size"
16970 for (i=2; i<15; i++)
16971 operands[i] = gen_reg_rtx (XFmode);
16972 temp = standard_80387_constant_rtx (5); /* fldl2e */
16973 emit_move_insn (operands[3], temp);
16974 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16977 (define_expand "expm1sf2"
16978 [(set (match_dup 2)
16979 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16980 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16981 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16982 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16983 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16984 (parallel [(set (match_dup 8)
16985 (unspec:XF [(match_dup 7) (match_dup 5)]
16986 UNSPEC_FSCALE_FRACT))
16988 (unspec:XF [(match_dup 7) (match_dup 5)]
16989 UNSPEC_FSCALE_EXP))])
16990 (parallel [(set (match_dup 11)
16991 (unspec:XF [(match_dup 10) (match_dup 9)]
16992 UNSPEC_FSCALE_FRACT))
16993 (set (match_dup 12)
16994 (unspec:XF [(match_dup 10) (match_dup 9)]
16995 UNSPEC_FSCALE_EXP))])
16996 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16997 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16998 (set (match_operand:SF 0 "register_operand" "")
16999 (float_truncate:SF (match_dup 14)))]
17000 "TARGET_USE_FANCY_MATH_387
17001 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17002 && flag_unsafe_math_optimizations && !optimize_size"
17007 for (i=2; i<15; i++)
17008 operands[i] = gen_reg_rtx (XFmode);
17009 temp = standard_80387_constant_rtx (5); /* fldl2e */
17010 emit_move_insn (operands[3], temp);
17011 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17014 (define_expand "expm1xf2"
17015 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17017 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17018 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17019 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17020 (parallel [(set (match_dup 7)
17021 (unspec:XF [(match_dup 6) (match_dup 4)]
17022 UNSPEC_FSCALE_FRACT))
17024 (unspec:XF [(match_dup 6) (match_dup 4)]
17025 UNSPEC_FSCALE_EXP))])
17026 (parallel [(set (match_dup 10)
17027 (unspec:XF [(match_dup 9) (match_dup 8)]
17028 UNSPEC_FSCALE_FRACT))
17029 (set (match_dup 11)
17030 (unspec:XF [(match_dup 9) (match_dup 8)]
17031 UNSPEC_FSCALE_EXP))])
17032 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17033 (set (match_operand:XF 0 "register_operand" "")
17034 (plus:XF (match_dup 12) (match_dup 7)))]
17035 "TARGET_USE_FANCY_MATH_387
17036 && flag_unsafe_math_optimizations && !optimize_size"
17041 for (i=2; i<13; i++)
17042 operands[i] = gen_reg_rtx (XFmode);
17043 temp = standard_80387_constant_rtx (5); /* fldl2e */
17044 emit_move_insn (operands[2], temp);
17045 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17048 (define_expand "ldexpdf3"
17049 [(set (match_dup 3)
17050 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17052 (float:XF (match_operand:SI 2 "register_operand" "")))
17053 (parallel [(set (match_dup 5)
17054 (unspec:XF [(match_dup 3) (match_dup 4)]
17055 UNSPEC_FSCALE_FRACT))
17057 (unspec:XF [(match_dup 3) (match_dup 4)]
17058 UNSPEC_FSCALE_EXP))])
17059 (set (match_operand:DF 0 "register_operand" "")
17060 (float_truncate:DF (match_dup 5)))]
17061 "TARGET_USE_FANCY_MATH_387
17062 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17063 && flag_unsafe_math_optimizations && !optimize_size"
17067 for (i=3; i<7; i++)
17068 operands[i] = gen_reg_rtx (XFmode);
17071 (define_expand "ldexpsf3"
17072 [(set (match_dup 3)
17073 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17075 (float:XF (match_operand:SI 2 "register_operand" "")))
17076 (parallel [(set (match_dup 5)
17077 (unspec:XF [(match_dup 3) (match_dup 4)]
17078 UNSPEC_FSCALE_FRACT))
17080 (unspec:XF [(match_dup 3) (match_dup 4)]
17081 UNSPEC_FSCALE_EXP))])
17082 (set (match_operand:SF 0 "register_operand" "")
17083 (float_truncate:SF (match_dup 5)))]
17084 "TARGET_USE_FANCY_MATH_387
17085 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17086 && flag_unsafe_math_optimizations && !optimize_size"
17090 for (i=3; i<7; i++)
17091 operands[i] = gen_reg_rtx (XFmode);
17094 (define_expand "ldexpxf3"
17095 [(set (match_dup 3)
17096 (float:XF (match_operand:SI 2 "register_operand" "")))
17097 (parallel [(set (match_operand:XF 0 " register_operand" "")
17098 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17100 UNSPEC_FSCALE_FRACT))
17102 (unspec:XF [(match_dup 1) (match_dup 3)]
17103 UNSPEC_FSCALE_EXP))])]
17104 "TARGET_USE_FANCY_MATH_387
17105 && flag_unsafe_math_optimizations && !optimize_size"
17109 for (i=3; i<5; i++)
17110 operands[i] = gen_reg_rtx (XFmode);
17114 (define_insn "frndintxf2"
17115 [(set (match_operand:XF 0 "register_operand" "=f")
17116 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17118 "TARGET_USE_FANCY_MATH_387
17119 && flag_unsafe_math_optimizations"
17121 [(set_attr "type" "fpspc")
17122 (set_attr "mode" "XF")])
17124 (define_expand "rintdf2"
17125 [(use (match_operand:DF 0 "register_operand" ""))
17126 (use (match_operand:DF 1 "register_operand" ""))]
17127 "(TARGET_USE_FANCY_MATH_387
17128 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17129 && flag_unsafe_math_optimizations)
17130 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17131 && !flag_trapping_math
17132 && !optimize_size)"
17134 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17135 && !flag_trapping_math
17137 ix86_expand_rint (operand0, operand1);
17140 rtx op0 = gen_reg_rtx (XFmode);
17141 rtx op1 = gen_reg_rtx (XFmode);
17143 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17144 emit_insn (gen_frndintxf2 (op0, op1));
17146 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17151 (define_expand "rintsf2"
17152 [(use (match_operand:SF 0 "register_operand" ""))
17153 (use (match_operand:SF 1 "register_operand" ""))]
17154 "(TARGET_USE_FANCY_MATH_387
17155 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17156 && flag_unsafe_math_optimizations)
17157 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17158 && !flag_trapping_math
17159 && !optimize_size)"
17161 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17162 && !flag_trapping_math
17164 ix86_expand_rint (operand0, operand1);
17167 rtx op0 = gen_reg_rtx (XFmode);
17168 rtx op1 = gen_reg_rtx (XFmode);
17170 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17171 emit_insn (gen_frndintxf2 (op0, op1));
17173 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17178 (define_expand "rintxf2"
17179 [(use (match_operand:XF 0 "register_operand" ""))
17180 (use (match_operand:XF 1 "register_operand" ""))]
17181 "TARGET_USE_FANCY_MATH_387
17182 && flag_unsafe_math_optimizations && !optimize_size"
17184 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17188 (define_expand "roundsf2"
17189 [(match_operand:SF 0 "register_operand" "")
17190 (match_operand:SF 1 "nonimmediate_operand" "")]
17191 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17192 && !flag_trapping_math && !flag_rounding_math
17195 ix86_expand_round (operand0, operand1);
17199 (define_expand "rounddf2"
17200 [(match_operand:DF 0 "register_operand" "")
17201 (match_operand:DF 1 "nonimmediate_operand" "")]
17202 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17203 && !flag_trapping_math && !flag_rounding_math
17207 ix86_expand_round (operand0, operand1);
17209 ix86_expand_rounddf_32 (operand0, operand1);
17213 (define_insn_and_split "*fistdi2_1"
17214 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17215 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17217 "TARGET_USE_FANCY_MATH_387
17218 && !(reload_completed || reload_in_progress)"
17223 if (memory_operand (operands[0], VOIDmode))
17224 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17227 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17228 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17233 [(set_attr "type" "fpspc")
17234 (set_attr "mode" "DI")])
17236 (define_insn "fistdi2"
17237 [(set (match_operand:DI 0 "memory_operand" "=m")
17238 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17240 (clobber (match_scratch:XF 2 "=&1f"))]
17241 "TARGET_USE_FANCY_MATH_387"
17242 "* return output_fix_trunc (insn, operands, 0);"
17243 [(set_attr "type" "fpspc")
17244 (set_attr "mode" "DI")])
17246 (define_insn "fistdi2_with_temp"
17247 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17248 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17250 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17251 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17252 "TARGET_USE_FANCY_MATH_387"
17254 [(set_attr "type" "fpspc")
17255 (set_attr "mode" "DI")])
17258 [(set (match_operand:DI 0 "register_operand" "")
17259 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17261 (clobber (match_operand:DI 2 "memory_operand" ""))
17262 (clobber (match_scratch 3 ""))]
17264 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17265 (clobber (match_dup 3))])
17266 (set (match_dup 0) (match_dup 2))]
17270 [(set (match_operand:DI 0 "memory_operand" "")
17271 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17273 (clobber (match_operand:DI 2 "memory_operand" ""))
17274 (clobber (match_scratch 3 ""))]
17276 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17277 (clobber (match_dup 3))])]
17280 (define_insn_and_split "*fist<mode>2_1"
17281 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17282 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17284 "TARGET_USE_FANCY_MATH_387
17285 && !(reload_completed || reload_in_progress)"
17290 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17291 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17295 [(set_attr "type" "fpspc")
17296 (set_attr "mode" "<MODE>")])
17298 (define_insn "fist<mode>2"
17299 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17300 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17302 "TARGET_USE_FANCY_MATH_387"
17303 "* return output_fix_trunc (insn, operands, 0);"
17304 [(set_attr "type" "fpspc")
17305 (set_attr "mode" "<MODE>")])
17307 (define_insn "fist<mode>2_with_temp"
17308 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17309 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17311 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17312 "TARGET_USE_FANCY_MATH_387"
17314 [(set_attr "type" "fpspc")
17315 (set_attr "mode" "<MODE>")])
17318 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17319 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17321 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17323 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17325 (set (match_dup 0) (match_dup 2))]
17329 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17330 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17332 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17334 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17338 (define_expand "lrintxf<mode>2"
17339 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17340 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17342 "TARGET_USE_FANCY_MATH_387"
17345 (define_expand "lrint<mode>di2"
17346 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17347 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17348 UNSPEC_FIX_NOTRUNC))]
17349 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17352 (define_expand "lrint<mode>si2"
17353 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17354 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17355 UNSPEC_FIX_NOTRUNC))]
17356 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17359 (define_expand "lround<mode>di2"
17360 [(match_operand:DI 0 "nonimmediate_operand" "")
17361 (match_operand:SSEMODEF 1 "register_operand" "")]
17362 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17363 && !flag_trapping_math && !flag_rounding_math
17366 ix86_expand_lround (operand0, operand1);
17370 (define_expand "lround<mode>si2"
17371 [(match_operand:SI 0 "nonimmediate_operand" "")
17372 (match_operand:SSEMODEF 1 "register_operand" "")]
17373 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17374 && !flag_trapping_math && !flag_rounding_math
17377 ix86_expand_lround (operand0, operand1);
17381 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17382 (define_insn_and_split "frndintxf2_floor"
17383 [(set (match_operand:XF 0 "register_operand" "=f")
17384 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17385 UNSPEC_FRNDINT_FLOOR))
17386 (clobber (reg:CC FLAGS_REG))]
17387 "TARGET_USE_FANCY_MATH_387
17388 && flag_unsafe_math_optimizations
17389 && !(reload_completed || reload_in_progress)"
17394 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17396 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17397 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17399 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17400 operands[2], operands[3]));
17403 [(set_attr "type" "frndint")
17404 (set_attr "i387_cw" "floor")
17405 (set_attr "mode" "XF")])
17407 (define_insn "frndintxf2_floor_i387"
17408 [(set (match_operand:XF 0 "register_operand" "=f")
17409 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17410 UNSPEC_FRNDINT_FLOOR))
17411 (use (match_operand:HI 2 "memory_operand" "m"))
17412 (use (match_operand:HI 3 "memory_operand" "m"))]
17413 "TARGET_USE_FANCY_MATH_387
17414 && flag_unsafe_math_optimizations"
17415 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17416 [(set_attr "type" "frndint")
17417 (set_attr "i387_cw" "floor")
17418 (set_attr "mode" "XF")])
17420 (define_expand "floorxf2"
17421 [(use (match_operand:XF 0 "register_operand" ""))
17422 (use (match_operand:XF 1 "register_operand" ""))]
17423 "TARGET_USE_FANCY_MATH_387
17424 && flag_unsafe_math_optimizations && !optimize_size"
17426 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17430 (define_expand "floordf2"
17431 [(use (match_operand:DF 0 "register_operand" ""))
17432 (use (match_operand:DF 1 "register_operand" ""))]
17433 "((TARGET_USE_FANCY_MATH_387
17434 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17435 && flag_unsafe_math_optimizations)
17436 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17437 && !flag_trapping_math))
17440 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17441 && !flag_trapping_math)
17444 ix86_expand_floorceil (operand0, operand1, true);
17446 ix86_expand_floorceildf_32 (operand0, operand1, true);
17450 rtx op0 = gen_reg_rtx (XFmode);
17451 rtx op1 = gen_reg_rtx (XFmode);
17453 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17454 emit_insn (gen_frndintxf2_floor (op0, op1));
17456 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17461 (define_expand "floorsf2"
17462 [(use (match_operand:SF 0 "register_operand" ""))
17463 (use (match_operand:SF 1 "register_operand" ""))]
17464 "((TARGET_USE_FANCY_MATH_387
17465 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17466 && flag_unsafe_math_optimizations)
17467 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17468 && !flag_trapping_math))
17471 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17472 && !flag_trapping_math)
17473 ix86_expand_floorceil (operand0, operand1, true);
17476 rtx op0 = gen_reg_rtx (XFmode);
17477 rtx op1 = gen_reg_rtx (XFmode);
17479 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17480 emit_insn (gen_frndintxf2_floor (op0, op1));
17482 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17487 (define_insn_and_split "*fist<mode>2_floor_1"
17488 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17489 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17490 UNSPEC_FIST_FLOOR))
17491 (clobber (reg:CC FLAGS_REG))]
17492 "TARGET_USE_FANCY_MATH_387
17493 && flag_unsafe_math_optimizations
17494 && !(reload_completed || reload_in_progress)"
17499 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17501 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17502 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17503 if (memory_operand (operands[0], VOIDmode))
17504 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17505 operands[2], operands[3]));
17508 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17509 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17510 operands[2], operands[3],
17515 [(set_attr "type" "fistp")
17516 (set_attr "i387_cw" "floor")
17517 (set_attr "mode" "<MODE>")])
17519 (define_insn "fistdi2_floor"
17520 [(set (match_operand:DI 0 "memory_operand" "=m")
17521 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17522 UNSPEC_FIST_FLOOR))
17523 (use (match_operand:HI 2 "memory_operand" "m"))
17524 (use (match_operand:HI 3 "memory_operand" "m"))
17525 (clobber (match_scratch:XF 4 "=&1f"))]
17526 "TARGET_USE_FANCY_MATH_387
17527 && flag_unsafe_math_optimizations"
17528 "* return output_fix_trunc (insn, operands, 0);"
17529 [(set_attr "type" "fistp")
17530 (set_attr "i387_cw" "floor")
17531 (set_attr "mode" "DI")])
17533 (define_insn "fistdi2_floor_with_temp"
17534 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17535 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17536 UNSPEC_FIST_FLOOR))
17537 (use (match_operand:HI 2 "memory_operand" "m,m"))
17538 (use (match_operand:HI 3 "memory_operand" "m,m"))
17539 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17540 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17541 "TARGET_USE_FANCY_MATH_387
17542 && flag_unsafe_math_optimizations"
17544 [(set_attr "type" "fistp")
17545 (set_attr "i387_cw" "floor")
17546 (set_attr "mode" "DI")])
17549 [(set (match_operand:DI 0 "register_operand" "")
17550 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17551 UNSPEC_FIST_FLOOR))
17552 (use (match_operand:HI 2 "memory_operand" ""))
17553 (use (match_operand:HI 3 "memory_operand" ""))
17554 (clobber (match_operand:DI 4 "memory_operand" ""))
17555 (clobber (match_scratch 5 ""))]
17557 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17558 (use (match_dup 2))
17559 (use (match_dup 3))
17560 (clobber (match_dup 5))])
17561 (set (match_dup 0) (match_dup 4))]
17565 [(set (match_operand:DI 0 "memory_operand" "")
17566 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17567 UNSPEC_FIST_FLOOR))
17568 (use (match_operand:HI 2 "memory_operand" ""))
17569 (use (match_operand:HI 3 "memory_operand" ""))
17570 (clobber (match_operand:DI 4 "memory_operand" ""))
17571 (clobber (match_scratch 5 ""))]
17573 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17574 (use (match_dup 2))
17575 (use (match_dup 3))
17576 (clobber (match_dup 5))])]
17579 (define_insn "fist<mode>2_floor"
17580 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17581 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17582 UNSPEC_FIST_FLOOR))
17583 (use (match_operand:HI 2 "memory_operand" "m"))
17584 (use (match_operand:HI 3 "memory_operand" "m"))]
17585 "TARGET_USE_FANCY_MATH_387
17586 && flag_unsafe_math_optimizations"
17587 "* return output_fix_trunc (insn, operands, 0);"
17588 [(set_attr "type" "fistp")
17589 (set_attr "i387_cw" "floor")
17590 (set_attr "mode" "<MODE>")])
17592 (define_insn "fist<mode>2_floor_with_temp"
17593 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17594 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17595 UNSPEC_FIST_FLOOR))
17596 (use (match_operand:HI 2 "memory_operand" "m,m"))
17597 (use (match_operand:HI 3 "memory_operand" "m,m"))
17598 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17599 "TARGET_USE_FANCY_MATH_387
17600 && flag_unsafe_math_optimizations"
17602 [(set_attr "type" "fistp")
17603 (set_attr "i387_cw" "floor")
17604 (set_attr "mode" "<MODE>")])
17607 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17608 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17609 UNSPEC_FIST_FLOOR))
17610 (use (match_operand:HI 2 "memory_operand" ""))
17611 (use (match_operand:HI 3 "memory_operand" ""))
17612 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17614 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17615 UNSPEC_FIST_FLOOR))
17616 (use (match_dup 2))
17617 (use (match_dup 3))])
17618 (set (match_dup 0) (match_dup 4))]
17622 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17623 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17624 UNSPEC_FIST_FLOOR))
17625 (use (match_operand:HI 2 "memory_operand" ""))
17626 (use (match_operand:HI 3 "memory_operand" ""))
17627 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17629 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17630 UNSPEC_FIST_FLOOR))
17631 (use (match_dup 2))
17632 (use (match_dup 3))])]
17635 (define_expand "lfloorxf<mode>2"
17636 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17637 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17638 UNSPEC_FIST_FLOOR))
17639 (clobber (reg:CC FLAGS_REG))])]
17640 "TARGET_USE_FANCY_MATH_387
17641 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17642 && flag_unsafe_math_optimizations"
17645 (define_expand "lfloor<mode>di2"
17646 [(match_operand:DI 0 "nonimmediate_operand" "")
17647 (match_operand:SSEMODEF 1 "register_operand" "")]
17648 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17649 && !flag_trapping_math
17652 ix86_expand_lfloorceil (operand0, operand1, true);
17656 (define_expand "lfloor<mode>si2"
17657 [(match_operand:SI 0 "nonimmediate_operand" "")
17658 (match_operand:SSEMODEF 1 "register_operand" "")]
17659 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17660 && !flag_trapping_math
17661 && (!optimize_size || !TARGET_64BIT)"
17663 ix86_expand_lfloorceil (operand0, operand1, true);
17667 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17668 (define_insn_and_split "frndintxf2_ceil"
17669 [(set (match_operand:XF 0 "register_operand" "=f")
17670 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17671 UNSPEC_FRNDINT_CEIL))
17672 (clobber (reg:CC FLAGS_REG))]
17673 "TARGET_USE_FANCY_MATH_387
17674 && flag_unsafe_math_optimizations
17675 && !(reload_completed || reload_in_progress)"
17680 ix86_optimize_mode_switching[I387_CEIL] = 1;
17682 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17683 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17685 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17686 operands[2], operands[3]));
17689 [(set_attr "type" "frndint")
17690 (set_attr "i387_cw" "ceil")
17691 (set_attr "mode" "XF")])
17693 (define_insn "frndintxf2_ceil_i387"
17694 [(set (match_operand:XF 0 "register_operand" "=f")
17695 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17696 UNSPEC_FRNDINT_CEIL))
17697 (use (match_operand:HI 2 "memory_operand" "m"))
17698 (use (match_operand:HI 3 "memory_operand" "m"))]
17699 "TARGET_USE_FANCY_MATH_387
17700 && flag_unsafe_math_optimizations"
17701 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17702 [(set_attr "type" "frndint")
17703 (set_attr "i387_cw" "ceil")
17704 (set_attr "mode" "XF")])
17706 (define_expand "ceilxf2"
17707 [(use (match_operand:XF 0 "register_operand" ""))
17708 (use (match_operand:XF 1 "register_operand" ""))]
17709 "TARGET_USE_FANCY_MATH_387
17710 && flag_unsafe_math_optimizations && !optimize_size"
17712 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17716 (define_expand "ceildf2"
17717 [(use (match_operand:DF 0 "register_operand" ""))
17718 (use (match_operand:DF 1 "register_operand" ""))]
17719 "((TARGET_USE_FANCY_MATH_387
17720 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17721 && flag_unsafe_math_optimizations)
17722 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17723 && !flag_trapping_math))
17726 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17727 && !flag_trapping_math)
17730 ix86_expand_floorceil (operand0, operand1, false);
17732 ix86_expand_floorceildf_32 (operand0, operand1, false);
17736 rtx op0 = gen_reg_rtx (XFmode);
17737 rtx op1 = gen_reg_rtx (XFmode);
17739 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17740 emit_insn (gen_frndintxf2_ceil (op0, op1));
17742 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17747 (define_expand "ceilsf2"
17748 [(use (match_operand:SF 0 "register_operand" ""))
17749 (use (match_operand:SF 1 "register_operand" ""))]
17750 "((TARGET_USE_FANCY_MATH_387
17751 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17752 && flag_unsafe_math_optimizations)
17753 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17754 && !flag_trapping_math))
17757 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17758 && !flag_trapping_math)
17759 ix86_expand_floorceil (operand0, operand1, false);
17762 rtx op0 = gen_reg_rtx (XFmode);
17763 rtx op1 = gen_reg_rtx (XFmode);
17765 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17766 emit_insn (gen_frndintxf2_ceil (op0, op1));
17768 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17773 (define_insn_and_split "*fist<mode>2_ceil_1"
17774 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17775 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17777 (clobber (reg:CC FLAGS_REG))]
17778 "TARGET_USE_FANCY_MATH_387
17779 && flag_unsafe_math_optimizations
17780 && !(reload_completed || reload_in_progress)"
17785 ix86_optimize_mode_switching[I387_CEIL] = 1;
17787 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17788 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17789 if (memory_operand (operands[0], VOIDmode))
17790 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17791 operands[2], operands[3]));
17794 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17795 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17796 operands[2], operands[3],
17801 [(set_attr "type" "fistp")
17802 (set_attr "i387_cw" "ceil")
17803 (set_attr "mode" "<MODE>")])
17805 (define_insn "fistdi2_ceil"
17806 [(set (match_operand:DI 0 "memory_operand" "=m")
17807 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17809 (use (match_operand:HI 2 "memory_operand" "m"))
17810 (use (match_operand:HI 3 "memory_operand" "m"))
17811 (clobber (match_scratch:XF 4 "=&1f"))]
17812 "TARGET_USE_FANCY_MATH_387
17813 && flag_unsafe_math_optimizations"
17814 "* return output_fix_trunc (insn, operands, 0);"
17815 [(set_attr "type" "fistp")
17816 (set_attr "i387_cw" "ceil")
17817 (set_attr "mode" "DI")])
17819 (define_insn "fistdi2_ceil_with_temp"
17820 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17821 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17823 (use (match_operand:HI 2 "memory_operand" "m,m"))
17824 (use (match_operand:HI 3 "memory_operand" "m,m"))
17825 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17826 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17827 "TARGET_USE_FANCY_MATH_387
17828 && flag_unsafe_math_optimizations"
17830 [(set_attr "type" "fistp")
17831 (set_attr "i387_cw" "ceil")
17832 (set_attr "mode" "DI")])
17835 [(set (match_operand:DI 0 "register_operand" "")
17836 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17838 (use (match_operand:HI 2 "memory_operand" ""))
17839 (use (match_operand:HI 3 "memory_operand" ""))
17840 (clobber (match_operand:DI 4 "memory_operand" ""))
17841 (clobber (match_scratch 5 ""))]
17843 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17844 (use (match_dup 2))
17845 (use (match_dup 3))
17846 (clobber (match_dup 5))])
17847 (set (match_dup 0) (match_dup 4))]
17851 [(set (match_operand:DI 0 "memory_operand" "")
17852 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17854 (use (match_operand:HI 2 "memory_operand" ""))
17855 (use (match_operand:HI 3 "memory_operand" ""))
17856 (clobber (match_operand:DI 4 "memory_operand" ""))
17857 (clobber (match_scratch 5 ""))]
17859 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17860 (use (match_dup 2))
17861 (use (match_dup 3))
17862 (clobber (match_dup 5))])]
17865 (define_insn "fist<mode>2_ceil"
17866 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17867 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17869 (use (match_operand:HI 2 "memory_operand" "m"))
17870 (use (match_operand:HI 3 "memory_operand" "m"))]
17871 "TARGET_USE_FANCY_MATH_387
17872 && flag_unsafe_math_optimizations"
17873 "* return output_fix_trunc (insn, operands, 0);"
17874 [(set_attr "type" "fistp")
17875 (set_attr "i387_cw" "ceil")
17876 (set_attr "mode" "<MODE>")])
17878 (define_insn "fist<mode>2_ceil_with_temp"
17879 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17880 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17882 (use (match_operand:HI 2 "memory_operand" "m,m"))
17883 (use (match_operand:HI 3 "memory_operand" "m,m"))
17884 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17885 "TARGET_USE_FANCY_MATH_387
17886 && flag_unsafe_math_optimizations"
17888 [(set_attr "type" "fistp")
17889 (set_attr "i387_cw" "ceil")
17890 (set_attr "mode" "<MODE>")])
17893 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17894 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17896 (use (match_operand:HI 2 "memory_operand" ""))
17897 (use (match_operand:HI 3 "memory_operand" ""))
17898 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17900 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17902 (use (match_dup 2))
17903 (use (match_dup 3))])
17904 (set (match_dup 0) (match_dup 4))]
17908 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17909 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17911 (use (match_operand:HI 2 "memory_operand" ""))
17912 (use (match_operand:HI 3 "memory_operand" ""))
17913 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17915 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17917 (use (match_dup 2))
17918 (use (match_dup 3))])]
17921 (define_expand "lceilxf<mode>2"
17922 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17923 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17925 (clobber (reg:CC FLAGS_REG))])]
17926 "TARGET_USE_FANCY_MATH_387
17927 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17928 && flag_unsafe_math_optimizations"
17931 (define_expand "lceil<mode>di2"
17932 [(match_operand:DI 0 "nonimmediate_operand" "")
17933 (match_operand:SSEMODEF 1 "register_operand" "")]
17934 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17935 && !flag_trapping_math"
17937 ix86_expand_lfloorceil (operand0, operand1, false);
17941 (define_expand "lceil<mode>si2"
17942 [(match_operand:SI 0 "nonimmediate_operand" "")
17943 (match_operand:SSEMODEF 1 "register_operand" "")]
17944 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17945 && !flag_trapping_math"
17947 ix86_expand_lfloorceil (operand0, operand1, false);
17951 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17952 (define_insn_and_split "frndintxf2_trunc"
17953 [(set (match_operand:XF 0 "register_operand" "=f")
17954 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17955 UNSPEC_FRNDINT_TRUNC))
17956 (clobber (reg:CC FLAGS_REG))]
17957 "TARGET_USE_FANCY_MATH_387
17958 && flag_unsafe_math_optimizations
17959 && !(reload_completed || reload_in_progress)"
17964 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17966 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17967 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17969 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17970 operands[2], operands[3]));
17973 [(set_attr "type" "frndint")
17974 (set_attr "i387_cw" "trunc")
17975 (set_attr "mode" "XF")])
17977 (define_insn "frndintxf2_trunc_i387"
17978 [(set (match_operand:XF 0 "register_operand" "=f")
17979 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17980 UNSPEC_FRNDINT_TRUNC))
17981 (use (match_operand:HI 2 "memory_operand" "m"))
17982 (use (match_operand:HI 3 "memory_operand" "m"))]
17983 "TARGET_USE_FANCY_MATH_387
17984 && flag_unsafe_math_optimizations"
17985 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17986 [(set_attr "type" "frndint")
17987 (set_attr "i387_cw" "trunc")
17988 (set_attr "mode" "XF")])
17990 (define_expand "btruncxf2"
17991 [(use (match_operand:XF 0 "register_operand" ""))
17992 (use (match_operand:XF 1 "register_operand" ""))]
17993 "TARGET_USE_FANCY_MATH_387
17994 && flag_unsafe_math_optimizations && !optimize_size"
17996 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18000 (define_expand "btruncdf2"
18001 [(use (match_operand:DF 0 "register_operand" ""))
18002 (use (match_operand:DF 1 "register_operand" ""))]
18003 "((TARGET_USE_FANCY_MATH_387
18004 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18005 && flag_unsafe_math_optimizations)
18006 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18007 && !flag_trapping_math))
18010 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18011 && !flag_trapping_math)
18014 ix86_expand_trunc (operand0, operand1);
18016 ix86_expand_truncdf_32 (operand0, operand1);
18020 rtx op0 = gen_reg_rtx (XFmode);
18021 rtx op1 = gen_reg_rtx (XFmode);
18023 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18024 emit_insn (gen_frndintxf2_trunc (op0, op1));
18026 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18031 (define_expand "btruncsf2"
18032 [(use (match_operand:SF 0 "register_operand" ""))
18033 (use (match_operand:SF 1 "register_operand" ""))]
18034 "((TARGET_USE_FANCY_MATH_387
18035 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18036 && flag_unsafe_math_optimizations)
18037 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18038 && !flag_trapping_math))
18041 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18042 && !flag_trapping_math)
18043 ix86_expand_trunc (operand0, operand1);
18046 rtx op0 = gen_reg_rtx (XFmode);
18047 rtx op1 = gen_reg_rtx (XFmode);
18049 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18050 emit_insn (gen_frndintxf2_trunc (op0, op1));
18052 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18057 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18058 (define_insn_and_split "frndintxf2_mask_pm"
18059 [(set (match_operand:XF 0 "register_operand" "=f")
18060 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18061 UNSPEC_FRNDINT_MASK_PM))
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_MASK_PM] = 1;
18072 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18073 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18075 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18076 operands[2], operands[3]));
18079 [(set_attr "type" "frndint")
18080 (set_attr "i387_cw" "mask_pm")
18081 (set_attr "mode" "XF")])
18083 (define_insn "frndintxf2_mask_pm_i387"
18084 [(set (match_operand:XF 0 "register_operand" "=f")
18085 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18086 UNSPEC_FRNDINT_MASK_PM))
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\tfclex\n\tfldcw\t%2"
18092 [(set_attr "type" "frndint")
18093 (set_attr "i387_cw" "mask_pm")
18094 (set_attr "mode" "XF")])
18096 (define_expand "nearbyintxf2"
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"
18102 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18107 (define_expand "nearbyintdf2"
18108 [(use (match_operand:DF 0 "register_operand" ""))
18109 (use (match_operand:DF 1 "register_operand" ""))]
18110 "TARGET_USE_FANCY_MATH_387
18111 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18112 && flag_unsafe_math_optimizations"
18114 rtx op0 = gen_reg_rtx (XFmode);
18115 rtx op1 = gen_reg_rtx (XFmode);
18117 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18118 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18120 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18124 (define_expand "nearbyintsf2"
18125 [(use (match_operand:SF 0 "register_operand" ""))
18126 (use (match_operand:SF 1 "register_operand" ""))]
18127 "TARGET_USE_FANCY_MATH_387
18128 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18129 && flag_unsafe_math_optimizations"
18131 rtx op0 = gen_reg_rtx (XFmode);
18132 rtx op1 = gen_reg_rtx (XFmode);
18134 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18135 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18137 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18142 ;; Block operation instructions
18145 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18148 [(set_attr "type" "cld")])
18150 (define_expand "movmemsi"
18151 [(use (match_operand:BLK 0 "memory_operand" ""))
18152 (use (match_operand:BLK 1 "memory_operand" ""))
18153 (use (match_operand:SI 2 "nonmemory_operand" ""))
18154 (use (match_operand:SI 3 "const_int_operand" ""))]
18157 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18158 operands[3], constm1_rtx))
18164 (define_expand "movmemdi"
18165 [(use (match_operand:BLK 0 "memory_operand" ""))
18166 (use (match_operand:BLK 1 "memory_operand" ""))
18167 (use (match_operand:DI 2 "nonmemory_operand" ""))
18168 (use (match_operand:DI 3 "const_int_operand" ""))]
18171 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18172 operands[3], constm1_rtx))
18178 ;; Most CPUs don't like single string operations
18179 ;; Handle this case here to simplify previous expander.
18181 (define_expand "strmov"
18182 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18183 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18184 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18185 (clobber (reg:CC FLAGS_REG))])
18186 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18187 (clobber (reg:CC FLAGS_REG))])]
18190 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18192 /* If .md ever supports :P for Pmode, these can be directly
18193 in the pattern above. */
18194 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18195 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18197 if (TARGET_SINGLE_STRINGOP || optimize_size)
18199 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18200 operands[2], operands[3],
18201 operands[5], operands[6]));
18205 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18208 (define_expand "strmov_singleop"
18209 [(parallel [(set (match_operand 1 "memory_operand" "")
18210 (match_operand 3 "memory_operand" ""))
18211 (set (match_operand 0 "register_operand" "")
18212 (match_operand 4 "" ""))
18213 (set (match_operand 2 "register_operand" "")
18214 (match_operand 5 "" ""))
18215 (use (reg:SI DIRFLAG_REG))])]
18216 "TARGET_SINGLE_STRINGOP || optimize_size"
18219 (define_insn "*strmovdi_rex_1"
18220 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18221 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18222 (set (match_operand:DI 0 "register_operand" "=D")
18223 (plus:DI (match_dup 2)
18225 (set (match_operand:DI 1 "register_operand" "=S")
18226 (plus:DI (match_dup 3)
18228 (use (reg:SI DIRFLAG_REG))]
18229 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18231 [(set_attr "type" "str")
18232 (set_attr "mode" "DI")
18233 (set_attr "memory" "both")])
18235 (define_insn "*strmovsi_1"
18236 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18237 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18238 (set (match_operand:SI 0 "register_operand" "=D")
18239 (plus:SI (match_dup 2)
18241 (set (match_operand:SI 1 "register_operand" "=S")
18242 (plus:SI (match_dup 3)
18244 (use (reg:SI DIRFLAG_REG))]
18245 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18247 [(set_attr "type" "str")
18248 (set_attr "mode" "SI")
18249 (set_attr "memory" "both")])
18251 (define_insn "*strmovsi_rex_1"
18252 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18253 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18254 (set (match_operand:DI 0 "register_operand" "=D")
18255 (plus:DI (match_dup 2)
18257 (set (match_operand:DI 1 "register_operand" "=S")
18258 (plus:DI (match_dup 3)
18260 (use (reg:SI DIRFLAG_REG))]
18261 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18263 [(set_attr "type" "str")
18264 (set_attr "mode" "SI")
18265 (set_attr "memory" "both")])
18267 (define_insn "*strmovhi_1"
18268 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18269 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18270 (set (match_operand:SI 0 "register_operand" "=D")
18271 (plus:SI (match_dup 2)
18273 (set (match_operand:SI 1 "register_operand" "=S")
18274 (plus:SI (match_dup 3)
18276 (use (reg:SI DIRFLAG_REG))]
18277 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18279 [(set_attr "type" "str")
18280 (set_attr "memory" "both")
18281 (set_attr "mode" "HI")])
18283 (define_insn "*strmovhi_rex_1"
18284 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18285 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18286 (set (match_operand:DI 0 "register_operand" "=D")
18287 (plus:DI (match_dup 2)
18289 (set (match_operand:DI 1 "register_operand" "=S")
18290 (plus:DI (match_dup 3)
18292 (use (reg:SI DIRFLAG_REG))]
18293 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18295 [(set_attr "type" "str")
18296 (set_attr "memory" "both")
18297 (set_attr "mode" "HI")])
18299 (define_insn "*strmovqi_1"
18300 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18301 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18302 (set (match_operand:SI 0 "register_operand" "=D")
18303 (plus:SI (match_dup 2)
18305 (set (match_operand:SI 1 "register_operand" "=S")
18306 (plus:SI (match_dup 3)
18308 (use (reg:SI DIRFLAG_REG))]
18309 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18311 [(set_attr "type" "str")
18312 (set_attr "memory" "both")
18313 (set_attr "mode" "QI")])
18315 (define_insn "*strmovqi_rex_1"
18316 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18317 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18318 (set (match_operand:DI 0 "register_operand" "=D")
18319 (plus:DI (match_dup 2)
18321 (set (match_operand:DI 1 "register_operand" "=S")
18322 (plus:DI (match_dup 3)
18324 (use (reg:SI DIRFLAG_REG))]
18325 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18327 [(set_attr "type" "str")
18328 (set_attr "memory" "both")
18329 (set_attr "mode" "QI")])
18331 (define_expand "rep_mov"
18332 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18333 (set (match_operand 0 "register_operand" "")
18334 (match_operand 5 "" ""))
18335 (set (match_operand 2 "register_operand" "")
18336 (match_operand 6 "" ""))
18337 (set (match_operand 1 "memory_operand" "")
18338 (match_operand 3 "memory_operand" ""))
18339 (use (match_dup 4))
18340 (use (reg:SI DIRFLAG_REG))])]
18344 (define_insn "*rep_movdi_rex64"
18345 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18346 (set (match_operand:DI 0 "register_operand" "=D")
18347 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18349 (match_operand:DI 3 "register_operand" "0")))
18350 (set (match_operand:DI 1 "register_operand" "=S")
18351 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18352 (match_operand:DI 4 "register_operand" "1")))
18353 (set (mem:BLK (match_dup 3))
18354 (mem:BLK (match_dup 4)))
18355 (use (match_dup 5))
18356 (use (reg:SI DIRFLAG_REG))]
18358 "{rep\;movsq|rep movsq}"
18359 [(set_attr "type" "str")
18360 (set_attr "prefix_rep" "1")
18361 (set_attr "memory" "both")
18362 (set_attr "mode" "DI")])
18364 (define_insn "*rep_movsi"
18365 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18366 (set (match_operand:SI 0 "register_operand" "=D")
18367 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18369 (match_operand:SI 3 "register_operand" "0")))
18370 (set (match_operand:SI 1 "register_operand" "=S")
18371 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18372 (match_operand:SI 4 "register_operand" "1")))
18373 (set (mem:BLK (match_dup 3))
18374 (mem:BLK (match_dup 4)))
18375 (use (match_dup 5))
18376 (use (reg:SI DIRFLAG_REG))]
18378 "{rep\;movsl|rep movsd}"
18379 [(set_attr "type" "str")
18380 (set_attr "prefix_rep" "1")
18381 (set_attr "memory" "both")
18382 (set_attr "mode" "SI")])
18384 (define_insn "*rep_movsi_rex64"
18385 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18386 (set (match_operand:DI 0 "register_operand" "=D")
18387 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18389 (match_operand:DI 3 "register_operand" "0")))
18390 (set (match_operand:DI 1 "register_operand" "=S")
18391 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18392 (match_operand:DI 4 "register_operand" "1")))
18393 (set (mem:BLK (match_dup 3))
18394 (mem:BLK (match_dup 4)))
18395 (use (match_dup 5))
18396 (use (reg:SI DIRFLAG_REG))]
18398 "{rep\;movsl|rep movsd}"
18399 [(set_attr "type" "str")
18400 (set_attr "prefix_rep" "1")
18401 (set_attr "memory" "both")
18402 (set_attr "mode" "SI")])
18404 (define_insn "*rep_movqi"
18405 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18406 (set (match_operand:SI 0 "register_operand" "=D")
18407 (plus:SI (match_operand:SI 3 "register_operand" "0")
18408 (match_operand:SI 5 "register_operand" "2")))
18409 (set (match_operand:SI 1 "register_operand" "=S")
18410 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18411 (set (mem:BLK (match_dup 3))
18412 (mem:BLK (match_dup 4)))
18413 (use (match_dup 5))
18414 (use (reg:SI DIRFLAG_REG))]
18416 "{rep\;movsb|rep movsb}"
18417 [(set_attr "type" "str")
18418 (set_attr "prefix_rep" "1")
18419 (set_attr "memory" "both")
18420 (set_attr "mode" "SI")])
18422 (define_insn "*rep_movqi_rex64"
18423 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18424 (set (match_operand:DI 0 "register_operand" "=D")
18425 (plus:DI (match_operand:DI 3 "register_operand" "0")
18426 (match_operand:DI 5 "register_operand" "2")))
18427 (set (match_operand:DI 1 "register_operand" "=S")
18428 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18429 (set (mem:BLK (match_dup 3))
18430 (mem:BLK (match_dup 4)))
18431 (use (match_dup 5))
18432 (use (reg:SI DIRFLAG_REG))]
18434 "{rep\;movsb|rep movsb}"
18435 [(set_attr "type" "str")
18436 (set_attr "prefix_rep" "1")
18437 (set_attr "memory" "both")
18438 (set_attr "mode" "SI")])
18440 (define_expand "setmemsi"
18441 [(use (match_operand:BLK 0 "memory_operand" ""))
18442 (use (match_operand:SI 1 "nonmemory_operand" ""))
18443 (use (match_operand 2 "const_int_operand" ""))
18444 (use (match_operand 3 "const_int_operand" ""))]
18447 if (ix86_expand_setmem (operands[0], operands[1],
18448 operands[2], operands[3],
18449 operands[3], constm1_rtx))
18455 (define_expand "setmemdi"
18456 [(use (match_operand:BLK 0 "memory_operand" ""))
18457 (use (match_operand:DI 1 "nonmemory_operand" ""))
18458 (use (match_operand 2 "const_int_operand" ""))
18459 (use (match_operand 3 "const_int_operand" ""))
18460 (use (match_operand 4 "const_int_operand" ""))
18461 (use (match_operand 5 "const_int_operand" ""))]
18464 if (ix86_expand_setmem (operands[0], operands[1],
18465 operands[2], operands[3],
18466 operands[3], constm1_rtx))
18472 ;; Most CPUs don't like single string operations
18473 ;; Handle this case here to simplify previous expander.
18475 (define_expand "strset"
18476 [(set (match_operand 1 "memory_operand" "")
18477 (match_operand 2 "register_operand" ""))
18478 (parallel [(set (match_operand 0 "register_operand" "")
18480 (clobber (reg:CC FLAGS_REG))])]
18483 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18484 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18486 /* If .md ever supports :P for Pmode, this can be directly
18487 in the pattern above. */
18488 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18489 GEN_INT (GET_MODE_SIZE (GET_MODE
18491 if (TARGET_SINGLE_STRINGOP || optimize_size)
18493 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18499 (define_expand "strset_singleop"
18500 [(parallel [(set (match_operand 1 "memory_operand" "")
18501 (match_operand 2 "register_operand" ""))
18502 (set (match_operand 0 "register_operand" "")
18503 (match_operand 3 "" ""))
18504 (use (reg:SI DIRFLAG_REG))])]
18505 "TARGET_SINGLE_STRINGOP || optimize_size"
18508 (define_insn "*strsetdi_rex_1"
18509 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18510 (match_operand:DI 2 "register_operand" "a"))
18511 (set (match_operand:DI 0 "register_operand" "=D")
18512 (plus:DI (match_dup 1)
18514 (use (reg:SI DIRFLAG_REG))]
18515 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18517 [(set_attr "type" "str")
18518 (set_attr "memory" "store")
18519 (set_attr "mode" "DI")])
18521 (define_insn "*strsetsi_1"
18522 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18523 (match_operand:SI 2 "register_operand" "a"))
18524 (set (match_operand:SI 0 "register_operand" "=D")
18525 (plus:SI (match_dup 1)
18527 (use (reg:SI DIRFLAG_REG))]
18528 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18530 [(set_attr "type" "str")
18531 (set_attr "memory" "store")
18532 (set_attr "mode" "SI")])
18534 (define_insn "*strsetsi_rex_1"
18535 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18536 (match_operand:SI 2 "register_operand" "a"))
18537 (set (match_operand:DI 0 "register_operand" "=D")
18538 (plus:DI (match_dup 1)
18540 (use (reg:SI DIRFLAG_REG))]
18541 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18543 [(set_attr "type" "str")
18544 (set_attr "memory" "store")
18545 (set_attr "mode" "SI")])
18547 (define_insn "*strsethi_1"
18548 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18549 (match_operand:HI 2 "register_operand" "a"))
18550 (set (match_operand:SI 0 "register_operand" "=D")
18551 (plus:SI (match_dup 1)
18553 (use (reg:SI DIRFLAG_REG))]
18554 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18556 [(set_attr "type" "str")
18557 (set_attr "memory" "store")
18558 (set_attr "mode" "HI")])
18560 (define_insn "*strsethi_rex_1"
18561 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18562 (match_operand:HI 2 "register_operand" "a"))
18563 (set (match_operand:DI 0 "register_operand" "=D")
18564 (plus:DI (match_dup 1)
18566 (use (reg:SI DIRFLAG_REG))]
18567 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18569 [(set_attr "type" "str")
18570 (set_attr "memory" "store")
18571 (set_attr "mode" "HI")])
18573 (define_insn "*strsetqi_1"
18574 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18575 (match_operand:QI 2 "register_operand" "a"))
18576 (set (match_operand:SI 0 "register_operand" "=D")
18577 (plus:SI (match_dup 1)
18579 (use (reg:SI DIRFLAG_REG))]
18580 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18582 [(set_attr "type" "str")
18583 (set_attr "memory" "store")
18584 (set_attr "mode" "QI")])
18586 (define_insn "*strsetqi_rex_1"
18587 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18588 (match_operand:QI 2 "register_operand" "a"))
18589 (set (match_operand:DI 0 "register_operand" "=D")
18590 (plus:DI (match_dup 1)
18592 (use (reg:SI DIRFLAG_REG))]
18593 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18595 [(set_attr "type" "str")
18596 (set_attr "memory" "store")
18597 (set_attr "mode" "QI")])
18599 (define_expand "rep_stos"
18600 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18601 (set (match_operand 0 "register_operand" "")
18602 (match_operand 4 "" ""))
18603 (set (match_operand 2 "memory_operand" "") (const_int 0))
18604 (use (match_operand 3 "register_operand" ""))
18605 (use (match_dup 1))
18606 (use (reg:SI DIRFLAG_REG))])]
18610 (define_insn "*rep_stosdi_rex64"
18611 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18612 (set (match_operand:DI 0 "register_operand" "=D")
18613 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18615 (match_operand:DI 3 "register_operand" "0")))
18616 (set (mem:BLK (match_dup 3))
18618 (use (match_operand:DI 2 "register_operand" "a"))
18619 (use (match_dup 4))
18620 (use (reg:SI DIRFLAG_REG))]
18622 "{rep\;stosq|rep stosq}"
18623 [(set_attr "type" "str")
18624 (set_attr "prefix_rep" "1")
18625 (set_attr "memory" "store")
18626 (set_attr "mode" "DI")])
18628 (define_insn "*rep_stossi"
18629 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18630 (set (match_operand:SI 0 "register_operand" "=D")
18631 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18633 (match_operand:SI 3 "register_operand" "0")))
18634 (set (mem:BLK (match_dup 3))
18636 (use (match_operand:SI 2 "register_operand" "a"))
18637 (use (match_dup 4))
18638 (use (reg:SI DIRFLAG_REG))]
18640 "{rep\;stosl|rep stosd}"
18641 [(set_attr "type" "str")
18642 (set_attr "prefix_rep" "1")
18643 (set_attr "memory" "store")
18644 (set_attr "mode" "SI")])
18646 (define_insn "*rep_stossi_rex64"
18647 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18648 (set (match_operand:DI 0 "register_operand" "=D")
18649 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18651 (match_operand:DI 3 "register_operand" "0")))
18652 (set (mem:BLK (match_dup 3))
18654 (use (match_operand:SI 2 "register_operand" "a"))
18655 (use (match_dup 4))
18656 (use (reg:SI DIRFLAG_REG))]
18658 "{rep\;stosl|rep stosd}"
18659 [(set_attr "type" "str")
18660 (set_attr "prefix_rep" "1")
18661 (set_attr "memory" "store")
18662 (set_attr "mode" "SI")])
18664 (define_insn "*rep_stosqi"
18665 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18666 (set (match_operand:SI 0 "register_operand" "=D")
18667 (plus:SI (match_operand:SI 3 "register_operand" "0")
18668 (match_operand:SI 4 "register_operand" "1")))
18669 (set (mem:BLK (match_dup 3))
18671 (use (match_operand:QI 2 "register_operand" "a"))
18672 (use (match_dup 4))
18673 (use (reg:SI DIRFLAG_REG))]
18675 "{rep\;stosb|rep stosb}"
18676 [(set_attr "type" "str")
18677 (set_attr "prefix_rep" "1")
18678 (set_attr "memory" "store")
18679 (set_attr "mode" "QI")])
18681 (define_insn "*rep_stosqi_rex64"
18682 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18683 (set (match_operand:DI 0 "register_operand" "=D")
18684 (plus:DI (match_operand:DI 3 "register_operand" "0")
18685 (match_operand:DI 4 "register_operand" "1")))
18686 (set (mem:BLK (match_dup 3))
18688 (use (match_operand:QI 2 "register_operand" "a"))
18689 (use (match_dup 4))
18690 (use (reg:SI DIRFLAG_REG))]
18692 "{rep\;stosb|rep stosb}"
18693 [(set_attr "type" "str")
18694 (set_attr "prefix_rep" "1")
18695 (set_attr "memory" "store")
18696 (set_attr "mode" "QI")])
18698 (define_expand "cmpstrnsi"
18699 [(set (match_operand:SI 0 "register_operand" "")
18700 (compare:SI (match_operand:BLK 1 "general_operand" "")
18701 (match_operand:BLK 2 "general_operand" "")))
18702 (use (match_operand 3 "general_operand" ""))
18703 (use (match_operand 4 "immediate_operand" ""))]
18704 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18706 rtx addr1, addr2, out, outlow, count, countreg, align;
18708 /* Can't use this if the user has appropriated esi or edi. */
18709 if (global_regs[4] || global_regs[5])
18713 if (GET_CODE (out) != REG)
18714 out = gen_reg_rtx (SImode);
18716 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18717 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18718 if (addr1 != XEXP (operands[1], 0))
18719 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18720 if (addr2 != XEXP (operands[2], 0))
18721 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18723 count = operands[3];
18724 countreg = ix86_zero_extend_to_Pmode (count);
18726 /* %%% Iff we are testing strict equality, we can use known alignment
18727 to good advantage. This may be possible with combine, particularly
18728 once cc0 is dead. */
18729 align = operands[4];
18731 emit_insn (gen_cld ());
18732 if (GET_CODE (count) == CONST_INT)
18734 if (INTVAL (count) == 0)
18736 emit_move_insn (operands[0], const0_rtx);
18739 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18740 operands[1], operands[2]));
18745 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18747 emit_insn (gen_cmpsi_1 (countreg, countreg));
18748 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18749 operands[1], operands[2]));
18752 outlow = gen_lowpart (QImode, out);
18753 emit_insn (gen_cmpintqi (outlow));
18754 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18756 if (operands[0] != out)
18757 emit_move_insn (operands[0], out);
18762 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18764 (define_expand "cmpintqi"
18765 [(set (match_dup 1)
18766 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18768 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18769 (parallel [(set (match_operand:QI 0 "register_operand" "")
18770 (minus:QI (match_dup 1)
18772 (clobber (reg:CC FLAGS_REG))])]
18774 "operands[1] = gen_reg_rtx (QImode);
18775 operands[2] = gen_reg_rtx (QImode);")
18777 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18778 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18780 (define_expand "cmpstrnqi_nz_1"
18781 [(parallel [(set (reg:CC FLAGS_REG)
18782 (compare:CC (match_operand 4 "memory_operand" "")
18783 (match_operand 5 "memory_operand" "")))
18784 (use (match_operand 2 "register_operand" ""))
18785 (use (match_operand:SI 3 "immediate_operand" ""))
18786 (use (reg:SI DIRFLAG_REG))
18787 (clobber (match_operand 0 "register_operand" ""))
18788 (clobber (match_operand 1 "register_operand" ""))
18789 (clobber (match_dup 2))])]
18793 (define_insn "*cmpstrnqi_nz_1"
18794 [(set (reg:CC FLAGS_REG)
18795 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18796 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18797 (use (match_operand:SI 6 "register_operand" "2"))
18798 (use (match_operand:SI 3 "immediate_operand" "i"))
18799 (use (reg:SI DIRFLAG_REG))
18800 (clobber (match_operand:SI 0 "register_operand" "=S"))
18801 (clobber (match_operand:SI 1 "register_operand" "=D"))
18802 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18805 [(set_attr "type" "str")
18806 (set_attr "mode" "QI")
18807 (set_attr "prefix_rep" "1")])
18809 (define_insn "*cmpstrnqi_nz_rex_1"
18810 [(set (reg:CC FLAGS_REG)
18811 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18812 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18813 (use (match_operand:DI 6 "register_operand" "2"))
18814 (use (match_operand:SI 3 "immediate_operand" "i"))
18815 (use (reg:SI DIRFLAG_REG))
18816 (clobber (match_operand:DI 0 "register_operand" "=S"))
18817 (clobber (match_operand:DI 1 "register_operand" "=D"))
18818 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18821 [(set_attr "type" "str")
18822 (set_attr "mode" "QI")
18823 (set_attr "prefix_rep" "1")])
18825 ;; The same, but the count is not known to not be zero.
18827 (define_expand "cmpstrnqi_1"
18828 [(parallel [(set (reg:CC FLAGS_REG)
18829 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18831 (compare:CC (match_operand 4 "memory_operand" "")
18832 (match_operand 5 "memory_operand" ""))
18834 (use (match_operand:SI 3 "immediate_operand" ""))
18835 (use (reg:CC FLAGS_REG))
18836 (use (reg:SI DIRFLAG_REG))
18837 (clobber (match_operand 0 "register_operand" ""))
18838 (clobber (match_operand 1 "register_operand" ""))
18839 (clobber (match_dup 2))])]
18843 (define_insn "*cmpstrnqi_1"
18844 [(set (reg:CC FLAGS_REG)
18845 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18847 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18848 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18850 (use (match_operand:SI 3 "immediate_operand" "i"))
18851 (use (reg:CC FLAGS_REG))
18852 (use (reg:SI DIRFLAG_REG))
18853 (clobber (match_operand:SI 0 "register_operand" "=S"))
18854 (clobber (match_operand:SI 1 "register_operand" "=D"))
18855 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18858 [(set_attr "type" "str")
18859 (set_attr "mode" "QI")
18860 (set_attr "prefix_rep" "1")])
18862 (define_insn "*cmpstrnqi_rex_1"
18863 [(set (reg:CC FLAGS_REG)
18864 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18866 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18867 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18869 (use (match_operand:SI 3 "immediate_operand" "i"))
18870 (use (reg:CC FLAGS_REG))
18871 (use (reg:SI DIRFLAG_REG))
18872 (clobber (match_operand:DI 0 "register_operand" "=S"))
18873 (clobber (match_operand:DI 1 "register_operand" "=D"))
18874 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18877 [(set_attr "type" "str")
18878 (set_attr "mode" "QI")
18879 (set_attr "prefix_rep" "1")])
18881 (define_expand "strlensi"
18882 [(set (match_operand:SI 0 "register_operand" "")
18883 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18884 (match_operand:QI 2 "immediate_operand" "")
18885 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18888 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18894 (define_expand "strlendi"
18895 [(set (match_operand:DI 0 "register_operand" "")
18896 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18897 (match_operand:QI 2 "immediate_operand" "")
18898 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18901 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18907 (define_expand "strlenqi_1"
18908 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18909 (use (reg:SI DIRFLAG_REG))
18910 (clobber (match_operand 1 "register_operand" ""))
18911 (clobber (reg:CC FLAGS_REG))])]
18915 (define_insn "*strlenqi_1"
18916 [(set (match_operand:SI 0 "register_operand" "=&c")
18917 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18918 (match_operand:QI 2 "register_operand" "a")
18919 (match_operand:SI 3 "immediate_operand" "i")
18920 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18921 (use (reg:SI DIRFLAG_REG))
18922 (clobber (match_operand:SI 1 "register_operand" "=D"))
18923 (clobber (reg:CC FLAGS_REG))]
18926 [(set_attr "type" "str")
18927 (set_attr "mode" "QI")
18928 (set_attr "prefix_rep" "1")])
18930 (define_insn "*strlenqi_rex_1"
18931 [(set (match_operand:DI 0 "register_operand" "=&c")
18932 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18933 (match_operand:QI 2 "register_operand" "a")
18934 (match_operand:DI 3 "immediate_operand" "i")
18935 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18936 (use (reg:SI DIRFLAG_REG))
18937 (clobber (match_operand:DI 1 "register_operand" "=D"))
18938 (clobber (reg:CC FLAGS_REG))]
18941 [(set_attr "type" "str")
18942 (set_attr "mode" "QI")
18943 (set_attr "prefix_rep" "1")])
18945 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18946 ;; handled in combine, but it is not currently up to the task.
18947 ;; When used for their truth value, the cmpstrn* expanders generate
18956 ;; The intermediate three instructions are unnecessary.
18958 ;; This one handles cmpstrn*_nz_1...
18961 (set (reg:CC FLAGS_REG)
18962 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18963 (mem:BLK (match_operand 5 "register_operand" ""))))
18964 (use (match_operand 6 "register_operand" ""))
18965 (use (match_operand:SI 3 "immediate_operand" ""))
18966 (use (reg:SI DIRFLAG_REG))
18967 (clobber (match_operand 0 "register_operand" ""))
18968 (clobber (match_operand 1 "register_operand" ""))
18969 (clobber (match_operand 2 "register_operand" ""))])
18970 (set (match_operand:QI 7 "register_operand" "")
18971 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18972 (set (match_operand:QI 8 "register_operand" "")
18973 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18974 (set (reg FLAGS_REG)
18975 (compare (match_dup 7) (match_dup 8)))
18977 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18979 (set (reg:CC FLAGS_REG)
18980 (compare:CC (mem:BLK (match_dup 4))
18981 (mem:BLK (match_dup 5))))
18982 (use (match_dup 6))
18983 (use (match_dup 3))
18984 (use (reg:SI DIRFLAG_REG))
18985 (clobber (match_dup 0))
18986 (clobber (match_dup 1))
18987 (clobber (match_dup 2))])]
18990 ;; ...and this one handles cmpstrn*_1.
18993 (set (reg:CC FLAGS_REG)
18994 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18996 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18997 (mem:BLK (match_operand 5 "register_operand" "")))
18999 (use (match_operand:SI 3 "immediate_operand" ""))
19000 (use (reg:CC FLAGS_REG))
19001 (use (reg:SI DIRFLAG_REG))
19002 (clobber (match_operand 0 "register_operand" ""))
19003 (clobber (match_operand 1 "register_operand" ""))
19004 (clobber (match_operand 2 "register_operand" ""))])
19005 (set (match_operand:QI 7 "register_operand" "")
19006 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19007 (set (match_operand:QI 8 "register_operand" "")
19008 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19009 (set (reg FLAGS_REG)
19010 (compare (match_dup 7) (match_dup 8)))
19012 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19014 (set (reg:CC FLAGS_REG)
19015 (if_then_else:CC (ne (match_dup 6)
19017 (compare:CC (mem:BLK (match_dup 4))
19018 (mem:BLK (match_dup 5)))
19020 (use (match_dup 3))
19021 (use (reg:CC FLAGS_REG))
19022 (use (reg:SI DIRFLAG_REG))
19023 (clobber (match_dup 0))
19024 (clobber (match_dup 1))
19025 (clobber (match_dup 2))])]
19030 ;; Conditional move instructions.
19032 (define_expand "movdicc"
19033 [(set (match_operand:DI 0 "register_operand" "")
19034 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19035 (match_operand:DI 2 "general_operand" "")
19036 (match_operand:DI 3 "general_operand" "")))]
19038 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19040 (define_insn "x86_movdicc_0_m1_rex64"
19041 [(set (match_operand:DI 0 "register_operand" "=r")
19042 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19045 (clobber (reg:CC FLAGS_REG))]
19048 ; Since we don't have the proper number of operands for an alu insn,
19049 ; fill in all the blanks.
19050 [(set_attr "type" "alu")
19051 (set_attr "pent_pair" "pu")
19052 (set_attr "memory" "none")
19053 (set_attr "imm_disp" "false")
19054 (set_attr "mode" "DI")
19055 (set_attr "length_immediate" "0")])
19057 (define_insn "*movdicc_c_rex64"
19058 [(set (match_operand:DI 0 "register_operand" "=r,r")
19059 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19060 [(reg FLAGS_REG) (const_int 0)])
19061 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19062 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19063 "TARGET_64BIT && TARGET_CMOVE
19064 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19066 cmov%O2%C1\t{%2, %0|%0, %2}
19067 cmov%O2%c1\t{%3, %0|%0, %3}"
19068 [(set_attr "type" "icmov")
19069 (set_attr "mode" "DI")])
19071 (define_expand "movsicc"
19072 [(set (match_operand:SI 0 "register_operand" "")
19073 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19074 (match_operand:SI 2 "general_operand" "")
19075 (match_operand:SI 3 "general_operand" "")))]
19077 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19079 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19080 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19081 ;; So just document what we're doing explicitly.
19083 (define_insn "x86_movsicc_0_m1"
19084 [(set (match_operand:SI 0 "register_operand" "=r")
19085 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19088 (clobber (reg:CC FLAGS_REG))]
19091 ; Since we don't have the proper number of operands for an alu insn,
19092 ; fill in all the blanks.
19093 [(set_attr "type" "alu")
19094 (set_attr "pent_pair" "pu")
19095 (set_attr "memory" "none")
19096 (set_attr "imm_disp" "false")
19097 (set_attr "mode" "SI")
19098 (set_attr "length_immediate" "0")])
19100 (define_insn "*movsicc_noc"
19101 [(set (match_operand:SI 0 "register_operand" "=r,r")
19102 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19103 [(reg FLAGS_REG) (const_int 0)])
19104 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19105 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19107 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19109 cmov%O2%C1\t{%2, %0|%0, %2}
19110 cmov%O2%c1\t{%3, %0|%0, %3}"
19111 [(set_attr "type" "icmov")
19112 (set_attr "mode" "SI")])
19114 (define_expand "movhicc"
19115 [(set (match_operand:HI 0 "register_operand" "")
19116 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19117 (match_operand:HI 2 "general_operand" "")
19118 (match_operand:HI 3 "general_operand" "")))]
19119 "TARGET_HIMODE_MATH"
19120 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19122 (define_insn "*movhicc_noc"
19123 [(set (match_operand:HI 0 "register_operand" "=r,r")
19124 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19125 [(reg FLAGS_REG) (const_int 0)])
19126 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19127 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19129 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19131 cmov%O2%C1\t{%2, %0|%0, %2}
19132 cmov%O2%c1\t{%3, %0|%0, %3}"
19133 [(set_attr "type" "icmov")
19134 (set_attr "mode" "HI")])
19136 (define_expand "movqicc"
19137 [(set (match_operand:QI 0 "register_operand" "")
19138 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19139 (match_operand:QI 2 "general_operand" "")
19140 (match_operand:QI 3 "general_operand" "")))]
19141 "TARGET_QIMODE_MATH"
19142 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19144 (define_insn_and_split "*movqicc_noc"
19145 [(set (match_operand:QI 0 "register_operand" "=r,r")
19146 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19147 [(match_operand 4 "flags_reg_operand" "")
19149 (match_operand:QI 2 "register_operand" "r,0")
19150 (match_operand:QI 3 "register_operand" "0,r")))]
19151 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19153 "&& reload_completed"
19154 [(set (match_dup 0)
19155 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19158 "operands[0] = gen_lowpart (SImode, operands[0]);
19159 operands[2] = gen_lowpart (SImode, operands[2]);
19160 operands[3] = gen_lowpart (SImode, operands[3]);"
19161 [(set_attr "type" "icmov")
19162 (set_attr "mode" "SI")])
19164 (define_expand "movsfcc"
19165 [(set (match_operand:SF 0 "register_operand" "")
19166 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19167 (match_operand:SF 2 "register_operand" "")
19168 (match_operand:SF 3 "register_operand" "")))]
19169 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19170 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19172 (define_insn "*movsfcc_1_387"
19173 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19174 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19175 [(reg FLAGS_REG) (const_int 0)])
19176 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19177 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19178 "TARGET_80387 && TARGET_CMOVE
19179 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19181 fcmov%F1\t{%2, %0|%0, %2}
19182 fcmov%f1\t{%3, %0|%0, %3}
19183 cmov%O2%C1\t{%2, %0|%0, %2}
19184 cmov%O2%c1\t{%3, %0|%0, %3}"
19185 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19186 (set_attr "mode" "SF,SF,SI,SI")])
19188 (define_expand "movdfcc"
19189 [(set (match_operand:DF 0 "register_operand" "")
19190 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19191 (match_operand:DF 2 "register_operand" "")
19192 (match_operand:DF 3 "register_operand" "")))]
19193 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19194 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19196 (define_insn "*movdfcc_1"
19197 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19198 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19199 [(reg FLAGS_REG) (const_int 0)])
19200 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19201 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19202 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19203 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19205 fcmov%F1\t{%2, %0|%0, %2}
19206 fcmov%f1\t{%3, %0|%0, %3}
19209 [(set_attr "type" "fcmov,fcmov,multi,multi")
19210 (set_attr "mode" "DF")])
19212 (define_insn "*movdfcc_1_rex64"
19213 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19214 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19215 [(reg FLAGS_REG) (const_int 0)])
19216 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19217 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19218 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19219 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19221 fcmov%F1\t{%2, %0|%0, %2}
19222 fcmov%f1\t{%3, %0|%0, %3}
19223 cmov%O2%C1\t{%2, %0|%0, %2}
19224 cmov%O2%c1\t{%3, %0|%0, %3}"
19225 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19226 (set_attr "mode" "DF")])
19229 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19230 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19231 [(match_operand 4 "flags_reg_operand" "")
19233 (match_operand:DF 2 "nonimmediate_operand" "")
19234 (match_operand:DF 3 "nonimmediate_operand" "")))]
19235 "!TARGET_64BIT && reload_completed"
19236 [(set (match_dup 2)
19237 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19241 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19244 "split_di (operands+2, 1, operands+5, operands+6);
19245 split_di (operands+3, 1, operands+7, operands+8);
19246 split_di (operands, 1, operands+2, operands+3);")
19248 (define_expand "movxfcc"
19249 [(set (match_operand:XF 0 "register_operand" "")
19250 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19251 (match_operand:XF 2 "register_operand" "")
19252 (match_operand:XF 3 "register_operand" "")))]
19253 "TARGET_80387 && TARGET_CMOVE"
19254 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19256 (define_insn "*movxfcc_1"
19257 [(set (match_operand:XF 0 "register_operand" "=f,f")
19258 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19259 [(reg FLAGS_REG) (const_int 0)])
19260 (match_operand:XF 2 "register_operand" "f,0")
19261 (match_operand:XF 3 "register_operand" "0,f")))]
19262 "TARGET_80387 && TARGET_CMOVE"
19264 fcmov%F1\t{%2, %0|%0, %2}
19265 fcmov%f1\t{%3, %0|%0, %3}"
19266 [(set_attr "type" "fcmov")
19267 (set_attr "mode" "XF")])
19269 ;; These versions of the min/max patterns are intentionally ignorant of
19270 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19271 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19272 ;; are undefined in this condition, we're certain this is correct.
19274 (define_insn "sminsf3"
19275 [(set (match_operand:SF 0 "register_operand" "=x")
19276 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19277 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19279 "minss\t{%2, %0|%0, %2}"
19280 [(set_attr "type" "sseadd")
19281 (set_attr "mode" "SF")])
19283 (define_insn "smaxsf3"
19284 [(set (match_operand:SF 0 "register_operand" "=x")
19285 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19286 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19288 "maxss\t{%2, %0|%0, %2}"
19289 [(set_attr "type" "sseadd")
19290 (set_attr "mode" "SF")])
19292 (define_insn "smindf3"
19293 [(set (match_operand:DF 0 "register_operand" "=x")
19294 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19295 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19296 "TARGET_SSE2 && TARGET_SSE_MATH"
19297 "minsd\t{%2, %0|%0, %2}"
19298 [(set_attr "type" "sseadd")
19299 (set_attr "mode" "DF")])
19301 (define_insn "smaxdf3"
19302 [(set (match_operand:DF 0 "register_operand" "=x")
19303 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19304 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19305 "TARGET_SSE2 && TARGET_SSE_MATH"
19306 "maxsd\t{%2, %0|%0, %2}"
19307 [(set_attr "type" "sseadd")
19308 (set_attr "mode" "DF")])
19310 ;; These versions of the min/max patterns implement exactly the operations
19311 ;; min = (op1 < op2 ? op1 : op2)
19312 ;; max = (!(op1 < op2) ? op1 : op2)
19313 ;; Their operands are not commutative, and thus they may be used in the
19314 ;; presence of -0.0 and NaN.
19316 (define_insn "*ieee_sminsf3"
19317 [(set (match_operand:SF 0 "register_operand" "=x")
19318 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19319 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19322 "minss\t{%2, %0|%0, %2}"
19323 [(set_attr "type" "sseadd")
19324 (set_attr "mode" "SF")])
19326 (define_insn "*ieee_smaxsf3"
19327 [(set (match_operand:SF 0 "register_operand" "=x")
19328 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19329 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19332 "maxss\t{%2, %0|%0, %2}"
19333 [(set_attr "type" "sseadd")
19334 (set_attr "mode" "SF")])
19336 (define_insn "*ieee_smindf3"
19337 [(set (match_operand:DF 0 "register_operand" "=x")
19338 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19339 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19341 "TARGET_SSE2 && TARGET_SSE_MATH"
19342 "minsd\t{%2, %0|%0, %2}"
19343 [(set_attr "type" "sseadd")
19344 (set_attr "mode" "DF")])
19346 (define_insn "*ieee_smaxdf3"
19347 [(set (match_operand:DF 0 "register_operand" "=x")
19348 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19349 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19351 "TARGET_SSE2 && TARGET_SSE_MATH"
19352 "maxsd\t{%2, %0|%0, %2}"
19353 [(set_attr "type" "sseadd")
19354 (set_attr "mode" "DF")])
19356 ;; Make two stack loads independent:
19358 ;; fld %st(0) -> fld bb
19359 ;; fmul bb fmul %st(1), %st
19361 ;; Actually we only match the last two instructions for simplicity.
19363 [(set (match_operand 0 "fp_register_operand" "")
19364 (match_operand 1 "fp_register_operand" ""))
19366 (match_operator 2 "binary_fp_operator"
19368 (match_operand 3 "memory_operand" "")]))]
19369 "REGNO (operands[0]) != REGNO (operands[1])"
19370 [(set (match_dup 0) (match_dup 3))
19371 (set (match_dup 0) (match_dup 4))]
19373 ;; The % modifier is not operational anymore in peephole2's, so we have to
19374 ;; swap the operands manually in the case of addition and multiplication.
19375 "if (COMMUTATIVE_ARITH_P (operands[2]))
19376 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19377 operands[0], operands[1]);
19379 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19380 operands[1], operands[0]);")
19382 ;; Conditional addition patterns
19383 (define_expand "addqicc"
19384 [(match_operand:QI 0 "register_operand" "")
19385 (match_operand 1 "comparison_operator" "")
19386 (match_operand:QI 2 "register_operand" "")
19387 (match_operand:QI 3 "const_int_operand" "")]
19389 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19391 (define_expand "addhicc"
19392 [(match_operand:HI 0 "register_operand" "")
19393 (match_operand 1 "comparison_operator" "")
19394 (match_operand:HI 2 "register_operand" "")
19395 (match_operand:HI 3 "const_int_operand" "")]
19397 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19399 (define_expand "addsicc"
19400 [(match_operand:SI 0 "register_operand" "")
19401 (match_operand 1 "comparison_operator" "")
19402 (match_operand:SI 2 "register_operand" "")
19403 (match_operand:SI 3 "const_int_operand" "")]
19405 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19407 (define_expand "adddicc"
19408 [(match_operand:DI 0 "register_operand" "")
19409 (match_operand 1 "comparison_operator" "")
19410 (match_operand:DI 2 "register_operand" "")
19411 (match_operand:DI 3 "const_int_operand" "")]
19413 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19416 ;; Misc patterns (?)
19418 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19419 ;; Otherwise there will be nothing to keep
19421 ;; [(set (reg ebp) (reg esp))]
19422 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19423 ;; (clobber (eflags)]
19424 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19426 ;; in proper program order.
19427 (define_insn "pro_epilogue_adjust_stack_1"
19428 [(set (match_operand:SI 0 "register_operand" "=r,r")
19429 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19430 (match_operand:SI 2 "immediate_operand" "i,i")))
19431 (clobber (reg:CC FLAGS_REG))
19432 (clobber (mem:BLK (scratch)))]
19435 switch (get_attr_type (insn))
19438 return "mov{l}\t{%1, %0|%0, %1}";
19441 if (GET_CODE (operands[2]) == CONST_INT
19442 && (INTVAL (operands[2]) == 128
19443 || (INTVAL (operands[2]) < 0
19444 && INTVAL (operands[2]) != -128)))
19446 operands[2] = GEN_INT (-INTVAL (operands[2]));
19447 return "sub{l}\t{%2, %0|%0, %2}";
19449 return "add{l}\t{%2, %0|%0, %2}";
19452 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19453 return "lea{l}\t{%a2, %0|%0, %a2}";
19456 gcc_unreachable ();
19459 [(set (attr "type")
19460 (cond [(eq_attr "alternative" "0")
19461 (const_string "alu")
19462 (match_operand:SI 2 "const0_operand" "")
19463 (const_string "imov")
19465 (const_string "lea")))
19466 (set_attr "mode" "SI")])
19468 (define_insn "pro_epilogue_adjust_stack_rex64"
19469 [(set (match_operand:DI 0 "register_operand" "=r,r")
19470 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19471 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19472 (clobber (reg:CC FLAGS_REG))
19473 (clobber (mem:BLK (scratch)))]
19476 switch (get_attr_type (insn))
19479 return "mov{q}\t{%1, %0|%0, %1}";
19482 if (GET_CODE (operands[2]) == CONST_INT
19483 /* Avoid overflows. */
19484 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19485 && (INTVAL (operands[2]) == 128
19486 || (INTVAL (operands[2]) < 0
19487 && INTVAL (operands[2]) != -128)))
19489 operands[2] = GEN_INT (-INTVAL (operands[2]));
19490 return "sub{q}\t{%2, %0|%0, %2}";
19492 return "add{q}\t{%2, %0|%0, %2}";
19495 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19496 return "lea{q}\t{%a2, %0|%0, %a2}";
19499 gcc_unreachable ();
19502 [(set (attr "type")
19503 (cond [(eq_attr "alternative" "0")
19504 (const_string "alu")
19505 (match_operand:DI 2 "const0_operand" "")
19506 (const_string "imov")
19508 (const_string "lea")))
19509 (set_attr "mode" "DI")])
19511 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19512 [(set (match_operand:DI 0 "register_operand" "=r,r")
19513 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19514 (match_operand:DI 3 "immediate_operand" "i,i")))
19515 (use (match_operand:DI 2 "register_operand" "r,r"))
19516 (clobber (reg:CC FLAGS_REG))
19517 (clobber (mem:BLK (scratch)))]
19520 switch (get_attr_type (insn))
19523 return "add{q}\t{%2, %0|%0, %2}";
19526 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19527 return "lea{q}\t{%a2, %0|%0, %a2}";
19530 gcc_unreachable ();
19533 [(set_attr "type" "alu,lea")
19534 (set_attr "mode" "DI")])
19536 (define_expand "allocate_stack_worker"
19537 [(match_operand:SI 0 "register_operand" "")]
19538 "TARGET_STACK_PROBE"
19540 if (reload_completed)
19543 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19545 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19550 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19552 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19557 (define_insn "allocate_stack_worker_1"
19558 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19559 UNSPECV_STACK_PROBE)
19560 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19561 (clobber (match_scratch:SI 1 "=0"))
19562 (clobber (reg:CC FLAGS_REG))]
19563 "!TARGET_64BIT && TARGET_STACK_PROBE"
19565 [(set_attr "type" "multi")
19566 (set_attr "length" "5")])
19568 (define_expand "allocate_stack_worker_postreload"
19569 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19570 UNSPECV_STACK_PROBE)
19571 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19572 (clobber (match_dup 0))
19573 (clobber (reg:CC FLAGS_REG))])]
19577 (define_insn "allocate_stack_worker_rex64"
19578 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19579 UNSPECV_STACK_PROBE)
19580 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19581 (clobber (match_scratch:DI 1 "=0"))
19582 (clobber (reg:CC FLAGS_REG))]
19583 "TARGET_64BIT && TARGET_STACK_PROBE"
19585 [(set_attr "type" "multi")
19586 (set_attr "length" "5")])
19588 (define_expand "allocate_stack_worker_rex64_postreload"
19589 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19590 UNSPECV_STACK_PROBE)
19591 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19592 (clobber (match_dup 0))
19593 (clobber (reg:CC FLAGS_REG))])]
19597 (define_expand "allocate_stack"
19598 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19599 (minus:SI (reg:SI SP_REG)
19600 (match_operand:SI 1 "general_operand" "")))
19601 (clobber (reg:CC FLAGS_REG))])
19602 (parallel [(set (reg:SI SP_REG)
19603 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19604 (clobber (reg:CC FLAGS_REG))])]
19605 "TARGET_STACK_PROBE"
19607 #ifdef CHECK_STACK_LIMIT
19608 if (GET_CODE (operands[1]) == CONST_INT
19609 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19610 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19614 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19617 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19621 (define_expand "builtin_setjmp_receiver"
19622 [(label_ref (match_operand 0 "" ""))]
19623 "!TARGET_64BIT && flag_pic"
19628 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19629 rtx label_rtx = gen_label_rtx ();
19630 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19631 xops[0] = xops[1] = picreg;
19632 xops[2] = gen_rtx_CONST (SImode,
19633 gen_rtx_MINUS (SImode,
19634 gen_rtx_LABEL_REF (SImode, label_rtx),
19635 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19636 ix86_expand_binary_operator (MINUS, SImode, xops);
19639 emit_insn (gen_set_got (pic_offset_table_rtx));
19643 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19646 [(set (match_operand 0 "register_operand" "")
19647 (match_operator 3 "promotable_binary_operator"
19648 [(match_operand 1 "register_operand" "")
19649 (match_operand 2 "aligned_operand" "")]))
19650 (clobber (reg:CC FLAGS_REG))]
19651 "! TARGET_PARTIAL_REG_STALL && reload_completed
19652 && ((GET_MODE (operands[0]) == HImode
19653 && ((!optimize_size && !TARGET_FAST_PREFIX)
19654 /* ??? next two lines just !satisfies_constraint_K (...) */
19655 || GET_CODE (operands[2]) != CONST_INT
19656 || satisfies_constraint_K (operands[2])))
19657 || (GET_MODE (operands[0]) == QImode
19658 && (TARGET_PROMOTE_QImode || optimize_size)))"
19659 [(parallel [(set (match_dup 0)
19660 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19661 (clobber (reg:CC FLAGS_REG))])]
19662 "operands[0] = gen_lowpart (SImode, operands[0]);
19663 operands[1] = gen_lowpart (SImode, operands[1]);
19664 if (GET_CODE (operands[3]) != ASHIFT)
19665 operands[2] = gen_lowpart (SImode, operands[2]);
19666 PUT_MODE (operands[3], SImode);")
19668 ; Promote the QImode tests, as i386 has encoding of the AND
19669 ; instruction with 32-bit sign-extended immediate and thus the
19670 ; instruction size is unchanged, except in the %eax case for
19671 ; which it is increased by one byte, hence the ! optimize_size.
19673 [(set (match_operand 0 "flags_reg_operand" "")
19674 (match_operator 2 "compare_operator"
19675 [(and (match_operand 3 "aligned_operand" "")
19676 (match_operand 4 "const_int_operand" ""))
19678 (set (match_operand 1 "register_operand" "")
19679 (and (match_dup 3) (match_dup 4)))]
19680 "! TARGET_PARTIAL_REG_STALL && reload_completed
19681 /* Ensure that the operand will remain sign-extended immediate. */
19682 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19684 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19685 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19686 [(parallel [(set (match_dup 0)
19687 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19690 (and:SI (match_dup 3) (match_dup 4)))])]
19693 = gen_int_mode (INTVAL (operands[4])
19694 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19695 operands[1] = gen_lowpart (SImode, operands[1]);
19696 operands[3] = gen_lowpart (SImode, operands[3]);
19699 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19700 ; the TEST instruction with 32-bit sign-extended immediate and thus
19701 ; the instruction size would at least double, which is not what we
19702 ; want even with ! optimize_size.
19704 [(set (match_operand 0 "flags_reg_operand" "")
19705 (match_operator 1 "compare_operator"
19706 [(and (match_operand:HI 2 "aligned_operand" "")
19707 (match_operand:HI 3 "const_int_operand" ""))
19709 "! TARGET_PARTIAL_REG_STALL && reload_completed
19710 /* Ensure that the operand will remain sign-extended immediate. */
19711 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19712 && ! TARGET_FAST_PREFIX
19713 && ! optimize_size"
19714 [(set (match_dup 0)
19715 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19719 = gen_int_mode (INTVAL (operands[3])
19720 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19721 operands[2] = gen_lowpart (SImode, operands[2]);
19725 [(set (match_operand 0 "register_operand" "")
19726 (neg (match_operand 1 "register_operand" "")))
19727 (clobber (reg:CC FLAGS_REG))]
19728 "! TARGET_PARTIAL_REG_STALL && reload_completed
19729 && (GET_MODE (operands[0]) == HImode
19730 || (GET_MODE (operands[0]) == QImode
19731 && (TARGET_PROMOTE_QImode || optimize_size)))"
19732 [(parallel [(set (match_dup 0)
19733 (neg:SI (match_dup 1)))
19734 (clobber (reg:CC FLAGS_REG))])]
19735 "operands[0] = gen_lowpart (SImode, operands[0]);
19736 operands[1] = gen_lowpart (SImode, operands[1]);")
19739 [(set (match_operand 0 "register_operand" "")
19740 (not (match_operand 1 "register_operand" "")))]
19741 "! TARGET_PARTIAL_REG_STALL && reload_completed
19742 && (GET_MODE (operands[0]) == HImode
19743 || (GET_MODE (operands[0]) == QImode
19744 && (TARGET_PROMOTE_QImode || optimize_size)))"
19745 [(set (match_dup 0)
19746 (not:SI (match_dup 1)))]
19747 "operands[0] = gen_lowpart (SImode, operands[0]);
19748 operands[1] = gen_lowpart (SImode, operands[1]);")
19751 [(set (match_operand 0 "register_operand" "")
19752 (if_then_else (match_operator 1 "comparison_operator"
19753 [(reg FLAGS_REG) (const_int 0)])
19754 (match_operand 2 "register_operand" "")
19755 (match_operand 3 "register_operand" "")))]
19756 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19757 && (GET_MODE (operands[0]) == HImode
19758 || (GET_MODE (operands[0]) == QImode
19759 && (TARGET_PROMOTE_QImode || optimize_size)))"
19760 [(set (match_dup 0)
19761 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19762 "operands[0] = gen_lowpart (SImode, operands[0]);
19763 operands[2] = gen_lowpart (SImode, operands[2]);
19764 operands[3] = gen_lowpart (SImode, operands[3]);")
19767 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19768 ;; transform a complex memory operation into two memory to register operations.
19770 ;; Don't push memory operands
19772 [(set (match_operand:SI 0 "push_operand" "")
19773 (match_operand:SI 1 "memory_operand" ""))
19774 (match_scratch:SI 2 "r")]
19775 "!optimize_size && !TARGET_PUSH_MEMORY
19776 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19777 [(set (match_dup 2) (match_dup 1))
19778 (set (match_dup 0) (match_dup 2))]
19782 [(set (match_operand:DI 0 "push_operand" "")
19783 (match_operand:DI 1 "memory_operand" ""))
19784 (match_scratch:DI 2 "r")]
19785 "!optimize_size && !TARGET_PUSH_MEMORY
19786 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19787 [(set (match_dup 2) (match_dup 1))
19788 (set (match_dup 0) (match_dup 2))]
19791 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19794 [(set (match_operand:SF 0 "push_operand" "")
19795 (match_operand:SF 1 "memory_operand" ""))
19796 (match_scratch:SF 2 "r")]
19797 "!optimize_size && !TARGET_PUSH_MEMORY
19798 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19799 [(set (match_dup 2) (match_dup 1))
19800 (set (match_dup 0) (match_dup 2))]
19804 [(set (match_operand:HI 0 "push_operand" "")
19805 (match_operand:HI 1 "memory_operand" ""))
19806 (match_scratch:HI 2 "r")]
19807 "!optimize_size && !TARGET_PUSH_MEMORY
19808 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19809 [(set (match_dup 2) (match_dup 1))
19810 (set (match_dup 0) (match_dup 2))]
19814 [(set (match_operand:QI 0 "push_operand" "")
19815 (match_operand:QI 1 "memory_operand" ""))
19816 (match_scratch:QI 2 "q")]
19817 "!optimize_size && !TARGET_PUSH_MEMORY
19818 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19819 [(set (match_dup 2) (match_dup 1))
19820 (set (match_dup 0) (match_dup 2))]
19823 ;; Don't move an immediate directly to memory when the instruction
19826 [(match_scratch:SI 1 "r")
19827 (set (match_operand:SI 0 "memory_operand" "")
19830 && ! TARGET_USE_MOV0
19831 && TARGET_SPLIT_LONG_MOVES
19832 && get_attr_length (insn) >= ix86_cost->large_insn
19833 && peep2_regno_dead_p (0, FLAGS_REG)"
19834 [(parallel [(set (match_dup 1) (const_int 0))
19835 (clobber (reg:CC FLAGS_REG))])
19836 (set (match_dup 0) (match_dup 1))]
19840 [(match_scratch:HI 1 "r")
19841 (set (match_operand:HI 0 "memory_operand" "")
19844 && ! TARGET_USE_MOV0
19845 && TARGET_SPLIT_LONG_MOVES
19846 && get_attr_length (insn) >= ix86_cost->large_insn
19847 && peep2_regno_dead_p (0, FLAGS_REG)"
19848 [(parallel [(set (match_dup 2) (const_int 0))
19849 (clobber (reg:CC FLAGS_REG))])
19850 (set (match_dup 0) (match_dup 1))]
19851 "operands[2] = gen_lowpart (SImode, operands[1]);")
19854 [(match_scratch:QI 1 "q")
19855 (set (match_operand:QI 0 "memory_operand" "")
19858 && ! TARGET_USE_MOV0
19859 && TARGET_SPLIT_LONG_MOVES
19860 && get_attr_length (insn) >= ix86_cost->large_insn
19861 && peep2_regno_dead_p (0, FLAGS_REG)"
19862 [(parallel [(set (match_dup 2) (const_int 0))
19863 (clobber (reg:CC FLAGS_REG))])
19864 (set (match_dup 0) (match_dup 1))]
19865 "operands[2] = gen_lowpart (SImode, operands[1]);")
19868 [(match_scratch:SI 2 "r")
19869 (set (match_operand:SI 0 "memory_operand" "")
19870 (match_operand:SI 1 "immediate_operand" ""))]
19872 && get_attr_length (insn) >= ix86_cost->large_insn
19873 && TARGET_SPLIT_LONG_MOVES"
19874 [(set (match_dup 2) (match_dup 1))
19875 (set (match_dup 0) (match_dup 2))]
19879 [(match_scratch:HI 2 "r")
19880 (set (match_operand:HI 0 "memory_operand" "")
19881 (match_operand:HI 1 "immediate_operand" ""))]
19882 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19883 && TARGET_SPLIT_LONG_MOVES"
19884 [(set (match_dup 2) (match_dup 1))
19885 (set (match_dup 0) (match_dup 2))]
19889 [(match_scratch:QI 2 "q")
19890 (set (match_operand:QI 0 "memory_operand" "")
19891 (match_operand:QI 1 "immediate_operand" ""))]
19892 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19893 && TARGET_SPLIT_LONG_MOVES"
19894 [(set (match_dup 2) (match_dup 1))
19895 (set (match_dup 0) (match_dup 2))]
19898 ;; Don't compare memory with zero, load and use a test instead.
19900 [(set (match_operand 0 "flags_reg_operand" "")
19901 (match_operator 1 "compare_operator"
19902 [(match_operand:SI 2 "memory_operand" "")
19904 (match_scratch:SI 3 "r")]
19905 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19906 [(set (match_dup 3) (match_dup 2))
19907 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19910 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19911 ;; Don't split NOTs with a displacement operand, because resulting XOR
19912 ;; will not be pairable anyway.
19914 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19915 ;; represented using a modRM byte. The XOR replacement is long decoded,
19916 ;; so this split helps here as well.
19918 ;; Note: Can't do this as a regular split because we can't get proper
19919 ;; lifetime information then.
19922 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19923 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19925 && peep2_regno_dead_p (0, FLAGS_REG)
19926 && ((TARGET_PENTIUM
19927 && (GET_CODE (operands[0]) != MEM
19928 || !memory_displacement_operand (operands[0], SImode)))
19929 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19930 [(parallel [(set (match_dup 0)
19931 (xor:SI (match_dup 1) (const_int -1)))
19932 (clobber (reg:CC FLAGS_REG))])]
19936 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19937 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19939 && peep2_regno_dead_p (0, FLAGS_REG)
19940 && ((TARGET_PENTIUM
19941 && (GET_CODE (operands[0]) != MEM
19942 || !memory_displacement_operand (operands[0], HImode)))
19943 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19944 [(parallel [(set (match_dup 0)
19945 (xor:HI (match_dup 1) (const_int -1)))
19946 (clobber (reg:CC FLAGS_REG))])]
19950 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19951 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19953 && peep2_regno_dead_p (0, FLAGS_REG)
19954 && ((TARGET_PENTIUM
19955 && (GET_CODE (operands[0]) != MEM
19956 || !memory_displacement_operand (operands[0], QImode)))
19957 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19958 [(parallel [(set (match_dup 0)
19959 (xor:QI (match_dup 1) (const_int -1)))
19960 (clobber (reg:CC FLAGS_REG))])]
19963 ;; Non pairable "test imm, reg" instructions can be translated to
19964 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19965 ;; byte opcode instead of two, have a short form for byte operands),
19966 ;; so do it for other CPUs as well. Given that the value was dead,
19967 ;; this should not create any new dependencies. Pass on the sub-word
19968 ;; versions if we're concerned about partial register stalls.
19971 [(set (match_operand 0 "flags_reg_operand" "")
19972 (match_operator 1 "compare_operator"
19973 [(and:SI (match_operand:SI 2 "register_operand" "")
19974 (match_operand:SI 3 "immediate_operand" ""))
19976 "ix86_match_ccmode (insn, CCNOmode)
19977 && (true_regnum (operands[2]) != 0
19978 || satisfies_constraint_K (operands[3]))
19979 && peep2_reg_dead_p (1, operands[2])"
19981 [(set (match_dup 0)
19982 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19985 (and:SI (match_dup 2) (match_dup 3)))])]
19988 ;; We don't need to handle HImode case, because it will be promoted to SImode
19989 ;; on ! TARGET_PARTIAL_REG_STALL
19992 [(set (match_operand 0 "flags_reg_operand" "")
19993 (match_operator 1 "compare_operator"
19994 [(and:QI (match_operand:QI 2 "register_operand" "")
19995 (match_operand:QI 3 "immediate_operand" ""))
19997 "! TARGET_PARTIAL_REG_STALL
19998 && ix86_match_ccmode (insn, CCNOmode)
19999 && true_regnum (operands[2]) != 0
20000 && peep2_reg_dead_p (1, operands[2])"
20002 [(set (match_dup 0)
20003 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20006 (and:QI (match_dup 2) (match_dup 3)))])]
20010 [(set (match_operand 0 "flags_reg_operand" "")
20011 (match_operator 1 "compare_operator"
20014 (match_operand 2 "ext_register_operand" "")
20017 (match_operand 3 "const_int_operand" ""))
20019 "! TARGET_PARTIAL_REG_STALL
20020 && ix86_match_ccmode (insn, CCNOmode)
20021 && true_regnum (operands[2]) != 0
20022 && peep2_reg_dead_p (1, operands[2])"
20023 [(parallel [(set (match_dup 0)
20032 (set (zero_extract:SI (match_dup 2)
20043 ;; Don't do logical operations with memory inputs.
20045 [(match_scratch:SI 2 "r")
20046 (parallel [(set (match_operand:SI 0 "register_operand" "")
20047 (match_operator:SI 3 "arith_or_logical_operator"
20049 (match_operand:SI 1 "memory_operand" "")]))
20050 (clobber (reg:CC FLAGS_REG))])]
20051 "! optimize_size && ! TARGET_READ_MODIFY"
20052 [(set (match_dup 2) (match_dup 1))
20053 (parallel [(set (match_dup 0)
20054 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20055 (clobber (reg:CC FLAGS_REG))])]
20059 [(match_scratch:SI 2 "r")
20060 (parallel [(set (match_operand:SI 0 "register_operand" "")
20061 (match_operator:SI 3 "arith_or_logical_operator"
20062 [(match_operand:SI 1 "memory_operand" "")
20064 (clobber (reg:CC FLAGS_REG))])]
20065 "! optimize_size && ! TARGET_READ_MODIFY"
20066 [(set (match_dup 2) (match_dup 1))
20067 (parallel [(set (match_dup 0)
20068 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20069 (clobber (reg:CC FLAGS_REG))])]
20072 ; Don't do logical operations with memory outputs
20074 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20075 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20076 ; the same decoder scheduling characteristics as the original.
20079 [(match_scratch:SI 2 "r")
20080 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20081 (match_operator:SI 3 "arith_or_logical_operator"
20083 (match_operand:SI 1 "nonmemory_operand" "")]))
20084 (clobber (reg:CC FLAGS_REG))])]
20085 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20086 [(set (match_dup 2) (match_dup 0))
20087 (parallel [(set (match_dup 2)
20088 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20089 (clobber (reg:CC FLAGS_REG))])
20090 (set (match_dup 0) (match_dup 2))]
20094 [(match_scratch:SI 2 "r")
20095 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20096 (match_operator:SI 3 "arith_or_logical_operator"
20097 [(match_operand:SI 1 "nonmemory_operand" "")
20099 (clobber (reg:CC FLAGS_REG))])]
20100 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20101 [(set (match_dup 2) (match_dup 0))
20102 (parallel [(set (match_dup 2)
20103 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20104 (clobber (reg:CC FLAGS_REG))])
20105 (set (match_dup 0) (match_dup 2))]
20108 ;; Attempt to always use XOR for zeroing registers.
20110 [(set (match_operand 0 "register_operand" "")
20111 (match_operand 1 "const0_operand" ""))]
20112 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20113 && (! TARGET_USE_MOV0 || optimize_size)
20114 && GENERAL_REG_P (operands[0])
20115 && peep2_regno_dead_p (0, FLAGS_REG)"
20116 [(parallel [(set (match_dup 0) (const_int 0))
20117 (clobber (reg:CC FLAGS_REG))])]
20119 operands[0] = gen_lowpart (word_mode, operands[0]);
20123 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20125 "(GET_MODE (operands[0]) == QImode
20126 || GET_MODE (operands[0]) == HImode)
20127 && (! TARGET_USE_MOV0 || optimize_size)
20128 && peep2_regno_dead_p (0, FLAGS_REG)"
20129 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20130 (clobber (reg:CC FLAGS_REG))])])
20132 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20134 [(set (match_operand 0 "register_operand" "")
20136 "(GET_MODE (operands[0]) == HImode
20137 || GET_MODE (operands[0]) == SImode
20138 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20139 && (optimize_size || TARGET_PENTIUM)
20140 && peep2_regno_dead_p (0, FLAGS_REG)"
20141 [(parallel [(set (match_dup 0) (const_int -1))
20142 (clobber (reg:CC FLAGS_REG))])]
20143 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20146 ;; Attempt to convert simple leas to adds. These can be created by
20149 [(set (match_operand:SI 0 "register_operand" "")
20150 (plus:SI (match_dup 0)
20151 (match_operand:SI 1 "nonmemory_operand" "")))]
20152 "peep2_regno_dead_p (0, FLAGS_REG)"
20153 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20154 (clobber (reg:CC FLAGS_REG))])]
20158 [(set (match_operand:SI 0 "register_operand" "")
20159 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20160 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20161 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20162 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20163 (clobber (reg:CC FLAGS_REG))])]
20164 "operands[2] = gen_lowpart (SImode, operands[2]);")
20167 [(set (match_operand:DI 0 "register_operand" "")
20168 (plus:DI (match_dup 0)
20169 (match_operand:DI 1 "x86_64_general_operand" "")))]
20170 "peep2_regno_dead_p (0, FLAGS_REG)"
20171 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20172 (clobber (reg:CC FLAGS_REG))])]
20176 [(set (match_operand:SI 0 "register_operand" "")
20177 (mult:SI (match_dup 0)
20178 (match_operand:SI 1 "const_int_operand" "")))]
20179 "exact_log2 (INTVAL (operands[1])) >= 0
20180 && peep2_regno_dead_p (0, FLAGS_REG)"
20181 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20182 (clobber (reg:CC FLAGS_REG))])]
20183 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20186 [(set (match_operand:DI 0 "register_operand" "")
20187 (mult:DI (match_dup 0)
20188 (match_operand:DI 1 "const_int_operand" "")))]
20189 "exact_log2 (INTVAL (operands[1])) >= 0
20190 && peep2_regno_dead_p (0, FLAGS_REG)"
20191 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20192 (clobber (reg:CC FLAGS_REG))])]
20193 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20196 [(set (match_operand:SI 0 "register_operand" "")
20197 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20198 (match_operand:DI 2 "const_int_operand" "")) 0))]
20199 "exact_log2 (INTVAL (operands[2])) >= 0
20200 && REGNO (operands[0]) == REGNO (operands[1])
20201 && peep2_regno_dead_p (0, FLAGS_REG)"
20202 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20203 (clobber (reg:CC FLAGS_REG))])]
20204 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20206 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20207 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20208 ;; many CPUs it is also faster, since special hardware to avoid esp
20209 ;; dependencies is present.
20211 ;; While some of these conversions may be done using splitters, we use peepholes
20212 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20214 ;; Convert prologue esp subtractions to push.
20215 ;; We need register to push. In order to keep verify_flow_info happy we have
20217 ;; - use scratch and clobber it in order to avoid dependencies
20218 ;; - use already live register
20219 ;; We can't use the second way right now, since there is no reliable way how to
20220 ;; verify that given register is live. First choice will also most likely in
20221 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20222 ;; call clobbered registers are dead. We may want to use base pointer as an
20223 ;; alternative when no register is available later.
20226 [(match_scratch:SI 0 "r")
20227 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20228 (clobber (reg:CC FLAGS_REG))
20229 (clobber (mem:BLK (scratch)))])]
20230 "optimize_size || !TARGET_SUB_ESP_4"
20231 [(clobber (match_dup 0))
20232 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20233 (clobber (mem:BLK (scratch)))])])
20236 [(match_scratch:SI 0 "r")
20237 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20238 (clobber (reg:CC FLAGS_REG))
20239 (clobber (mem:BLK (scratch)))])]
20240 "optimize_size || !TARGET_SUB_ESP_8"
20241 [(clobber (match_dup 0))
20242 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20243 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20244 (clobber (mem:BLK (scratch)))])])
20246 ;; Convert esp subtractions to push.
20248 [(match_scratch:SI 0 "r")
20249 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20250 (clobber (reg:CC FLAGS_REG))])]
20251 "optimize_size || !TARGET_SUB_ESP_4"
20252 [(clobber (match_dup 0))
20253 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20256 [(match_scratch:SI 0 "r")
20257 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20258 (clobber (reg:CC FLAGS_REG))])]
20259 "optimize_size || !TARGET_SUB_ESP_8"
20260 [(clobber (match_dup 0))
20261 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20262 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20264 ;; Convert epilogue deallocator to pop.
20266 [(match_scratch:SI 0 "r")
20267 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20268 (clobber (reg:CC FLAGS_REG))
20269 (clobber (mem:BLK (scratch)))])]
20270 "optimize_size || !TARGET_ADD_ESP_4"
20271 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20272 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20273 (clobber (mem:BLK (scratch)))])]
20276 ;; Two pops case is tricky, since pop causes dependency on destination register.
20277 ;; We use two registers if available.
20279 [(match_scratch:SI 0 "r")
20280 (match_scratch:SI 1 "r")
20281 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20282 (clobber (reg:CC FLAGS_REG))
20283 (clobber (mem:BLK (scratch)))])]
20284 "optimize_size || !TARGET_ADD_ESP_8"
20285 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20286 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20287 (clobber (mem:BLK (scratch)))])
20288 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20289 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20293 [(match_scratch:SI 0 "r")
20294 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20295 (clobber (reg:CC FLAGS_REG))
20296 (clobber (mem:BLK (scratch)))])]
20298 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20299 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20300 (clobber (mem:BLK (scratch)))])
20301 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20302 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20305 ;; Convert esp additions to pop.
20307 [(match_scratch:SI 0 "r")
20308 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20309 (clobber (reg:CC FLAGS_REG))])]
20311 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20312 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20315 ;; Two pops case is tricky, since pop causes dependency on destination register.
20316 ;; We use two registers if available.
20318 [(match_scratch:SI 0 "r")
20319 (match_scratch:SI 1 "r")
20320 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20321 (clobber (reg:CC FLAGS_REG))])]
20323 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20324 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20325 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20326 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20330 [(match_scratch:SI 0 "r")
20331 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20332 (clobber (reg:CC FLAGS_REG))])]
20334 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20335 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20336 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20337 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20340 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20341 ;; required and register dies. Similarly for 128 to plus -128.
20343 [(set (match_operand 0 "flags_reg_operand" "")
20344 (match_operator 1 "compare_operator"
20345 [(match_operand 2 "register_operand" "")
20346 (match_operand 3 "const_int_operand" "")]))]
20347 "(INTVAL (operands[3]) == -1
20348 || INTVAL (operands[3]) == 1
20349 || INTVAL (operands[3]) == 128)
20350 && ix86_match_ccmode (insn, CCGCmode)
20351 && peep2_reg_dead_p (1, operands[2])"
20352 [(parallel [(set (match_dup 0)
20353 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20354 (clobber (match_dup 2))])]
20358 [(match_scratch:DI 0 "r")
20359 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20360 (clobber (reg:CC FLAGS_REG))
20361 (clobber (mem:BLK (scratch)))])]
20362 "optimize_size || !TARGET_SUB_ESP_4"
20363 [(clobber (match_dup 0))
20364 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20365 (clobber (mem:BLK (scratch)))])])
20368 [(match_scratch:DI 0 "r")
20369 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20370 (clobber (reg:CC FLAGS_REG))
20371 (clobber (mem:BLK (scratch)))])]
20372 "optimize_size || !TARGET_SUB_ESP_8"
20373 [(clobber (match_dup 0))
20374 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20375 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20376 (clobber (mem:BLK (scratch)))])])
20378 ;; Convert esp subtractions to push.
20380 [(match_scratch:DI 0 "r")
20381 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20382 (clobber (reg:CC FLAGS_REG))])]
20383 "optimize_size || !TARGET_SUB_ESP_4"
20384 [(clobber (match_dup 0))
20385 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20388 [(match_scratch:DI 0 "r")
20389 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20390 (clobber (reg:CC FLAGS_REG))])]
20391 "optimize_size || !TARGET_SUB_ESP_8"
20392 [(clobber (match_dup 0))
20393 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20394 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20396 ;; Convert epilogue deallocator to pop.
20398 [(match_scratch:DI 0 "r")
20399 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20400 (clobber (reg:CC FLAGS_REG))
20401 (clobber (mem:BLK (scratch)))])]
20402 "optimize_size || !TARGET_ADD_ESP_4"
20403 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20404 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20405 (clobber (mem:BLK (scratch)))])]
20408 ;; Two pops case is tricky, since pop causes dependency on destination register.
20409 ;; We use two registers if available.
20411 [(match_scratch:DI 0 "r")
20412 (match_scratch:DI 1 "r")
20413 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20414 (clobber (reg:CC FLAGS_REG))
20415 (clobber (mem:BLK (scratch)))])]
20416 "optimize_size || !TARGET_ADD_ESP_8"
20417 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20418 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20419 (clobber (mem:BLK (scratch)))])
20420 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20421 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20425 [(match_scratch:DI 0 "r")
20426 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20427 (clobber (reg:CC FLAGS_REG))
20428 (clobber (mem:BLK (scratch)))])]
20430 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20431 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20432 (clobber (mem:BLK (scratch)))])
20433 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20434 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20437 ;; Convert esp additions to pop.
20439 [(match_scratch:DI 0 "r")
20440 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20441 (clobber (reg:CC FLAGS_REG))])]
20443 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20444 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20447 ;; Two pops case is tricky, since pop causes dependency on destination register.
20448 ;; We use two registers if available.
20450 [(match_scratch:DI 0 "r")
20451 (match_scratch:DI 1 "r")
20452 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20453 (clobber (reg:CC FLAGS_REG))])]
20455 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20456 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20457 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20458 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20462 [(match_scratch:DI 0 "r")
20463 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20464 (clobber (reg:CC FLAGS_REG))])]
20466 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20467 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20468 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20469 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20472 ;; Convert imul by three, five and nine into lea
20475 [(set (match_operand:SI 0 "register_operand" "")
20476 (mult:SI (match_operand:SI 1 "register_operand" "")
20477 (match_operand:SI 2 "const_int_operand" "")))
20478 (clobber (reg:CC FLAGS_REG))])]
20479 "INTVAL (operands[2]) == 3
20480 || INTVAL (operands[2]) == 5
20481 || INTVAL (operands[2]) == 9"
20482 [(set (match_dup 0)
20483 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20485 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20489 [(set (match_operand:SI 0 "register_operand" "")
20490 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20491 (match_operand:SI 2 "const_int_operand" "")))
20492 (clobber (reg:CC FLAGS_REG))])]
20494 && (INTVAL (operands[2]) == 3
20495 || INTVAL (operands[2]) == 5
20496 || INTVAL (operands[2]) == 9)"
20497 [(set (match_dup 0) (match_dup 1))
20499 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20501 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20505 [(set (match_operand:DI 0 "register_operand" "")
20506 (mult:DI (match_operand:DI 1 "register_operand" "")
20507 (match_operand:DI 2 "const_int_operand" "")))
20508 (clobber (reg:CC FLAGS_REG))])]
20510 && (INTVAL (operands[2]) == 3
20511 || INTVAL (operands[2]) == 5
20512 || INTVAL (operands[2]) == 9)"
20513 [(set (match_dup 0)
20514 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20516 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20520 [(set (match_operand:DI 0 "register_operand" "")
20521 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20522 (match_operand:DI 2 "const_int_operand" "")))
20523 (clobber (reg:CC FLAGS_REG))])]
20526 && (INTVAL (operands[2]) == 3
20527 || INTVAL (operands[2]) == 5
20528 || INTVAL (operands[2]) == 9)"
20529 [(set (match_dup 0) (match_dup 1))
20531 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20533 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20535 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20536 ;; imul $32bit_imm, reg, reg is direct decoded.
20538 [(match_scratch:DI 3 "r")
20539 (parallel [(set (match_operand:DI 0 "register_operand" "")
20540 (mult:DI (match_operand:DI 1 "memory_operand" "")
20541 (match_operand:DI 2 "immediate_operand" "")))
20542 (clobber (reg:CC FLAGS_REG))])]
20543 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20544 && !satisfies_constraint_K (operands[2])"
20545 [(set (match_dup 3) (match_dup 1))
20546 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20547 (clobber (reg:CC FLAGS_REG))])]
20551 [(match_scratch:SI 3 "r")
20552 (parallel [(set (match_operand:SI 0 "register_operand" "")
20553 (mult:SI (match_operand:SI 1 "memory_operand" "")
20554 (match_operand:SI 2 "immediate_operand" "")))
20555 (clobber (reg:CC FLAGS_REG))])]
20556 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20557 && !satisfies_constraint_K (operands[2])"
20558 [(set (match_dup 3) (match_dup 1))
20559 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20560 (clobber (reg:CC FLAGS_REG))])]
20564 [(match_scratch:SI 3 "r")
20565 (parallel [(set (match_operand:DI 0 "register_operand" "")
20567 (mult:SI (match_operand:SI 1 "memory_operand" "")
20568 (match_operand:SI 2 "immediate_operand" ""))))
20569 (clobber (reg:CC FLAGS_REG))])]
20570 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20571 && !satisfies_constraint_K (operands[2])"
20572 [(set (match_dup 3) (match_dup 1))
20573 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20574 (clobber (reg:CC FLAGS_REG))])]
20577 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20578 ;; Convert it into imul reg, reg
20579 ;; It would be better to force assembler to encode instruction using long
20580 ;; immediate, but there is apparently no way to do so.
20582 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20583 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20584 (match_operand:DI 2 "const_int_operand" "")))
20585 (clobber (reg:CC FLAGS_REG))])
20586 (match_scratch:DI 3 "r")]
20587 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20588 && satisfies_constraint_K (operands[2])"
20589 [(set (match_dup 3) (match_dup 2))
20590 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20591 (clobber (reg:CC FLAGS_REG))])]
20593 if (!rtx_equal_p (operands[0], operands[1]))
20594 emit_move_insn (operands[0], operands[1]);
20598 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20599 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20600 (match_operand:SI 2 "const_int_operand" "")))
20601 (clobber (reg:CC FLAGS_REG))])
20602 (match_scratch:SI 3 "r")]
20603 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20604 && satisfies_constraint_K (operands[2])"
20605 [(set (match_dup 3) (match_dup 2))
20606 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20607 (clobber (reg:CC FLAGS_REG))])]
20609 if (!rtx_equal_p (operands[0], operands[1]))
20610 emit_move_insn (operands[0], operands[1]);
20614 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20615 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20616 (match_operand:HI 2 "immediate_operand" "")))
20617 (clobber (reg:CC FLAGS_REG))])
20618 (match_scratch:HI 3 "r")]
20619 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20620 [(set (match_dup 3) (match_dup 2))
20621 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20622 (clobber (reg:CC FLAGS_REG))])]
20624 if (!rtx_equal_p (operands[0], operands[1]))
20625 emit_move_insn (operands[0], operands[1]);
20628 ;; After splitting up read-modify operations, array accesses with memory
20629 ;; operands might end up in form:
20631 ;; movl 4(%esp), %edx
20633 ;; instead of pre-splitting:
20635 ;; addl 4(%esp), %eax
20637 ;; movl 4(%esp), %edx
20638 ;; leal (%edx,%eax,4), %eax
20641 [(parallel [(set (match_operand 0 "register_operand" "")
20642 (ashift (match_operand 1 "register_operand" "")
20643 (match_operand 2 "const_int_operand" "")))
20644 (clobber (reg:CC FLAGS_REG))])
20645 (set (match_operand 3 "register_operand")
20646 (match_operand 4 "x86_64_general_operand" ""))
20647 (parallel [(set (match_operand 5 "register_operand" "")
20648 (plus (match_operand 6 "register_operand" "")
20649 (match_operand 7 "register_operand" "")))
20650 (clobber (reg:CC FLAGS_REG))])]
20651 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20652 /* Validate MODE for lea. */
20653 && ((!TARGET_PARTIAL_REG_STALL
20654 && (GET_MODE (operands[0]) == QImode
20655 || GET_MODE (operands[0]) == HImode))
20656 || GET_MODE (operands[0]) == SImode
20657 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20658 /* We reorder load and the shift. */
20659 && !rtx_equal_p (operands[1], operands[3])
20660 && !reg_overlap_mentioned_p (operands[0], operands[4])
20661 /* Last PLUS must consist of operand 0 and 3. */
20662 && !rtx_equal_p (operands[0], operands[3])
20663 && (rtx_equal_p (operands[3], operands[6])
20664 || rtx_equal_p (operands[3], operands[7]))
20665 && (rtx_equal_p (operands[0], operands[6])
20666 || rtx_equal_p (operands[0], operands[7]))
20667 /* The intermediate operand 0 must die or be same as output. */
20668 && (rtx_equal_p (operands[0], operands[5])
20669 || peep2_reg_dead_p (3, operands[0]))"
20670 [(set (match_dup 3) (match_dup 4))
20671 (set (match_dup 0) (match_dup 1))]
20673 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20674 int scale = 1 << INTVAL (operands[2]);
20675 rtx index = gen_lowpart (Pmode, operands[1]);
20676 rtx base = gen_lowpart (Pmode, operands[3]);
20677 rtx dest = gen_lowpart (mode, operands[5]);
20679 operands[1] = gen_rtx_PLUS (Pmode, base,
20680 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20682 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20683 operands[0] = dest;
20686 ;; Call-value patterns last so that the wildcard operand does not
20687 ;; disrupt insn-recog's switch tables.
20689 (define_insn "*call_value_pop_0"
20690 [(set (match_operand 0 "" "")
20691 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20692 (match_operand:SI 2 "" "")))
20693 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20694 (match_operand:SI 3 "immediate_operand" "")))]
20697 if (SIBLING_CALL_P (insn))
20700 return "call\t%P1";
20702 [(set_attr "type" "callv")])
20704 (define_insn "*call_value_pop_1"
20705 [(set (match_operand 0 "" "")
20706 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20707 (match_operand:SI 2 "" "")))
20708 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20709 (match_operand:SI 3 "immediate_operand" "i")))]
20712 if (constant_call_address_operand (operands[1], Pmode))
20714 if (SIBLING_CALL_P (insn))
20717 return "call\t%P1";
20719 if (SIBLING_CALL_P (insn))
20722 return "call\t%A1";
20724 [(set_attr "type" "callv")])
20726 (define_insn "*call_value_0"
20727 [(set (match_operand 0 "" "")
20728 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20729 (match_operand:SI 2 "" "")))]
20732 if (SIBLING_CALL_P (insn))
20735 return "call\t%P1";
20737 [(set_attr "type" "callv")])
20739 (define_insn "*call_value_0_rex64"
20740 [(set (match_operand 0 "" "")
20741 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20742 (match_operand:DI 2 "const_int_operand" "")))]
20745 if (SIBLING_CALL_P (insn))
20748 return "call\t%P1";
20750 [(set_attr "type" "callv")])
20752 (define_insn "*call_value_1"
20753 [(set (match_operand 0 "" "")
20754 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20755 (match_operand:SI 2 "" "")))]
20756 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20758 if (constant_call_address_operand (operands[1], Pmode))
20759 return "call\t%P1";
20760 return "call\t%A1";
20762 [(set_attr "type" "callv")])
20764 (define_insn "*sibcall_value_1"
20765 [(set (match_operand 0 "" "")
20766 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20767 (match_operand:SI 2 "" "")))]
20768 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20770 if (constant_call_address_operand (operands[1], Pmode))
20774 [(set_attr "type" "callv")])
20776 (define_insn "*call_value_1_rex64"
20777 [(set (match_operand 0 "" "")
20778 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20779 (match_operand:DI 2 "" "")))]
20780 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20782 if (constant_call_address_operand (operands[1], Pmode))
20783 return "call\t%P1";
20784 return "call\t%A1";
20786 [(set_attr "type" "callv")])
20788 (define_insn "*sibcall_value_1_rex64"
20789 [(set (match_operand 0 "" "")
20790 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20791 (match_operand:DI 2 "" "")))]
20792 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20794 [(set_attr "type" "callv")])
20796 (define_insn "*sibcall_value_1_rex64_v"
20797 [(set (match_operand 0 "" "")
20798 (call (mem:QI (reg:DI R11_REG))
20799 (match_operand:DI 1 "" "")))]
20800 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20802 [(set_attr "type" "callv")])
20804 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20805 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20806 ;; caught for use by garbage collectors and the like. Using an insn that
20807 ;; maps to SIGILL makes it more likely the program will rightfully die.
20808 ;; Keeping with tradition, "6" is in honor of #UD.
20809 (define_insn "trap"
20810 [(trap_if (const_int 1) (const_int 6))]
20812 { return ASM_SHORT "0x0b0f"; }
20813 [(set_attr "length" "2")])
20815 (define_expand "sse_prologue_save"
20816 [(parallel [(set (match_operand:BLK 0 "" "")
20817 (unspec:BLK [(reg:DI 22)
20824 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20825 (use (match_operand:DI 1 "register_operand" ""))
20826 (use (match_operand:DI 2 "immediate_operand" ""))
20827 (use (label_ref:DI (match_operand 3 "" "")))])]
20831 (define_insn "*sse_prologue_save_insn"
20832 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20833 (match_operand:DI 4 "const_int_operand" "n")))
20834 (unspec:BLK [(reg:DI 22)
20841 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20842 (use (match_operand:DI 1 "register_operand" "r"))
20843 (use (match_operand:DI 2 "const_int_operand" "i"))
20844 (use (label_ref:DI (match_operand 3 "" "X")))]
20846 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20847 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20851 operands[0] = gen_rtx_MEM (Pmode,
20852 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20853 output_asm_insn (\"jmp\\t%A1\", operands);
20854 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20856 operands[4] = adjust_address (operands[0], DImode, i*16);
20857 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20858 PUT_MODE (operands[4], TImode);
20859 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20860 output_asm_insn (\"rex\", operands);
20861 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20863 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20864 CODE_LABEL_NUMBER (operands[3]));
20868 [(set_attr "type" "other")
20869 (set_attr "length_immediate" "0")
20870 (set_attr "length_address" "0")
20871 (set_attr "length" "135")
20872 (set_attr "memory" "store")
20873 (set_attr "modrm" "0")
20874 (set_attr "mode" "DI")])
20876 (define_expand "prefetch"
20877 [(prefetch (match_operand 0 "address_operand" "")
20878 (match_operand:SI 1 "const_int_operand" "")
20879 (match_operand:SI 2 "const_int_operand" ""))]
20880 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20882 int rw = INTVAL (operands[1]);
20883 int locality = INTVAL (operands[2]);
20885 gcc_assert (rw == 0 || rw == 1);
20886 gcc_assert (locality >= 0 && locality <= 3);
20887 gcc_assert (GET_MODE (operands[0]) == Pmode
20888 || GET_MODE (operands[0]) == VOIDmode);
20890 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20891 supported by SSE counterpart or the SSE prefetch is not available
20892 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20894 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20895 operands[2] = GEN_INT (3);
20897 operands[1] = const0_rtx;
20900 (define_insn "*prefetch_sse"
20901 [(prefetch (match_operand:SI 0 "address_operand" "p")
20903 (match_operand:SI 1 "const_int_operand" ""))]
20904 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20906 static const char * const patterns[4] = {
20907 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20910 int locality = INTVAL (operands[1]);
20911 gcc_assert (locality >= 0 && locality <= 3);
20913 return patterns[locality];
20915 [(set_attr "type" "sse")
20916 (set_attr "memory" "none")])
20918 (define_insn "*prefetch_sse_rex"
20919 [(prefetch (match_operand:DI 0 "address_operand" "p")
20921 (match_operand:SI 1 "const_int_operand" ""))]
20922 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20924 static const char * const patterns[4] = {
20925 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20928 int locality = INTVAL (operands[1]);
20929 gcc_assert (locality >= 0 && locality <= 3);
20931 return patterns[locality];
20933 [(set_attr "type" "sse")
20934 (set_attr "memory" "none")])
20936 (define_insn "*prefetch_3dnow"
20937 [(prefetch (match_operand:SI 0 "address_operand" "p")
20938 (match_operand:SI 1 "const_int_operand" "n")
20940 "TARGET_3DNOW && !TARGET_64BIT"
20942 if (INTVAL (operands[1]) == 0)
20943 return "prefetch\t%a0";
20945 return "prefetchw\t%a0";
20947 [(set_attr "type" "mmx")
20948 (set_attr "memory" "none")])
20950 (define_insn "*prefetch_3dnow_rex"
20951 [(prefetch (match_operand:DI 0 "address_operand" "p")
20952 (match_operand:SI 1 "const_int_operand" "n")
20954 "TARGET_3DNOW && TARGET_64BIT"
20956 if (INTVAL (operands[1]) == 0)
20957 return "prefetch\t%a0";
20959 return "prefetchw\t%a0";
20961 [(set_attr "type" "mmx")
20962 (set_attr "memory" "none")])
20964 (define_expand "stack_protect_set"
20965 [(match_operand 0 "memory_operand" "")
20966 (match_operand 1 "memory_operand" "")]
20969 #ifdef TARGET_THREAD_SSP_OFFSET
20971 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20972 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20974 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20975 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20978 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20980 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20985 (define_insn "stack_protect_set_si"
20986 [(set (match_operand:SI 0 "memory_operand" "=m")
20987 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20988 (set (match_scratch:SI 2 "=&r") (const_int 0))
20989 (clobber (reg:CC FLAGS_REG))]
20991 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20992 [(set_attr "type" "multi")])
20994 (define_insn "stack_protect_set_di"
20995 [(set (match_operand:DI 0 "memory_operand" "=m")
20996 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20997 (set (match_scratch:DI 2 "=&r") (const_int 0))
20998 (clobber (reg:CC FLAGS_REG))]
21000 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21001 [(set_attr "type" "multi")])
21003 (define_insn "stack_tls_protect_set_si"
21004 [(set (match_operand:SI 0 "memory_operand" "=m")
21005 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21006 (set (match_scratch:SI 2 "=&r") (const_int 0))
21007 (clobber (reg:CC FLAGS_REG))]
21009 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21010 [(set_attr "type" "multi")])
21012 (define_insn "stack_tls_protect_set_di"
21013 [(set (match_operand:DI 0 "memory_operand" "=m")
21014 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21015 (set (match_scratch:DI 2 "=&r") (const_int 0))
21016 (clobber (reg:CC FLAGS_REG))]
21019 /* The kernel uses a different segment register for performance reasons; a
21020 system call would not have to trash the userspace segment register,
21021 which would be expensive */
21022 if (ix86_cmodel != CM_KERNEL)
21023 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21025 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21027 [(set_attr "type" "multi")])
21029 (define_expand "stack_protect_test"
21030 [(match_operand 0 "memory_operand" "")
21031 (match_operand 1 "memory_operand" "")
21032 (match_operand 2 "" "")]
21035 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21036 ix86_compare_op0 = operands[0];
21037 ix86_compare_op1 = operands[1];
21038 ix86_compare_emitted = flags;
21040 #ifdef TARGET_THREAD_SSP_OFFSET
21042 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21043 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21045 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21046 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21049 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21051 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21053 emit_jump_insn (gen_beq (operands[2]));
21057 (define_insn "stack_protect_test_si"
21058 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21059 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21060 (match_operand:SI 2 "memory_operand" "m")]
21062 (clobber (match_scratch:SI 3 "=&r"))]
21064 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21065 [(set_attr "type" "multi")])
21067 (define_insn "stack_protect_test_di"
21068 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21069 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21070 (match_operand:DI 2 "memory_operand" "m")]
21072 (clobber (match_scratch:DI 3 "=&r"))]
21074 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21075 [(set_attr "type" "multi")])
21077 (define_insn "stack_tls_protect_test_si"
21078 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21079 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21080 (match_operand:SI 2 "const_int_operand" "i")]
21081 UNSPEC_SP_TLS_TEST))
21082 (clobber (match_scratch:SI 3 "=r"))]
21084 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21085 [(set_attr "type" "multi")])
21087 (define_insn "stack_tls_protect_test_di"
21088 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21089 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21090 (match_operand:DI 2 "const_int_operand" "i")]
21091 UNSPEC_SP_TLS_TEST))
21092 (clobber (match_scratch:DI 3 "=r"))]
21095 /* The kernel uses a different segment register for performance reasons; a
21096 system call would not have to trash the userspace segment register,
21097 which would be expensive */
21098 if (ix86_cmodel != CM_KERNEL)
21099 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21101 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21103 [(set_attr "type" "multi")])
21107 (include "sync.md")