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
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 30)
98 (UNSPEC_NOP 38) ; prevents combiner cleverness
109 ; Generic math support
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (UNSPEC_IEEE_MAX 52) ; not commutative
125 (UNSPEC_FRNDINT_FLOOR 70)
126 (UNSPEC_FRNDINT_CEIL 71)
127 (UNSPEC_FRNDINT_TRUNC 72)
128 (UNSPEC_FRNDINT_MASK_PM 73)
129 (UNSPEC_FIST_FLOOR 74)
130 (UNSPEC_FIST_CEIL 75)
132 ; x87 Double output FP
133 (UNSPEC_SINCOS_COS 80)
134 (UNSPEC_SINCOS_SIN 81)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
149 (UNSPEC_SP_TLS_SET 102)
150 (UNSPEC_SP_TLS_TEST 103)
154 [(UNSPECV_BLOCKAGE 0)
155 (UNSPECV_STACK_PROBE 1)
164 (UNSPECV_CMPXCHG_1 10)
165 (UNSPECV_CMPXCHG_2 11)
170 ;; Registers by name.
179 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
182 ;; In C guard expressions, put expressions which may be compile-time
183 ;; constants first. This allows for better optimization. For
184 ;; example, write "TARGET_64BIT && reload_completed", not
185 ;; "reload_completed && TARGET_64BIT".
188 ;; Processor type. This attribute must exactly match the processor_type
189 ;; enumeration in i386.h.
190 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
191 (const (symbol_ref "ix86_tune")))
193 ;; A basic instruction type. Refinements due to arguments to be
194 ;; provided in other attributes.
197 alu,alu1,negnot,imov,imovx,lea,
198 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
199 icmp,test,ibr,setcc,icmov,
200 push,pop,call,callv,leave,
202 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
203 sselog,sselog1,sseiadd,sseishft,sseimul,
204 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
205 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
206 (const_string "other"))
208 ;; Main data type used by the insn
210 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
211 (const_string "unknown"))
213 ;; The CPU unit operations uses.
214 (define_attr "unit" "integer,i387,sse,mmx,unknown"
215 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
216 (const_string "i387")
217 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
218 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
220 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
222 (eq_attr "type" "other")
223 (const_string "unknown")]
224 (const_string "integer")))
226 ;; The (bounding maximum) length of an instruction immediate.
227 (define_attr "length_immediate" ""
228 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
230 (eq_attr "unit" "i387,sse,mmx")
232 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
234 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
235 (eq_attr "type" "imov,test")
236 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
237 (eq_attr "type" "call")
238 (if_then_else (match_operand 0 "constant_call_address_operand" "")
241 (eq_attr "type" "callv")
242 (if_then_else (match_operand 1 "constant_call_address_operand" "")
245 ;; We don't know the size before shorten_branches. Expect
246 ;; the instruction to fit for better scheduling.
247 (eq_attr "type" "ibr")
250 (symbol_ref "/* Update immediate_length and other attributes! */
251 gcc_unreachable (),1")))
253 ;; The (bounding maximum) length of an instruction address.
254 (define_attr "length_address" ""
255 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
257 (and (eq_attr "type" "call")
258 (match_operand 0 "constant_call_address_operand" ""))
260 (and (eq_attr "type" "callv")
261 (match_operand 1 "constant_call_address_operand" ""))
264 (symbol_ref "ix86_attr_length_address_default (insn)")))
266 ;; Set when length prefix is used.
267 (define_attr "prefix_data16" ""
268 (if_then_else (ior (eq_attr "mode" "HI")
269 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
273 ;; Set when string REP prefix is used.
274 (define_attr "prefix_rep" ""
275 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
279 ;; Set when 0f opcode prefix is used.
280 (define_attr "prefix_0f" ""
282 (ior (eq_attr "type" "imovx,setcc,icmov")
283 (eq_attr "unit" "sse,mmx"))
287 ;; Set when REX opcode prefix is used.
288 (define_attr "prefix_rex" ""
289 (cond [(and (eq_attr "mode" "DI")
290 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
292 (and (eq_attr "mode" "QI")
293 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
296 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
302 ;; Set when modrm byte is used.
303 (define_attr "modrm" ""
304 (cond [(eq_attr "type" "str,cld,leave")
306 (eq_attr "unit" "i387")
308 (and (eq_attr "type" "incdec")
309 (ior (match_operand:SI 1 "register_operand" "")
310 (match_operand:HI 1 "register_operand" "")))
312 (and (eq_attr "type" "push")
313 (not (match_operand 1 "memory_operand" "")))
315 (and (eq_attr "type" "pop")
316 (not (match_operand 0 "memory_operand" "")))
318 (and (eq_attr "type" "imov")
319 (ior (and (match_operand 0 "register_operand" "")
320 (match_operand 1 "immediate_operand" ""))
321 (ior (and (match_operand 0 "ax_reg_operand" "")
322 (match_operand 1 "memory_displacement_only_operand" ""))
323 (and (match_operand 0 "memory_displacement_only_operand" "")
324 (match_operand 1 "ax_reg_operand" "")))))
326 (and (eq_attr "type" "call")
327 (match_operand 0 "constant_call_address_operand" ""))
329 (and (eq_attr "type" "callv")
330 (match_operand 1 "constant_call_address_operand" ""))
335 ;; The (bounding maximum) length of an instruction in bytes.
336 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
337 ;; Later we may want to split them and compute proper length as for
339 (define_attr "length" ""
340 (cond [(eq_attr "type" "other,multi,fistp,frndint")
342 (eq_attr "type" "fcmp")
344 (eq_attr "unit" "i387")
346 (plus (attr "prefix_data16")
347 (attr "length_address")))]
348 (plus (plus (attr "modrm")
349 (plus (attr "prefix_0f")
350 (plus (attr "prefix_rex")
352 (plus (attr "prefix_rep")
353 (plus (attr "prefix_data16")
354 (plus (attr "length_immediate")
355 (attr "length_address")))))))
357 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
358 ;; `store' if there is a simple memory reference therein, or `unknown'
359 ;; if the instruction is complex.
361 (define_attr "memory" "none,load,store,both,unknown"
362 (cond [(eq_attr "type" "other,multi,str")
363 (const_string "unknown")
364 (eq_attr "type" "lea,fcmov,fpspc,cld")
365 (const_string "none")
366 (eq_attr "type" "fistp,leave")
367 (const_string "both")
368 (eq_attr "type" "frndint")
369 (const_string "load")
370 (eq_attr "type" "push")
371 (if_then_else (match_operand 1 "memory_operand" "")
372 (const_string "both")
373 (const_string "store"))
374 (eq_attr "type" "pop")
375 (if_then_else (match_operand 0 "memory_operand" "")
376 (const_string "both")
377 (const_string "load"))
378 (eq_attr "type" "setcc")
379 (if_then_else (match_operand 0 "memory_operand" "")
380 (const_string "store")
381 (const_string "none"))
382 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
383 (if_then_else (ior (match_operand 0 "memory_operand" "")
384 (match_operand 1 "memory_operand" ""))
385 (const_string "load")
386 (const_string "none"))
387 (eq_attr "type" "ibr")
388 (if_then_else (match_operand 0 "memory_operand" "")
389 (const_string "load")
390 (const_string "none"))
391 (eq_attr "type" "call")
392 (if_then_else (match_operand 0 "constant_call_address_operand" "")
393 (const_string "none")
394 (const_string "load"))
395 (eq_attr "type" "callv")
396 (if_then_else (match_operand 1 "constant_call_address_operand" "")
397 (const_string "none")
398 (const_string "load"))
399 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
400 (match_operand 1 "memory_operand" ""))
401 (const_string "both")
402 (and (match_operand 0 "memory_operand" "")
403 (match_operand 1 "memory_operand" ""))
404 (const_string "both")
405 (match_operand 0 "memory_operand" "")
406 (const_string "store")
407 (match_operand 1 "memory_operand" "")
408 (const_string "load")
410 "!alu1,negnot,ishift1,
411 imov,imovx,icmp,test,
413 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
414 mmx,mmxmov,mmxcmp,mmxcvt")
415 (match_operand 2 "memory_operand" ""))
416 (const_string "load")
417 (and (eq_attr "type" "icmov")
418 (match_operand 3 "memory_operand" ""))
419 (const_string "load")
421 (const_string "none")))
423 ;; Indicates if an instruction has both an immediate and a displacement.
425 (define_attr "imm_disp" "false,true,unknown"
426 (cond [(eq_attr "type" "other,multi")
427 (const_string "unknown")
428 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
429 (and (match_operand 0 "memory_displacement_operand" "")
430 (match_operand 1 "immediate_operand" "")))
431 (const_string "true")
432 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
433 (and (match_operand 0 "memory_displacement_operand" "")
434 (match_operand 2 "immediate_operand" "")))
435 (const_string "true")
437 (const_string "false")))
439 ;; Indicates if an FP operation has an integer source.
441 (define_attr "fp_int_src" "false,true"
442 (const_string "false"))
444 ;; Defines rounding mode of an FP operation.
446 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
447 (const_string "any"))
449 ;; Describe a user's asm statement.
450 (define_asm_attributes
451 [(set_attr "length" "128")
452 (set_attr "type" "multi")])
454 ;; All x87 floating point modes
455 (define_mode_macro X87MODEF [SF DF XF])
457 ;; All integer modes handled by x87 fisttp operator.
458 (define_mode_macro X87MODEI [HI SI DI])
460 ;; All integer modes handled by integer x87 operators.
461 (define_mode_macro X87MODEI12 [HI SI])
463 ;; All SSE floating point modes
464 (define_mode_macro SSEMODEF [SF DF])
466 ;; All integer modes handled by SSE cvtts?2si* operators.
467 (define_mode_macro SSEMODEI24 [SI DI])
470 ;; Scheduling descriptions
472 (include "pentium.md")
475 (include "athlon.md")
478 ;; Operand and operator predicates
480 (include "predicates.md")
483 ;; Compare instructions.
485 ;; All compare insns have expanders that save the operands away without
486 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
487 ;; after the cmp) will actually emit the cmpM.
489 (define_expand "cmpti"
490 [(set (reg:CC FLAGS_REG)
491 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
492 (match_operand:TI 1 "x86_64_general_operand" "")))]
495 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
496 operands[0] = force_reg (TImode, operands[0]);
497 ix86_compare_op0 = operands[0];
498 ix86_compare_op1 = operands[1];
502 (define_expand "cmpdi"
503 [(set (reg:CC FLAGS_REG)
504 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
505 (match_operand:DI 1 "x86_64_general_operand" "")))]
508 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
509 operands[0] = force_reg (DImode, operands[0]);
510 ix86_compare_op0 = operands[0];
511 ix86_compare_op1 = operands[1];
515 (define_expand "cmpsi"
516 [(set (reg:CC FLAGS_REG)
517 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
518 (match_operand:SI 1 "general_operand" "")))]
521 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
522 operands[0] = force_reg (SImode, operands[0]);
523 ix86_compare_op0 = operands[0];
524 ix86_compare_op1 = operands[1];
528 (define_expand "cmphi"
529 [(set (reg:CC FLAGS_REG)
530 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
531 (match_operand:HI 1 "general_operand" "")))]
534 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
535 operands[0] = force_reg (HImode, operands[0]);
536 ix86_compare_op0 = operands[0];
537 ix86_compare_op1 = operands[1];
541 (define_expand "cmpqi"
542 [(set (reg:CC FLAGS_REG)
543 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
544 (match_operand:QI 1 "general_operand" "")))]
547 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
548 operands[0] = force_reg (QImode, operands[0]);
549 ix86_compare_op0 = operands[0];
550 ix86_compare_op1 = operands[1];
554 (define_insn "cmpdi_ccno_1_rex64"
555 [(set (reg FLAGS_REG)
556 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
557 (match_operand:DI 1 "const0_operand" "n,n")))]
558 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
560 test{q}\t{%0, %0|%0, %0}
561 cmp{q}\t{%1, %0|%0, %1}"
562 [(set_attr "type" "test,icmp")
563 (set_attr "length_immediate" "0,1")
564 (set_attr "mode" "DI")])
566 (define_insn "*cmpdi_minus_1_rex64"
567 [(set (reg FLAGS_REG)
568 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
569 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
571 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
572 "cmp{q}\t{%1, %0|%0, %1}"
573 [(set_attr "type" "icmp")
574 (set_attr "mode" "DI")])
576 (define_expand "cmpdi_1_rex64"
577 [(set (reg:CC FLAGS_REG)
578 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
579 (match_operand:DI 1 "general_operand" "")))]
583 (define_insn "cmpdi_1_insn_rex64"
584 [(set (reg FLAGS_REG)
585 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
586 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
587 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
588 "cmp{q}\t{%1, %0|%0, %1}"
589 [(set_attr "type" "icmp")
590 (set_attr "mode" "DI")])
593 (define_insn "*cmpsi_ccno_1"
594 [(set (reg FLAGS_REG)
595 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
596 (match_operand:SI 1 "const0_operand" "n,n")))]
597 "ix86_match_ccmode (insn, CCNOmode)"
599 test{l}\t{%0, %0|%0, %0}
600 cmp{l}\t{%1, %0|%0, %1}"
601 [(set_attr "type" "test,icmp")
602 (set_attr "length_immediate" "0,1")
603 (set_attr "mode" "SI")])
605 (define_insn "*cmpsi_minus_1"
606 [(set (reg FLAGS_REG)
607 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
608 (match_operand:SI 1 "general_operand" "ri,mr"))
610 "ix86_match_ccmode (insn, CCGOCmode)"
611 "cmp{l}\t{%1, %0|%0, %1}"
612 [(set_attr "type" "icmp")
613 (set_attr "mode" "SI")])
615 (define_expand "cmpsi_1"
616 [(set (reg:CC FLAGS_REG)
617 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
618 (match_operand:SI 1 "general_operand" "ri,mr")))]
622 (define_insn "*cmpsi_1_insn"
623 [(set (reg FLAGS_REG)
624 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
625 (match_operand:SI 1 "general_operand" "ri,mr")))]
626 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
627 && ix86_match_ccmode (insn, CCmode)"
628 "cmp{l}\t{%1, %0|%0, %1}"
629 [(set_attr "type" "icmp")
630 (set_attr "mode" "SI")])
632 (define_insn "*cmphi_ccno_1"
633 [(set (reg FLAGS_REG)
634 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
635 (match_operand:HI 1 "const0_operand" "n,n")))]
636 "ix86_match_ccmode (insn, CCNOmode)"
638 test{w}\t{%0, %0|%0, %0}
639 cmp{w}\t{%1, %0|%0, %1}"
640 [(set_attr "type" "test,icmp")
641 (set_attr "length_immediate" "0,1")
642 (set_attr "mode" "HI")])
644 (define_insn "*cmphi_minus_1"
645 [(set (reg FLAGS_REG)
646 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
647 (match_operand:HI 1 "general_operand" "ri,mr"))
649 "ix86_match_ccmode (insn, CCGOCmode)"
650 "cmp{w}\t{%1, %0|%0, %1}"
651 [(set_attr "type" "icmp")
652 (set_attr "mode" "HI")])
654 (define_insn "*cmphi_1"
655 [(set (reg FLAGS_REG)
656 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
657 (match_operand:HI 1 "general_operand" "ri,mr")))]
658 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
659 && ix86_match_ccmode (insn, CCmode)"
660 "cmp{w}\t{%1, %0|%0, %1}"
661 [(set_attr "type" "icmp")
662 (set_attr "mode" "HI")])
664 (define_insn "*cmpqi_ccno_1"
665 [(set (reg FLAGS_REG)
666 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
667 (match_operand:QI 1 "const0_operand" "n,n")))]
668 "ix86_match_ccmode (insn, CCNOmode)"
670 test{b}\t{%0, %0|%0, %0}
671 cmp{b}\t{$0, %0|%0, 0}"
672 [(set_attr "type" "test,icmp")
673 (set_attr "length_immediate" "0,1")
674 (set_attr "mode" "QI")])
676 (define_insn "*cmpqi_1"
677 [(set (reg FLAGS_REG)
678 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
679 (match_operand:QI 1 "general_operand" "qi,mq")))]
680 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
681 && ix86_match_ccmode (insn, CCmode)"
682 "cmp{b}\t{%1, %0|%0, %1}"
683 [(set_attr "type" "icmp")
684 (set_attr "mode" "QI")])
686 (define_insn "*cmpqi_minus_1"
687 [(set (reg FLAGS_REG)
688 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
689 (match_operand:QI 1 "general_operand" "qi,mq"))
691 "ix86_match_ccmode (insn, CCGOCmode)"
692 "cmp{b}\t{%1, %0|%0, %1}"
693 [(set_attr "type" "icmp")
694 (set_attr "mode" "QI")])
696 (define_insn "*cmpqi_ext_1"
697 [(set (reg FLAGS_REG)
699 (match_operand:QI 0 "general_operand" "Qm")
702 (match_operand 1 "ext_register_operand" "Q")
705 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
706 "cmp{b}\t{%h1, %0|%0, %h1}"
707 [(set_attr "type" "icmp")
708 (set_attr "mode" "QI")])
710 (define_insn "*cmpqi_ext_1_rex64"
711 [(set (reg FLAGS_REG)
713 (match_operand:QI 0 "register_operand" "Q")
716 (match_operand 1 "ext_register_operand" "Q")
719 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720 "cmp{b}\t{%h1, %0|%0, %h1}"
721 [(set_attr "type" "icmp")
722 (set_attr "mode" "QI")])
724 (define_insn "*cmpqi_ext_2"
725 [(set (reg FLAGS_REG)
729 (match_operand 0 "ext_register_operand" "Q")
732 (match_operand:QI 1 "const0_operand" "n")))]
733 "ix86_match_ccmode (insn, CCNOmode)"
735 [(set_attr "type" "test")
736 (set_attr "length_immediate" "0")
737 (set_attr "mode" "QI")])
739 (define_expand "cmpqi_ext_3"
740 [(set (reg:CC FLAGS_REG)
744 (match_operand 0 "ext_register_operand" "")
747 (match_operand:QI 1 "general_operand" "")))]
751 (define_insn "cmpqi_ext_3_insn"
752 [(set (reg FLAGS_REG)
756 (match_operand 0 "ext_register_operand" "Q")
759 (match_operand:QI 1 "general_operand" "Qmn")))]
760 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
761 "cmp{b}\t{%1, %h0|%h0, %1}"
762 [(set_attr "type" "icmp")
763 (set_attr "mode" "QI")])
765 (define_insn "cmpqi_ext_3_insn_rex64"
766 [(set (reg FLAGS_REG)
770 (match_operand 0 "ext_register_operand" "Q")
773 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
774 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
775 "cmp{b}\t{%1, %h0|%h0, %1}"
776 [(set_attr "type" "icmp")
777 (set_attr "mode" "QI")])
779 (define_insn "*cmpqi_ext_4"
780 [(set (reg FLAGS_REG)
784 (match_operand 0 "ext_register_operand" "Q")
789 (match_operand 1 "ext_register_operand" "Q")
792 "ix86_match_ccmode (insn, CCmode)"
793 "cmp{b}\t{%h1, %h0|%h0, %h1}"
794 [(set_attr "type" "icmp")
795 (set_attr "mode" "QI")])
797 ;; These implement float point compares.
798 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
799 ;; which would allow mix and match FP modes on the compares. Which is what
800 ;; the old patterns did, but with many more of them.
802 (define_expand "cmpxf"
803 [(set (reg:CC FLAGS_REG)
804 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
805 (match_operand:XF 1 "nonmemory_operand" "")))]
808 ix86_compare_op0 = operands[0];
809 ix86_compare_op1 = operands[1];
813 (define_expand "cmpdf"
814 [(set (reg:CC FLAGS_REG)
815 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
816 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
817 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
819 ix86_compare_op0 = operands[0];
820 ix86_compare_op1 = operands[1];
824 (define_expand "cmpsf"
825 [(set (reg:CC FLAGS_REG)
826 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
827 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
828 "TARGET_80387 || TARGET_SSE_MATH"
830 ix86_compare_op0 = operands[0];
831 ix86_compare_op1 = operands[1];
835 ;; FP compares, step 1:
836 ;; Set the FP condition codes.
838 ;; CCFPmode compare with exceptions
839 ;; CCFPUmode compare with no exceptions
841 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
842 ;; used to manage the reg stack popping would not be preserved.
844 (define_insn "*cmpfp_0"
845 [(set (match_operand:HI 0 "register_operand" "=a")
848 (match_operand 1 "register_operand" "f")
849 (match_operand 2 "const0_operand" "X"))]
852 && FLOAT_MODE_P (GET_MODE (operands[1]))
853 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
854 "* return output_fp_compare (insn, operands, 0, 0);"
855 [(set_attr "type" "multi")
856 (set_attr "unit" "i387")
858 (cond [(match_operand:SF 1 "" "")
860 (match_operand:DF 1 "" "")
863 (const_string "XF")))])
865 (define_insn "*cmpfp_sf"
866 [(set (match_operand:HI 0 "register_operand" "=a")
869 (match_operand:SF 1 "register_operand" "f")
870 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
873 "* return output_fp_compare (insn, operands, 0, 0);"
874 [(set_attr "type" "multi")
875 (set_attr "unit" "i387")
876 (set_attr "mode" "SF")])
878 (define_insn "*cmpfp_df"
879 [(set (match_operand:HI 0 "register_operand" "=a")
882 (match_operand:DF 1 "register_operand" "f")
883 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
886 "* return output_fp_compare (insn, operands, 0, 0);"
887 [(set_attr "type" "multi")
888 (set_attr "unit" "i387")
889 (set_attr "mode" "DF")])
891 (define_insn "*cmpfp_xf"
892 [(set (match_operand:HI 0 "register_operand" "=a")
895 (match_operand:XF 1 "register_operand" "f")
896 (match_operand:XF 2 "register_operand" "f"))]
899 "* return output_fp_compare (insn, operands, 0, 0);"
900 [(set_attr "type" "multi")
901 (set_attr "unit" "i387")
902 (set_attr "mode" "XF")])
904 (define_insn "*cmpfp_u"
905 [(set (match_operand:HI 0 "register_operand" "=a")
908 (match_operand 1 "register_operand" "f")
909 (match_operand 2 "register_operand" "f"))]
912 && FLOAT_MODE_P (GET_MODE (operands[1]))
913 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
914 "* return output_fp_compare (insn, operands, 0, 1);"
915 [(set_attr "type" "multi")
916 (set_attr "unit" "i387")
918 (cond [(match_operand:SF 1 "" "")
920 (match_operand:DF 1 "" "")
923 (const_string "XF")))])
925 (define_insn "*cmpfp_<mode>"
926 [(set (match_operand:HI 0 "register_operand" "=a")
929 (match_operand 1 "register_operand" "f")
930 (match_operator 3 "float_operator"
931 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
933 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
934 && FLOAT_MODE_P (GET_MODE (operands[1]))
935 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
936 "* return output_fp_compare (insn, operands, 0, 0);"
937 [(set_attr "type" "multi")
938 (set_attr "unit" "i387")
939 (set_attr "fp_int_src" "true")
940 (set_attr "mode" "<MODE>")])
942 ;; FP compares, step 2
943 ;; Move the fpsw to ax.
945 (define_insn "x86_fnstsw_1"
946 [(set (match_operand:HI 0 "register_operand" "=a")
947 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
950 [(set_attr "length" "2")
951 (set_attr "mode" "SI")
952 (set_attr "unit" "i387")])
954 ;; FP compares, step 3
955 ;; Get ax into flags, general case.
957 (define_insn "x86_sahf_1"
958 [(set (reg:CC FLAGS_REG)
959 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
962 [(set_attr "length" "1")
963 (set_attr "athlon_decode" "vector")
964 (set_attr "mode" "SI")])
966 ;; Pentium Pro can do steps 1 through 3 in one go.
968 (define_insn "*cmpfp_i_mixed"
969 [(set (reg:CCFP FLAGS_REG)
970 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
971 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
973 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
974 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
975 "* return output_fp_compare (insn, operands, 1, 0);"
976 [(set_attr "type" "fcmp,ssecomi")
978 (if_then_else (match_operand:SF 1 "" "")
980 (const_string "DF")))
981 (set_attr "athlon_decode" "vector")])
983 (define_insn "*cmpfp_i_sse"
984 [(set (reg:CCFP FLAGS_REG)
985 (compare:CCFP (match_operand 0 "register_operand" "x")
986 (match_operand 1 "nonimmediate_operand" "xm")))]
988 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
989 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
990 "* return output_fp_compare (insn, operands, 1, 0);"
991 [(set_attr "type" "ssecomi")
993 (if_then_else (match_operand:SF 1 "" "")
995 (const_string "DF")))
996 (set_attr "athlon_decode" "vector")])
998 (define_insn "*cmpfp_i_i387"
999 [(set (reg:CCFP FLAGS_REG)
1000 (compare:CCFP (match_operand 0 "register_operand" "f")
1001 (match_operand 1 "register_operand" "f")))]
1002 "TARGET_80387 && TARGET_CMOVE
1003 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1004 && FLOAT_MODE_P (GET_MODE (operands[0]))
1005 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006 "* return output_fp_compare (insn, operands, 1, 0);"
1007 [(set_attr "type" "fcmp")
1009 (cond [(match_operand:SF 1 "" "")
1011 (match_operand:DF 1 "" "")
1014 (const_string "XF")))
1015 (set_attr "athlon_decode" "vector")])
1017 (define_insn "*cmpfp_iu_mixed"
1018 [(set (reg:CCFPU FLAGS_REG)
1019 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1020 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1021 "TARGET_MIX_SSE_I387
1022 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1023 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1024 "* return output_fp_compare (insn, operands, 1, 1);"
1025 [(set_attr "type" "fcmp,ssecomi")
1027 (if_then_else (match_operand:SF 1 "" "")
1029 (const_string "DF")))
1030 (set_attr "athlon_decode" "vector")])
1032 (define_insn "*cmpfp_iu_sse"
1033 [(set (reg:CCFPU FLAGS_REG)
1034 (compare:CCFPU (match_operand 0 "register_operand" "x")
1035 (match_operand 1 "nonimmediate_operand" "xm")))]
1037 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1038 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039 "* return output_fp_compare (insn, operands, 1, 1);"
1040 [(set_attr "type" "ssecomi")
1042 (if_then_else (match_operand:SF 1 "" "")
1044 (const_string "DF")))
1045 (set_attr "athlon_decode" "vector")])
1047 (define_insn "*cmpfp_iu_387"
1048 [(set (reg:CCFPU FLAGS_REG)
1049 (compare:CCFPU (match_operand 0 "register_operand" "f")
1050 (match_operand 1 "register_operand" "f")))]
1051 "TARGET_80387 && TARGET_CMOVE
1052 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1053 && FLOAT_MODE_P (GET_MODE (operands[0]))
1054 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055 "* return output_fp_compare (insn, operands, 1, 1);"
1056 [(set_attr "type" "fcmp")
1058 (cond [(match_operand:SF 1 "" "")
1060 (match_operand:DF 1 "" "")
1063 (const_string "XF")))
1064 (set_attr "athlon_decode" "vector")])
1066 ;; Move instructions.
1068 ;; General case of fullword move.
1070 (define_expand "movsi"
1071 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1072 (match_operand:SI 1 "general_operand" ""))]
1074 "ix86_expand_move (SImode, operands); DONE;")
1076 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1079 ;; %%% We don't use a post-inc memory reference because x86 is not a
1080 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1081 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1082 ;; targets without our curiosities, and it is just as easy to represent
1083 ;; this differently.
1085 (define_insn "*pushsi2"
1086 [(set (match_operand:SI 0 "push_operand" "=<")
1087 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1090 [(set_attr "type" "push")
1091 (set_attr "mode" "SI")])
1093 ;; For 64BIT abi we always round up to 8 bytes.
1094 (define_insn "*pushsi2_rex64"
1095 [(set (match_operand:SI 0 "push_operand" "=X")
1096 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1099 [(set_attr "type" "push")
1100 (set_attr "mode" "SI")])
1102 (define_insn "*pushsi2_prologue"
1103 [(set (match_operand:SI 0 "push_operand" "=<")
1104 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1105 (clobber (mem:BLK (scratch)))]
1108 [(set_attr "type" "push")
1109 (set_attr "mode" "SI")])
1111 (define_insn "*popsi1_epilogue"
1112 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1113 (mem:SI (reg:SI SP_REG)))
1114 (set (reg:SI SP_REG)
1115 (plus:SI (reg:SI SP_REG) (const_int 4)))
1116 (clobber (mem:BLK (scratch)))]
1119 [(set_attr "type" "pop")
1120 (set_attr "mode" "SI")])
1122 (define_insn "popsi1"
1123 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1124 (mem:SI (reg:SI SP_REG)))
1125 (set (reg:SI SP_REG)
1126 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1129 [(set_attr "type" "pop")
1130 (set_attr "mode" "SI")])
1132 (define_insn "*movsi_xor"
1133 [(set (match_operand:SI 0 "register_operand" "=r")
1134 (match_operand:SI 1 "const0_operand" "i"))
1135 (clobber (reg:CC FLAGS_REG))]
1136 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1137 "xor{l}\t{%0, %0|%0, %0}"
1138 [(set_attr "type" "alu1")
1139 (set_attr "mode" "SI")
1140 (set_attr "length_immediate" "0")])
1142 (define_insn "*movsi_or"
1143 [(set (match_operand:SI 0 "register_operand" "=r")
1144 (match_operand:SI 1 "immediate_operand" "i"))
1145 (clobber (reg:CC FLAGS_REG))]
1147 && operands[1] == constm1_rtx
1148 && (TARGET_PENTIUM || optimize_size)"
1150 operands[1] = constm1_rtx;
1151 return "or{l}\t{%1, %0|%0, %1}";
1153 [(set_attr "type" "alu1")
1154 (set_attr "mode" "SI")
1155 (set_attr "length_immediate" "1")])
1157 (define_insn "*movsi_1"
1158 [(set (match_operand:SI 0 "nonimmediate_operand"
1159 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1160 (match_operand:SI 1 "general_operand"
1161 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1162 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1164 switch (get_attr_type (insn))
1167 if (get_attr_mode (insn) == MODE_TI)
1168 return "pxor\t%0, %0";
1169 return "xorps\t%0, %0";
1172 switch (get_attr_mode (insn))
1175 return "movdqa\t{%1, %0|%0, %1}";
1177 return "movaps\t{%1, %0|%0, %1}";
1179 return "movd\t{%1, %0|%0, %1}";
1181 return "movss\t{%1, %0|%0, %1}";
1187 return "pxor\t%0, %0";
1190 if (get_attr_mode (insn) == MODE_DI)
1191 return "movq\t{%1, %0|%0, %1}";
1192 return "movd\t{%1, %0|%0, %1}";
1195 return "lea{l}\t{%1, %0|%0, %1}";
1198 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1199 return "mov{l}\t{%1, %0|%0, %1}";
1203 (cond [(eq_attr "alternative" "2")
1204 (const_string "mmxadd")
1205 (eq_attr "alternative" "3,4,5")
1206 (const_string "mmxmov")
1207 (eq_attr "alternative" "6")
1208 (const_string "sselog1")
1209 (eq_attr "alternative" "7,8,9,10,11")
1210 (const_string "ssemov")
1211 (match_operand:DI 1 "pic_32bit_operand" "")
1212 (const_string "lea")
1214 (const_string "imov")))
1216 (cond [(eq_attr "alternative" "2,3")
1218 (eq_attr "alternative" "6,7")
1220 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1221 (const_string "V4SF")
1222 (const_string "TI"))
1223 (and (eq_attr "alternative" "8,9,10,11")
1224 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1227 (const_string "SI")))])
1229 ;; Stores and loads of ax to arbitrary constant address.
1230 ;; We fake an second form of instruction to force reload to load address
1231 ;; into register when rax is not available
1232 (define_insn "*movabssi_1_rex64"
1233 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1234 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1235 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1237 movabs{l}\t{%1, %P0|%P0, %1}
1238 mov{l}\t{%1, %a0|%a0, %1}"
1239 [(set_attr "type" "imov")
1240 (set_attr "modrm" "0,*")
1241 (set_attr "length_address" "8,0")
1242 (set_attr "length_immediate" "0,*")
1243 (set_attr "memory" "store")
1244 (set_attr "mode" "SI")])
1246 (define_insn "*movabssi_2_rex64"
1247 [(set (match_operand:SI 0 "register_operand" "=a,r")
1248 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1249 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1251 movabs{l}\t{%P1, %0|%0, %P1}
1252 mov{l}\t{%a1, %0|%0, %a1}"
1253 [(set_attr "type" "imov")
1254 (set_attr "modrm" "0,*")
1255 (set_attr "length_address" "8,0")
1256 (set_attr "length_immediate" "0")
1257 (set_attr "memory" "load")
1258 (set_attr "mode" "SI")])
1260 (define_insn "*swapsi"
1261 [(set (match_operand:SI 0 "register_operand" "+r")
1262 (match_operand:SI 1 "register_operand" "+r"))
1267 [(set_attr "type" "imov")
1268 (set_attr "mode" "SI")
1269 (set_attr "pent_pair" "np")
1270 (set_attr "athlon_decode" "vector")])
1272 (define_expand "movhi"
1273 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1274 (match_operand:HI 1 "general_operand" ""))]
1276 "ix86_expand_move (HImode, operands); DONE;")
1278 (define_insn "*pushhi2"
1279 [(set (match_operand:HI 0 "push_operand" "=X")
1280 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1283 [(set_attr "type" "push")
1284 (set_attr "mode" "SI")])
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288 [(set (match_operand:HI 0 "push_operand" "=X")
1289 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1292 [(set_attr "type" "push")
1293 (set_attr "mode" "DI")])
1295 (define_insn "*movhi_1"
1296 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1300 switch (get_attr_type (insn))
1303 /* movzwl is faster than movw on p2 due to partial word stalls,
1304 though not as fast as an aligned movl. */
1305 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1307 if (get_attr_mode (insn) == MODE_SI)
1308 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1310 return "mov{w}\t{%1, %0|%0, %1}";
1314 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1315 (const_string "imov")
1316 (and (eq_attr "alternative" "0")
1317 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1319 (eq (symbol_ref "TARGET_HIMODE_MATH")
1321 (const_string "imov")
1322 (and (eq_attr "alternative" "1,2")
1323 (match_operand:HI 1 "aligned_operand" ""))
1324 (const_string "imov")
1325 (and (ne (symbol_ref "TARGET_MOVX")
1327 (eq_attr "alternative" "0,2"))
1328 (const_string "imovx")
1330 (const_string "imov")))
1332 (cond [(eq_attr "type" "imovx")
1334 (and (eq_attr "alternative" "1,2")
1335 (match_operand:HI 1 "aligned_operand" ""))
1337 (and (eq_attr "alternative" "0")
1338 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1340 (eq (symbol_ref "TARGET_HIMODE_MATH")
1344 (const_string "HI")))])
1346 ;; Stores and loads of ax to arbitrary constant address.
1347 ;; We fake an second form of instruction to force reload to load address
1348 ;; into register when rax is not available
1349 (define_insn "*movabshi_1_rex64"
1350 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1354 movabs{w}\t{%1, %P0|%P0, %1}
1355 mov{w}\t{%1, %a0|%a0, %1}"
1356 [(set_attr "type" "imov")
1357 (set_attr "modrm" "0,*")
1358 (set_attr "length_address" "8,0")
1359 (set_attr "length_immediate" "0,*")
1360 (set_attr "memory" "store")
1361 (set_attr "mode" "HI")])
1363 (define_insn "*movabshi_2_rex64"
1364 [(set (match_operand:HI 0 "register_operand" "=a,r")
1365 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1368 movabs{w}\t{%P1, %0|%0, %P1}
1369 mov{w}\t{%a1, %0|%0, %a1}"
1370 [(set_attr "type" "imov")
1371 (set_attr "modrm" "0,*")
1372 (set_attr "length_address" "8,0")
1373 (set_attr "length_immediate" "0")
1374 (set_attr "memory" "load")
1375 (set_attr "mode" "HI")])
1377 (define_insn "*swaphi_1"
1378 [(set (match_operand:HI 0 "register_operand" "+r")
1379 (match_operand:HI 1 "register_operand" "+r"))
1382 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1384 [(set_attr "type" "imov")
1385 (set_attr "mode" "SI")
1386 (set_attr "pent_pair" "np")
1387 (set_attr "athlon_decode" "vector")])
1389 (define_insn "*swaphi_2"
1390 [(set (match_operand:HI 0 "register_operand" "+r")
1391 (match_operand:HI 1 "register_operand" "+r"))
1394 "TARGET_PARTIAL_REG_STALL"
1396 [(set_attr "type" "imov")
1397 (set_attr "mode" "HI")
1398 (set_attr "pent_pair" "np")
1399 (set_attr "athlon_decode" "vector")])
1401 (define_expand "movstricthi"
1402 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403 (match_operand:HI 1 "general_operand" ""))]
1404 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1406 /* Don't generate memory->memory moves, go through a register */
1407 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408 operands[1] = force_reg (HImode, operands[1]);
1411 (define_insn "*movstricthi_1"
1412 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413 (match_operand:HI 1 "general_operand" "rn,m"))]
1414 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416 "mov{w}\t{%1, %0|%0, %1}"
1417 [(set_attr "type" "imov")
1418 (set_attr "mode" "HI")])
1420 (define_insn "*movstricthi_xor"
1421 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422 (match_operand:HI 1 "const0_operand" "i"))
1423 (clobber (reg:CC FLAGS_REG))]
1425 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426 "xor{w}\t{%0, %0|%0, %0}"
1427 [(set_attr "type" "alu1")
1428 (set_attr "mode" "HI")
1429 (set_attr "length_immediate" "0")])
1431 (define_expand "movqi"
1432 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433 (match_operand:QI 1 "general_operand" ""))]
1435 "ix86_expand_move (QImode, operands); DONE;")
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte". But actually we use pushl, which has the effect
1439 ;; of rounding the amount pushed up to a word.
1441 (define_insn "*pushqi2"
1442 [(set (match_operand:QI 0 "push_operand" "=X")
1443 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1446 [(set_attr "type" "push")
1447 (set_attr "mode" "SI")])
1449 ;; For 64BIT abi we always round up to 8 bytes.
1450 (define_insn "*pushqi2_rex64"
1451 [(set (match_operand:QI 0 "push_operand" "=X")
1452 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1455 [(set_attr "type" "push")
1456 (set_attr "mode" "DI")])
1458 ;; Situation is quite tricky about when to choose full sized (SImode) move
1459 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1460 ;; partial register dependency machines (such as AMD Athlon), where QImode
1461 ;; moves issue extra dependency and for partial register stalls machines
1462 ;; that don't use QImode patterns (and QImode move cause stall on the next
1465 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1466 ;; register stall machines with, where we use QImode instructions, since
1467 ;; partial register stall can be caused there. Then we use movzx.
1468 (define_insn "*movqi_1"
1469 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1470 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1471 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1473 switch (get_attr_type (insn))
1476 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1477 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1479 if (get_attr_mode (insn) == MODE_SI)
1480 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1482 return "mov{b}\t{%1, %0|%0, %1}";
1486 (cond [(and (eq_attr "alternative" "5")
1487 (not (match_operand:QI 1 "aligned_operand" "")))
1488 (const_string "imovx")
1489 (ne (symbol_ref "optimize_size") (const_int 0))
1490 (const_string "imov")
1491 (and (eq_attr "alternative" "3")
1492 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1494 (eq (symbol_ref "TARGET_QIMODE_MATH")
1496 (const_string "imov")
1497 (eq_attr "alternative" "3,5")
1498 (const_string "imovx")
1499 (and (ne (symbol_ref "TARGET_MOVX")
1501 (eq_attr "alternative" "2"))
1502 (const_string "imovx")
1504 (const_string "imov")))
1506 (cond [(eq_attr "alternative" "3,4,5")
1508 (eq_attr "alternative" "6")
1510 (eq_attr "type" "imovx")
1512 (and (eq_attr "type" "imov")
1513 (and (eq_attr "alternative" "0,1")
1514 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1517 ;; Avoid partial register stalls when not using QImode arithmetic
1518 (and (eq_attr "type" "imov")
1519 (and (eq_attr "alternative" "0,1")
1520 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1522 (eq (symbol_ref "TARGET_QIMODE_MATH")
1526 (const_string "QI")))])
1528 (define_expand "reload_outqi"
1529 [(parallel [(match_operand:QI 0 "" "=m")
1530 (match_operand:QI 1 "register_operand" "r")
1531 (match_operand:QI 2 "register_operand" "=&q")])]
1535 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1537 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1538 if (! q_regs_operand (op1, QImode))
1540 emit_insn (gen_movqi (op2, op1));
1543 emit_insn (gen_movqi (op0, op1));
1547 (define_insn "*swapqi_1"
1548 [(set (match_operand:QI 0 "register_operand" "+r")
1549 (match_operand:QI 1 "register_operand" "+r"))
1552 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1554 [(set_attr "type" "imov")
1555 (set_attr "mode" "SI")
1556 (set_attr "pent_pair" "np")
1557 (set_attr "athlon_decode" "vector")])
1559 (define_insn "*swapqi_2"
1560 [(set (match_operand:QI 0 "register_operand" "+q")
1561 (match_operand:QI 1 "register_operand" "+q"))
1564 "TARGET_PARTIAL_REG_STALL"
1566 [(set_attr "type" "imov")
1567 (set_attr "mode" "QI")
1568 (set_attr "pent_pair" "np")
1569 (set_attr "athlon_decode" "vector")])
1571 (define_expand "movstrictqi"
1572 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1573 (match_operand:QI 1 "general_operand" ""))]
1574 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1576 /* Don't generate memory->memory moves, go through a register. */
1577 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1578 operands[1] = force_reg (QImode, operands[1]);
1581 (define_insn "*movstrictqi_1"
1582 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1583 (match_operand:QI 1 "general_operand" "*qn,m"))]
1584 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1585 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1586 "mov{b}\t{%1, %0|%0, %1}"
1587 [(set_attr "type" "imov")
1588 (set_attr "mode" "QI")])
1590 (define_insn "*movstrictqi_xor"
1591 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1592 (match_operand:QI 1 "const0_operand" "i"))
1593 (clobber (reg:CC FLAGS_REG))]
1594 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1595 "xor{b}\t{%0, %0|%0, %0}"
1596 [(set_attr "type" "alu1")
1597 (set_attr "mode" "QI")
1598 (set_attr "length_immediate" "0")])
1600 (define_insn "*movsi_extv_1"
1601 [(set (match_operand:SI 0 "register_operand" "=R")
1602 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1606 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1607 [(set_attr "type" "imovx")
1608 (set_attr "mode" "SI")])
1610 (define_insn "*movhi_extv_1"
1611 [(set (match_operand:HI 0 "register_operand" "=R")
1612 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1616 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1617 [(set_attr "type" "imovx")
1618 (set_attr "mode" "SI")])
1620 (define_insn "*movqi_extv_1"
1621 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1622 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1627 switch (get_attr_type (insn))
1630 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1632 return "mov{b}\t{%h1, %0|%0, %h1}";
1636 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1637 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1638 (ne (symbol_ref "TARGET_MOVX")
1640 (const_string "imovx")
1641 (const_string "imov")))
1643 (if_then_else (eq_attr "type" "imovx")
1645 (const_string "QI")))])
1647 (define_insn "*movqi_extv_1_rex64"
1648 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1649 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1654 switch (get_attr_type (insn))
1657 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1659 return "mov{b}\t{%h1, %0|%0, %h1}";
1663 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1664 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1665 (ne (symbol_ref "TARGET_MOVX")
1667 (const_string "imovx")
1668 (const_string "imov")))
1670 (if_then_else (eq_attr "type" "imovx")
1672 (const_string "QI")))])
1674 ;; Stores and loads of ax to arbitrary constant address.
1675 ;; We fake an second form of instruction to force reload to load address
1676 ;; into register when rax is not available
1677 (define_insn "*movabsqi_1_rex64"
1678 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1679 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1680 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1682 movabs{b}\t{%1, %P0|%P0, %1}
1683 mov{b}\t{%1, %a0|%a0, %1}"
1684 [(set_attr "type" "imov")
1685 (set_attr "modrm" "0,*")
1686 (set_attr "length_address" "8,0")
1687 (set_attr "length_immediate" "0,*")
1688 (set_attr "memory" "store")
1689 (set_attr "mode" "QI")])
1691 (define_insn "*movabsqi_2_rex64"
1692 [(set (match_operand:QI 0 "register_operand" "=a,r")
1693 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1694 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1696 movabs{b}\t{%P1, %0|%0, %P1}
1697 mov{b}\t{%a1, %0|%0, %a1}"
1698 [(set_attr "type" "imov")
1699 (set_attr "modrm" "0,*")
1700 (set_attr "length_address" "8,0")
1701 (set_attr "length_immediate" "0")
1702 (set_attr "memory" "load")
1703 (set_attr "mode" "QI")])
1705 (define_insn "*movdi_extzv_1"
1706 [(set (match_operand:DI 0 "register_operand" "=R")
1707 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1711 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1712 [(set_attr "type" "imovx")
1713 (set_attr "mode" "DI")])
1715 (define_insn "*movsi_extzv_1"
1716 [(set (match_operand:SI 0 "register_operand" "=R")
1717 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1721 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1722 [(set_attr "type" "imovx")
1723 (set_attr "mode" "SI")])
1725 (define_insn "*movqi_extzv_2"
1726 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1727 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1732 switch (get_attr_type (insn))
1735 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1737 return "mov{b}\t{%h1, %0|%0, %h1}";
1741 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1742 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1743 (ne (symbol_ref "TARGET_MOVX")
1745 (const_string "imovx")
1746 (const_string "imov")))
1748 (if_then_else (eq_attr "type" "imovx")
1750 (const_string "QI")))])
1752 (define_insn "*movqi_extzv_2_rex64"
1753 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1754 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1759 switch (get_attr_type (insn))
1762 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1764 return "mov{b}\t{%h1, %0|%0, %h1}";
1768 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1769 (ne (symbol_ref "TARGET_MOVX")
1771 (const_string "imovx")
1772 (const_string "imov")))
1774 (if_then_else (eq_attr "type" "imovx")
1776 (const_string "QI")))])
1778 (define_insn "movsi_insv_1"
1779 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1782 (match_operand:SI 1 "general_operand" "Qmn"))]
1784 "mov{b}\t{%b1, %h0|%h0, %b1}"
1785 [(set_attr "type" "imov")
1786 (set_attr "mode" "QI")])
1788 (define_insn "movdi_insv_1_rex64"
1789 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1792 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1794 "mov{b}\t{%b1, %h0|%h0, %b1}"
1795 [(set_attr "type" "imov")
1796 (set_attr "mode" "QI")])
1798 (define_insn "*movqi_insv_2"
1799 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1802 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1805 "mov{b}\t{%h1, %h0|%h0, %h1}"
1806 [(set_attr "type" "imov")
1807 (set_attr "mode" "QI")])
1809 (define_expand "movdi"
1810 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1811 (match_operand:DI 1 "general_operand" ""))]
1813 "ix86_expand_move (DImode, operands); DONE;")
1815 (define_insn "*pushdi"
1816 [(set (match_operand:DI 0 "push_operand" "=<")
1817 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1821 (define_insn "*pushdi2_rex64"
1822 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1823 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1828 [(set_attr "type" "push,multi")
1829 (set_attr "mode" "DI")])
1831 ;; Convert impossible pushes of immediate to existing instructions.
1832 ;; First try to get scratch register and go through it. In case this
1833 ;; fails, push sign extended lower part first and then overwrite
1834 ;; upper part by 32bit move.
1836 [(match_scratch:DI 2 "r")
1837 (set (match_operand:DI 0 "push_operand" "")
1838 (match_operand:DI 1 "immediate_operand" ""))]
1839 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1840 && !x86_64_immediate_operand (operands[1], DImode)"
1841 [(set (match_dup 2) (match_dup 1))
1842 (set (match_dup 0) (match_dup 2))]
1845 ;; We need to define this as both peepholer and splitter for case
1846 ;; peephole2 pass is not run.
1847 ;; "&& 1" is needed to keep it from matching the previous pattern.
1849 [(set (match_operand:DI 0 "push_operand" "")
1850 (match_operand:DI 1 "immediate_operand" ""))]
1851 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1852 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1853 [(set (match_dup 0) (match_dup 1))
1854 (set (match_dup 2) (match_dup 3))]
1855 "split_di (operands + 1, 1, operands + 2, operands + 3);
1856 operands[1] = gen_lowpart (DImode, operands[2]);
1857 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1862 [(set (match_operand:DI 0 "push_operand" "")
1863 (match_operand:DI 1 "immediate_operand" ""))]
1864 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1865 ? flow2_completed : reload_completed)
1866 && !symbolic_operand (operands[1], DImode)
1867 && !x86_64_immediate_operand (operands[1], DImode)"
1868 [(set (match_dup 0) (match_dup 1))
1869 (set (match_dup 2) (match_dup 3))]
1870 "split_di (operands + 1, 1, operands + 2, operands + 3);
1871 operands[1] = gen_lowpart (DImode, operands[2]);
1872 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1876 (define_insn "*pushdi2_prologue_rex64"
1877 [(set (match_operand:DI 0 "push_operand" "=<")
1878 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1879 (clobber (mem:BLK (scratch)))]
1882 [(set_attr "type" "push")
1883 (set_attr "mode" "DI")])
1885 (define_insn "*popdi1_epilogue_rex64"
1886 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1887 (mem:DI (reg:DI SP_REG)))
1888 (set (reg:DI SP_REG)
1889 (plus:DI (reg:DI SP_REG) (const_int 8)))
1890 (clobber (mem:BLK (scratch)))]
1893 [(set_attr "type" "pop")
1894 (set_attr "mode" "DI")])
1896 (define_insn "popdi1"
1897 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1898 (mem:DI (reg:DI SP_REG)))
1899 (set (reg:DI SP_REG)
1900 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1903 [(set_attr "type" "pop")
1904 (set_attr "mode" "DI")])
1906 (define_insn "*movdi_xor_rex64"
1907 [(set (match_operand:DI 0 "register_operand" "=r")
1908 (match_operand:DI 1 "const0_operand" "i"))
1909 (clobber (reg:CC FLAGS_REG))]
1910 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1911 && reload_completed"
1912 "xor{l}\t{%k0, %k0|%k0, %k0}"
1913 [(set_attr "type" "alu1")
1914 (set_attr "mode" "SI")
1915 (set_attr "length_immediate" "0")])
1917 (define_insn "*movdi_or_rex64"
1918 [(set (match_operand:DI 0 "register_operand" "=r")
1919 (match_operand:DI 1 "const_int_operand" "i"))
1920 (clobber (reg:CC FLAGS_REG))]
1921 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1923 && operands[1] == constm1_rtx"
1925 operands[1] = constm1_rtx;
1926 return "or{q}\t{%1, %0|%0, %1}";
1928 [(set_attr "type" "alu1")
1929 (set_attr "mode" "DI")
1930 (set_attr "length_immediate" "1")])
1932 (define_insn "*movdi_2"
1933 [(set (match_operand:DI 0 "nonimmediate_operand"
1934 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1935 (match_operand:DI 1 "general_operand"
1936 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1937 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1942 movq\t{%1, %0|%0, %1}
1943 movq\t{%1, %0|%0, %1}
1945 movq\t{%1, %0|%0, %1}
1946 movdqa\t{%1, %0|%0, %1}
1947 movq\t{%1, %0|%0, %1}
1949 movlps\t{%1, %0|%0, %1}
1950 movaps\t{%1, %0|%0, %1}
1951 movlps\t{%1, %0|%0, %1}"
1952 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1953 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1956 [(set (match_operand:DI 0 "push_operand" "")
1957 (match_operand:DI 1 "general_operand" ""))]
1958 "!TARGET_64BIT && reload_completed
1959 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1961 "ix86_split_long_move (operands); DONE;")
1963 ;; %%% This multiword shite has got to go.
1965 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1966 (match_operand:DI 1 "general_operand" ""))]
1967 "!TARGET_64BIT && reload_completed
1968 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1969 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1971 "ix86_split_long_move (operands); DONE;")
1973 (define_insn "*movdi_1_rex64"
1974 [(set (match_operand:DI 0 "nonimmediate_operand"
1975 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1976 (match_operand:DI 1 "general_operand"
1977 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1978 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1980 switch (get_attr_type (insn))
1983 if (which_alternative == 13)
1984 return "movq2dq\t{%1, %0|%0, %1}";
1986 return "movdq2q\t{%1, %0|%0, %1}";
1988 if (get_attr_mode (insn) == MODE_TI)
1989 return "movdqa\t{%1, %0|%0, %1}";
1992 /* Moves from and into integer register is done using movd opcode with
1994 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1995 return "movd\t{%1, %0|%0, %1}";
1996 return "movq\t{%1, %0|%0, %1}";
1999 return "pxor\t%0, %0";
2003 return "lea{q}\t{%a1, %0|%0, %a1}";
2005 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2006 if (get_attr_mode (insn) == MODE_SI)
2007 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2008 else if (which_alternative == 2)
2009 return "movabs{q}\t{%1, %0|%0, %1}";
2011 return "mov{q}\t{%1, %0|%0, %1}";
2015 (cond [(eq_attr "alternative" "5")
2016 (const_string "mmxadd")
2017 (eq_attr "alternative" "6,7,8")
2018 (const_string "mmxmov")
2019 (eq_attr "alternative" "9")
2020 (const_string "sselog1")
2021 (eq_attr "alternative" "10,11,12")
2022 (const_string "ssemov")
2023 (eq_attr "alternative" "13,14")
2024 (const_string "ssecvt")
2025 (eq_attr "alternative" "4")
2026 (const_string "multi")
2027 (match_operand:DI 1 "pic_32bit_operand" "")
2028 (const_string "lea")
2030 (const_string "imov")))
2031 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2032 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2033 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2035 ;; Stores and loads of ax to arbitrary constant address.
2036 ;; We fake an second form of instruction to force reload to load address
2037 ;; into register when rax is not available
2038 (define_insn "*movabsdi_1_rex64"
2039 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2040 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2041 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2043 movabs{q}\t{%1, %P0|%P0, %1}
2044 mov{q}\t{%1, %a0|%a0, %1}"
2045 [(set_attr "type" "imov")
2046 (set_attr "modrm" "0,*")
2047 (set_attr "length_address" "8,0")
2048 (set_attr "length_immediate" "0,*")
2049 (set_attr "memory" "store")
2050 (set_attr "mode" "DI")])
2052 (define_insn "*movabsdi_2_rex64"
2053 [(set (match_operand:DI 0 "register_operand" "=a,r")
2054 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2055 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2057 movabs{q}\t{%P1, %0|%0, %P1}
2058 mov{q}\t{%a1, %0|%0, %a1}"
2059 [(set_attr "type" "imov")
2060 (set_attr "modrm" "0,*")
2061 (set_attr "length_address" "8,0")
2062 (set_attr "length_immediate" "0")
2063 (set_attr "memory" "load")
2064 (set_attr "mode" "DI")])
2066 ;; Convert impossible stores of immediate to existing instructions.
2067 ;; First try to get scratch register and go through it. In case this
2068 ;; fails, move by 32bit parts.
2070 [(match_scratch:DI 2 "r")
2071 (set (match_operand:DI 0 "memory_operand" "")
2072 (match_operand:DI 1 "immediate_operand" ""))]
2073 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2074 && !x86_64_immediate_operand (operands[1], DImode)"
2075 [(set (match_dup 2) (match_dup 1))
2076 (set (match_dup 0) (match_dup 2))]
2079 ;; We need to define this as both peepholer and splitter for case
2080 ;; peephole2 pass is not run.
2081 ;; "&& 1" is needed to keep it from matching the previous pattern.
2083 [(set (match_operand:DI 0 "memory_operand" "")
2084 (match_operand:DI 1 "immediate_operand" ""))]
2085 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2086 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2087 [(set (match_dup 2) (match_dup 3))
2088 (set (match_dup 4) (match_dup 5))]
2089 "split_di (operands, 2, operands + 2, operands + 4);")
2092 [(set (match_operand:DI 0 "memory_operand" "")
2093 (match_operand:DI 1 "immediate_operand" ""))]
2094 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2095 ? flow2_completed : reload_completed)
2096 && !symbolic_operand (operands[1], DImode)
2097 && !x86_64_immediate_operand (operands[1], DImode)"
2098 [(set (match_dup 2) (match_dup 3))
2099 (set (match_dup 4) (match_dup 5))]
2100 "split_di (operands, 2, operands + 2, operands + 4);")
2102 (define_insn "*swapdi_rex64"
2103 [(set (match_operand:DI 0 "register_operand" "+r")
2104 (match_operand:DI 1 "register_operand" "+r"))
2109 [(set_attr "type" "imov")
2110 (set_attr "mode" "DI")
2111 (set_attr "pent_pair" "np")
2112 (set_attr "athlon_decode" "vector")])
2114 (define_expand "movti"
2115 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2116 (match_operand:TI 1 "nonimmediate_operand" ""))]
2117 "TARGET_SSE || TARGET_64BIT"
2120 ix86_expand_move (TImode, operands);
2122 ix86_expand_vector_move (TImode, operands);
2126 (define_insn "*movti_internal"
2127 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2128 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2129 "TARGET_SSE && !TARGET_64BIT
2130 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2132 switch (which_alternative)
2135 if (get_attr_mode (insn) == MODE_V4SF)
2136 return "xorps\t%0, %0";
2138 return "pxor\t%0, %0";
2141 if (get_attr_mode (insn) == MODE_V4SF)
2142 return "movaps\t{%1, %0|%0, %1}";
2144 return "movdqa\t{%1, %0|%0, %1}";
2149 [(set_attr "type" "sselog1,ssemov,ssemov")
2151 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2152 (ne (symbol_ref "optimize_size") (const_int 0)))
2153 (const_string "V4SF")
2154 (and (eq_attr "alternative" "2")
2155 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2157 (const_string "V4SF")]
2158 (const_string "TI")))])
2160 (define_insn "*movti_rex64"
2161 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2162 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2164 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2166 switch (which_alternative)
2172 if (get_attr_mode (insn) == MODE_V4SF)
2173 return "xorps\t%0, %0";
2175 return "pxor\t%0, %0";
2178 if (get_attr_mode (insn) == MODE_V4SF)
2179 return "movaps\t{%1, %0|%0, %1}";
2181 return "movdqa\t{%1, %0|%0, %1}";
2186 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2188 (cond [(eq_attr "alternative" "2,3")
2190 (ne (symbol_ref "optimize_size")
2192 (const_string "V4SF")
2193 (const_string "TI"))
2194 (eq_attr "alternative" "4")
2196 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2198 (ne (symbol_ref "optimize_size")
2200 (const_string "V4SF")
2201 (const_string "TI"))]
2202 (const_string "DI")))])
2205 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2206 (match_operand:TI 1 "general_operand" ""))]
2207 "reload_completed && !SSE_REG_P (operands[0])
2208 && !SSE_REG_P (operands[1])"
2210 "ix86_split_long_move (operands); DONE;")
2212 (define_expand "movsf"
2213 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2214 (match_operand:SF 1 "general_operand" ""))]
2216 "ix86_expand_move (SFmode, operands); DONE;")
2218 (define_insn "*pushsf"
2219 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2220 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2223 /* Anything else should be already split before reg-stack. */
2224 gcc_assert (which_alternative == 1);
2225 return "push{l}\t%1";
2227 [(set_attr "type" "multi,push,multi")
2228 (set_attr "unit" "i387,*,*")
2229 (set_attr "mode" "SF,SI,SF")])
2231 (define_insn "*pushsf_rex64"
2232 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2233 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2236 /* Anything else should be already split before reg-stack. */
2237 gcc_assert (which_alternative == 1);
2238 return "push{q}\t%q1";
2240 [(set_attr "type" "multi,push,multi")
2241 (set_attr "unit" "i387,*,*")
2242 (set_attr "mode" "SF,DI,SF")])
2245 [(set (match_operand:SF 0 "push_operand" "")
2246 (match_operand:SF 1 "memory_operand" ""))]
2248 && GET_CODE (operands[1]) == MEM
2249 && constant_pool_reference_p (operands[1])"
2252 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2255 ;; %%% Kill this when call knows how to work this out.
2257 [(set (match_operand:SF 0 "push_operand" "")
2258 (match_operand:SF 1 "any_fp_register_operand" ""))]
2260 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2261 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2264 [(set (match_operand:SF 0 "push_operand" "")
2265 (match_operand:SF 1 "any_fp_register_operand" ""))]
2267 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2268 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2270 (define_insn "*movsf_1"
2271 [(set (match_operand:SF 0 "nonimmediate_operand"
2272 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2273 (match_operand:SF 1 "general_operand"
2274 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2275 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2276 && (reload_in_progress || reload_completed
2277 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2278 || GET_CODE (operands[1]) != CONST_DOUBLE
2279 || memory_operand (operands[0], SFmode))"
2281 switch (which_alternative)
2284 return output_387_reg_move (insn, operands);
2287 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2288 return "fstp%z0\t%y0";
2290 return "fst%z0\t%y0";
2293 return standard_80387_constant_opcode (operands[1]);
2297 return "mov{l}\t{%1, %0|%0, %1}";
2299 if (get_attr_mode (insn) == MODE_TI)
2300 return "pxor\t%0, %0";
2302 return "xorps\t%0, %0";
2304 if (get_attr_mode (insn) == MODE_V4SF)
2305 return "movaps\t{%1, %0|%0, %1}";
2307 return "movss\t{%1, %0|%0, %1}";
2310 return "movss\t{%1, %0|%0, %1}";
2314 return "movd\t{%1, %0|%0, %1}";
2317 return "movq\t{%1, %0|%0, %1}";
2323 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2325 (cond [(eq_attr "alternative" "3,4,9,10")
2327 (eq_attr "alternative" "5")
2329 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2331 (ne (symbol_ref "TARGET_SSE2")
2333 (eq (symbol_ref "optimize_size")
2336 (const_string "V4SF"))
2337 /* For architectures resolving dependencies on
2338 whole SSE registers use APS move to break dependency
2339 chains, otherwise use short move to avoid extra work.
2341 Do the same for architectures resolving dependencies on
2342 the parts. While in DF mode it is better to always handle
2343 just register parts, the SF mode is different due to lack
2344 of instructions to load just part of the register. It is
2345 better to maintain the whole registers in single format
2346 to avoid problems on using packed logical operations. */
2347 (eq_attr "alternative" "6")
2349 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2351 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2353 (const_string "V4SF")
2354 (const_string "SF"))
2355 (eq_attr "alternative" "11")
2356 (const_string "DI")]
2357 (const_string "SF")))])
2359 (define_insn "*swapsf"
2360 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2361 (match_operand:SF 1 "fp_register_operand" "+f"))
2364 "reload_completed || TARGET_80387"
2366 if (STACK_TOP_P (operands[0]))
2371 [(set_attr "type" "fxch")
2372 (set_attr "mode" "SF")])
2374 (define_expand "movdf"
2375 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2376 (match_operand:DF 1 "general_operand" ""))]
2378 "ix86_expand_move (DFmode, operands); DONE;")
2380 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2381 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2382 ;; On the average, pushdf using integers can be still shorter. Allow this
2383 ;; pattern for optimize_size too.
2385 (define_insn "*pushdf_nointeger"
2386 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2387 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2388 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2390 /* This insn should be already split before reg-stack. */
2393 [(set_attr "type" "multi")
2394 (set_attr "unit" "i387,*,*,*")
2395 (set_attr "mode" "DF,SI,SI,DF")])
2397 (define_insn "*pushdf_integer"
2398 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2399 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2400 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2402 /* This insn should be already split before reg-stack. */
2405 [(set_attr "type" "multi")
2406 (set_attr "unit" "i387,*,*")
2407 (set_attr "mode" "DF,SI,DF")])
2409 ;; %%% Kill this when call knows how to work this out.
2411 [(set (match_operand:DF 0 "push_operand" "")
2412 (match_operand:DF 1 "any_fp_register_operand" ""))]
2413 "!TARGET_64BIT && reload_completed"
2414 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2415 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2419 [(set (match_operand:DF 0 "push_operand" "")
2420 (match_operand:DF 1 "any_fp_register_operand" ""))]
2421 "TARGET_64BIT && reload_completed"
2422 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2423 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2427 [(set (match_operand:DF 0 "push_operand" "")
2428 (match_operand:DF 1 "general_operand" ""))]
2431 "ix86_split_long_move (operands); DONE;")
2433 ;; Moving is usually shorter when only FP registers are used. This separate
2434 ;; movdf pattern avoids the use of integer registers for FP operations
2435 ;; when optimizing for size.
2437 (define_insn "*movdf_nointeger"
2438 [(set (match_operand:DF 0 "nonimmediate_operand"
2439 "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ")
2440 (match_operand:DF 1 "general_operand"
2441 "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))]
2442 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2443 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2444 && (reload_in_progress || reload_completed
2445 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2446 || GET_CODE (operands[1]) != CONST_DOUBLE
2447 || memory_operand (operands[0], DFmode))"
2449 switch (which_alternative)
2452 return output_387_reg_move (insn, operands);
2455 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2456 return "fstp%z0\t%y0";
2458 return "fst%z0\t%y0";
2461 return standard_80387_constant_opcode (operands[1]);
2467 switch (get_attr_mode (insn))
2470 return "xorps\t%0, %0";
2472 return "xorpd\t%0, %0";
2474 return "pxor\t%0, %0";
2481 switch (get_attr_mode (insn))
2484 return "movaps\t{%1, %0|%0, %1}";
2486 return "movapd\t{%1, %0|%0, %1}";
2488 return "movdqa\t{%1, %0|%0, %1}";
2490 return "movq\t{%1, %0|%0, %1}";
2492 return "movsd\t{%1, %0|%0, %1}";
2494 return "movlpd\t{%1, %0|%0, %1}";
2496 return "movlps\t{%1, %0|%0, %1}";
2505 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2507 (cond [(eq_attr "alternative" "0,1,2")
2509 (eq_attr "alternative" "3,4")
2512 /* For SSE1, we have many fewer alternatives. */
2513 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2514 (cond [(eq_attr "alternative" "5,6")
2515 (const_string "V4SF")
2517 (const_string "V2SF"))
2519 /* xorps is one byte shorter. */
2520 (eq_attr "alternative" "5")
2521 (cond [(ne (symbol_ref "optimize_size")
2523 (const_string "V4SF")
2524 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2528 (const_string "V2DF"))
2530 /* For architectures resolving dependencies on
2531 whole SSE registers use APD move to break dependency
2532 chains, otherwise use short move to avoid extra work.
2534 movaps encodes one byte shorter. */
2535 (eq_attr "alternative" "6")
2537 [(ne (symbol_ref "optimize_size")
2539 (const_string "V4SF")
2540 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2542 (const_string "V2DF")
2544 (const_string "DF"))
2545 /* For architectures resolving dependencies on register
2546 parts we may avoid extra work to zero out upper part
2548 (eq_attr "alternative" "7")
2550 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2552 (const_string "V1DF")
2553 (const_string "DF"))
2555 (const_string "DF")))])
2557 (define_insn "*movdf_integer"
2558 [(set (match_operand:DF 0 "nonimmediate_operand"
2559 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2560 (match_operand:DF 1 "general_operand"
2561 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))]
2562 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2563 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2564 && (reload_in_progress || reload_completed
2565 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2566 || GET_CODE (operands[1]) != CONST_DOUBLE
2567 || memory_operand (operands[0], DFmode))"
2569 switch (which_alternative)
2572 return output_387_reg_move (insn, operands);
2575 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2576 return "fstp%z0\t%y0";
2578 return "fst%z0\t%y0";
2581 return standard_80387_constant_opcode (operands[1]);
2588 switch (get_attr_mode (insn))
2591 return "xorps\t%0, %0";
2593 return "xorpd\t%0, %0";
2595 return "pxor\t%0, %0";
2602 switch (get_attr_mode (insn))
2605 return "movaps\t{%1, %0|%0, %1}";
2607 return "movapd\t{%1, %0|%0, %1}";
2609 return "movdqa\t{%1, %0|%0, %1}";
2611 return "movq\t{%1, %0|%0, %1}";
2613 return "movsd\t{%1, %0|%0, %1}";
2615 return "movlpd\t{%1, %0|%0, %1}";
2617 return "movlps\t{%1, %0|%0, %1}";
2626 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2628 (cond [(eq_attr "alternative" "0,1,2")
2630 (eq_attr "alternative" "3,4")
2633 /* For SSE1, we have many fewer alternatives. */
2634 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2635 (cond [(eq_attr "alternative" "5,6")
2636 (const_string "V4SF")
2638 (const_string "V2SF"))
2640 /* xorps is one byte shorter. */
2641 (eq_attr "alternative" "5")
2642 (cond [(ne (symbol_ref "optimize_size")
2644 (const_string "V4SF")
2645 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2649 (const_string "V2DF"))
2651 /* For architectures resolving dependencies on
2652 whole SSE registers use APD move to break dependency
2653 chains, otherwise use short move to avoid extra work.
2655 movaps encodes one byte shorter. */
2656 (eq_attr "alternative" "6")
2658 [(ne (symbol_ref "optimize_size")
2660 (const_string "V4SF")
2661 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2663 (const_string "V2DF")
2665 (const_string "DF"))
2666 /* For architectures resolving dependencies on register
2667 parts we may avoid extra work to zero out upper part
2669 (eq_attr "alternative" "7")
2671 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2673 (const_string "V1DF")
2674 (const_string "DF"))
2676 (const_string "DF")))])
2679 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2680 (match_operand:DF 1 "general_operand" ""))]
2682 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2683 && ! (ANY_FP_REG_P (operands[0]) ||
2684 (GET_CODE (operands[0]) == SUBREG
2685 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2686 && ! (ANY_FP_REG_P (operands[1]) ||
2687 (GET_CODE (operands[1]) == SUBREG
2688 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2690 "ix86_split_long_move (operands); DONE;")
2692 (define_insn "*swapdf"
2693 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2694 (match_operand:DF 1 "fp_register_operand" "+f"))
2697 "reload_completed || TARGET_80387"
2699 if (STACK_TOP_P (operands[0]))
2704 [(set_attr "type" "fxch")
2705 (set_attr "mode" "DF")])
2707 (define_expand "movxf"
2708 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2709 (match_operand:XF 1 "general_operand" ""))]
2711 "ix86_expand_move (XFmode, operands); DONE;")
2713 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2714 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2715 ;; Pushing using integer instructions is longer except for constants
2716 ;; and direct memory references.
2717 ;; (assuming that any given constant is pushed only once, but this ought to be
2718 ;; handled elsewhere).
2720 (define_insn "*pushxf_nointeger"
2721 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2722 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2725 /* This insn should be already split before reg-stack. */
2728 [(set_attr "type" "multi")
2729 (set_attr "unit" "i387,*,*")
2730 (set_attr "mode" "XF,SI,SI")])
2732 (define_insn "*pushxf_integer"
2733 [(set (match_operand:XF 0 "push_operand" "=<,<")
2734 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2737 /* This insn should be already split before reg-stack. */
2740 [(set_attr "type" "multi")
2741 (set_attr "unit" "i387,*")
2742 (set_attr "mode" "XF,SI")])
2745 [(set (match_operand 0 "push_operand" "")
2746 (match_operand 1 "general_operand" ""))]
2748 && (GET_MODE (operands[0]) == XFmode
2749 || GET_MODE (operands[0]) == DFmode)
2750 && !ANY_FP_REG_P (operands[1])"
2752 "ix86_split_long_move (operands); DONE;")
2755 [(set (match_operand:XF 0 "push_operand" "")
2756 (match_operand:XF 1 "any_fp_register_operand" ""))]
2758 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2759 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2760 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2763 [(set (match_operand:XF 0 "push_operand" "")
2764 (match_operand:XF 1 "any_fp_register_operand" ""))]
2766 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2767 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2768 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2770 ;; Do not use integer registers when optimizing for size
2771 (define_insn "*movxf_nointeger"
2772 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2773 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2775 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2776 && (reload_in_progress || reload_completed
2777 || GET_CODE (operands[1]) != CONST_DOUBLE
2778 || memory_operand (operands[0], XFmode))"
2780 switch (which_alternative)
2783 return output_387_reg_move (insn, operands);
2786 /* There is no non-popping store to memory for XFmode. So if
2787 we need one, follow the store with a load. */
2788 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2789 return "fstp%z0\t%y0\;fld%z0\t%y0";
2791 return "fstp%z0\t%y0";
2794 return standard_80387_constant_opcode (operands[1]);
2802 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2803 (set_attr "mode" "XF,XF,XF,SI,SI")])
2805 (define_insn "*movxf_integer"
2806 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2807 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2809 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2810 && (reload_in_progress || reload_completed
2811 || GET_CODE (operands[1]) != CONST_DOUBLE
2812 || memory_operand (operands[0], XFmode))"
2814 switch (which_alternative)
2817 return output_387_reg_move (insn, operands);
2820 /* There is no non-popping store to memory for XFmode. So if
2821 we need one, follow the store with a load. */
2822 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2823 return "fstp%z0\t%y0\;fld%z0\t%y0";
2825 return "fstp%z0\t%y0";
2828 return standard_80387_constant_opcode (operands[1]);
2837 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2838 (set_attr "mode" "XF,XF,XF,SI,SI")])
2841 [(set (match_operand 0 "nonimmediate_operand" "")
2842 (match_operand 1 "general_operand" ""))]
2844 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2845 && GET_MODE (operands[0]) == XFmode
2846 && ! (ANY_FP_REG_P (operands[0]) ||
2847 (GET_CODE (operands[0]) == SUBREG
2848 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2849 && ! (ANY_FP_REG_P (operands[1]) ||
2850 (GET_CODE (operands[1]) == SUBREG
2851 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2853 "ix86_split_long_move (operands); DONE;")
2856 [(set (match_operand 0 "register_operand" "")
2857 (match_operand 1 "memory_operand" ""))]
2859 && GET_CODE (operands[1]) == MEM
2860 && (GET_MODE (operands[0]) == XFmode
2861 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2862 && constant_pool_reference_p (operands[1])"
2863 [(set (match_dup 0) (match_dup 1))]
2865 rtx c = avoid_constant_pool_reference (operands[1]);
2866 rtx r = operands[0];
2868 if (GET_CODE (r) == SUBREG)
2873 if (!standard_sse_constant_p (c))
2876 else if (FP_REG_P (r))
2878 if (!standard_80387_constant_p (c))
2881 else if (MMX_REG_P (r))
2887 (define_insn "swapxf"
2888 [(set (match_operand:XF 0 "register_operand" "+f")
2889 (match_operand:XF 1 "register_operand" "+f"))
2894 if (STACK_TOP_P (operands[0]))
2899 [(set_attr "type" "fxch")
2900 (set_attr "mode" "XF")])
2902 (define_expand "movtf"
2903 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2904 (match_operand:TF 1 "nonimmediate_operand" ""))]
2907 ix86_expand_move (TFmode, operands);
2911 (define_insn "*movtf_internal"
2912 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2913 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2915 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2917 switch (which_alternative)
2923 if (get_attr_mode (insn) == MODE_V4SF)
2924 return "xorps\t%0, %0";
2926 return "pxor\t%0, %0";
2929 if (get_attr_mode (insn) == MODE_V4SF)
2930 return "movaps\t{%1, %0|%0, %1}";
2932 return "movdqa\t{%1, %0|%0, %1}";
2937 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2939 (cond [(eq_attr "alternative" "2,3")
2941 (ne (symbol_ref "optimize_size")
2943 (const_string "V4SF")
2944 (const_string "TI"))
2945 (eq_attr "alternative" "4")
2947 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2949 (ne (symbol_ref "optimize_size")
2951 (const_string "V4SF")
2952 (const_string "TI"))]
2953 (const_string "DI")))])
2956 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2957 (match_operand:TF 1 "general_operand" ""))]
2958 "reload_completed && !SSE_REG_P (operands[0])
2959 && !SSE_REG_P (operands[1])"
2961 "ix86_split_long_move (operands); DONE;")
2963 ;; Zero extension instructions
2965 (define_expand "zero_extendhisi2"
2966 [(set (match_operand:SI 0 "register_operand" "")
2967 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2970 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2972 operands[1] = force_reg (HImode, operands[1]);
2973 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2978 (define_insn "zero_extendhisi2_and"
2979 [(set (match_operand:SI 0 "register_operand" "=r")
2980 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2981 (clobber (reg:CC FLAGS_REG))]
2982 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2984 [(set_attr "type" "alu1")
2985 (set_attr "mode" "SI")])
2988 [(set (match_operand:SI 0 "register_operand" "")
2989 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2990 (clobber (reg:CC FLAGS_REG))]
2991 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2992 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2993 (clobber (reg:CC FLAGS_REG))])]
2996 (define_insn "*zero_extendhisi2_movzwl"
2997 [(set (match_operand:SI 0 "register_operand" "=r")
2998 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2999 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3000 "movz{wl|x}\t{%1, %0|%0, %1}"
3001 [(set_attr "type" "imovx")
3002 (set_attr "mode" "SI")])
3004 (define_expand "zero_extendqihi2"
3006 [(set (match_operand:HI 0 "register_operand" "")
3007 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3008 (clobber (reg:CC FLAGS_REG))])]
3012 (define_insn "*zero_extendqihi2_and"
3013 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3014 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3015 (clobber (reg:CC FLAGS_REG))]
3016 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3018 [(set_attr "type" "alu1")
3019 (set_attr "mode" "HI")])
3021 (define_insn "*zero_extendqihi2_movzbw_and"
3022 [(set (match_operand:HI 0 "register_operand" "=r,r")
3023 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3024 (clobber (reg:CC FLAGS_REG))]
3025 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3027 [(set_attr "type" "imovx,alu1")
3028 (set_attr "mode" "HI")])
3030 ; zero extend to SImode here to avoid partial register stalls
3031 (define_insn "*zero_extendqihi2_movzbl"
3032 [(set (match_operand:HI 0 "register_operand" "=r")
3033 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3034 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3035 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3036 [(set_attr "type" "imovx")
3037 (set_attr "mode" "SI")])
3039 ;; For the movzbw case strip only the clobber
3041 [(set (match_operand:HI 0 "register_operand" "")
3042 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3043 (clobber (reg:CC FLAGS_REG))]
3045 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3046 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3047 [(set (match_operand:HI 0 "register_operand" "")
3048 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3050 ;; When source and destination does not overlap, clear destination
3051 ;; first and then do the movb
3053 [(set (match_operand:HI 0 "register_operand" "")
3054 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3055 (clobber (reg:CC FLAGS_REG))]
3057 && ANY_QI_REG_P (operands[0])
3058 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3059 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3060 [(set (match_dup 0) (const_int 0))
3061 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3062 "operands[2] = gen_lowpart (QImode, operands[0]);")
3064 ;; Rest is handled by single and.
3066 [(set (match_operand:HI 0 "register_operand" "")
3067 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3068 (clobber (reg:CC FLAGS_REG))]
3070 && true_regnum (operands[0]) == true_regnum (operands[1])"
3071 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3072 (clobber (reg:CC FLAGS_REG))])]
3075 (define_expand "zero_extendqisi2"
3077 [(set (match_operand:SI 0 "register_operand" "")
3078 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3079 (clobber (reg:CC FLAGS_REG))])]
3083 (define_insn "*zero_extendqisi2_and"
3084 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3085 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3086 (clobber (reg:CC FLAGS_REG))]
3087 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3089 [(set_attr "type" "alu1")
3090 (set_attr "mode" "SI")])
3092 (define_insn "*zero_extendqisi2_movzbw_and"
3093 [(set (match_operand:SI 0 "register_operand" "=r,r")
3094 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3095 (clobber (reg:CC FLAGS_REG))]
3096 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3098 [(set_attr "type" "imovx,alu1")
3099 (set_attr "mode" "SI")])
3101 (define_insn "*zero_extendqisi2_movzbw"
3102 [(set (match_operand:SI 0 "register_operand" "=r")
3103 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3104 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3105 "movz{bl|x}\t{%1, %0|%0, %1}"
3106 [(set_attr "type" "imovx")
3107 (set_attr "mode" "SI")])
3109 ;; For the movzbl case strip only the clobber
3111 [(set (match_operand:SI 0 "register_operand" "")
3112 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3113 (clobber (reg:CC FLAGS_REG))]
3115 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3116 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3118 (zero_extend:SI (match_dup 1)))])
3120 ;; When source and destination does not overlap, clear destination
3121 ;; first and then do the movb
3123 [(set (match_operand:SI 0 "register_operand" "")
3124 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3125 (clobber (reg:CC FLAGS_REG))]
3127 && ANY_QI_REG_P (operands[0])
3128 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3129 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3130 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3131 [(set (match_dup 0) (const_int 0))
3132 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3133 "operands[2] = gen_lowpart (QImode, operands[0]);")
3135 ;; Rest is handled by single and.
3137 [(set (match_operand:SI 0 "register_operand" "")
3138 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3139 (clobber (reg:CC FLAGS_REG))]
3141 && true_regnum (operands[0]) == true_regnum (operands[1])"
3142 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3143 (clobber (reg:CC FLAGS_REG))])]
3146 ;; %%% Kill me once multi-word ops are sane.
3147 (define_expand "zero_extendsidi2"
3148 [(set (match_operand:DI 0 "register_operand" "=r")
3149 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3153 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3158 (define_insn "zero_extendsidi2_32"
3159 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3160 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3161 (clobber (reg:CC FLAGS_REG))]
3167 movd\t{%1, %0|%0, %1}
3168 movd\t{%1, %0|%0, %1}"
3169 [(set_attr "mode" "SI,SI,SI,DI,TI")
3170 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3172 (define_insn "zero_extendsidi2_rex64"
3173 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3174 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3177 mov\t{%k1, %k0|%k0, %k1}
3179 movd\t{%1, %0|%0, %1}
3180 movd\t{%1, %0|%0, %1}"
3181 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3182 (set_attr "mode" "SI,DI,SI,SI")])
3185 [(set (match_operand:DI 0 "memory_operand" "")
3186 (zero_extend:DI (match_dup 0)))]
3188 [(set (match_dup 4) (const_int 0))]
3189 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3192 [(set (match_operand:DI 0 "register_operand" "")
3193 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3194 (clobber (reg:CC FLAGS_REG))]
3195 "!TARGET_64BIT && reload_completed
3196 && true_regnum (operands[0]) == true_regnum (operands[1])"
3197 [(set (match_dup 4) (const_int 0))]
3198 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3201 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3202 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3203 (clobber (reg:CC FLAGS_REG))]
3204 "!TARGET_64BIT && reload_completed
3205 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3206 [(set (match_dup 3) (match_dup 1))
3207 (set (match_dup 4) (const_int 0))]
3208 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3210 (define_insn "zero_extendhidi2"
3211 [(set (match_operand:DI 0 "register_operand" "=r")
3212 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3214 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3215 [(set_attr "type" "imovx")
3216 (set_attr "mode" "DI")])
3218 (define_insn "zero_extendqidi2"
3219 [(set (match_operand:DI 0 "register_operand" "=r")
3220 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3222 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3223 [(set_attr "type" "imovx")
3224 (set_attr "mode" "DI")])
3226 ;; Sign extension instructions
3228 (define_expand "extendsidi2"
3229 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3230 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3231 (clobber (reg:CC FLAGS_REG))
3232 (clobber (match_scratch:SI 2 ""))])]
3237 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3242 (define_insn "*extendsidi2_1"
3243 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3244 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3245 (clobber (reg:CC FLAGS_REG))
3246 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3250 (define_insn "extendsidi2_rex64"
3251 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3252 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3256 movs{lq|x}\t{%1,%0|%0, %1}"
3257 [(set_attr "type" "imovx")
3258 (set_attr "mode" "DI")
3259 (set_attr "prefix_0f" "0")
3260 (set_attr "modrm" "0,1")])
3262 (define_insn "extendhidi2"
3263 [(set (match_operand:DI 0 "register_operand" "=r")
3264 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3266 "movs{wq|x}\t{%1,%0|%0, %1}"
3267 [(set_attr "type" "imovx")
3268 (set_attr "mode" "DI")])
3270 (define_insn "extendqidi2"
3271 [(set (match_operand:DI 0 "register_operand" "=r")
3272 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3274 "movs{bq|x}\t{%1,%0|%0, %1}"
3275 [(set_attr "type" "imovx")
3276 (set_attr "mode" "DI")])
3278 ;; Extend to memory case when source register does die.
3280 [(set (match_operand:DI 0 "memory_operand" "")
3281 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3282 (clobber (reg:CC FLAGS_REG))
3283 (clobber (match_operand:SI 2 "register_operand" ""))]
3285 && dead_or_set_p (insn, operands[1])
3286 && !reg_mentioned_p (operands[1], operands[0]))"
3287 [(set (match_dup 3) (match_dup 1))
3288 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3289 (clobber (reg:CC FLAGS_REG))])
3290 (set (match_dup 4) (match_dup 1))]
3291 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3293 ;; Extend to memory case when source register does not die.
3295 [(set (match_operand:DI 0 "memory_operand" "")
3296 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3297 (clobber (reg:CC FLAGS_REG))
3298 (clobber (match_operand:SI 2 "register_operand" ""))]
3302 split_di (&operands[0], 1, &operands[3], &operands[4]);
3304 emit_move_insn (operands[3], operands[1]);
3306 /* Generate a cltd if possible and doing so it profitable. */
3307 if (true_regnum (operands[1]) == 0
3308 && true_regnum (operands[2]) == 1
3309 && (optimize_size || TARGET_USE_CLTD))
3311 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3315 emit_move_insn (operands[2], operands[1]);
3316 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3318 emit_move_insn (operands[4], operands[2]);
3322 ;; Extend to register case. Optimize case where source and destination
3323 ;; registers match and cases where we can use cltd.
3325 [(set (match_operand:DI 0 "register_operand" "")
3326 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3327 (clobber (reg:CC FLAGS_REG))
3328 (clobber (match_scratch:SI 2 ""))]
3332 split_di (&operands[0], 1, &operands[3], &operands[4]);
3334 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3335 emit_move_insn (operands[3], operands[1]);
3337 /* Generate a cltd if possible and doing so it profitable. */
3338 if (true_regnum (operands[3]) == 0
3339 && (optimize_size || TARGET_USE_CLTD))
3341 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3345 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3346 emit_move_insn (operands[4], operands[1]);
3348 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3352 (define_insn "extendhisi2"
3353 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3354 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3357 switch (get_attr_prefix_0f (insn))
3360 return "{cwtl|cwde}";
3362 return "movs{wl|x}\t{%1,%0|%0, %1}";
3365 [(set_attr "type" "imovx")
3366 (set_attr "mode" "SI")
3367 (set (attr "prefix_0f")
3368 ;; movsx is short decodable while cwtl is vector decoded.
3369 (if_then_else (and (eq_attr "cpu" "!k6")
3370 (eq_attr "alternative" "0"))
3372 (const_string "1")))
3374 (if_then_else (eq_attr "prefix_0f" "0")
3376 (const_string "1")))])
3378 (define_insn "*extendhisi2_zext"
3379 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3381 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3384 switch (get_attr_prefix_0f (insn))
3387 return "{cwtl|cwde}";
3389 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3392 [(set_attr "type" "imovx")
3393 (set_attr "mode" "SI")
3394 (set (attr "prefix_0f")
3395 ;; movsx is short decodable while cwtl is vector decoded.
3396 (if_then_else (and (eq_attr "cpu" "!k6")
3397 (eq_attr "alternative" "0"))
3399 (const_string "1")))
3401 (if_then_else (eq_attr "prefix_0f" "0")
3403 (const_string "1")))])
3405 (define_insn "extendqihi2"
3406 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3407 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3410 switch (get_attr_prefix_0f (insn))
3413 return "{cbtw|cbw}";
3415 return "movs{bw|x}\t{%1,%0|%0, %1}";
3418 [(set_attr "type" "imovx")
3419 (set_attr "mode" "HI")
3420 (set (attr "prefix_0f")
3421 ;; movsx is short decodable while cwtl is vector decoded.
3422 (if_then_else (and (eq_attr "cpu" "!k6")
3423 (eq_attr "alternative" "0"))
3425 (const_string "1")))
3427 (if_then_else (eq_attr "prefix_0f" "0")
3429 (const_string "1")))])
3431 (define_insn "extendqisi2"
3432 [(set (match_operand:SI 0 "register_operand" "=r")
3433 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3435 "movs{bl|x}\t{%1,%0|%0, %1}"
3436 [(set_attr "type" "imovx")
3437 (set_attr "mode" "SI")])
3439 (define_insn "*extendqisi2_zext"
3440 [(set (match_operand:DI 0 "register_operand" "=r")
3442 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3444 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3445 [(set_attr "type" "imovx")
3446 (set_attr "mode" "SI")])
3448 ;; Conversions between float and double.
3450 ;; These are all no-ops in the model used for the 80387. So just
3453 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3454 (define_insn "*dummy_extendsfdf2"
3455 [(set (match_operand:DF 0 "push_operand" "=<")
3456 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3461 [(set (match_operand:DF 0 "push_operand" "")
3462 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3464 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3465 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3468 [(set (match_operand:DF 0 "push_operand" "")
3469 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3471 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3472 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3474 (define_insn "*dummy_extendsfxf2"
3475 [(set (match_operand:XF 0 "push_operand" "=<")
3476 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3481 [(set (match_operand:XF 0 "push_operand" "")
3482 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3484 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3485 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3486 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3489 [(set (match_operand:XF 0 "push_operand" "")
3490 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3492 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3493 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3494 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3497 [(set (match_operand:XF 0 "push_operand" "")
3498 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3500 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3501 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3502 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3505 [(set (match_operand:XF 0 "push_operand" "")
3506 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3508 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3509 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3510 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3512 (define_expand "extendsfdf2"
3513 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3514 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3515 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3517 /* ??? Needed for compress_float_constant since all fp constants
3518 are LEGITIMATE_CONSTANT_P. */
3519 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3520 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3521 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3522 operands[1] = force_reg (SFmode, operands[1]);
3525 (define_insn "*extendsfdf2_mixed"
3526 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3527 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3528 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3529 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3531 switch (which_alternative)
3534 return output_387_reg_move (insn, operands);
3537 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3538 return "fstp%z0\t%y0";
3540 return "fst%z0\t%y0";
3543 return "cvtss2sd\t{%1, %0|%0, %1}";
3549 [(set_attr "type" "fmov,fmov,ssecvt")
3550 (set_attr "mode" "SF,XF,DF")])
3552 (define_insn "*extendsfdf2_sse"
3553 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3554 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3555 "TARGET_SSE2 && TARGET_SSE_MATH
3556 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3557 "cvtss2sd\t{%1, %0|%0, %1}"
3558 [(set_attr "type" "ssecvt")
3559 (set_attr "mode" "DF")])
3561 (define_insn "*extendsfdf2_i387"
3562 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3563 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3565 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3567 switch (which_alternative)
3570 return output_387_reg_move (insn, operands);
3573 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3574 return "fstp%z0\t%y0";
3576 return "fst%z0\t%y0";
3582 [(set_attr "type" "fmov")
3583 (set_attr "mode" "SF,XF")])
3585 (define_expand "extendsfxf2"
3586 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3587 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3590 /* ??? Needed for compress_float_constant since all fp constants
3591 are LEGITIMATE_CONSTANT_P. */
3592 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3593 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3594 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3595 operands[1] = force_reg (SFmode, operands[1]);
3598 (define_insn "*extendsfxf2_i387"
3599 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3600 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3602 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3604 switch (which_alternative)
3607 return output_387_reg_move (insn, operands);
3610 /* There is no non-popping store to memory for XFmode. So if
3611 we need one, follow the store with a load. */
3612 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3613 return "fstp%z0\t%y0";
3615 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3621 [(set_attr "type" "fmov")
3622 (set_attr "mode" "SF,XF")])
3624 (define_expand "extenddfxf2"
3625 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3626 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3629 /* ??? Needed for compress_float_constant since all fp constants
3630 are LEGITIMATE_CONSTANT_P. */
3631 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3632 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3633 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3634 operands[1] = force_reg (DFmode, operands[1]);
3637 (define_insn "*extenddfxf2_i387"
3638 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3639 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3641 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3643 switch (which_alternative)
3646 return output_387_reg_move (insn, operands);
3649 /* There is no non-popping store to memory for XFmode. So if
3650 we need one, follow the store with a load. */
3651 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3652 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3654 return "fstp%z0\t%y0";
3660 [(set_attr "type" "fmov")
3661 (set_attr "mode" "DF,XF")])
3663 ;; %%% This seems bad bad news.
3664 ;; This cannot output into an f-reg because there is no way to be sure
3665 ;; of truncating in that case. Otherwise this is just like a simple move
3666 ;; insn. So we pretend we can output to a reg in order to get better
3667 ;; register preferencing, but we really use a stack slot.
3669 ;; Conversion from DFmode to SFmode.
3671 (define_expand "truncdfsf2"
3672 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3674 (match_operand:DF 1 "nonimmediate_operand" "")))]
3675 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3677 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3678 operands[1] = force_reg (DFmode, operands[1]);
3680 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3682 else if (flag_unsafe_math_optimizations)
3686 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3687 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3692 (define_expand "truncdfsf2_with_temp"
3693 [(parallel [(set (match_operand:SF 0 "" "")
3694 (float_truncate:SF (match_operand:DF 1 "" "")))
3695 (clobber (match_operand:SF 2 "" ""))])]
3698 (define_insn "*truncdfsf_fast_mixed"
3699 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3701 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3702 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3704 switch (which_alternative)
3707 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3708 return "fstp%z0\t%y0";
3710 return "fst%z0\t%y0";
3712 return output_387_reg_move (insn, operands);
3714 return "cvtsd2ss\t{%1, %0|%0, %1}";
3719 [(set_attr "type" "fmov,fmov,ssecvt")
3720 (set_attr "mode" "SF")])
3722 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3723 ;; because nothing we do here is unsafe.
3724 (define_insn "*truncdfsf_fast_sse"
3725 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3727 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3728 "TARGET_SSE2 && TARGET_SSE_MATH"
3729 "cvtsd2ss\t{%1, %0|%0, %1}"
3730 [(set_attr "type" "ssecvt")
3731 (set_attr "mode" "SF")])
3733 (define_insn "*truncdfsf_fast_i387"
3734 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3736 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3737 "TARGET_80387 && flag_unsafe_math_optimizations"
3738 "* return output_387_reg_move (insn, operands);"
3739 [(set_attr "type" "fmov")
3740 (set_attr "mode" "SF")])
3742 (define_insn "*truncdfsf_mixed"
3743 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3745 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3746 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3747 "TARGET_MIX_SSE_I387"
3749 switch (which_alternative)
3752 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3753 return "fstp%z0\t%y0";
3755 return "fst%z0\t%y0";
3759 return "cvtsd2ss\t{%1, %0|%0, %1}";
3764 [(set_attr "type" "fmov,multi,ssecvt")
3765 (set_attr "unit" "*,i387,*")
3766 (set_attr "mode" "SF")])
3768 (define_insn "*truncdfsf_i387"
3769 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3771 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3772 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3775 switch (which_alternative)
3778 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3779 return "fstp%z0\t%y0";
3781 return "fst%z0\t%y0";
3788 [(set_attr "type" "fmov,multi")
3789 (set_attr "unit" "*,i387")
3790 (set_attr "mode" "SF")])
3792 (define_insn "*truncdfsf2_i387_1"
3793 [(set (match_operand:SF 0 "memory_operand" "=m")
3795 (match_operand:DF 1 "register_operand" "f")))]
3797 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3798 && !TARGET_MIX_SSE_I387"
3800 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3801 return "fstp%z0\t%y0";
3803 return "fst%z0\t%y0";
3805 [(set_attr "type" "fmov")
3806 (set_attr "mode" "SF")])
3809 [(set (match_operand:SF 0 "register_operand" "")
3811 (match_operand:DF 1 "fp_register_operand" "")))
3812 (clobber (match_operand 2 "" ""))]
3814 [(set (match_dup 2) (match_dup 1))
3815 (set (match_dup 0) (match_dup 2))]
3817 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3820 ;; Conversion from XFmode to SFmode.
3822 (define_expand "truncxfsf2"
3823 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3825 (match_operand:XF 1 "register_operand" "")))
3826 (clobber (match_dup 2))])]
3829 if (flag_unsafe_math_optimizations)
3831 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3832 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3833 if (reg != operands[0])
3834 emit_move_insn (operands[0], reg);
3838 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3841 (define_insn "*truncxfsf2_mixed"
3842 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3844 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3845 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3846 "TARGET_MIX_SSE_I387"
3848 gcc_assert (!which_alternative);
3849 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3850 return "fstp%z0\t%y0";
3852 return "fst%z0\t%y0";
3854 [(set_attr "type" "fmov,multi,multi,multi")
3855 (set_attr "unit" "*,i387,i387,i387")
3856 (set_attr "mode" "SF")])
3858 (define_insn "truncxfsf2_i387_noop"
3859 [(set (match_operand:SF 0 "register_operand" "=f")
3860 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3861 "TARGET_80387 && flag_unsafe_math_optimizations"
3863 return output_387_reg_move (insn, operands);
3865 [(set_attr "type" "fmov")
3866 (set_attr "mode" "SF")])
3868 (define_insn "*truncxfsf2_i387"
3869 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3871 (match_operand:XF 1 "register_operand" "f,f,f")))
3872 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3875 gcc_assert (!which_alternative);
3876 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3877 return "fstp%z0\t%y0";
3879 return "fst%z0\t%y0";
3881 [(set_attr "type" "fmov,multi,multi")
3882 (set_attr "unit" "*,i387,i387")
3883 (set_attr "mode" "SF")])
3885 (define_insn "*truncxfsf2_i387_1"
3886 [(set (match_operand:SF 0 "memory_operand" "=m")
3888 (match_operand:XF 1 "register_operand" "f")))]
3891 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3892 return "fstp%z0\t%y0";
3894 return "fst%z0\t%y0";
3896 [(set_attr "type" "fmov")
3897 (set_attr "mode" "SF")])
3900 [(set (match_operand:SF 0 "register_operand" "")
3902 (match_operand:XF 1 "register_operand" "")))
3903 (clobber (match_operand:SF 2 "memory_operand" ""))]
3904 "TARGET_80387 && reload_completed"
3905 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3906 (set (match_dup 0) (match_dup 2))]
3910 [(set (match_operand:SF 0 "memory_operand" "")
3912 (match_operand:XF 1 "register_operand" "")))
3913 (clobber (match_operand:SF 2 "memory_operand" ""))]
3915 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3918 ;; Conversion from XFmode to DFmode.
3920 (define_expand "truncxfdf2"
3921 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3923 (match_operand:XF 1 "register_operand" "")))
3924 (clobber (match_dup 2))])]
3927 if (flag_unsafe_math_optimizations)
3929 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3930 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3931 if (reg != operands[0])
3932 emit_move_insn (operands[0], reg);
3936 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3939 (define_insn "*truncxfdf2_mixed"
3940 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3942 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3943 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3944 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3946 gcc_assert (!which_alternative);
3947 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3948 return "fstp%z0\t%y0";
3950 return "fst%z0\t%y0";
3952 [(set_attr "type" "fmov,multi,multi,multi")
3953 (set_attr "unit" "*,i387,i387,i387")
3954 (set_attr "mode" "DF")])
3956 (define_insn "truncxfdf2_i387_noop"
3957 [(set (match_operand:DF 0 "register_operand" "=f")
3958 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3959 "TARGET_80387 && flag_unsafe_math_optimizations"
3961 return output_387_reg_move (insn, operands);
3963 [(set_attr "type" "fmov")
3964 (set_attr "mode" "DF")])
3966 (define_insn "*truncxfdf2_i387"
3967 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3969 (match_operand:XF 1 "register_operand" "f,f,f")))
3970 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3973 gcc_assert (!which_alternative);
3974 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3975 return "fstp%z0\t%y0";
3977 return "fst%z0\t%y0";
3979 [(set_attr "type" "fmov,multi,multi")
3980 (set_attr "unit" "*,i387,i387")
3981 (set_attr "mode" "DF")])
3983 (define_insn "*truncxfdf2_i387_1"
3984 [(set (match_operand:DF 0 "memory_operand" "=m")
3986 (match_operand:XF 1 "register_operand" "f")))]
3989 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3990 return "fstp%z0\t%y0";
3992 return "fst%z0\t%y0";
3994 [(set_attr "type" "fmov")
3995 (set_attr "mode" "DF")])
3998 [(set (match_operand:DF 0 "register_operand" "")
4000 (match_operand:XF 1 "register_operand" "")))
4001 (clobber (match_operand:DF 2 "memory_operand" ""))]
4002 "TARGET_80387 && reload_completed"
4003 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4004 (set (match_dup 0) (match_dup 2))]
4008 [(set (match_operand:DF 0 "memory_operand" "")
4010 (match_operand:XF 1 "register_operand" "")))
4011 (clobber (match_operand:DF 2 "memory_operand" ""))]
4013 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4016 ;; Signed conversion to DImode.
4018 (define_expand "fix_truncxfdi2"
4019 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4020 (fix:DI (match_operand:XF 1 "register_operand" "")))
4021 (clobber (reg:CC FLAGS_REG))])]
4026 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4031 (define_expand "fix_trunc<mode>di2"
4032 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4033 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4034 (clobber (reg:CC FLAGS_REG))])]
4035 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4038 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4040 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4043 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4045 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4046 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4047 if (out != operands[0])
4048 emit_move_insn (operands[0], out);
4053 ;; Signed conversion to SImode.
4055 (define_expand "fix_truncxfsi2"
4056 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4057 (fix:SI (match_operand:XF 1 "register_operand" "")))
4058 (clobber (reg:CC FLAGS_REG))])]
4063 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4068 (define_expand "fix_trunc<mode>si2"
4069 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4070 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4071 (clobber (reg:CC FLAGS_REG))])]
4072 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4075 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4077 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4080 if (SSE_FLOAT_MODE_P (<MODE>mode))
4082 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4083 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4084 if (out != operands[0])
4085 emit_move_insn (operands[0], out);
4090 ;; Signed conversion to HImode.
4092 (define_expand "fix_trunc<mode>hi2"
4093 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4094 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4095 (clobber (reg:CC FLAGS_REG))])]
4097 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4101 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4106 ;; When SSE is available, it is always faster to use it!
4107 (define_insn "fix_truncsfdi_sse"
4108 [(set (match_operand:DI 0 "register_operand" "=r,r")
4109 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4110 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4111 "cvttss2si{q}\t{%1, %0|%0, %1}"
4112 [(set_attr "type" "sseicvt")
4113 (set_attr "mode" "SF")
4114 (set_attr "athlon_decode" "double,vector")])
4116 (define_insn "fix_truncdfdi_sse"
4117 [(set (match_operand:DI 0 "register_operand" "=r,r")
4118 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4119 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4120 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4121 [(set_attr "type" "sseicvt")
4122 (set_attr "mode" "DF")
4123 (set_attr "athlon_decode" "double,vector")])
4125 (define_insn "fix_truncsfsi_sse"
4126 [(set (match_operand:SI 0 "register_operand" "=r,r")
4127 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4128 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4129 "cvttss2si\t{%1, %0|%0, %1}"
4130 [(set_attr "type" "sseicvt")
4131 (set_attr "mode" "DF")
4132 (set_attr "athlon_decode" "double,vector")])
4134 (define_insn "fix_truncdfsi_sse"
4135 [(set (match_operand:SI 0 "register_operand" "=r,r")
4136 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4137 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4138 "cvttsd2si\t{%1, %0|%0, %1}"
4139 [(set_attr "type" "sseicvt")
4140 (set_attr "mode" "DF")
4141 (set_attr "athlon_decode" "double,vector")])
4143 ;; Avoid vector decoded forms of the instruction.
4145 [(match_scratch:DF 2 "Y")
4146 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4147 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4148 "TARGET_K8 && !optimize_size"
4149 [(set (match_dup 2) (match_dup 1))
4150 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4154 [(match_scratch:SF 2 "x")
4155 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4156 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4157 "TARGET_K8 && !optimize_size"
4158 [(set (match_dup 2) (match_dup 1))
4159 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4162 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4163 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4164 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4166 && FLOAT_MODE_P (GET_MODE (operands[1]))
4167 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4168 && (TARGET_64BIT || <MODE>mode != DImode))
4170 && !(reload_completed || reload_in_progress)"
4175 if (memory_operand (operands[0], VOIDmode))
4176 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4179 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4180 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4186 [(set_attr "type" "fisttp")
4187 (set_attr "mode" "<MODE>")])
4189 (define_insn "fix_trunc<mode>_i387_fisttp"
4190 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4191 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4192 (clobber (match_scratch:XF 2 "=&1f"))]
4194 && FLOAT_MODE_P (GET_MODE (operands[1]))
4195 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4196 && (TARGET_64BIT || <MODE>mode != DImode))
4197 && TARGET_SSE_MATH)"
4198 "* return output_fix_trunc (insn, operands, 1);"
4199 [(set_attr "type" "fisttp")
4200 (set_attr "mode" "<MODE>")])
4202 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4203 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4204 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4205 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4206 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4208 && FLOAT_MODE_P (GET_MODE (operands[1]))
4209 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4210 && (TARGET_64BIT || <MODE>mode != DImode))
4211 && TARGET_SSE_MATH)"
4213 [(set_attr "type" "fisttp")
4214 (set_attr "mode" "<MODE>")])
4217 [(set (match_operand:X87MODEI 0 "register_operand" "")
4218 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4219 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4220 (clobber (match_scratch 3 ""))]
4222 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4223 (clobber (match_dup 3))])
4224 (set (match_dup 0) (match_dup 2))]
4228 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4229 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4230 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4231 (clobber (match_scratch 3 ""))]
4233 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4234 (clobber (match_dup 3))])]
4237 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4238 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4239 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4240 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4241 ;; function in i386.c.
4242 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4243 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4244 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4245 (clobber (reg:CC FLAGS_REG))]
4246 "TARGET_80387 && !TARGET_FISTTP
4247 && FLOAT_MODE_P (GET_MODE (operands[1]))
4248 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4249 && (TARGET_64BIT || <MODE>mode != DImode))
4250 && !(reload_completed || reload_in_progress)"
4255 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4257 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4258 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4259 if (memory_operand (operands[0], VOIDmode))
4260 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4261 operands[2], operands[3]));
4264 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4265 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4266 operands[2], operands[3],
4271 [(set_attr "type" "fistp")
4272 (set_attr "i387_cw" "trunc")
4273 (set_attr "mode" "<MODE>")])
4275 (define_insn "fix_truncdi_i387"
4276 [(set (match_operand:DI 0 "memory_operand" "=m")
4277 (fix:DI (match_operand 1 "register_operand" "f")))
4278 (use (match_operand:HI 2 "memory_operand" "m"))
4279 (use (match_operand:HI 3 "memory_operand" "m"))
4280 (clobber (match_scratch:XF 4 "=&1f"))]
4281 "TARGET_80387 && !TARGET_FISTTP
4282 && FLOAT_MODE_P (GET_MODE (operands[1]))
4283 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4284 "* return output_fix_trunc (insn, operands, 0);"
4285 [(set_attr "type" "fistp")
4286 (set_attr "i387_cw" "trunc")
4287 (set_attr "mode" "DI")])
4289 (define_insn "fix_truncdi_i387_with_temp"
4290 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4291 (fix:DI (match_operand 1 "register_operand" "f,f")))
4292 (use (match_operand:HI 2 "memory_operand" "m,m"))
4293 (use (match_operand:HI 3 "memory_operand" "m,m"))
4294 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4295 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4296 "TARGET_80387 && !TARGET_FISTTP
4297 && FLOAT_MODE_P (GET_MODE (operands[1]))
4298 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4300 [(set_attr "type" "fistp")
4301 (set_attr "i387_cw" "trunc")
4302 (set_attr "mode" "DI")])
4305 [(set (match_operand:DI 0 "register_operand" "")
4306 (fix:DI (match_operand 1 "register_operand" "")))
4307 (use (match_operand:HI 2 "memory_operand" ""))
4308 (use (match_operand:HI 3 "memory_operand" ""))
4309 (clobber (match_operand:DI 4 "memory_operand" ""))
4310 (clobber (match_scratch 5 ""))]
4312 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4315 (clobber (match_dup 5))])
4316 (set (match_dup 0) (match_dup 4))]
4320 [(set (match_operand:DI 0 "memory_operand" "")
4321 (fix:DI (match_operand 1 "register_operand" "")))
4322 (use (match_operand:HI 2 "memory_operand" ""))
4323 (use (match_operand:HI 3 "memory_operand" ""))
4324 (clobber (match_operand:DI 4 "memory_operand" ""))
4325 (clobber (match_scratch 5 ""))]
4327 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4330 (clobber (match_dup 5))])]
4333 (define_insn "fix_trunc<mode>_i387"
4334 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4335 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4336 (use (match_operand:HI 2 "memory_operand" "m"))
4337 (use (match_operand:HI 3 "memory_operand" "m"))]
4338 "TARGET_80387 && !TARGET_FISTTP
4339 && FLOAT_MODE_P (GET_MODE (operands[1]))
4340 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4341 "* return output_fix_trunc (insn, operands, 0);"
4342 [(set_attr "type" "fistp")
4343 (set_attr "i387_cw" "trunc")
4344 (set_attr "mode" "<MODE>")])
4346 (define_insn "fix_trunc<mode>_i387_with_temp"
4347 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4348 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4349 (use (match_operand:HI 2 "memory_operand" "m,m"))
4350 (use (match_operand:HI 3 "memory_operand" "m,m"))
4351 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4352 "TARGET_80387 && !TARGET_FISTTP
4353 && FLOAT_MODE_P (GET_MODE (operands[1]))
4354 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4356 [(set_attr "type" "fistp")
4357 (set_attr "i387_cw" "trunc")
4358 (set_attr "mode" "<MODE>")])
4361 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4362 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4363 (use (match_operand:HI 2 "memory_operand" ""))
4364 (use (match_operand:HI 3 "memory_operand" ""))
4365 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4367 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4369 (use (match_dup 3))])
4370 (set (match_dup 0) (match_dup 4))]
4374 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4375 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4376 (use (match_operand:HI 2 "memory_operand" ""))
4377 (use (match_operand:HI 3 "memory_operand" ""))
4378 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4380 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4382 (use (match_dup 3))])]
4385 (define_insn "x86_fnstcw_1"
4386 [(set (match_operand:HI 0 "memory_operand" "=m")
4387 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4390 [(set_attr "length" "2")
4391 (set_attr "mode" "HI")
4392 (set_attr "unit" "i387")])
4394 (define_insn "x86_fldcw_1"
4395 [(set (reg:HI FPSR_REG)
4396 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4399 [(set_attr "length" "2")
4400 (set_attr "mode" "HI")
4401 (set_attr "unit" "i387")
4402 (set_attr "athlon_decode" "vector")])
4404 ;; Conversion between fixed point and floating point.
4406 ;; Even though we only accept memory inputs, the backend _really_
4407 ;; wants to be able to do this between registers.
4409 (define_expand "floathisf2"
4410 [(set (match_operand:SF 0 "register_operand" "")
4411 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4412 "TARGET_80387 || TARGET_SSE_MATH"
4414 if (TARGET_SSE_MATH)
4416 emit_insn (gen_floatsisf2 (operands[0],
4417 convert_to_mode (SImode, operands[1], 0)));
4422 (define_insn "*floathisf2_i387"
4423 [(set (match_operand:SF 0 "register_operand" "=f,f")
4424 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4425 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4429 [(set_attr "type" "fmov,multi")
4430 (set_attr "mode" "SF")
4431 (set_attr "unit" "*,i387")
4432 (set_attr "fp_int_src" "true")])
4434 (define_expand "floatsisf2"
4435 [(set (match_operand:SF 0 "register_operand" "")
4436 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4437 "TARGET_80387 || TARGET_SSE_MATH"
4440 (define_insn "*floatsisf2_mixed"
4441 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4442 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4443 "TARGET_MIX_SSE_I387"
4447 cvtsi2ss\t{%1, %0|%0, %1}
4448 cvtsi2ss\t{%1, %0|%0, %1}"
4449 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4450 (set_attr "mode" "SF")
4451 (set_attr "unit" "*,i387,*,*")
4452 (set_attr "athlon_decode" "*,*,vector,double")
4453 (set_attr "fp_int_src" "true")])
4455 (define_insn "*floatsisf2_sse"
4456 [(set (match_operand:SF 0 "register_operand" "=x,x")
4457 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4459 "cvtsi2ss\t{%1, %0|%0, %1}"
4460 [(set_attr "type" "sseicvt")
4461 (set_attr "mode" "SF")
4462 (set_attr "athlon_decode" "vector,double")
4463 (set_attr "fp_int_src" "true")])
4465 (define_insn "*floatsisf2_i387"
4466 [(set (match_operand:SF 0 "register_operand" "=f,f")
4467 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4472 [(set_attr "type" "fmov,multi")
4473 (set_attr "mode" "SF")
4474 (set_attr "unit" "*,i387")
4475 (set_attr "fp_int_src" "true")])
4477 (define_expand "floatdisf2"
4478 [(set (match_operand:SF 0 "register_operand" "")
4479 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4480 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4483 (define_insn "*floatdisf2_mixed"
4484 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4485 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4486 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4490 cvtsi2ss{q}\t{%1, %0|%0, %1}
4491 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4492 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4493 (set_attr "mode" "SF")
4494 (set_attr "unit" "*,i387,*,*")
4495 (set_attr "athlon_decode" "*,*,vector,double")
4496 (set_attr "fp_int_src" "true")])
4498 (define_insn "*floatdisf2_sse"
4499 [(set (match_operand:SF 0 "register_operand" "=x,x")
4500 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4501 "TARGET_64BIT && TARGET_SSE_MATH"
4502 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4503 [(set_attr "type" "sseicvt")
4504 (set_attr "mode" "SF")
4505 (set_attr "athlon_decode" "vector,double")
4506 (set_attr "fp_int_src" "true")])
4508 (define_insn "*floatdisf2_i387"
4509 [(set (match_operand:SF 0 "register_operand" "=f,f")
4510 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4515 [(set_attr "type" "fmov,multi")
4516 (set_attr "mode" "SF")
4517 (set_attr "unit" "*,i387")
4518 (set_attr "fp_int_src" "true")])
4520 (define_expand "floathidf2"
4521 [(set (match_operand:DF 0 "register_operand" "")
4522 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4523 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4525 if (TARGET_SSE2 && TARGET_SSE_MATH)
4527 emit_insn (gen_floatsidf2 (operands[0],
4528 convert_to_mode (SImode, operands[1], 0)));
4533 (define_insn "*floathidf2_i387"
4534 [(set (match_operand:DF 0 "register_operand" "=f,f")
4535 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4536 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4540 [(set_attr "type" "fmov,multi")
4541 (set_attr "mode" "DF")
4542 (set_attr "unit" "*,i387")
4543 (set_attr "fp_int_src" "true")])
4545 (define_expand "floatsidf2"
4546 [(set (match_operand:DF 0 "register_operand" "")
4547 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4548 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4551 (define_insn "*floatsidf2_mixed"
4552 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4553 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4554 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4558 cvtsi2sd\t{%1, %0|%0, %1}
4559 cvtsi2sd\t{%1, %0|%0, %1}"
4560 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4561 (set_attr "mode" "DF")
4562 (set_attr "unit" "*,i387,*,*")
4563 (set_attr "athlon_decode" "*,*,double,direct")
4564 (set_attr "fp_int_src" "true")])
4566 (define_insn "*floatsidf2_sse"
4567 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4568 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4569 "TARGET_SSE2 && TARGET_SSE_MATH"
4570 "cvtsi2sd\t{%1, %0|%0, %1}"
4571 [(set_attr "type" "sseicvt")
4572 (set_attr "mode" "DF")
4573 (set_attr "athlon_decode" "double,direct")
4574 (set_attr "fp_int_src" "true")])
4576 (define_insn "*floatsidf2_i387"
4577 [(set (match_operand:DF 0 "register_operand" "=f,f")
4578 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4583 [(set_attr "type" "fmov,multi")
4584 (set_attr "mode" "DF")
4585 (set_attr "unit" "*,i387")
4586 (set_attr "fp_int_src" "true")])
4588 (define_expand "floatdidf2"
4589 [(set (match_operand:DF 0 "register_operand" "")
4590 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4591 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4594 (define_insn "*floatdidf2_mixed"
4595 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4596 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4597 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4601 cvtsi2sd{q}\t{%1, %0|%0, %1}
4602 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4603 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4604 (set_attr "mode" "DF")
4605 (set_attr "unit" "*,i387,*,*")
4606 (set_attr "athlon_decode" "*,*,double,direct")
4607 (set_attr "fp_int_src" "true")])
4609 (define_insn "*floatdidf2_sse"
4610 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4611 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4612 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4613 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4614 [(set_attr "type" "sseicvt")
4615 (set_attr "mode" "DF")
4616 (set_attr "athlon_decode" "double,direct")
4617 (set_attr "fp_int_src" "true")])
4619 (define_insn "*floatdidf2_i387"
4620 [(set (match_operand:DF 0 "register_operand" "=f,f")
4621 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4626 [(set_attr "type" "fmov,multi")
4627 (set_attr "mode" "DF")
4628 (set_attr "unit" "*,i387")
4629 (set_attr "fp_int_src" "true")])
4631 (define_insn "floathixf2"
4632 [(set (match_operand:XF 0 "register_operand" "=f,f")
4633 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4638 [(set_attr "type" "fmov,multi")
4639 (set_attr "mode" "XF")
4640 (set_attr "unit" "*,i387")
4641 (set_attr "fp_int_src" "true")])
4643 (define_insn "floatsixf2"
4644 [(set (match_operand:XF 0 "register_operand" "=f,f")
4645 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4650 [(set_attr "type" "fmov,multi")
4651 (set_attr "mode" "XF")
4652 (set_attr "unit" "*,i387")
4653 (set_attr "fp_int_src" "true")])
4655 (define_insn "floatdixf2"
4656 [(set (match_operand:XF 0 "register_operand" "=f,f")
4657 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4662 [(set_attr "type" "fmov,multi")
4663 (set_attr "mode" "XF")
4664 (set_attr "unit" "*,i387")
4665 (set_attr "fp_int_src" "true")])
4667 ;; %%% Kill these when reload knows how to do it.
4669 [(set (match_operand 0 "fp_register_operand" "")
4670 (float (match_operand 1 "register_operand" "")))]
4673 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4676 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4677 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4678 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4679 ix86_free_from_memory (GET_MODE (operands[1]));
4683 (define_expand "floatunssisf2"
4684 [(use (match_operand:SF 0 "register_operand" ""))
4685 (use (match_operand:SI 1 "register_operand" ""))]
4686 "!TARGET_64BIT && TARGET_SSE_MATH"
4687 "x86_emit_floatuns (operands); DONE;")
4689 (define_expand "floatunsdisf2"
4690 [(use (match_operand:SF 0 "register_operand" ""))
4691 (use (match_operand:DI 1 "register_operand" ""))]
4692 "TARGET_64BIT && TARGET_SSE_MATH"
4693 "x86_emit_floatuns (operands); DONE;")
4695 (define_expand "floatunsdidf2"
4696 [(use (match_operand:DF 0 "register_operand" ""))
4697 (use (match_operand:DI 1 "register_operand" ""))]
4698 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4699 "x86_emit_floatuns (operands); DONE;")
4701 ;; SSE extract/set expanders
4706 ;; %%% splits for addditi3
4708 (define_expand "addti3"
4709 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4710 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4711 (match_operand:TI 2 "x86_64_general_operand" "")))
4712 (clobber (reg:CC FLAGS_REG))]
4714 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4716 (define_insn "*addti3_1"
4717 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4718 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4719 (match_operand:TI 2 "general_operand" "roiF,riF")))
4720 (clobber (reg:CC FLAGS_REG))]
4721 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4725 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4726 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4727 (match_operand:TI 2 "general_operand" "")))
4728 (clobber (reg:CC FLAGS_REG))]
4729 "TARGET_64BIT && reload_completed"
4730 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4732 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4733 (parallel [(set (match_dup 3)
4734 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4737 (clobber (reg:CC FLAGS_REG))])]
4738 "split_ti (operands+0, 1, operands+0, operands+3);
4739 split_ti (operands+1, 1, operands+1, operands+4);
4740 split_ti (operands+2, 1, operands+2, operands+5);")
4742 ;; %%% splits for addsidi3
4743 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4744 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4745 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4747 (define_expand "adddi3"
4748 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4749 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4750 (match_operand:DI 2 "x86_64_general_operand" "")))
4751 (clobber (reg:CC FLAGS_REG))]
4753 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4755 (define_insn "*adddi3_1"
4756 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4757 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4758 (match_operand:DI 2 "general_operand" "roiF,riF")))
4759 (clobber (reg:CC FLAGS_REG))]
4760 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4764 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4765 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4766 (match_operand:DI 2 "general_operand" "")))
4767 (clobber (reg:CC FLAGS_REG))]
4768 "!TARGET_64BIT && reload_completed"
4769 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4771 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4772 (parallel [(set (match_dup 3)
4773 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4776 (clobber (reg:CC FLAGS_REG))])]
4777 "split_di (operands+0, 1, operands+0, operands+3);
4778 split_di (operands+1, 1, operands+1, operands+4);
4779 split_di (operands+2, 1, operands+2, operands+5);")
4781 (define_insn "adddi3_carry_rex64"
4782 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4783 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4784 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4785 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4786 (clobber (reg:CC FLAGS_REG))]
4787 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4788 "adc{q}\t{%2, %0|%0, %2}"
4789 [(set_attr "type" "alu")
4790 (set_attr "pent_pair" "pu")
4791 (set_attr "mode" "DI")])
4793 (define_insn "*adddi3_cc_rex64"
4794 [(set (reg:CC FLAGS_REG)
4795 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4796 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4798 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4799 (plus:DI (match_dup 1) (match_dup 2)))]
4800 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4801 "add{q}\t{%2, %0|%0, %2}"
4802 [(set_attr "type" "alu")
4803 (set_attr "mode" "DI")])
4805 (define_insn "addqi3_carry"
4806 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4807 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4808 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4809 (match_operand:QI 2 "general_operand" "qi,qm")))
4810 (clobber (reg:CC FLAGS_REG))]
4811 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4812 "adc{b}\t{%2, %0|%0, %2}"
4813 [(set_attr "type" "alu")
4814 (set_attr "pent_pair" "pu")
4815 (set_attr "mode" "QI")])
4817 (define_insn "addhi3_carry"
4818 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4819 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4820 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4821 (match_operand:HI 2 "general_operand" "ri,rm")))
4822 (clobber (reg:CC FLAGS_REG))]
4823 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4824 "adc{w}\t{%2, %0|%0, %2}"
4825 [(set_attr "type" "alu")
4826 (set_attr "pent_pair" "pu")
4827 (set_attr "mode" "HI")])
4829 (define_insn "addsi3_carry"
4830 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4831 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4832 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4833 (match_operand:SI 2 "general_operand" "ri,rm")))
4834 (clobber (reg:CC FLAGS_REG))]
4835 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4836 "adc{l}\t{%2, %0|%0, %2}"
4837 [(set_attr "type" "alu")
4838 (set_attr "pent_pair" "pu")
4839 (set_attr "mode" "SI")])
4841 (define_insn "*addsi3_carry_zext"
4842 [(set (match_operand:DI 0 "register_operand" "=r")
4844 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4845 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4846 (match_operand:SI 2 "general_operand" "rim"))))
4847 (clobber (reg:CC FLAGS_REG))]
4848 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4849 "adc{l}\t{%2, %k0|%k0, %2}"
4850 [(set_attr "type" "alu")
4851 (set_attr "pent_pair" "pu")
4852 (set_attr "mode" "SI")])
4854 (define_insn "*addsi3_cc"
4855 [(set (reg:CC FLAGS_REG)
4856 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4857 (match_operand:SI 2 "general_operand" "ri,rm")]
4859 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4860 (plus:SI (match_dup 1) (match_dup 2)))]
4861 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4862 "add{l}\t{%2, %0|%0, %2}"
4863 [(set_attr "type" "alu")
4864 (set_attr "mode" "SI")])
4866 (define_insn "addqi3_cc"
4867 [(set (reg:CC FLAGS_REG)
4868 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4869 (match_operand:QI 2 "general_operand" "qi,qm")]
4871 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4872 (plus:QI (match_dup 1) (match_dup 2)))]
4873 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4874 "add{b}\t{%2, %0|%0, %2}"
4875 [(set_attr "type" "alu")
4876 (set_attr "mode" "QI")])
4878 (define_expand "addsi3"
4879 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4880 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4881 (match_operand:SI 2 "general_operand" "")))
4882 (clobber (reg:CC FLAGS_REG))])]
4884 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4886 (define_insn "*lea_1"
4887 [(set (match_operand:SI 0 "register_operand" "=r")
4888 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4890 "lea{l}\t{%a1, %0|%0, %a1}"
4891 [(set_attr "type" "lea")
4892 (set_attr "mode" "SI")])
4894 (define_insn "*lea_1_rex64"
4895 [(set (match_operand:SI 0 "register_operand" "=r")
4896 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4898 "lea{l}\t{%a1, %0|%0, %a1}"
4899 [(set_attr "type" "lea")
4900 (set_attr "mode" "SI")])
4902 (define_insn "*lea_1_zext"
4903 [(set (match_operand:DI 0 "register_operand" "=r")
4905 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4907 "lea{l}\t{%a1, %k0|%k0, %a1}"
4908 [(set_attr "type" "lea")
4909 (set_attr "mode" "SI")])
4911 (define_insn "*lea_2_rex64"
4912 [(set (match_operand:DI 0 "register_operand" "=r")
4913 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4915 "lea{q}\t{%a1, %0|%0, %a1}"
4916 [(set_attr "type" "lea")
4917 (set_attr "mode" "DI")])
4919 ;; The lea patterns for non-Pmodes needs to be matched by several
4920 ;; insns converted to real lea by splitters.
4922 (define_insn_and_split "*lea_general_1"
4923 [(set (match_operand 0 "register_operand" "=r")
4924 (plus (plus (match_operand 1 "index_register_operand" "l")
4925 (match_operand 2 "register_operand" "r"))
4926 (match_operand 3 "immediate_operand" "i")))]
4927 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4928 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4929 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4930 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4931 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4932 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4933 || GET_MODE (operands[3]) == VOIDmode)"
4935 "&& reload_completed"
4939 operands[0] = gen_lowpart (SImode, operands[0]);
4940 operands[1] = gen_lowpart (Pmode, operands[1]);
4941 operands[2] = gen_lowpart (Pmode, operands[2]);
4942 operands[3] = gen_lowpart (Pmode, operands[3]);
4943 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4945 if (Pmode != SImode)
4946 pat = gen_rtx_SUBREG (SImode, pat, 0);
4947 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4950 [(set_attr "type" "lea")
4951 (set_attr "mode" "SI")])
4953 (define_insn_and_split "*lea_general_1_zext"
4954 [(set (match_operand:DI 0 "register_operand" "=r")
4956 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4957 (match_operand:SI 2 "register_operand" "r"))
4958 (match_operand:SI 3 "immediate_operand" "i"))))]
4961 "&& reload_completed"
4963 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4965 (match_dup 3)) 0)))]
4967 operands[1] = gen_lowpart (Pmode, operands[1]);
4968 operands[2] = gen_lowpart (Pmode, operands[2]);
4969 operands[3] = gen_lowpart (Pmode, operands[3]);
4971 [(set_attr "type" "lea")
4972 (set_attr "mode" "SI")])
4974 (define_insn_and_split "*lea_general_2"
4975 [(set (match_operand 0 "register_operand" "=r")
4976 (plus (mult (match_operand 1 "index_register_operand" "l")
4977 (match_operand 2 "const248_operand" "i"))
4978 (match_operand 3 "nonmemory_operand" "ri")))]
4979 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4980 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4981 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4982 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4983 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4984 || GET_MODE (operands[3]) == VOIDmode)"
4986 "&& reload_completed"
4990 operands[0] = gen_lowpart (SImode, operands[0]);
4991 operands[1] = gen_lowpart (Pmode, operands[1]);
4992 operands[3] = gen_lowpart (Pmode, operands[3]);
4993 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4995 if (Pmode != SImode)
4996 pat = gen_rtx_SUBREG (SImode, pat, 0);
4997 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5000 [(set_attr "type" "lea")
5001 (set_attr "mode" "SI")])
5003 (define_insn_and_split "*lea_general_2_zext"
5004 [(set (match_operand:DI 0 "register_operand" "=r")
5006 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5007 (match_operand:SI 2 "const248_operand" "n"))
5008 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5011 "&& reload_completed"
5013 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5015 (match_dup 3)) 0)))]
5017 operands[1] = gen_lowpart (Pmode, operands[1]);
5018 operands[3] = gen_lowpart (Pmode, operands[3]);
5020 [(set_attr "type" "lea")
5021 (set_attr "mode" "SI")])
5023 (define_insn_and_split "*lea_general_3"
5024 [(set (match_operand 0 "register_operand" "=r")
5025 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5026 (match_operand 2 "const248_operand" "i"))
5027 (match_operand 3 "register_operand" "r"))
5028 (match_operand 4 "immediate_operand" "i")))]
5029 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5030 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5031 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5032 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5033 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5035 "&& reload_completed"
5039 operands[0] = gen_lowpart (SImode, operands[0]);
5040 operands[1] = gen_lowpart (Pmode, operands[1]);
5041 operands[3] = gen_lowpart (Pmode, operands[3]);
5042 operands[4] = gen_lowpart (Pmode, operands[4]);
5043 pat = gen_rtx_PLUS (Pmode,
5044 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5048 if (Pmode != SImode)
5049 pat = gen_rtx_SUBREG (SImode, pat, 0);
5050 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5053 [(set_attr "type" "lea")
5054 (set_attr "mode" "SI")])
5056 (define_insn_and_split "*lea_general_3_zext"
5057 [(set (match_operand:DI 0 "register_operand" "=r")
5059 (plus:SI (plus:SI (mult:SI
5060 (match_operand:SI 1 "index_register_operand" "l")
5061 (match_operand:SI 2 "const248_operand" "n"))
5062 (match_operand:SI 3 "register_operand" "r"))
5063 (match_operand:SI 4 "immediate_operand" "i"))))]
5066 "&& reload_completed"
5068 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5071 (match_dup 4)) 0)))]
5073 operands[1] = gen_lowpart (Pmode, operands[1]);
5074 operands[3] = gen_lowpart (Pmode, operands[3]);
5075 operands[4] = gen_lowpart (Pmode, operands[4]);
5077 [(set_attr "type" "lea")
5078 (set_attr "mode" "SI")])
5080 (define_insn "*adddi_1_rex64"
5081 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5082 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5083 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5084 (clobber (reg:CC FLAGS_REG))]
5085 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5087 switch (get_attr_type (insn))
5090 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5091 return "lea{q}\t{%a2, %0|%0, %a2}";
5094 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5095 if (operands[2] == const1_rtx)
5096 return "inc{q}\t%0";
5099 gcc_assert (operands[2] == constm1_rtx);
5100 return "dec{q}\t%0";
5104 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5106 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5107 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5108 if (GET_CODE (operands[2]) == CONST_INT
5109 /* Avoid overflows. */
5110 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5111 && (INTVAL (operands[2]) == 128
5112 || (INTVAL (operands[2]) < 0
5113 && INTVAL (operands[2]) != -128)))
5115 operands[2] = GEN_INT (-INTVAL (operands[2]));
5116 return "sub{q}\t{%2, %0|%0, %2}";
5118 return "add{q}\t{%2, %0|%0, %2}";
5122 (cond [(eq_attr "alternative" "2")
5123 (const_string "lea")
5124 ; Current assemblers are broken and do not allow @GOTOFF in
5125 ; ought but a memory context.
5126 (match_operand:DI 2 "pic_symbolic_operand" "")
5127 (const_string "lea")
5128 (match_operand:DI 2 "incdec_operand" "")
5129 (const_string "incdec")
5131 (const_string "alu")))
5132 (set_attr "mode" "DI")])
5134 ;; Convert lea to the lea pattern to avoid flags dependency.
5136 [(set (match_operand:DI 0 "register_operand" "")
5137 (plus:DI (match_operand:DI 1 "register_operand" "")
5138 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5139 (clobber (reg:CC FLAGS_REG))]
5140 "TARGET_64BIT && reload_completed
5141 && true_regnum (operands[0]) != true_regnum (operands[1])"
5143 (plus:DI (match_dup 1)
5147 (define_insn "*adddi_2_rex64"
5148 [(set (reg FLAGS_REG)
5150 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5151 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5153 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5154 (plus:DI (match_dup 1) (match_dup 2)))]
5155 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5156 && ix86_binary_operator_ok (PLUS, DImode, operands)
5157 /* Current assemblers are broken and do not allow @GOTOFF in
5158 ought but a memory context. */
5159 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5161 switch (get_attr_type (insn))
5164 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5165 if (operands[2] == const1_rtx)
5166 return "inc{q}\t%0";
5169 gcc_assert (operands[2] == constm1_rtx);
5170 return "dec{q}\t%0";
5174 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5175 /* ???? We ought to handle there the 32bit case too
5176 - do we need new constraint? */
5177 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5178 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5179 if (GET_CODE (operands[2]) == CONST_INT
5180 /* Avoid overflows. */
5181 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5182 && (INTVAL (operands[2]) == 128
5183 || (INTVAL (operands[2]) < 0
5184 && INTVAL (operands[2]) != -128)))
5186 operands[2] = GEN_INT (-INTVAL (operands[2]));
5187 return "sub{q}\t{%2, %0|%0, %2}";
5189 return "add{q}\t{%2, %0|%0, %2}";
5193 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5194 (const_string "incdec")
5195 (const_string "alu")))
5196 (set_attr "mode" "DI")])
5198 (define_insn "*adddi_3_rex64"
5199 [(set (reg FLAGS_REG)
5200 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5201 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5202 (clobber (match_scratch:DI 0 "=r"))]
5204 && ix86_match_ccmode (insn, CCZmode)
5205 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5206 /* Current assemblers are broken and do not allow @GOTOFF in
5207 ought but a memory context. */
5208 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5210 switch (get_attr_type (insn))
5213 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5214 if (operands[2] == const1_rtx)
5215 return "inc{q}\t%0";
5218 gcc_assert (operands[2] == constm1_rtx);
5219 return "dec{q}\t%0";
5223 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5224 /* ???? We ought to handle there the 32bit case too
5225 - do we need new constraint? */
5226 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5227 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5228 if (GET_CODE (operands[2]) == CONST_INT
5229 /* Avoid overflows. */
5230 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5231 && (INTVAL (operands[2]) == 128
5232 || (INTVAL (operands[2]) < 0
5233 && INTVAL (operands[2]) != -128)))
5235 operands[2] = GEN_INT (-INTVAL (operands[2]));
5236 return "sub{q}\t{%2, %0|%0, %2}";
5238 return "add{q}\t{%2, %0|%0, %2}";
5242 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5243 (const_string "incdec")
5244 (const_string "alu")))
5245 (set_attr "mode" "DI")])
5247 ; For comparisons against 1, -1 and 128, we may generate better code
5248 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5249 ; is matched then. We can't accept general immediate, because for
5250 ; case of overflows, the result is messed up.
5251 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5253 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5254 ; only for comparisons not depending on it.
5255 (define_insn "*adddi_4_rex64"
5256 [(set (reg FLAGS_REG)
5257 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5258 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5259 (clobber (match_scratch:DI 0 "=rm"))]
5261 && ix86_match_ccmode (insn, CCGCmode)"
5263 switch (get_attr_type (insn))
5266 if (operands[2] == constm1_rtx)
5267 return "inc{q}\t%0";
5270 gcc_assert (operands[2] == const1_rtx);
5271 return "dec{q}\t%0";
5275 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5276 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5277 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5278 if ((INTVAL (operands[2]) == -128
5279 || (INTVAL (operands[2]) > 0
5280 && INTVAL (operands[2]) != 128))
5281 /* Avoid overflows. */
5282 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5283 return "sub{q}\t{%2, %0|%0, %2}";
5284 operands[2] = GEN_INT (-INTVAL (operands[2]));
5285 return "add{q}\t{%2, %0|%0, %2}";
5289 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5290 (const_string "incdec")
5291 (const_string "alu")))
5292 (set_attr "mode" "DI")])
5294 (define_insn "*adddi_5_rex64"
5295 [(set (reg FLAGS_REG)
5297 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5298 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5300 (clobber (match_scratch:DI 0 "=r"))]
5302 && ix86_match_ccmode (insn, CCGOCmode)
5303 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5304 /* Current assemblers are broken and do not allow @GOTOFF in
5305 ought but a memory context. */
5306 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5308 switch (get_attr_type (insn))
5311 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5312 if (operands[2] == const1_rtx)
5313 return "inc{q}\t%0";
5316 gcc_assert (operands[2] == constm1_rtx);
5317 return "dec{q}\t%0";
5321 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5322 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5323 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5324 if (GET_CODE (operands[2]) == CONST_INT
5325 /* Avoid overflows. */
5326 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5327 && (INTVAL (operands[2]) == 128
5328 || (INTVAL (operands[2]) < 0
5329 && INTVAL (operands[2]) != -128)))
5331 operands[2] = GEN_INT (-INTVAL (operands[2]));
5332 return "sub{q}\t{%2, %0|%0, %2}";
5334 return "add{q}\t{%2, %0|%0, %2}";
5338 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5339 (const_string "incdec")
5340 (const_string "alu")))
5341 (set_attr "mode" "DI")])
5344 (define_insn "*addsi_1"
5345 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5346 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5347 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5348 (clobber (reg:CC FLAGS_REG))]
5349 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5351 switch (get_attr_type (insn))
5354 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5355 return "lea{l}\t{%a2, %0|%0, %a2}";
5358 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5359 if (operands[2] == const1_rtx)
5360 return "inc{l}\t%0";
5363 gcc_assert (operands[2] == constm1_rtx);
5364 return "dec{l}\t%0";
5368 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5370 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5371 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5372 if (GET_CODE (operands[2]) == CONST_INT
5373 && (INTVAL (operands[2]) == 128
5374 || (INTVAL (operands[2]) < 0
5375 && INTVAL (operands[2]) != -128)))
5377 operands[2] = GEN_INT (-INTVAL (operands[2]));
5378 return "sub{l}\t{%2, %0|%0, %2}";
5380 return "add{l}\t{%2, %0|%0, %2}";
5384 (cond [(eq_attr "alternative" "2")
5385 (const_string "lea")
5386 ; Current assemblers are broken and do not allow @GOTOFF in
5387 ; ought but a memory context.
5388 (match_operand:SI 2 "pic_symbolic_operand" "")
5389 (const_string "lea")
5390 (match_operand:SI 2 "incdec_operand" "")
5391 (const_string "incdec")
5393 (const_string "alu")))
5394 (set_attr "mode" "SI")])
5396 ;; Convert lea to the lea pattern to avoid flags dependency.
5398 [(set (match_operand 0 "register_operand" "")
5399 (plus (match_operand 1 "register_operand" "")
5400 (match_operand 2 "nonmemory_operand" "")))
5401 (clobber (reg:CC FLAGS_REG))]
5403 && true_regnum (operands[0]) != true_regnum (operands[1])"
5407 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5408 may confuse gen_lowpart. */
5409 if (GET_MODE (operands[0]) != Pmode)
5411 operands[1] = gen_lowpart (Pmode, operands[1]);
5412 operands[2] = gen_lowpart (Pmode, operands[2]);
5414 operands[0] = gen_lowpart (SImode, operands[0]);
5415 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5416 if (Pmode != SImode)
5417 pat = gen_rtx_SUBREG (SImode, pat, 0);
5418 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5422 ;; It may seem that nonimmediate operand is proper one for operand 1.
5423 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5424 ;; we take care in ix86_binary_operator_ok to not allow two memory
5425 ;; operands so proper swapping will be done in reload. This allow
5426 ;; patterns constructed from addsi_1 to match.
5427 (define_insn "addsi_1_zext"
5428 [(set (match_operand:DI 0 "register_operand" "=r,r")
5430 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5431 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5432 (clobber (reg:CC FLAGS_REG))]
5433 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5435 switch (get_attr_type (insn))
5438 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5439 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5442 if (operands[2] == const1_rtx)
5443 return "inc{l}\t%k0";
5446 gcc_assert (operands[2] == constm1_rtx);
5447 return "dec{l}\t%k0";
5451 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5452 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5453 if (GET_CODE (operands[2]) == CONST_INT
5454 && (INTVAL (operands[2]) == 128
5455 || (INTVAL (operands[2]) < 0
5456 && INTVAL (operands[2]) != -128)))
5458 operands[2] = GEN_INT (-INTVAL (operands[2]));
5459 return "sub{l}\t{%2, %k0|%k0, %2}";
5461 return "add{l}\t{%2, %k0|%k0, %2}";
5465 (cond [(eq_attr "alternative" "1")
5466 (const_string "lea")
5467 ; Current assemblers are broken and do not allow @GOTOFF in
5468 ; ought but a memory context.
5469 (match_operand:SI 2 "pic_symbolic_operand" "")
5470 (const_string "lea")
5471 (match_operand:SI 2 "incdec_operand" "")
5472 (const_string "incdec")
5474 (const_string "alu")))
5475 (set_attr "mode" "SI")])
5477 ;; Convert lea to the lea pattern to avoid flags dependency.
5479 [(set (match_operand:DI 0 "register_operand" "")
5481 (plus:SI (match_operand:SI 1 "register_operand" "")
5482 (match_operand:SI 2 "nonmemory_operand" ""))))
5483 (clobber (reg:CC FLAGS_REG))]
5484 "TARGET_64BIT && reload_completed
5485 && true_regnum (operands[0]) != true_regnum (operands[1])"
5487 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5489 operands[1] = gen_lowpart (Pmode, operands[1]);
5490 operands[2] = gen_lowpart (Pmode, operands[2]);
5493 (define_insn "*addsi_2"
5494 [(set (reg FLAGS_REG)
5496 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5497 (match_operand:SI 2 "general_operand" "rmni,rni"))
5499 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5500 (plus:SI (match_dup 1) (match_dup 2)))]
5501 "ix86_match_ccmode (insn, CCGOCmode)
5502 && ix86_binary_operator_ok (PLUS, SImode, operands)
5503 /* Current assemblers are broken and do not allow @GOTOFF in
5504 ought but a memory context. */
5505 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5507 switch (get_attr_type (insn))
5510 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5511 if (operands[2] == const1_rtx)
5512 return "inc{l}\t%0";
5515 gcc_assert (operands[2] == constm1_rtx);
5516 return "dec{l}\t%0";
5520 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5521 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5522 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5523 if (GET_CODE (operands[2]) == CONST_INT
5524 && (INTVAL (operands[2]) == 128
5525 || (INTVAL (operands[2]) < 0
5526 && INTVAL (operands[2]) != -128)))
5528 operands[2] = GEN_INT (-INTVAL (operands[2]));
5529 return "sub{l}\t{%2, %0|%0, %2}";
5531 return "add{l}\t{%2, %0|%0, %2}";
5535 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5536 (const_string "incdec")
5537 (const_string "alu")))
5538 (set_attr "mode" "SI")])
5540 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5541 (define_insn "*addsi_2_zext"
5542 [(set (reg FLAGS_REG)
5544 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5545 (match_operand:SI 2 "general_operand" "rmni"))
5547 (set (match_operand:DI 0 "register_operand" "=r")
5548 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5549 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5550 && ix86_binary_operator_ok (PLUS, SImode, operands)
5551 /* Current assemblers are broken and do not allow @GOTOFF in
5552 ought but a memory context. */
5553 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5555 switch (get_attr_type (insn))
5558 if (operands[2] == const1_rtx)
5559 return "inc{l}\t%k0";
5562 gcc_assert (operands[2] == constm1_rtx);
5563 return "dec{l}\t%k0";
5567 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5568 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5569 if (GET_CODE (operands[2]) == CONST_INT
5570 && (INTVAL (operands[2]) == 128
5571 || (INTVAL (operands[2]) < 0
5572 && INTVAL (operands[2]) != -128)))
5574 operands[2] = GEN_INT (-INTVAL (operands[2]));
5575 return "sub{l}\t{%2, %k0|%k0, %2}";
5577 return "add{l}\t{%2, %k0|%k0, %2}";
5581 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5582 (const_string "incdec")
5583 (const_string "alu")))
5584 (set_attr "mode" "SI")])
5586 (define_insn "*addsi_3"
5587 [(set (reg FLAGS_REG)
5588 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5589 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5590 (clobber (match_scratch:SI 0 "=r"))]
5591 "ix86_match_ccmode (insn, CCZmode)
5592 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5593 /* Current assemblers are broken and do not allow @GOTOFF in
5594 ought but a memory context. */
5595 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5597 switch (get_attr_type (insn))
5600 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5601 if (operands[2] == const1_rtx)
5602 return "inc{l}\t%0";
5605 gcc_assert (operands[2] == constm1_rtx);
5606 return "dec{l}\t%0";
5610 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5611 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5612 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5613 if (GET_CODE (operands[2]) == CONST_INT
5614 && (INTVAL (operands[2]) == 128
5615 || (INTVAL (operands[2]) < 0
5616 && INTVAL (operands[2]) != -128)))
5618 operands[2] = GEN_INT (-INTVAL (operands[2]));
5619 return "sub{l}\t{%2, %0|%0, %2}";
5621 return "add{l}\t{%2, %0|%0, %2}";
5625 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5626 (const_string "incdec")
5627 (const_string "alu")))
5628 (set_attr "mode" "SI")])
5630 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5631 (define_insn "*addsi_3_zext"
5632 [(set (reg FLAGS_REG)
5633 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5634 (match_operand:SI 1 "nonimmediate_operand" "%0")))
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, CCZmode)
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 ; For comparisons against 1, -1 and 128, we may generate better code
5675 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5676 ; is matched then. We can't accept general immediate, because for
5677 ; case of overflows, the result is messed up.
5678 ; This pattern also don't hold of 0x80000000, since the value overflows
5680 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5681 ; only for comparisons not depending on it.
5682 (define_insn "*addsi_4"
5683 [(set (reg FLAGS_REG)
5684 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5685 (match_operand:SI 2 "const_int_operand" "n")))
5686 (clobber (match_scratch:SI 0 "=rm"))]
5687 "ix86_match_ccmode (insn, CCGCmode)
5688 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5690 switch (get_attr_type (insn))
5693 if (operands[2] == constm1_rtx)
5694 return "inc{l}\t%0";
5697 gcc_assert (operands[2] == const1_rtx);
5698 return "dec{l}\t%0";
5702 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5703 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5704 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5705 if ((INTVAL (operands[2]) == -128
5706 || (INTVAL (operands[2]) > 0
5707 && INTVAL (operands[2]) != 128)))
5708 return "sub{l}\t{%2, %0|%0, %2}";
5709 operands[2] = GEN_INT (-INTVAL (operands[2]));
5710 return "add{l}\t{%2, %0|%0, %2}";
5714 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5715 (const_string "incdec")
5716 (const_string "alu")))
5717 (set_attr "mode" "SI")])
5719 (define_insn "*addsi_5"
5720 [(set (reg FLAGS_REG)
5722 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5723 (match_operand:SI 2 "general_operand" "rmni"))
5725 (clobber (match_scratch:SI 0 "=r"))]
5726 "ix86_match_ccmode (insn, CCGOCmode)
5727 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5728 /* Current assemblers are broken and do not allow @GOTOFF in
5729 ought but a memory context. */
5730 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5732 switch (get_attr_type (insn))
5735 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5736 if (operands[2] == const1_rtx)
5737 return "inc{l}\t%0";
5740 gcc_assert (operands[2] == constm1_rtx);
5741 return "dec{l}\t%0";
5745 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5746 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5747 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5748 if (GET_CODE (operands[2]) == CONST_INT
5749 && (INTVAL (operands[2]) == 128
5750 || (INTVAL (operands[2]) < 0
5751 && INTVAL (operands[2]) != -128)))
5753 operands[2] = GEN_INT (-INTVAL (operands[2]));
5754 return "sub{l}\t{%2, %0|%0, %2}";
5756 return "add{l}\t{%2, %0|%0, %2}";
5760 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5761 (const_string "incdec")
5762 (const_string "alu")))
5763 (set_attr "mode" "SI")])
5765 (define_expand "addhi3"
5766 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5767 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5768 (match_operand:HI 2 "general_operand" "")))
5769 (clobber (reg:CC FLAGS_REG))])]
5770 "TARGET_HIMODE_MATH"
5771 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5773 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5774 ;; type optimizations enabled by define-splits. This is not important
5775 ;; for PII, and in fact harmful because of partial register stalls.
5777 (define_insn "*addhi_1_lea"
5778 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5779 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5780 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5781 (clobber (reg:CC FLAGS_REG))]
5782 "!TARGET_PARTIAL_REG_STALL
5783 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5785 switch (get_attr_type (insn))
5790 if (operands[2] == const1_rtx)
5791 return "inc{w}\t%0";
5794 gcc_assert (operands[2] == constm1_rtx);
5795 return "dec{w}\t%0";
5799 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5800 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5801 if (GET_CODE (operands[2]) == CONST_INT
5802 && (INTVAL (operands[2]) == 128
5803 || (INTVAL (operands[2]) < 0
5804 && INTVAL (operands[2]) != -128)))
5806 operands[2] = GEN_INT (-INTVAL (operands[2]));
5807 return "sub{w}\t{%2, %0|%0, %2}";
5809 return "add{w}\t{%2, %0|%0, %2}";
5813 (if_then_else (eq_attr "alternative" "2")
5814 (const_string "lea")
5815 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5816 (const_string "incdec")
5817 (const_string "alu"))))
5818 (set_attr "mode" "HI,HI,SI")])
5820 (define_insn "*addhi_1"
5821 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5822 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5823 (match_operand:HI 2 "general_operand" "ri,rm")))
5824 (clobber (reg:CC FLAGS_REG))]
5825 "TARGET_PARTIAL_REG_STALL
5826 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5828 switch (get_attr_type (insn))
5831 if (operands[2] == const1_rtx)
5832 return "inc{w}\t%0";
5835 gcc_assert (operands[2] == constm1_rtx);
5836 return "dec{w}\t%0";
5840 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5841 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5842 if (GET_CODE (operands[2]) == CONST_INT
5843 && (INTVAL (operands[2]) == 128
5844 || (INTVAL (operands[2]) < 0
5845 && INTVAL (operands[2]) != -128)))
5847 operands[2] = GEN_INT (-INTVAL (operands[2]));
5848 return "sub{w}\t{%2, %0|%0, %2}";
5850 return "add{w}\t{%2, %0|%0, %2}";
5854 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5855 (const_string "incdec")
5856 (const_string "alu")))
5857 (set_attr "mode" "HI")])
5859 (define_insn "*addhi_2"
5860 [(set (reg FLAGS_REG)
5862 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5863 (match_operand:HI 2 "general_operand" "rmni,rni"))
5865 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5866 (plus:HI (match_dup 1) (match_dup 2)))]
5867 "ix86_match_ccmode (insn, CCGOCmode)
5868 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5870 switch (get_attr_type (insn))
5873 if (operands[2] == const1_rtx)
5874 return "inc{w}\t%0";
5877 gcc_assert (operands[2] == constm1_rtx);
5878 return "dec{w}\t%0";
5882 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5883 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5884 if (GET_CODE (operands[2]) == CONST_INT
5885 && (INTVAL (operands[2]) == 128
5886 || (INTVAL (operands[2]) < 0
5887 && INTVAL (operands[2]) != -128)))
5889 operands[2] = GEN_INT (-INTVAL (operands[2]));
5890 return "sub{w}\t{%2, %0|%0, %2}";
5892 return "add{w}\t{%2, %0|%0, %2}";
5896 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5897 (const_string "incdec")
5898 (const_string "alu")))
5899 (set_attr "mode" "HI")])
5901 (define_insn "*addhi_3"
5902 [(set (reg FLAGS_REG)
5903 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5904 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5905 (clobber (match_scratch:HI 0 "=r"))]
5906 "ix86_match_ccmode (insn, CCZmode)
5907 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5909 switch (get_attr_type (insn))
5912 if (operands[2] == const1_rtx)
5913 return "inc{w}\t%0";
5916 gcc_assert (operands[2] == constm1_rtx);
5917 return "dec{w}\t%0";
5921 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5922 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5923 if (GET_CODE (operands[2]) == CONST_INT
5924 && (INTVAL (operands[2]) == 128
5925 || (INTVAL (operands[2]) < 0
5926 && INTVAL (operands[2]) != -128)))
5928 operands[2] = GEN_INT (-INTVAL (operands[2]));
5929 return "sub{w}\t{%2, %0|%0, %2}";
5931 return "add{w}\t{%2, %0|%0, %2}";
5935 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5936 (const_string "incdec")
5937 (const_string "alu")))
5938 (set_attr "mode" "HI")])
5940 ; See comments above addsi_4 for details.
5941 (define_insn "*addhi_4"
5942 [(set (reg FLAGS_REG)
5943 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5944 (match_operand:HI 2 "const_int_operand" "n")))
5945 (clobber (match_scratch:HI 0 "=rm"))]
5946 "ix86_match_ccmode (insn, CCGCmode)
5947 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5949 switch (get_attr_type (insn))
5952 if (operands[2] == constm1_rtx)
5953 return "inc{w}\t%0";
5956 gcc_assert (operands[2] == const1_rtx);
5957 return "dec{w}\t%0";
5961 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5962 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5963 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5964 if ((INTVAL (operands[2]) == -128
5965 || (INTVAL (operands[2]) > 0
5966 && INTVAL (operands[2]) != 128)))
5967 return "sub{w}\t{%2, %0|%0, %2}";
5968 operands[2] = GEN_INT (-INTVAL (operands[2]));
5969 return "add{w}\t{%2, %0|%0, %2}";
5973 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5974 (const_string "incdec")
5975 (const_string "alu")))
5976 (set_attr "mode" "SI")])
5979 (define_insn "*addhi_5"
5980 [(set (reg FLAGS_REG)
5982 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5983 (match_operand:HI 2 "general_operand" "rmni"))
5985 (clobber (match_scratch:HI 0 "=r"))]
5986 "ix86_match_ccmode (insn, CCGOCmode)
5987 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5989 switch (get_attr_type (insn))
5992 if (operands[2] == const1_rtx)
5993 return "inc{w}\t%0";
5996 gcc_assert (operands[2] == constm1_rtx);
5997 return "dec{w}\t%0";
6001 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6003 if (GET_CODE (operands[2]) == CONST_INT
6004 && (INTVAL (operands[2]) == 128
6005 || (INTVAL (operands[2]) < 0
6006 && INTVAL (operands[2]) != -128)))
6008 operands[2] = GEN_INT (-INTVAL (operands[2]));
6009 return "sub{w}\t{%2, %0|%0, %2}";
6011 return "add{w}\t{%2, %0|%0, %2}";
6015 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6016 (const_string "incdec")
6017 (const_string "alu")))
6018 (set_attr "mode" "HI")])
6020 (define_expand "addqi3"
6021 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6022 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6023 (match_operand:QI 2 "general_operand" "")))
6024 (clobber (reg:CC FLAGS_REG))])]
6025 "TARGET_QIMODE_MATH"
6026 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6028 ;; %%% Potential partial reg stall on alternative 2. What to do?
6029 (define_insn "*addqi_1_lea"
6030 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6031 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6032 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6033 (clobber (reg:CC FLAGS_REG))]
6034 "!TARGET_PARTIAL_REG_STALL
6035 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6037 int widen = (which_alternative == 2);
6038 switch (get_attr_type (insn))
6043 if (operands[2] == const1_rtx)
6044 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6047 gcc_assert (operands[2] == constm1_rtx);
6048 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6052 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6053 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6054 if (GET_CODE (operands[2]) == CONST_INT
6055 && (INTVAL (operands[2]) == 128
6056 || (INTVAL (operands[2]) < 0
6057 && INTVAL (operands[2]) != -128)))
6059 operands[2] = GEN_INT (-INTVAL (operands[2]));
6061 return "sub{l}\t{%2, %k0|%k0, %2}";
6063 return "sub{b}\t{%2, %0|%0, %2}";
6066 return "add{l}\t{%k2, %k0|%k0, %k2}";
6068 return "add{b}\t{%2, %0|%0, %2}";
6072 (if_then_else (eq_attr "alternative" "3")
6073 (const_string "lea")
6074 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6075 (const_string "incdec")
6076 (const_string "alu"))))
6077 (set_attr "mode" "QI,QI,SI,SI")])
6079 (define_insn "*addqi_1"
6080 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6081 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6082 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6083 (clobber (reg:CC FLAGS_REG))]
6084 "TARGET_PARTIAL_REG_STALL
6085 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6087 int widen = (which_alternative == 2);
6088 switch (get_attr_type (insn))
6091 if (operands[2] == const1_rtx)
6092 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6095 gcc_assert (operands[2] == constm1_rtx);
6096 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6100 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6102 if (GET_CODE (operands[2]) == CONST_INT
6103 && (INTVAL (operands[2]) == 128
6104 || (INTVAL (operands[2]) < 0
6105 && INTVAL (operands[2]) != -128)))
6107 operands[2] = GEN_INT (-INTVAL (operands[2]));
6109 return "sub{l}\t{%2, %k0|%k0, %2}";
6111 return "sub{b}\t{%2, %0|%0, %2}";
6114 return "add{l}\t{%k2, %k0|%k0, %k2}";
6116 return "add{b}\t{%2, %0|%0, %2}";
6120 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6121 (const_string "incdec")
6122 (const_string "alu")))
6123 (set_attr "mode" "QI,QI,SI")])
6125 (define_insn "*addqi_1_slp"
6126 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6127 (plus:QI (match_dup 0)
6128 (match_operand:QI 1 "general_operand" "qn,qnm")))
6129 (clobber (reg:CC FLAGS_REG))]
6130 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6131 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6133 switch (get_attr_type (insn))
6136 if (operands[1] == const1_rtx)
6137 return "inc{b}\t%0";
6140 gcc_assert (operands[1] == constm1_rtx);
6141 return "dec{b}\t%0";
6145 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6146 if (GET_CODE (operands[1]) == CONST_INT
6147 && INTVAL (operands[1]) < 0)
6149 operands[1] = GEN_INT (-INTVAL (operands[1]));
6150 return "sub{b}\t{%1, %0|%0, %1}";
6152 return "add{b}\t{%1, %0|%0, %1}";
6156 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6157 (const_string "incdec")
6158 (const_string "alu1")))
6159 (set (attr "memory")
6160 (if_then_else (match_operand 1 "memory_operand" "")
6161 (const_string "load")
6162 (const_string "none")))
6163 (set_attr "mode" "QI")])
6165 (define_insn "*addqi_2"
6166 [(set (reg FLAGS_REG)
6168 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6169 (match_operand:QI 2 "general_operand" "qmni,qni"))
6171 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6172 (plus:QI (match_dup 1) (match_dup 2)))]
6173 "ix86_match_ccmode (insn, CCGOCmode)
6174 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6176 switch (get_attr_type (insn))
6179 if (operands[2] == const1_rtx)
6180 return "inc{b}\t%0";
6183 gcc_assert (operands[2] == constm1_rtx
6184 || (GET_CODE (operands[2]) == CONST_INT
6185 && INTVAL (operands[2]) == 255));
6186 return "dec{b}\t%0";
6190 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6191 if (GET_CODE (operands[2]) == CONST_INT
6192 && INTVAL (operands[2]) < 0)
6194 operands[2] = GEN_INT (-INTVAL (operands[2]));
6195 return "sub{b}\t{%2, %0|%0, %2}";
6197 return "add{b}\t{%2, %0|%0, %2}";
6201 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6202 (const_string "incdec")
6203 (const_string "alu")))
6204 (set_attr "mode" "QI")])
6206 (define_insn "*addqi_3"
6207 [(set (reg FLAGS_REG)
6208 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6209 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6210 (clobber (match_scratch:QI 0 "=q"))]
6211 "ix86_match_ccmode (insn, CCZmode)
6212 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6214 switch (get_attr_type (insn))
6217 if (operands[2] == const1_rtx)
6218 return "inc{b}\t%0";
6221 gcc_assert (operands[2] == constm1_rtx
6222 || (GET_CODE (operands[2]) == CONST_INT
6223 && INTVAL (operands[2]) == 255));
6224 return "dec{b}\t%0";
6228 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6229 if (GET_CODE (operands[2]) == CONST_INT
6230 && INTVAL (operands[2]) < 0)
6232 operands[2] = GEN_INT (-INTVAL (operands[2]));
6233 return "sub{b}\t{%2, %0|%0, %2}";
6235 return "add{b}\t{%2, %0|%0, %2}";
6239 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6240 (const_string "incdec")
6241 (const_string "alu")))
6242 (set_attr "mode" "QI")])
6244 ; See comments above addsi_4 for details.
6245 (define_insn "*addqi_4"
6246 [(set (reg FLAGS_REG)
6247 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6248 (match_operand:QI 2 "const_int_operand" "n")))
6249 (clobber (match_scratch:QI 0 "=qm"))]
6250 "ix86_match_ccmode (insn, CCGCmode)
6251 && (INTVAL (operands[2]) & 0xff) != 0x80"
6253 switch (get_attr_type (insn))
6256 if (operands[2] == constm1_rtx
6257 || (GET_CODE (operands[2]) == CONST_INT
6258 && INTVAL (operands[2]) == 255))
6259 return "inc{b}\t%0";
6262 gcc_assert (operands[2] == const1_rtx);
6263 return "dec{b}\t%0";
6267 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6268 if (INTVAL (operands[2]) < 0)
6270 operands[2] = GEN_INT (-INTVAL (operands[2]));
6271 return "add{b}\t{%2, %0|%0, %2}";
6273 return "sub{b}\t{%2, %0|%0, %2}";
6277 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6278 (const_string "incdec")
6279 (const_string "alu")))
6280 (set_attr "mode" "QI")])
6283 (define_insn "*addqi_5"
6284 [(set (reg FLAGS_REG)
6286 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6287 (match_operand:QI 2 "general_operand" "qmni"))
6289 (clobber (match_scratch:QI 0 "=q"))]
6290 "ix86_match_ccmode (insn, CCGOCmode)
6291 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6293 switch (get_attr_type (insn))
6296 if (operands[2] == const1_rtx)
6297 return "inc{b}\t%0";
6300 gcc_assert (operands[2] == constm1_rtx
6301 || (GET_CODE (operands[2]) == CONST_INT
6302 && INTVAL (operands[2]) == 255));
6303 return "dec{b}\t%0";
6307 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6308 if (GET_CODE (operands[2]) == CONST_INT
6309 && INTVAL (operands[2]) < 0)
6311 operands[2] = GEN_INT (-INTVAL (operands[2]));
6312 return "sub{b}\t{%2, %0|%0, %2}";
6314 return "add{b}\t{%2, %0|%0, %2}";
6318 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6319 (const_string "incdec")
6320 (const_string "alu")))
6321 (set_attr "mode" "QI")])
6324 (define_insn "addqi_ext_1"
6325 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6330 (match_operand 1 "ext_register_operand" "0")
6333 (match_operand:QI 2 "general_operand" "Qmn")))
6334 (clobber (reg:CC FLAGS_REG))]
6337 switch (get_attr_type (insn))
6340 if (operands[2] == const1_rtx)
6341 return "inc{b}\t%h0";
6344 gcc_assert (operands[2] == constm1_rtx
6345 || (GET_CODE (operands[2]) == CONST_INT
6346 && INTVAL (operands[2]) == 255));
6347 return "dec{b}\t%h0";
6351 return "add{b}\t{%2, %h0|%h0, %2}";
6355 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6356 (const_string "incdec")
6357 (const_string "alu")))
6358 (set_attr "mode" "QI")])
6360 (define_insn "*addqi_ext_1_rex64"
6361 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6366 (match_operand 1 "ext_register_operand" "0")
6369 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6370 (clobber (reg:CC FLAGS_REG))]
6373 switch (get_attr_type (insn))
6376 if (operands[2] == const1_rtx)
6377 return "inc{b}\t%h0";
6380 gcc_assert (operands[2] == constm1_rtx
6381 || (GET_CODE (operands[2]) == CONST_INT
6382 && INTVAL (operands[2]) == 255));
6383 return "dec{b}\t%h0";
6387 return "add{b}\t{%2, %h0|%h0, %2}";
6391 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6392 (const_string "incdec")
6393 (const_string "alu")))
6394 (set_attr "mode" "QI")])
6396 (define_insn "*addqi_ext_2"
6397 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6402 (match_operand 1 "ext_register_operand" "%0")
6406 (match_operand 2 "ext_register_operand" "Q")
6409 (clobber (reg:CC FLAGS_REG))]
6411 "add{b}\t{%h2, %h0|%h0, %h2}"
6412 [(set_attr "type" "alu")
6413 (set_attr "mode" "QI")])
6415 ;; The patterns that match these are at the end of this file.
6417 (define_expand "addxf3"
6418 [(set (match_operand:XF 0 "register_operand" "")
6419 (plus:XF (match_operand:XF 1 "register_operand" "")
6420 (match_operand:XF 2 "register_operand" "")))]
6424 (define_expand "adddf3"
6425 [(set (match_operand:DF 0 "register_operand" "")
6426 (plus:DF (match_operand:DF 1 "register_operand" "")
6427 (match_operand:DF 2 "nonimmediate_operand" "")))]
6428 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6431 (define_expand "addsf3"
6432 [(set (match_operand:SF 0 "register_operand" "")
6433 (plus:SF (match_operand:SF 1 "register_operand" "")
6434 (match_operand:SF 2 "nonimmediate_operand" "")))]
6435 "TARGET_80387 || TARGET_SSE_MATH"
6438 ;; Subtract instructions
6440 ;; %%% splits for subditi3
6442 (define_expand "subti3"
6443 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6444 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6445 (match_operand:TI 2 "x86_64_general_operand" "")))
6446 (clobber (reg:CC FLAGS_REG))])]
6448 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6450 (define_insn "*subti3_1"
6451 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6452 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6453 (match_operand:TI 2 "general_operand" "roiF,riF")))
6454 (clobber (reg:CC FLAGS_REG))]
6455 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6459 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6460 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6461 (match_operand:TI 2 "general_operand" "")))
6462 (clobber (reg:CC FLAGS_REG))]
6463 "TARGET_64BIT && reload_completed"
6464 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6465 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6466 (parallel [(set (match_dup 3)
6467 (minus:DI (match_dup 4)
6468 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6470 (clobber (reg:CC FLAGS_REG))])]
6471 "split_ti (operands+0, 1, operands+0, operands+3);
6472 split_ti (operands+1, 1, operands+1, operands+4);
6473 split_ti (operands+2, 1, operands+2, operands+5);")
6475 ;; %%% splits for subsidi3
6477 (define_expand "subdi3"
6478 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6479 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6480 (match_operand:DI 2 "x86_64_general_operand" "")))
6481 (clobber (reg:CC FLAGS_REG))])]
6483 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6485 (define_insn "*subdi3_1"
6486 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6487 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6488 (match_operand:DI 2 "general_operand" "roiF,riF")))
6489 (clobber (reg:CC FLAGS_REG))]
6490 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6494 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6495 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6496 (match_operand:DI 2 "general_operand" "")))
6497 (clobber (reg:CC FLAGS_REG))]
6498 "!TARGET_64BIT && reload_completed"
6499 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6500 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6501 (parallel [(set (match_dup 3)
6502 (minus:SI (match_dup 4)
6503 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6505 (clobber (reg:CC FLAGS_REG))])]
6506 "split_di (operands+0, 1, operands+0, operands+3);
6507 split_di (operands+1, 1, operands+1, operands+4);
6508 split_di (operands+2, 1, operands+2, operands+5);")
6510 (define_insn "subdi3_carry_rex64"
6511 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6512 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6513 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6514 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6515 (clobber (reg:CC FLAGS_REG))]
6516 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6517 "sbb{q}\t{%2, %0|%0, %2}"
6518 [(set_attr "type" "alu")
6519 (set_attr "pent_pair" "pu")
6520 (set_attr "mode" "DI")])
6522 (define_insn "*subdi_1_rex64"
6523 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6524 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6525 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6526 (clobber (reg:CC FLAGS_REG))]
6527 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6528 "sub{q}\t{%2, %0|%0, %2}"
6529 [(set_attr "type" "alu")
6530 (set_attr "mode" "DI")])
6532 (define_insn "*subdi_2_rex64"
6533 [(set (reg FLAGS_REG)
6535 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6536 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6538 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6539 (minus:DI (match_dup 1) (match_dup 2)))]
6540 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6541 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6542 "sub{q}\t{%2, %0|%0, %2}"
6543 [(set_attr "type" "alu")
6544 (set_attr "mode" "DI")])
6546 (define_insn "*subdi_3_rex63"
6547 [(set (reg FLAGS_REG)
6548 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6549 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6550 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6551 (minus:DI (match_dup 1) (match_dup 2)))]
6552 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6553 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6554 "sub{q}\t{%2, %0|%0, %2}"
6555 [(set_attr "type" "alu")
6556 (set_attr "mode" "DI")])
6558 (define_insn "subqi3_carry"
6559 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6560 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6561 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6562 (match_operand:QI 2 "general_operand" "qi,qm"))))
6563 (clobber (reg:CC FLAGS_REG))]
6564 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6565 "sbb{b}\t{%2, %0|%0, %2}"
6566 [(set_attr "type" "alu")
6567 (set_attr "pent_pair" "pu")
6568 (set_attr "mode" "QI")])
6570 (define_insn "subhi3_carry"
6571 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6572 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6573 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6574 (match_operand:HI 2 "general_operand" "ri,rm"))))
6575 (clobber (reg:CC FLAGS_REG))]
6576 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6577 "sbb{w}\t{%2, %0|%0, %2}"
6578 [(set_attr "type" "alu")
6579 (set_attr "pent_pair" "pu")
6580 (set_attr "mode" "HI")])
6582 (define_insn "subsi3_carry"
6583 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6584 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6585 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6586 (match_operand:SI 2 "general_operand" "ri,rm"))))
6587 (clobber (reg:CC FLAGS_REG))]
6588 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6589 "sbb{l}\t{%2, %0|%0, %2}"
6590 [(set_attr "type" "alu")
6591 (set_attr "pent_pair" "pu")
6592 (set_attr "mode" "SI")])
6594 (define_insn "subsi3_carry_zext"
6595 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6597 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6598 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6599 (match_operand:SI 2 "general_operand" "ri,rm")))))
6600 (clobber (reg:CC FLAGS_REG))]
6601 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6602 "sbb{l}\t{%2, %k0|%k0, %2}"
6603 [(set_attr "type" "alu")
6604 (set_attr "pent_pair" "pu")
6605 (set_attr "mode" "SI")])
6607 (define_expand "subsi3"
6608 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6609 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6610 (match_operand:SI 2 "general_operand" "")))
6611 (clobber (reg:CC FLAGS_REG))])]
6613 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6615 (define_insn "*subsi_1"
6616 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6617 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6618 (match_operand:SI 2 "general_operand" "ri,rm")))
6619 (clobber (reg:CC FLAGS_REG))]
6620 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6621 "sub{l}\t{%2, %0|%0, %2}"
6622 [(set_attr "type" "alu")
6623 (set_attr "mode" "SI")])
6625 (define_insn "*subsi_1_zext"
6626 [(set (match_operand:DI 0 "register_operand" "=r")
6628 (minus:SI (match_operand:SI 1 "register_operand" "0")
6629 (match_operand:SI 2 "general_operand" "rim"))))
6630 (clobber (reg:CC FLAGS_REG))]
6631 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6632 "sub{l}\t{%2, %k0|%k0, %2}"
6633 [(set_attr "type" "alu")
6634 (set_attr "mode" "SI")])
6636 (define_insn "*subsi_2"
6637 [(set (reg FLAGS_REG)
6639 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6640 (match_operand:SI 2 "general_operand" "ri,rm"))
6642 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6643 (minus:SI (match_dup 1) (match_dup 2)))]
6644 "ix86_match_ccmode (insn, CCGOCmode)
6645 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6646 "sub{l}\t{%2, %0|%0, %2}"
6647 [(set_attr "type" "alu")
6648 (set_attr "mode" "SI")])
6650 (define_insn "*subsi_2_zext"
6651 [(set (reg FLAGS_REG)
6653 (minus:SI (match_operand:SI 1 "register_operand" "0")
6654 (match_operand:SI 2 "general_operand" "rim"))
6656 (set (match_operand:DI 0 "register_operand" "=r")
6658 (minus:SI (match_dup 1)
6660 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6661 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6662 "sub{l}\t{%2, %k0|%k0, %2}"
6663 [(set_attr "type" "alu")
6664 (set_attr "mode" "SI")])
6666 (define_insn "*subsi_3"
6667 [(set (reg FLAGS_REG)
6668 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6669 (match_operand:SI 2 "general_operand" "ri,rm")))
6670 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6671 (minus:SI (match_dup 1) (match_dup 2)))]
6672 "ix86_match_ccmode (insn, CCmode)
6673 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6674 "sub{l}\t{%2, %0|%0, %2}"
6675 [(set_attr "type" "alu")
6676 (set_attr "mode" "SI")])
6678 (define_insn "*subsi_3_zext"
6679 [(set (reg FLAGS_REG)
6680 (compare (match_operand:SI 1 "register_operand" "0")
6681 (match_operand:SI 2 "general_operand" "rim")))
6682 (set (match_operand:DI 0 "register_operand" "=r")
6684 (minus:SI (match_dup 1)
6686 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6687 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6688 "sub{q}\t{%2, %0|%0, %2}"
6689 [(set_attr "type" "alu")
6690 (set_attr "mode" "DI")])
6692 (define_expand "subhi3"
6693 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6694 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6695 (match_operand:HI 2 "general_operand" "")))
6696 (clobber (reg:CC FLAGS_REG))])]
6697 "TARGET_HIMODE_MATH"
6698 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6700 (define_insn "*subhi_1"
6701 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6702 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6703 (match_operand:HI 2 "general_operand" "ri,rm")))
6704 (clobber (reg:CC FLAGS_REG))]
6705 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6706 "sub{w}\t{%2, %0|%0, %2}"
6707 [(set_attr "type" "alu")
6708 (set_attr "mode" "HI")])
6710 (define_insn "*subhi_2"
6711 [(set (reg FLAGS_REG)
6713 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6714 (match_operand:HI 2 "general_operand" "ri,rm"))
6716 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6717 (minus:HI (match_dup 1) (match_dup 2)))]
6718 "ix86_match_ccmode (insn, CCGOCmode)
6719 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6720 "sub{w}\t{%2, %0|%0, %2}"
6721 [(set_attr "type" "alu")
6722 (set_attr "mode" "HI")])
6724 (define_insn "*subhi_3"
6725 [(set (reg FLAGS_REG)
6726 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6727 (match_operand:HI 2 "general_operand" "ri,rm")))
6728 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6729 (minus:HI (match_dup 1) (match_dup 2)))]
6730 "ix86_match_ccmode (insn, CCmode)
6731 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6732 "sub{w}\t{%2, %0|%0, %2}"
6733 [(set_attr "type" "alu")
6734 (set_attr "mode" "HI")])
6736 (define_expand "subqi3"
6737 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6738 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6739 (match_operand:QI 2 "general_operand" "")))
6740 (clobber (reg:CC FLAGS_REG))])]
6741 "TARGET_QIMODE_MATH"
6742 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6744 (define_insn "*subqi_1"
6745 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6746 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6747 (match_operand:QI 2 "general_operand" "qn,qmn")))
6748 (clobber (reg:CC FLAGS_REG))]
6749 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6750 "sub{b}\t{%2, %0|%0, %2}"
6751 [(set_attr "type" "alu")
6752 (set_attr "mode" "QI")])
6754 (define_insn "*subqi_1_slp"
6755 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6756 (minus:QI (match_dup 0)
6757 (match_operand:QI 1 "general_operand" "qn,qmn")))
6758 (clobber (reg:CC FLAGS_REG))]
6759 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6760 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6761 "sub{b}\t{%1, %0|%0, %1}"
6762 [(set_attr "type" "alu1")
6763 (set_attr "mode" "QI")])
6765 (define_insn "*subqi_2"
6766 [(set (reg FLAGS_REG)
6768 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6769 (match_operand:QI 2 "general_operand" "qi,qm"))
6771 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6772 (minus:HI (match_dup 1) (match_dup 2)))]
6773 "ix86_match_ccmode (insn, CCGOCmode)
6774 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6775 "sub{b}\t{%2, %0|%0, %2}"
6776 [(set_attr "type" "alu")
6777 (set_attr "mode" "QI")])
6779 (define_insn "*subqi_3"
6780 [(set (reg FLAGS_REG)
6781 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6782 (match_operand:QI 2 "general_operand" "qi,qm")))
6783 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6784 (minus:HI (match_dup 1) (match_dup 2)))]
6785 "ix86_match_ccmode (insn, CCmode)
6786 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6787 "sub{b}\t{%2, %0|%0, %2}"
6788 [(set_attr "type" "alu")
6789 (set_attr "mode" "QI")])
6791 ;; The patterns that match these are at the end of this file.
6793 (define_expand "subxf3"
6794 [(set (match_operand:XF 0 "register_operand" "")
6795 (minus:XF (match_operand:XF 1 "register_operand" "")
6796 (match_operand:XF 2 "register_operand" "")))]
6800 (define_expand "subdf3"
6801 [(set (match_operand:DF 0 "register_operand" "")
6802 (minus:DF (match_operand:DF 1 "register_operand" "")
6803 (match_operand:DF 2 "nonimmediate_operand" "")))]
6804 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6807 (define_expand "subsf3"
6808 [(set (match_operand:SF 0 "register_operand" "")
6809 (minus:SF (match_operand:SF 1 "register_operand" "")
6810 (match_operand:SF 2 "nonimmediate_operand" "")))]
6811 "TARGET_80387 || TARGET_SSE_MATH"
6814 ;; Multiply instructions
6816 (define_expand "muldi3"
6817 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6818 (mult:DI (match_operand:DI 1 "register_operand" "")
6819 (match_operand:DI 2 "x86_64_general_operand" "")))
6820 (clobber (reg:CC FLAGS_REG))])]
6824 (define_insn "*muldi3_1_rex64"
6825 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6826 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6827 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6828 (clobber (reg:CC FLAGS_REG))]
6830 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6832 imul{q}\t{%2, %1, %0|%0, %1, %2}
6833 imul{q}\t{%2, %1, %0|%0, %1, %2}
6834 imul{q}\t{%2, %0|%0, %2}"
6835 [(set_attr "type" "imul")
6836 (set_attr "prefix_0f" "0,0,1")
6837 (set (attr "athlon_decode")
6838 (cond [(eq_attr "cpu" "athlon")
6839 (const_string "vector")
6840 (eq_attr "alternative" "1")
6841 (const_string "vector")
6842 (and (eq_attr "alternative" "2")
6843 (match_operand 1 "memory_operand" ""))
6844 (const_string "vector")]
6845 (const_string "direct")))
6846 (set_attr "mode" "DI")])
6848 (define_expand "mulsi3"
6849 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6850 (mult:SI (match_operand:SI 1 "register_operand" "")
6851 (match_operand:SI 2 "general_operand" "")))
6852 (clobber (reg:CC FLAGS_REG))])]
6856 (define_insn "*mulsi3_1"
6857 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6858 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6859 (match_operand:SI 2 "general_operand" "K,i,mr")))
6860 (clobber (reg:CC FLAGS_REG))]
6861 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6863 imul{l}\t{%2, %1, %0|%0, %1, %2}
6864 imul{l}\t{%2, %1, %0|%0, %1, %2}
6865 imul{l}\t{%2, %0|%0, %2}"
6866 [(set_attr "type" "imul")
6867 (set_attr "prefix_0f" "0,0,1")
6868 (set (attr "athlon_decode")
6869 (cond [(eq_attr "cpu" "athlon")
6870 (const_string "vector")
6871 (eq_attr "alternative" "1")
6872 (const_string "vector")
6873 (and (eq_attr "alternative" "2")
6874 (match_operand 1 "memory_operand" ""))
6875 (const_string "vector")]
6876 (const_string "direct")))
6877 (set_attr "mode" "SI")])
6879 (define_insn "*mulsi3_1_zext"
6880 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6882 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6883 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6884 (clobber (reg:CC FLAGS_REG))]
6886 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6888 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6889 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6890 imul{l}\t{%2, %k0|%k0, %2}"
6891 [(set_attr "type" "imul")
6892 (set_attr "prefix_0f" "0,0,1")
6893 (set (attr "athlon_decode")
6894 (cond [(eq_attr "cpu" "athlon")
6895 (const_string "vector")
6896 (eq_attr "alternative" "1")
6897 (const_string "vector")
6898 (and (eq_attr "alternative" "2")
6899 (match_operand 1 "memory_operand" ""))
6900 (const_string "vector")]
6901 (const_string "direct")))
6902 (set_attr "mode" "SI")])
6904 (define_expand "mulhi3"
6905 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6906 (mult:HI (match_operand:HI 1 "register_operand" "")
6907 (match_operand:HI 2 "general_operand" "")))
6908 (clobber (reg:CC FLAGS_REG))])]
6909 "TARGET_HIMODE_MATH"
6912 (define_insn "*mulhi3_1"
6913 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6914 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6915 (match_operand:HI 2 "general_operand" "K,i,mr")))
6916 (clobber (reg:CC FLAGS_REG))]
6917 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6919 imul{w}\t{%2, %1, %0|%0, %1, %2}
6920 imul{w}\t{%2, %1, %0|%0, %1, %2}
6921 imul{w}\t{%2, %0|%0, %2}"
6922 [(set_attr "type" "imul")
6923 (set_attr "prefix_0f" "0,0,1")
6924 (set (attr "athlon_decode")
6925 (cond [(eq_attr "cpu" "athlon")
6926 (const_string "vector")
6927 (eq_attr "alternative" "1,2")
6928 (const_string "vector")]
6929 (const_string "direct")))
6930 (set_attr "mode" "HI")])
6932 (define_expand "mulqi3"
6933 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6934 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6935 (match_operand:QI 2 "register_operand" "")))
6936 (clobber (reg:CC FLAGS_REG))])]
6937 "TARGET_QIMODE_MATH"
6940 (define_insn "*mulqi3_1"
6941 [(set (match_operand:QI 0 "register_operand" "=a")
6942 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6943 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6944 (clobber (reg:CC FLAGS_REG))]
6946 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6948 [(set_attr "type" "imul")
6949 (set_attr "length_immediate" "0")
6950 (set (attr "athlon_decode")
6951 (if_then_else (eq_attr "cpu" "athlon")
6952 (const_string "vector")
6953 (const_string "direct")))
6954 (set_attr "mode" "QI")])
6956 (define_expand "umulqihi3"
6957 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6958 (mult:HI (zero_extend:HI
6959 (match_operand:QI 1 "nonimmediate_operand" ""))
6961 (match_operand:QI 2 "register_operand" ""))))
6962 (clobber (reg:CC FLAGS_REG))])]
6963 "TARGET_QIMODE_MATH"
6966 (define_insn "*umulqihi3_1"
6967 [(set (match_operand:HI 0 "register_operand" "=a")
6968 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6969 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6970 (clobber (reg:CC FLAGS_REG))]
6972 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6974 [(set_attr "type" "imul")
6975 (set_attr "length_immediate" "0")
6976 (set (attr "athlon_decode")
6977 (if_then_else (eq_attr "cpu" "athlon")
6978 (const_string "vector")
6979 (const_string "direct")))
6980 (set_attr "mode" "QI")])
6982 (define_expand "mulqihi3"
6983 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6984 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6985 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6986 (clobber (reg:CC FLAGS_REG))])]
6987 "TARGET_QIMODE_MATH"
6990 (define_insn "*mulqihi3_insn"
6991 [(set (match_operand:HI 0 "register_operand" "=a")
6992 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6993 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6994 (clobber (reg:CC FLAGS_REG))]
6996 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6998 [(set_attr "type" "imul")
6999 (set_attr "length_immediate" "0")
7000 (set (attr "athlon_decode")
7001 (if_then_else (eq_attr "cpu" "athlon")
7002 (const_string "vector")
7003 (const_string "direct")))
7004 (set_attr "mode" "QI")])
7006 (define_expand "umulditi3"
7007 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7008 (mult:TI (zero_extend:TI
7009 (match_operand:DI 1 "nonimmediate_operand" ""))
7011 (match_operand:DI 2 "register_operand" ""))))
7012 (clobber (reg:CC FLAGS_REG))])]
7016 (define_insn "*umulditi3_insn"
7017 [(set (match_operand:TI 0 "register_operand" "=A")
7018 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7019 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7020 (clobber (reg:CC FLAGS_REG))]
7022 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7024 [(set_attr "type" "imul")
7025 (set_attr "length_immediate" "0")
7026 (set (attr "athlon_decode")
7027 (if_then_else (eq_attr "cpu" "athlon")
7028 (const_string "vector")
7029 (const_string "double")))
7030 (set_attr "mode" "DI")])
7032 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7033 (define_expand "umulsidi3"
7034 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7035 (mult:DI (zero_extend:DI
7036 (match_operand:SI 1 "nonimmediate_operand" ""))
7038 (match_operand:SI 2 "register_operand" ""))))
7039 (clobber (reg:CC FLAGS_REG))])]
7043 (define_insn "*umulsidi3_insn"
7044 [(set (match_operand:DI 0 "register_operand" "=A")
7045 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7046 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7047 (clobber (reg:CC FLAGS_REG))]
7049 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7051 [(set_attr "type" "imul")
7052 (set_attr "length_immediate" "0")
7053 (set (attr "athlon_decode")
7054 (if_then_else (eq_attr "cpu" "athlon")
7055 (const_string "vector")
7056 (const_string "double")))
7057 (set_attr "mode" "SI")])
7059 (define_expand "mulditi3"
7060 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7061 (mult:TI (sign_extend:TI
7062 (match_operand:DI 1 "nonimmediate_operand" ""))
7064 (match_operand:DI 2 "register_operand" ""))))
7065 (clobber (reg:CC FLAGS_REG))])]
7069 (define_insn "*mulditi3_insn"
7070 [(set (match_operand:TI 0 "register_operand" "=A")
7071 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7072 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7073 (clobber (reg:CC FLAGS_REG))]
7075 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7077 [(set_attr "type" "imul")
7078 (set_attr "length_immediate" "0")
7079 (set (attr "athlon_decode")
7080 (if_then_else (eq_attr "cpu" "athlon")
7081 (const_string "vector")
7082 (const_string "double")))
7083 (set_attr "mode" "DI")])
7085 (define_expand "mulsidi3"
7086 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7087 (mult:DI (sign_extend:DI
7088 (match_operand:SI 1 "nonimmediate_operand" ""))
7090 (match_operand:SI 2 "register_operand" ""))))
7091 (clobber (reg:CC FLAGS_REG))])]
7095 (define_insn "*mulsidi3_insn"
7096 [(set (match_operand:DI 0 "register_operand" "=A")
7097 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7098 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7099 (clobber (reg:CC FLAGS_REG))]
7101 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7103 [(set_attr "type" "imul")
7104 (set_attr "length_immediate" "0")
7105 (set (attr "athlon_decode")
7106 (if_then_else (eq_attr "cpu" "athlon")
7107 (const_string "vector")
7108 (const_string "double")))
7109 (set_attr "mode" "SI")])
7111 (define_expand "umuldi3_highpart"
7112 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7115 (mult:TI (zero_extend:TI
7116 (match_operand:DI 1 "nonimmediate_operand" ""))
7118 (match_operand:DI 2 "register_operand" "")))
7120 (clobber (match_scratch:DI 3 ""))
7121 (clobber (reg:CC FLAGS_REG))])]
7125 (define_insn "*umuldi3_highpart_rex64"
7126 [(set (match_operand:DI 0 "register_operand" "=d")
7129 (mult:TI (zero_extend:TI
7130 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7132 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7134 (clobber (match_scratch:DI 3 "=1"))
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" "DI")])
7147 (define_expand "umulsi3_highpart"
7148 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7151 (mult:DI (zero_extend:DI
7152 (match_operand:SI 1 "nonimmediate_operand" ""))
7154 (match_operand:SI 2 "register_operand" "")))
7156 (clobber (match_scratch:SI 3 ""))
7157 (clobber (reg:CC FLAGS_REG))])]
7161 (define_insn "*umulsi3_highpart_insn"
7162 [(set (match_operand:SI 0 "register_operand" "=d")
7165 (mult:DI (zero_extend:DI
7166 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7168 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7170 (clobber (match_scratch:SI 3 "=1"))
7171 (clobber (reg:CC FLAGS_REG))]
7172 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7174 [(set_attr "type" "imul")
7175 (set_attr "length_immediate" "0")
7176 (set (attr "athlon_decode")
7177 (if_then_else (eq_attr "cpu" "athlon")
7178 (const_string "vector")
7179 (const_string "double")))
7180 (set_attr "mode" "SI")])
7182 (define_insn "*umulsi3_highpart_zext"
7183 [(set (match_operand:DI 0 "register_operand" "=d")
7184 (zero_extend:DI (truncate:SI
7186 (mult:DI (zero_extend:DI
7187 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7189 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7191 (clobber (match_scratch:SI 3 "=1"))
7192 (clobber (reg:CC FLAGS_REG))]
7194 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7196 [(set_attr "type" "imul")
7197 (set_attr "length_immediate" "0")
7198 (set (attr "athlon_decode")
7199 (if_then_else (eq_attr "cpu" "athlon")
7200 (const_string "vector")
7201 (const_string "double")))
7202 (set_attr "mode" "SI")])
7204 (define_expand "smuldi3_highpart"
7205 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7208 (mult:TI (sign_extend:TI
7209 (match_operand:DI 1 "nonimmediate_operand" ""))
7211 (match_operand:DI 2 "register_operand" "")))
7213 (clobber (match_scratch:DI 3 ""))
7214 (clobber (reg:CC FLAGS_REG))])]
7218 (define_insn "*smuldi3_highpart_rex64"
7219 [(set (match_operand:DI 0 "register_operand" "=d")
7222 (mult:TI (sign_extend:TI
7223 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7225 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7227 (clobber (match_scratch:DI 3 "=1"))
7228 (clobber (reg:CC FLAGS_REG))]
7230 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7232 [(set_attr "type" "imul")
7233 (set (attr "athlon_decode")
7234 (if_then_else (eq_attr "cpu" "athlon")
7235 (const_string "vector")
7236 (const_string "double")))
7237 (set_attr "mode" "DI")])
7239 (define_expand "smulsi3_highpart"
7240 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7243 (mult:DI (sign_extend:DI
7244 (match_operand:SI 1 "nonimmediate_operand" ""))
7246 (match_operand:SI 2 "register_operand" "")))
7248 (clobber (match_scratch:SI 3 ""))
7249 (clobber (reg:CC FLAGS_REG))])]
7253 (define_insn "*smulsi3_highpart_insn"
7254 [(set (match_operand:SI 0 "register_operand" "=d")
7257 (mult:DI (sign_extend:DI
7258 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7260 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7262 (clobber (match_scratch:SI 3 "=1"))
7263 (clobber (reg:CC FLAGS_REG))]
7264 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7266 [(set_attr "type" "imul")
7267 (set (attr "athlon_decode")
7268 (if_then_else (eq_attr "cpu" "athlon")
7269 (const_string "vector")
7270 (const_string "double")))
7271 (set_attr "mode" "SI")])
7273 (define_insn "*smulsi3_highpart_zext"
7274 [(set (match_operand:DI 0 "register_operand" "=d")
7275 (zero_extend:DI (truncate:SI
7277 (mult:DI (sign_extend:DI
7278 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7280 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7282 (clobber (match_scratch:SI 3 "=1"))
7283 (clobber (reg:CC FLAGS_REG))]
7285 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7287 [(set_attr "type" "imul")
7288 (set (attr "athlon_decode")
7289 (if_then_else (eq_attr "cpu" "athlon")
7290 (const_string "vector")
7291 (const_string "double")))
7292 (set_attr "mode" "SI")])
7294 ;; The patterns that match these are at the end of this file.
7296 (define_expand "mulxf3"
7297 [(set (match_operand:XF 0 "register_operand" "")
7298 (mult:XF (match_operand:XF 1 "register_operand" "")
7299 (match_operand:XF 2 "register_operand" "")))]
7303 (define_expand "muldf3"
7304 [(set (match_operand:DF 0 "register_operand" "")
7305 (mult:DF (match_operand:DF 1 "register_operand" "")
7306 (match_operand:DF 2 "nonimmediate_operand" "")))]
7307 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7310 (define_expand "mulsf3"
7311 [(set (match_operand:SF 0 "register_operand" "")
7312 (mult:SF (match_operand:SF 1 "register_operand" "")
7313 (match_operand:SF 2 "nonimmediate_operand" "")))]
7314 "TARGET_80387 || TARGET_SSE_MATH"
7317 ;; Divide instructions
7319 (define_insn "divqi3"
7320 [(set (match_operand:QI 0 "register_operand" "=a")
7321 (div:QI (match_operand:HI 1 "register_operand" "0")
7322 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7323 (clobber (reg:CC FLAGS_REG))]
7324 "TARGET_QIMODE_MATH"
7326 [(set_attr "type" "idiv")
7327 (set_attr "mode" "QI")])
7329 (define_insn "udivqi3"
7330 [(set (match_operand:QI 0 "register_operand" "=a")
7331 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7332 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7333 (clobber (reg:CC FLAGS_REG))]
7334 "TARGET_QIMODE_MATH"
7336 [(set_attr "type" "idiv")
7337 (set_attr "mode" "QI")])
7339 ;; The patterns that match these are at the end of this file.
7341 (define_expand "divxf3"
7342 [(set (match_operand:XF 0 "register_operand" "")
7343 (div:XF (match_operand:XF 1 "register_operand" "")
7344 (match_operand:XF 2 "register_operand" "")))]
7348 (define_expand "divdf3"
7349 [(set (match_operand:DF 0 "register_operand" "")
7350 (div:DF (match_operand:DF 1 "register_operand" "")
7351 (match_operand:DF 2 "nonimmediate_operand" "")))]
7352 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7355 (define_expand "divsf3"
7356 [(set (match_operand:SF 0 "register_operand" "")
7357 (div:SF (match_operand:SF 1 "register_operand" "")
7358 (match_operand:SF 2 "nonimmediate_operand" "")))]
7359 "TARGET_80387 || TARGET_SSE_MATH"
7362 ;; Remainder instructions.
7364 (define_expand "divmoddi4"
7365 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7366 (div:DI (match_operand:DI 1 "register_operand" "")
7367 (match_operand:DI 2 "nonimmediate_operand" "")))
7368 (set (match_operand:DI 3 "register_operand" "")
7369 (mod:DI (match_dup 1) (match_dup 2)))
7370 (clobber (reg:CC FLAGS_REG))])]
7374 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7375 ;; Penalize eax case slightly because it results in worse scheduling
7377 (define_insn "*divmoddi4_nocltd_rex64"
7378 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7379 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7380 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7381 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7382 (mod:DI (match_dup 2) (match_dup 3)))
7383 (clobber (reg:CC FLAGS_REG))]
7384 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7386 [(set_attr "type" "multi")])
7388 (define_insn "*divmoddi4_cltd_rex64"
7389 [(set (match_operand:DI 0 "register_operand" "=a")
7390 (div:DI (match_operand:DI 2 "register_operand" "a")
7391 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7392 (set (match_operand:DI 1 "register_operand" "=&d")
7393 (mod:DI (match_dup 2) (match_dup 3)))
7394 (clobber (reg:CC FLAGS_REG))]
7395 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7397 [(set_attr "type" "multi")])
7399 (define_insn "*divmoddi_noext_rex64"
7400 [(set (match_operand:DI 0 "register_operand" "=a")
7401 (div:DI (match_operand:DI 1 "register_operand" "0")
7402 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7403 (set (match_operand:DI 3 "register_operand" "=d")
7404 (mod:DI (match_dup 1) (match_dup 2)))
7405 (use (match_operand:DI 4 "register_operand" "3"))
7406 (clobber (reg:CC FLAGS_REG))]
7409 [(set_attr "type" "idiv")
7410 (set_attr "mode" "DI")])
7413 [(set (match_operand:DI 0 "register_operand" "")
7414 (div:DI (match_operand:DI 1 "register_operand" "")
7415 (match_operand:DI 2 "nonimmediate_operand" "")))
7416 (set (match_operand:DI 3 "register_operand" "")
7417 (mod:DI (match_dup 1) (match_dup 2)))
7418 (clobber (reg:CC FLAGS_REG))]
7419 "TARGET_64BIT && reload_completed"
7420 [(parallel [(set (match_dup 3)
7421 (ashiftrt:DI (match_dup 4) (const_int 63)))
7422 (clobber (reg:CC FLAGS_REG))])
7423 (parallel [(set (match_dup 0)
7424 (div:DI (reg:DI 0) (match_dup 2)))
7426 (mod:DI (reg:DI 0) (match_dup 2)))
7428 (clobber (reg:CC FLAGS_REG))])]
7430 /* Avoid use of cltd in favor of a mov+shift. */
7431 if (!TARGET_USE_CLTD && !optimize_size)
7433 if (true_regnum (operands[1]))
7434 emit_move_insn (operands[0], operands[1]);
7436 emit_move_insn (operands[3], operands[1]);
7437 operands[4] = operands[3];
7441 gcc_assert (!true_regnum (operands[1]));
7442 operands[4] = operands[1];
7447 (define_expand "divmodsi4"
7448 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7449 (div:SI (match_operand:SI 1 "register_operand" "")
7450 (match_operand:SI 2 "nonimmediate_operand" "")))
7451 (set (match_operand:SI 3 "register_operand" "")
7452 (mod:SI (match_dup 1) (match_dup 2)))
7453 (clobber (reg:CC FLAGS_REG))])]
7457 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7458 ;; Penalize eax case slightly because it results in worse scheduling
7460 (define_insn "*divmodsi4_nocltd"
7461 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7462 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7463 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7464 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7465 (mod:SI (match_dup 2) (match_dup 3)))
7466 (clobber (reg:CC FLAGS_REG))]
7467 "!optimize_size && !TARGET_USE_CLTD"
7469 [(set_attr "type" "multi")])
7471 (define_insn "*divmodsi4_cltd"
7472 [(set (match_operand:SI 0 "register_operand" "=a")
7473 (div:SI (match_operand:SI 2 "register_operand" "a")
7474 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7475 (set (match_operand:SI 1 "register_operand" "=&d")
7476 (mod:SI (match_dup 2) (match_dup 3)))
7477 (clobber (reg:CC FLAGS_REG))]
7478 "optimize_size || TARGET_USE_CLTD"
7480 [(set_attr "type" "multi")])
7482 (define_insn "*divmodsi_noext"
7483 [(set (match_operand:SI 0 "register_operand" "=a")
7484 (div:SI (match_operand:SI 1 "register_operand" "0")
7485 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7486 (set (match_operand:SI 3 "register_operand" "=d")
7487 (mod:SI (match_dup 1) (match_dup 2)))
7488 (use (match_operand:SI 4 "register_operand" "3"))
7489 (clobber (reg:CC FLAGS_REG))]
7492 [(set_attr "type" "idiv")
7493 (set_attr "mode" "SI")])
7496 [(set (match_operand:SI 0 "register_operand" "")
7497 (div:SI (match_operand:SI 1 "register_operand" "")
7498 (match_operand:SI 2 "nonimmediate_operand" "")))
7499 (set (match_operand:SI 3 "register_operand" "")
7500 (mod:SI (match_dup 1) (match_dup 2)))
7501 (clobber (reg:CC FLAGS_REG))]
7503 [(parallel [(set (match_dup 3)
7504 (ashiftrt:SI (match_dup 4) (const_int 31)))
7505 (clobber (reg:CC FLAGS_REG))])
7506 (parallel [(set (match_dup 0)
7507 (div:SI (reg:SI 0) (match_dup 2)))
7509 (mod:SI (reg:SI 0) (match_dup 2)))
7511 (clobber (reg:CC FLAGS_REG))])]
7513 /* Avoid use of cltd in favor of a mov+shift. */
7514 if (!TARGET_USE_CLTD && !optimize_size)
7516 if (true_regnum (operands[1]))
7517 emit_move_insn (operands[0], operands[1]);
7519 emit_move_insn (operands[3], operands[1]);
7520 operands[4] = operands[3];
7524 gcc_assert (!true_regnum (operands[1]));
7525 operands[4] = operands[1];
7529 (define_insn "divmodhi4"
7530 [(set (match_operand:HI 0 "register_operand" "=a")
7531 (div:HI (match_operand:HI 1 "register_operand" "0")
7532 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7533 (set (match_operand:HI 3 "register_operand" "=&d")
7534 (mod:HI (match_dup 1) (match_dup 2)))
7535 (clobber (reg:CC FLAGS_REG))]
7536 "TARGET_HIMODE_MATH"
7538 [(set_attr "type" "multi")
7539 (set_attr "length_immediate" "0")
7540 (set_attr "mode" "SI")])
7542 (define_insn "udivmoddi4"
7543 [(set (match_operand:DI 0 "register_operand" "=a")
7544 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7545 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7546 (set (match_operand:DI 3 "register_operand" "=&d")
7547 (umod:DI (match_dup 1) (match_dup 2)))
7548 (clobber (reg:CC FLAGS_REG))]
7550 "xor{q}\t%3, %3\;div{q}\t%2"
7551 [(set_attr "type" "multi")
7552 (set_attr "length_immediate" "0")
7553 (set_attr "mode" "DI")])
7555 (define_insn "*udivmoddi4_noext"
7556 [(set (match_operand:DI 0 "register_operand" "=a")
7557 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7558 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7559 (set (match_operand:DI 3 "register_operand" "=d")
7560 (umod:DI (match_dup 1) (match_dup 2)))
7562 (clobber (reg:CC FLAGS_REG))]
7565 [(set_attr "type" "idiv")
7566 (set_attr "mode" "DI")])
7569 [(set (match_operand:DI 0 "register_operand" "")
7570 (udiv:DI (match_operand:DI 1 "register_operand" "")
7571 (match_operand:DI 2 "nonimmediate_operand" "")))
7572 (set (match_operand:DI 3 "register_operand" "")
7573 (umod:DI (match_dup 1) (match_dup 2)))
7574 (clobber (reg:CC FLAGS_REG))]
7575 "TARGET_64BIT && reload_completed"
7576 [(set (match_dup 3) (const_int 0))
7577 (parallel [(set (match_dup 0)
7578 (udiv:DI (match_dup 1) (match_dup 2)))
7580 (umod:DI (match_dup 1) (match_dup 2)))
7582 (clobber (reg:CC FLAGS_REG))])]
7585 (define_insn "udivmodsi4"
7586 [(set (match_operand:SI 0 "register_operand" "=a")
7587 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7588 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7589 (set (match_operand:SI 3 "register_operand" "=&d")
7590 (umod:SI (match_dup 1) (match_dup 2)))
7591 (clobber (reg:CC FLAGS_REG))]
7593 "xor{l}\t%3, %3\;div{l}\t%2"
7594 [(set_attr "type" "multi")
7595 (set_attr "length_immediate" "0")
7596 (set_attr "mode" "SI")])
7598 (define_insn "*udivmodsi4_noext"
7599 [(set (match_operand:SI 0 "register_operand" "=a")
7600 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7601 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7602 (set (match_operand:SI 3 "register_operand" "=d")
7603 (umod:SI (match_dup 1) (match_dup 2)))
7605 (clobber (reg:CC FLAGS_REG))]
7608 [(set_attr "type" "idiv")
7609 (set_attr "mode" "SI")])
7612 [(set (match_operand:SI 0 "register_operand" "")
7613 (udiv:SI (match_operand:SI 1 "register_operand" "")
7614 (match_operand:SI 2 "nonimmediate_operand" "")))
7615 (set (match_operand:SI 3 "register_operand" "")
7616 (umod:SI (match_dup 1) (match_dup 2)))
7617 (clobber (reg:CC FLAGS_REG))]
7619 [(set (match_dup 3) (const_int 0))
7620 (parallel [(set (match_dup 0)
7621 (udiv:SI (match_dup 1) (match_dup 2)))
7623 (umod:SI (match_dup 1) (match_dup 2)))
7625 (clobber (reg:CC FLAGS_REG))])]
7628 (define_expand "udivmodhi4"
7629 [(set (match_dup 4) (const_int 0))
7630 (parallel [(set (match_operand:HI 0 "register_operand" "")
7631 (udiv:HI (match_operand:HI 1 "register_operand" "")
7632 (match_operand:HI 2 "nonimmediate_operand" "")))
7633 (set (match_operand:HI 3 "register_operand" "")
7634 (umod:HI (match_dup 1) (match_dup 2)))
7636 (clobber (reg:CC FLAGS_REG))])]
7637 "TARGET_HIMODE_MATH"
7638 "operands[4] = gen_reg_rtx (HImode);")
7640 (define_insn "*udivmodhi_noext"
7641 [(set (match_operand:HI 0 "register_operand" "=a")
7642 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7643 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7644 (set (match_operand:HI 3 "register_operand" "=d")
7645 (umod:HI (match_dup 1) (match_dup 2)))
7646 (use (match_operand:HI 4 "register_operand" "3"))
7647 (clobber (reg:CC FLAGS_REG))]
7650 [(set_attr "type" "idiv")
7651 (set_attr "mode" "HI")])
7653 ;; We cannot use div/idiv for double division, because it causes
7654 ;; "division by zero" on the overflow and that's not what we expect
7655 ;; from truncate. Because true (non truncating) double division is
7656 ;; never generated, we can't create this insn anyway.
7659 ; [(set (match_operand:SI 0 "register_operand" "=a")
7661 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7663 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7664 ; (set (match_operand:SI 3 "register_operand" "=d")
7666 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7667 ; (clobber (reg:CC FLAGS_REG))]
7669 ; "div{l}\t{%2, %0|%0, %2}"
7670 ; [(set_attr "type" "idiv")])
7672 ;;- Logical AND instructions
7674 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7675 ;; Note that this excludes ah.
7677 (define_insn "*testdi_1_rex64"
7678 [(set (reg FLAGS_REG)
7680 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7681 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7683 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7684 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7686 test{l}\t{%k1, %k0|%k0, %k1}
7687 test{l}\t{%k1, %k0|%k0, %k1}
7688 test{q}\t{%1, %0|%0, %1}
7689 test{q}\t{%1, %0|%0, %1}
7690 test{q}\t{%1, %0|%0, %1}"
7691 [(set_attr "type" "test")
7692 (set_attr "modrm" "0,1,0,1,1")
7693 (set_attr "mode" "SI,SI,DI,DI,DI")
7694 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7696 (define_insn "testsi_1"
7697 [(set (reg FLAGS_REG)
7699 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7700 (match_operand:SI 1 "general_operand" "in,in,rin"))
7702 "ix86_match_ccmode (insn, CCNOmode)
7703 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7704 "test{l}\t{%1, %0|%0, %1}"
7705 [(set_attr "type" "test")
7706 (set_attr "modrm" "0,1,1")
7707 (set_attr "mode" "SI")
7708 (set_attr "pent_pair" "uv,np,uv")])
7710 (define_expand "testsi_ccno_1"
7711 [(set (reg:CCNO FLAGS_REG)
7713 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7714 (match_operand:SI 1 "nonmemory_operand" ""))
7719 (define_insn "*testhi_1"
7720 [(set (reg FLAGS_REG)
7721 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7722 (match_operand:HI 1 "general_operand" "n,n,rn"))
7724 "ix86_match_ccmode (insn, CCNOmode)
7725 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7726 "test{w}\t{%1, %0|%0, %1}"
7727 [(set_attr "type" "test")
7728 (set_attr "modrm" "0,1,1")
7729 (set_attr "mode" "HI")
7730 (set_attr "pent_pair" "uv,np,uv")])
7732 (define_expand "testqi_ccz_1"
7733 [(set (reg:CCZ FLAGS_REG)
7734 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7735 (match_operand:QI 1 "nonmemory_operand" ""))
7740 (define_insn "*testqi_1_maybe_si"
7741 [(set (reg FLAGS_REG)
7744 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7745 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7747 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7748 && ix86_match_ccmode (insn,
7749 GET_CODE (operands[1]) == CONST_INT
7750 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7752 if (which_alternative == 3)
7754 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7755 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7756 return "test{l}\t{%1, %k0|%k0, %1}";
7758 return "test{b}\t{%1, %0|%0, %1}";
7760 [(set_attr "type" "test")
7761 (set_attr "modrm" "0,1,1,1")
7762 (set_attr "mode" "QI,QI,QI,SI")
7763 (set_attr "pent_pair" "uv,np,uv,np")])
7765 (define_insn "*testqi_1"
7766 [(set (reg FLAGS_REG)
7769 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7770 (match_operand:QI 1 "general_operand" "n,n,qn"))
7772 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7773 && ix86_match_ccmode (insn, CCNOmode)"
7774 "test{b}\t{%1, %0|%0, %1}"
7775 [(set_attr "type" "test")
7776 (set_attr "modrm" "0,1,1")
7777 (set_attr "mode" "QI")
7778 (set_attr "pent_pair" "uv,np,uv")])
7780 (define_expand "testqi_ext_ccno_0"
7781 [(set (reg:CCNO FLAGS_REG)
7785 (match_operand 0 "ext_register_operand" "")
7788 (match_operand 1 "const_int_operand" ""))
7793 (define_insn "*testqi_ext_0"
7794 [(set (reg FLAGS_REG)
7798 (match_operand 0 "ext_register_operand" "Q")
7801 (match_operand 1 "const_int_operand" "n"))
7803 "ix86_match_ccmode (insn, CCNOmode)"
7804 "test{b}\t{%1, %h0|%h0, %1}"
7805 [(set_attr "type" "test")
7806 (set_attr "mode" "QI")
7807 (set_attr "length_immediate" "1")
7808 (set_attr "pent_pair" "np")])
7810 (define_insn "*testqi_ext_1"
7811 [(set (reg FLAGS_REG)
7815 (match_operand 0 "ext_register_operand" "Q")
7819 (match_operand:QI 1 "general_operand" "Qm")))
7821 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7822 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7823 "test{b}\t{%1, %h0|%h0, %1}"
7824 [(set_attr "type" "test")
7825 (set_attr "mode" "QI")])
7827 (define_insn "*testqi_ext_1_rex64"
7828 [(set (reg FLAGS_REG)
7832 (match_operand 0 "ext_register_operand" "Q")
7836 (match_operand:QI 1 "register_operand" "Q")))
7838 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7839 "test{b}\t{%1, %h0|%h0, %1}"
7840 [(set_attr "type" "test")
7841 (set_attr "mode" "QI")])
7843 (define_insn "*testqi_ext_2"
7844 [(set (reg FLAGS_REG)
7848 (match_operand 0 "ext_register_operand" "Q")
7852 (match_operand 1 "ext_register_operand" "Q")
7856 "ix86_match_ccmode (insn, CCNOmode)"
7857 "test{b}\t{%h1, %h0|%h0, %h1}"
7858 [(set_attr "type" "test")
7859 (set_attr "mode" "QI")])
7861 ;; Combine likes to form bit extractions for some tests. Humor it.
7862 (define_insn "*testqi_ext_3"
7863 [(set (reg FLAGS_REG)
7864 (compare (zero_extract:SI
7865 (match_operand 0 "nonimmediate_operand" "rm")
7866 (match_operand:SI 1 "const_int_operand" "")
7867 (match_operand:SI 2 "const_int_operand" ""))
7869 "ix86_match_ccmode (insn, CCNOmode)
7870 && INTVAL (operands[1]) > 0
7871 && INTVAL (operands[2]) >= 0
7872 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7873 && (GET_MODE (operands[0]) == SImode
7874 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7875 || GET_MODE (operands[0]) == HImode
7876 || GET_MODE (operands[0]) == QImode)"
7879 (define_insn "*testqi_ext_3_rex64"
7880 [(set (reg FLAGS_REG)
7881 (compare (zero_extract:DI
7882 (match_operand 0 "nonimmediate_operand" "rm")
7883 (match_operand:DI 1 "const_int_operand" "")
7884 (match_operand:DI 2 "const_int_operand" ""))
7887 && ix86_match_ccmode (insn, CCNOmode)
7888 && INTVAL (operands[1]) > 0
7889 && INTVAL (operands[2]) >= 0
7890 /* Ensure that resulting mask is zero or sign extended operand. */
7891 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7892 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7893 && INTVAL (operands[1]) > 32))
7894 && (GET_MODE (operands[0]) == SImode
7895 || GET_MODE (operands[0]) == DImode
7896 || GET_MODE (operands[0]) == HImode
7897 || GET_MODE (operands[0]) == QImode)"
7901 [(set (match_operand 0 "flags_reg_operand" "")
7902 (match_operator 1 "compare_operator"
7904 (match_operand 2 "nonimmediate_operand" "")
7905 (match_operand 3 "const_int_operand" "")
7906 (match_operand 4 "const_int_operand" ""))
7908 "ix86_match_ccmode (insn, CCNOmode)"
7909 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7911 rtx val = operands[2];
7912 HOST_WIDE_INT len = INTVAL (operands[3]);
7913 HOST_WIDE_INT pos = INTVAL (operands[4]);
7915 enum machine_mode mode, submode;
7917 mode = GET_MODE (val);
7918 if (GET_CODE (val) == MEM)
7920 /* ??? Combine likes to put non-volatile mem extractions in QImode
7921 no matter the size of the test. So find a mode that works. */
7922 if (! MEM_VOLATILE_P (val))
7924 mode = smallest_mode_for_size (pos + len, MODE_INT);
7925 val = adjust_address (val, mode, 0);
7928 else if (GET_CODE (val) == SUBREG
7929 && (submode = GET_MODE (SUBREG_REG (val)),
7930 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7931 && pos + len <= GET_MODE_BITSIZE (submode))
7933 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7935 val = SUBREG_REG (val);
7937 else if (mode == HImode && pos + len <= 8)
7939 /* Small HImode tests can be converted to QImode. */
7941 val = gen_lowpart (QImode, val);
7944 if (len == HOST_BITS_PER_WIDE_INT)
7947 mask = ((HOST_WIDE_INT)1 << len) - 1;
7950 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7953 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7954 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7955 ;; this is relatively important trick.
7956 ;; Do the conversion only post-reload to avoid limiting of the register class
7959 [(set (match_operand 0 "flags_reg_operand" "")
7960 (match_operator 1 "compare_operator"
7961 [(and (match_operand 2 "register_operand" "")
7962 (match_operand 3 "const_int_operand" ""))
7965 && QI_REG_P (operands[2])
7966 && GET_MODE (operands[2]) != QImode
7967 && ((ix86_match_ccmode (insn, CCZmode)
7968 && !(INTVAL (operands[3]) & ~(255 << 8)))
7969 || (ix86_match_ccmode (insn, CCNOmode)
7970 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7973 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7976 "operands[2] = gen_lowpart (SImode, operands[2]);
7977 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7980 [(set (match_operand 0 "flags_reg_operand" "")
7981 (match_operator 1 "compare_operator"
7982 [(and (match_operand 2 "nonimmediate_operand" "")
7983 (match_operand 3 "const_int_operand" ""))
7986 && GET_MODE (operands[2]) != QImode
7987 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7988 && ((ix86_match_ccmode (insn, CCZmode)
7989 && !(INTVAL (operands[3]) & ~255))
7990 || (ix86_match_ccmode (insn, CCNOmode)
7991 && !(INTVAL (operands[3]) & ~127)))"
7993 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7995 "operands[2] = gen_lowpart (QImode, operands[2]);
7996 operands[3] = gen_lowpart (QImode, operands[3]);")
7999 ;; %%% This used to optimize known byte-wide and operations to memory,
8000 ;; and sometimes to QImode registers. If this is considered useful,
8001 ;; it should be done with splitters.
8003 (define_expand "anddi3"
8004 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8005 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8006 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8007 (clobber (reg:CC FLAGS_REG))]
8009 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8011 (define_insn "*anddi_1_rex64"
8012 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8013 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8014 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8015 (clobber (reg:CC FLAGS_REG))]
8016 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8018 switch (get_attr_type (insn))
8022 enum machine_mode mode;
8024 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8025 if (INTVAL (operands[2]) == 0xff)
8029 gcc_assert (INTVAL (operands[2]) == 0xffff);
8033 operands[1] = gen_lowpart (mode, operands[1]);
8035 return "movz{bq|x}\t{%1,%0|%0, %1}";
8037 return "movz{wq|x}\t{%1,%0|%0, %1}";
8041 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8042 if (get_attr_mode (insn) == MODE_SI)
8043 return "and{l}\t{%k2, %k0|%k0, %k2}";
8045 return "and{q}\t{%2, %0|%0, %2}";
8048 [(set_attr "type" "alu,alu,alu,imovx")
8049 (set_attr "length_immediate" "*,*,*,0")
8050 (set_attr "mode" "SI,DI,DI,DI")])
8052 (define_insn "*anddi_2"
8053 [(set (reg FLAGS_REG)
8054 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8055 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8057 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8058 (and:DI (match_dup 1) (match_dup 2)))]
8059 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8060 && ix86_binary_operator_ok (AND, DImode, operands)"
8062 and{l}\t{%k2, %k0|%k0, %k2}
8063 and{q}\t{%2, %0|%0, %2}
8064 and{q}\t{%2, %0|%0, %2}"
8065 [(set_attr "type" "alu")
8066 (set_attr "mode" "SI,DI,DI")])
8068 (define_expand "andsi3"
8069 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8070 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8071 (match_operand:SI 2 "general_operand" "")))
8072 (clobber (reg:CC FLAGS_REG))]
8074 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8076 (define_insn "*andsi_1"
8077 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8078 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8079 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8080 (clobber (reg:CC FLAGS_REG))]
8081 "ix86_binary_operator_ok (AND, SImode, operands)"
8083 switch (get_attr_type (insn))
8087 enum machine_mode mode;
8089 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8090 if (INTVAL (operands[2]) == 0xff)
8094 gcc_assert (INTVAL (operands[2]) == 0xffff);
8098 operands[1] = gen_lowpart (mode, operands[1]);
8100 return "movz{bl|x}\t{%1,%0|%0, %1}";
8102 return "movz{wl|x}\t{%1,%0|%0, %1}";
8106 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8107 return "and{l}\t{%2, %0|%0, %2}";
8110 [(set_attr "type" "alu,alu,imovx")
8111 (set_attr "length_immediate" "*,*,0")
8112 (set_attr "mode" "SI")])
8115 [(set (match_operand 0 "register_operand" "")
8117 (const_int -65536)))
8118 (clobber (reg:CC FLAGS_REG))]
8119 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8120 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8121 "operands[1] = gen_lowpart (HImode, operands[0]);")
8124 [(set (match_operand 0 "ext_register_operand" "")
8127 (clobber (reg:CC FLAGS_REG))]
8128 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8129 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8130 "operands[1] = gen_lowpart (QImode, operands[0]);")
8133 [(set (match_operand 0 "ext_register_operand" "")
8135 (const_int -65281)))
8136 (clobber (reg:CC FLAGS_REG))]
8137 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8138 [(parallel [(set (zero_extract:SI (match_dup 0)
8142 (zero_extract:SI (match_dup 0)
8145 (zero_extract:SI (match_dup 0)
8148 (clobber (reg:CC FLAGS_REG))])]
8149 "operands[0] = gen_lowpart (SImode, operands[0]);")
8151 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8152 (define_insn "*andsi_1_zext"
8153 [(set (match_operand:DI 0 "register_operand" "=r")
8155 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8156 (match_operand:SI 2 "general_operand" "rim"))))
8157 (clobber (reg:CC FLAGS_REG))]
8158 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8159 "and{l}\t{%2, %k0|%k0, %2}"
8160 [(set_attr "type" "alu")
8161 (set_attr "mode" "SI")])
8163 (define_insn "*andsi_2"
8164 [(set (reg FLAGS_REG)
8165 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8166 (match_operand:SI 2 "general_operand" "rim,ri"))
8168 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8169 (and:SI (match_dup 1) (match_dup 2)))]
8170 "ix86_match_ccmode (insn, CCNOmode)
8171 && ix86_binary_operator_ok (AND, SImode, operands)"
8172 "and{l}\t{%2, %0|%0, %2}"
8173 [(set_attr "type" "alu")
8174 (set_attr "mode" "SI")])
8176 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8177 (define_insn "*andsi_2_zext"
8178 [(set (reg FLAGS_REG)
8179 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8180 (match_operand:SI 2 "general_operand" "rim"))
8182 (set (match_operand:DI 0 "register_operand" "=r")
8183 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8184 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8185 && ix86_binary_operator_ok (AND, SImode, operands)"
8186 "and{l}\t{%2, %k0|%k0, %2}"
8187 [(set_attr "type" "alu")
8188 (set_attr "mode" "SI")])
8190 (define_expand "andhi3"
8191 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8192 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8193 (match_operand:HI 2 "general_operand" "")))
8194 (clobber (reg:CC FLAGS_REG))]
8195 "TARGET_HIMODE_MATH"
8196 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8198 (define_insn "*andhi_1"
8199 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8200 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8201 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8202 (clobber (reg:CC FLAGS_REG))]
8203 "ix86_binary_operator_ok (AND, HImode, operands)"
8205 switch (get_attr_type (insn))
8208 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8209 gcc_assert (INTVAL (operands[2]) == 0xff);
8210 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8213 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8215 return "and{w}\t{%2, %0|%0, %2}";
8218 [(set_attr "type" "alu,alu,imovx")
8219 (set_attr "length_immediate" "*,*,0")
8220 (set_attr "mode" "HI,HI,SI")])
8222 (define_insn "*andhi_2"
8223 [(set (reg FLAGS_REG)
8224 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8225 (match_operand:HI 2 "general_operand" "rim,ri"))
8227 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8228 (and:HI (match_dup 1) (match_dup 2)))]
8229 "ix86_match_ccmode (insn, CCNOmode)
8230 && ix86_binary_operator_ok (AND, HImode, operands)"
8231 "and{w}\t{%2, %0|%0, %2}"
8232 [(set_attr "type" "alu")
8233 (set_attr "mode" "HI")])
8235 (define_expand "andqi3"
8236 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8237 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8238 (match_operand:QI 2 "general_operand" "")))
8239 (clobber (reg:CC FLAGS_REG))]
8240 "TARGET_QIMODE_MATH"
8241 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8243 ;; %%% Potential partial reg stall on alternative 2. What to do?
8244 (define_insn "*andqi_1"
8245 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8246 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8247 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8248 (clobber (reg:CC FLAGS_REG))]
8249 "ix86_binary_operator_ok (AND, QImode, operands)"
8251 and{b}\t{%2, %0|%0, %2}
8252 and{b}\t{%2, %0|%0, %2}
8253 and{l}\t{%k2, %k0|%k0, %k2}"
8254 [(set_attr "type" "alu")
8255 (set_attr "mode" "QI,QI,SI")])
8257 (define_insn "*andqi_1_slp"
8258 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8259 (and:QI (match_dup 0)
8260 (match_operand:QI 1 "general_operand" "qi,qmi")))
8261 (clobber (reg:CC FLAGS_REG))]
8262 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8263 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8264 "and{b}\t{%1, %0|%0, %1}"
8265 [(set_attr "type" "alu1")
8266 (set_attr "mode" "QI")])
8268 (define_insn "*andqi_2_maybe_si"
8269 [(set (reg FLAGS_REG)
8271 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8272 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8274 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8275 (and:QI (match_dup 1) (match_dup 2)))]
8276 "ix86_binary_operator_ok (AND, QImode, operands)
8277 && ix86_match_ccmode (insn,
8278 GET_CODE (operands[2]) == CONST_INT
8279 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8281 if (which_alternative == 2)
8283 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8284 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8285 return "and{l}\t{%2, %k0|%k0, %2}";
8287 return "and{b}\t{%2, %0|%0, %2}";
8289 [(set_attr "type" "alu")
8290 (set_attr "mode" "QI,QI,SI")])
8292 (define_insn "*andqi_2"
8293 [(set (reg FLAGS_REG)
8295 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8296 (match_operand:QI 2 "general_operand" "qim,qi"))
8298 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8299 (and:QI (match_dup 1) (match_dup 2)))]
8300 "ix86_match_ccmode (insn, CCNOmode)
8301 && ix86_binary_operator_ok (AND, QImode, operands)"
8302 "and{b}\t{%2, %0|%0, %2}"
8303 [(set_attr "type" "alu")
8304 (set_attr "mode" "QI")])
8306 (define_insn "*andqi_2_slp"
8307 [(set (reg FLAGS_REG)
8309 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8310 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8312 (set (strict_low_part (match_dup 0))
8313 (and:QI (match_dup 0) (match_dup 1)))]
8314 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8315 && ix86_match_ccmode (insn, CCNOmode)
8316 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8317 "and{b}\t{%1, %0|%0, %1}"
8318 [(set_attr "type" "alu1")
8319 (set_attr "mode" "QI")])
8321 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8322 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8323 ;; for a QImode operand, which of course failed.
8325 (define_insn "andqi_ext_0"
8326 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8331 (match_operand 1 "ext_register_operand" "0")
8334 (match_operand 2 "const_int_operand" "n")))
8335 (clobber (reg:CC FLAGS_REG))]
8337 "and{b}\t{%2, %h0|%h0, %2}"
8338 [(set_attr "type" "alu")
8339 (set_attr "length_immediate" "1")
8340 (set_attr "mode" "QI")])
8342 ;; Generated by peephole translating test to and. This shows up
8343 ;; often in fp comparisons.
8345 (define_insn "*andqi_ext_0_cc"
8346 [(set (reg FLAGS_REG)
8350 (match_operand 1 "ext_register_operand" "0")
8353 (match_operand 2 "const_int_operand" "n"))
8355 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8364 "ix86_match_ccmode (insn, CCNOmode)"
8365 "and{b}\t{%2, %h0|%h0, %2}"
8366 [(set_attr "type" "alu")
8367 (set_attr "length_immediate" "1")
8368 (set_attr "mode" "QI")])
8370 (define_insn "*andqi_ext_1"
8371 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8376 (match_operand 1 "ext_register_operand" "0")
8380 (match_operand:QI 2 "general_operand" "Qm"))))
8381 (clobber (reg:CC FLAGS_REG))]
8383 "and{b}\t{%2, %h0|%h0, %2}"
8384 [(set_attr "type" "alu")
8385 (set_attr "length_immediate" "0")
8386 (set_attr "mode" "QI")])
8388 (define_insn "*andqi_ext_1_rex64"
8389 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8394 (match_operand 1 "ext_register_operand" "0")
8398 (match_operand 2 "ext_register_operand" "Q"))))
8399 (clobber (reg:CC FLAGS_REG))]
8401 "and{b}\t{%2, %h0|%h0, %2}"
8402 [(set_attr "type" "alu")
8403 (set_attr "length_immediate" "0")
8404 (set_attr "mode" "QI")])
8406 (define_insn "*andqi_ext_2"
8407 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8412 (match_operand 1 "ext_register_operand" "%0")
8416 (match_operand 2 "ext_register_operand" "Q")
8419 (clobber (reg:CC FLAGS_REG))]
8421 "and{b}\t{%h2, %h0|%h0, %h2}"
8422 [(set_attr "type" "alu")
8423 (set_attr "length_immediate" "0")
8424 (set_attr "mode" "QI")])
8426 ;; Convert wide AND instructions with immediate operand to shorter QImode
8427 ;; equivalents when possible.
8428 ;; Don't do the splitting with memory operands, since it introduces risk
8429 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8430 ;; for size, but that can (should?) be handled by generic code instead.
8432 [(set (match_operand 0 "register_operand" "")
8433 (and (match_operand 1 "register_operand" "")
8434 (match_operand 2 "const_int_operand" "")))
8435 (clobber (reg:CC FLAGS_REG))]
8437 && QI_REG_P (operands[0])
8438 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8439 && !(~INTVAL (operands[2]) & ~(255 << 8))
8440 && GET_MODE (operands[0]) != QImode"
8441 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8442 (and:SI (zero_extract:SI (match_dup 1)
8443 (const_int 8) (const_int 8))
8445 (clobber (reg:CC FLAGS_REG))])]
8446 "operands[0] = gen_lowpart (SImode, operands[0]);
8447 operands[1] = gen_lowpart (SImode, operands[1]);
8448 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8450 ;; Since AND can be encoded with sign extended immediate, this is only
8451 ;; profitable when 7th bit is not set.
8453 [(set (match_operand 0 "register_operand" "")
8454 (and (match_operand 1 "general_operand" "")
8455 (match_operand 2 "const_int_operand" "")))
8456 (clobber (reg:CC FLAGS_REG))]
8458 && ANY_QI_REG_P (operands[0])
8459 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8460 && !(~INTVAL (operands[2]) & ~255)
8461 && !(INTVAL (operands[2]) & 128)
8462 && GET_MODE (operands[0]) != QImode"
8463 [(parallel [(set (strict_low_part (match_dup 0))
8464 (and:QI (match_dup 1)
8466 (clobber (reg:CC FLAGS_REG))])]
8467 "operands[0] = gen_lowpart (QImode, operands[0]);
8468 operands[1] = gen_lowpart (QImode, operands[1]);
8469 operands[2] = gen_lowpart (QImode, operands[2]);")
8471 ;; Logical inclusive OR instructions
8473 ;; %%% This used to optimize known byte-wide and operations to memory.
8474 ;; If this is considered useful, it should be done with splitters.
8476 (define_expand "iordi3"
8477 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8478 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8479 (match_operand:DI 2 "x86_64_general_operand" "")))
8480 (clobber (reg:CC FLAGS_REG))]
8482 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8484 (define_insn "*iordi_1_rex64"
8485 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8486 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8487 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8488 (clobber (reg:CC FLAGS_REG))]
8490 && ix86_binary_operator_ok (IOR, DImode, operands)"
8491 "or{q}\t{%2, %0|%0, %2}"
8492 [(set_attr "type" "alu")
8493 (set_attr "mode" "DI")])
8495 (define_insn "*iordi_2_rex64"
8496 [(set (reg FLAGS_REG)
8497 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8498 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8500 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8501 (ior:DI (match_dup 1) (match_dup 2)))]
8503 && ix86_match_ccmode (insn, CCNOmode)
8504 && ix86_binary_operator_ok (IOR, DImode, operands)"
8505 "or{q}\t{%2, %0|%0, %2}"
8506 [(set_attr "type" "alu")
8507 (set_attr "mode" "DI")])
8509 (define_insn "*iordi_3_rex64"
8510 [(set (reg FLAGS_REG)
8511 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8512 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8514 (clobber (match_scratch:DI 0 "=r"))]
8516 && ix86_match_ccmode (insn, CCNOmode)
8517 && ix86_binary_operator_ok (IOR, DImode, operands)"
8518 "or{q}\t{%2, %0|%0, %2}"
8519 [(set_attr "type" "alu")
8520 (set_attr "mode" "DI")])
8523 (define_expand "iorsi3"
8524 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8525 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8526 (match_operand:SI 2 "general_operand" "")))
8527 (clobber (reg:CC FLAGS_REG))]
8529 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8531 (define_insn "*iorsi_1"
8532 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8533 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8534 (match_operand:SI 2 "general_operand" "ri,rmi")))
8535 (clobber (reg:CC FLAGS_REG))]
8536 "ix86_binary_operator_ok (IOR, SImode, operands)"
8537 "or{l}\t{%2, %0|%0, %2}"
8538 [(set_attr "type" "alu")
8539 (set_attr "mode" "SI")])
8541 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8542 (define_insn "*iorsi_1_zext"
8543 [(set (match_operand:DI 0 "register_operand" "=rm")
8545 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8546 (match_operand:SI 2 "general_operand" "rim"))))
8547 (clobber (reg:CC FLAGS_REG))]
8548 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8549 "or{l}\t{%2, %k0|%k0, %2}"
8550 [(set_attr "type" "alu")
8551 (set_attr "mode" "SI")])
8553 (define_insn "*iorsi_1_zext_imm"
8554 [(set (match_operand:DI 0 "register_operand" "=rm")
8555 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8556 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8557 (clobber (reg:CC FLAGS_REG))]
8559 "or{l}\t{%2, %k0|%k0, %2}"
8560 [(set_attr "type" "alu")
8561 (set_attr "mode" "SI")])
8563 (define_insn "*iorsi_2"
8564 [(set (reg FLAGS_REG)
8565 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8566 (match_operand:SI 2 "general_operand" "rim,ri"))
8568 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8569 (ior:SI (match_dup 1) (match_dup 2)))]
8570 "ix86_match_ccmode (insn, CCNOmode)
8571 && ix86_binary_operator_ok (IOR, SImode, operands)"
8572 "or{l}\t{%2, %0|%0, %2}"
8573 [(set_attr "type" "alu")
8574 (set_attr "mode" "SI")])
8576 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8577 ;; ??? Special case for immediate operand is missing - it is tricky.
8578 (define_insn "*iorsi_2_zext"
8579 [(set (reg FLAGS_REG)
8580 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8581 (match_operand:SI 2 "general_operand" "rim"))
8583 (set (match_operand:DI 0 "register_operand" "=r")
8584 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8585 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8586 && ix86_binary_operator_ok (IOR, SImode, operands)"
8587 "or{l}\t{%2, %k0|%k0, %2}"
8588 [(set_attr "type" "alu")
8589 (set_attr "mode" "SI")])
8591 (define_insn "*iorsi_2_zext_imm"
8592 [(set (reg FLAGS_REG)
8593 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8594 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8596 (set (match_operand:DI 0 "register_operand" "=r")
8597 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8598 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8599 && ix86_binary_operator_ok (IOR, SImode, operands)"
8600 "or{l}\t{%2, %k0|%k0, %2}"
8601 [(set_attr "type" "alu")
8602 (set_attr "mode" "SI")])
8604 (define_insn "*iorsi_3"
8605 [(set (reg FLAGS_REG)
8606 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8607 (match_operand:SI 2 "general_operand" "rim"))
8609 (clobber (match_scratch:SI 0 "=r"))]
8610 "ix86_match_ccmode (insn, CCNOmode)
8611 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8612 "or{l}\t{%2, %0|%0, %2}"
8613 [(set_attr "type" "alu")
8614 (set_attr "mode" "SI")])
8616 (define_expand "iorhi3"
8617 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8618 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8619 (match_operand:HI 2 "general_operand" "")))
8620 (clobber (reg:CC FLAGS_REG))]
8621 "TARGET_HIMODE_MATH"
8622 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8624 (define_insn "*iorhi_1"
8625 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8626 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8627 (match_operand:HI 2 "general_operand" "rmi,ri")))
8628 (clobber (reg:CC FLAGS_REG))]
8629 "ix86_binary_operator_ok (IOR, HImode, operands)"
8630 "or{w}\t{%2, %0|%0, %2}"
8631 [(set_attr "type" "alu")
8632 (set_attr "mode" "HI")])
8634 (define_insn "*iorhi_2"
8635 [(set (reg FLAGS_REG)
8636 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8637 (match_operand:HI 2 "general_operand" "rim,ri"))
8639 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8640 (ior:HI (match_dup 1) (match_dup 2)))]
8641 "ix86_match_ccmode (insn, CCNOmode)
8642 && ix86_binary_operator_ok (IOR, HImode, operands)"
8643 "or{w}\t{%2, %0|%0, %2}"
8644 [(set_attr "type" "alu")
8645 (set_attr "mode" "HI")])
8647 (define_insn "*iorhi_3"
8648 [(set (reg FLAGS_REG)
8649 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8650 (match_operand:HI 2 "general_operand" "rim"))
8652 (clobber (match_scratch:HI 0 "=r"))]
8653 "ix86_match_ccmode (insn, CCNOmode)
8654 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8655 "or{w}\t{%2, %0|%0, %2}"
8656 [(set_attr "type" "alu")
8657 (set_attr "mode" "HI")])
8659 (define_expand "iorqi3"
8660 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8661 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8662 (match_operand:QI 2 "general_operand" "")))
8663 (clobber (reg:CC FLAGS_REG))]
8664 "TARGET_QIMODE_MATH"
8665 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8667 ;; %%% Potential partial reg stall on alternative 2. What to do?
8668 (define_insn "*iorqi_1"
8669 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8670 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8671 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8672 (clobber (reg:CC FLAGS_REG))]
8673 "ix86_binary_operator_ok (IOR, QImode, operands)"
8675 or{b}\t{%2, %0|%0, %2}
8676 or{b}\t{%2, %0|%0, %2}
8677 or{l}\t{%k2, %k0|%k0, %k2}"
8678 [(set_attr "type" "alu")
8679 (set_attr "mode" "QI,QI,SI")])
8681 (define_insn "*iorqi_1_slp"
8682 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8683 (ior:QI (match_dup 0)
8684 (match_operand:QI 1 "general_operand" "qmi,qi")))
8685 (clobber (reg:CC FLAGS_REG))]
8686 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8687 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8688 "or{b}\t{%1, %0|%0, %1}"
8689 [(set_attr "type" "alu1")
8690 (set_attr "mode" "QI")])
8692 (define_insn "*iorqi_2"
8693 [(set (reg FLAGS_REG)
8694 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8695 (match_operand:QI 2 "general_operand" "qim,qi"))
8697 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8698 (ior:QI (match_dup 1) (match_dup 2)))]
8699 "ix86_match_ccmode (insn, CCNOmode)
8700 && ix86_binary_operator_ok (IOR, QImode, operands)"
8701 "or{b}\t{%2, %0|%0, %2}"
8702 [(set_attr "type" "alu")
8703 (set_attr "mode" "QI")])
8705 (define_insn "*iorqi_2_slp"
8706 [(set (reg FLAGS_REG)
8707 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8708 (match_operand:QI 1 "general_operand" "qim,qi"))
8710 (set (strict_low_part (match_dup 0))
8711 (ior:QI (match_dup 0) (match_dup 1)))]
8712 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8713 && ix86_match_ccmode (insn, CCNOmode)
8714 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8715 "or{b}\t{%1, %0|%0, %1}"
8716 [(set_attr "type" "alu1")
8717 (set_attr "mode" "QI")])
8719 (define_insn "*iorqi_3"
8720 [(set (reg FLAGS_REG)
8721 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8722 (match_operand:QI 2 "general_operand" "qim"))
8724 (clobber (match_scratch:QI 0 "=q"))]
8725 "ix86_match_ccmode (insn, CCNOmode)
8726 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8727 "or{b}\t{%2, %0|%0, %2}"
8728 [(set_attr "type" "alu")
8729 (set_attr "mode" "QI")])
8731 (define_insn "iorqi_ext_0"
8732 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8737 (match_operand 1 "ext_register_operand" "0")
8740 (match_operand 2 "const_int_operand" "n")))
8741 (clobber (reg:CC FLAGS_REG))]
8742 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8743 "or{b}\t{%2, %h0|%h0, %2}"
8744 [(set_attr "type" "alu")
8745 (set_attr "length_immediate" "1")
8746 (set_attr "mode" "QI")])
8748 (define_insn "*iorqi_ext_1"
8749 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8754 (match_operand 1 "ext_register_operand" "0")
8758 (match_operand:QI 2 "general_operand" "Qm"))))
8759 (clobber (reg:CC FLAGS_REG))]
8761 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8762 "or{b}\t{%2, %h0|%h0, %2}"
8763 [(set_attr "type" "alu")
8764 (set_attr "length_immediate" "0")
8765 (set_attr "mode" "QI")])
8767 (define_insn "*iorqi_ext_1_rex64"
8768 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8773 (match_operand 1 "ext_register_operand" "0")
8777 (match_operand 2 "ext_register_operand" "Q"))))
8778 (clobber (reg:CC FLAGS_REG))]
8780 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8781 "or{b}\t{%2, %h0|%h0, %2}"
8782 [(set_attr "type" "alu")
8783 (set_attr "length_immediate" "0")
8784 (set_attr "mode" "QI")])
8786 (define_insn "*iorqi_ext_2"
8787 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8791 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8794 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8797 (clobber (reg:CC FLAGS_REG))]
8798 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8799 "ior{b}\t{%h2, %h0|%h0, %h2}"
8800 [(set_attr "type" "alu")
8801 (set_attr "length_immediate" "0")
8802 (set_attr "mode" "QI")])
8805 [(set (match_operand 0 "register_operand" "")
8806 (ior (match_operand 1 "register_operand" "")
8807 (match_operand 2 "const_int_operand" "")))
8808 (clobber (reg:CC FLAGS_REG))]
8810 && QI_REG_P (operands[0])
8811 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8812 && !(INTVAL (operands[2]) & ~(255 << 8))
8813 && GET_MODE (operands[0]) != QImode"
8814 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8815 (ior:SI (zero_extract:SI (match_dup 1)
8816 (const_int 8) (const_int 8))
8818 (clobber (reg:CC FLAGS_REG))])]
8819 "operands[0] = gen_lowpart (SImode, operands[0]);
8820 operands[1] = gen_lowpart (SImode, operands[1]);
8821 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8823 ;; Since OR can be encoded with sign extended immediate, this is only
8824 ;; profitable when 7th bit is set.
8826 [(set (match_operand 0 "register_operand" "")
8827 (ior (match_operand 1 "general_operand" "")
8828 (match_operand 2 "const_int_operand" "")))
8829 (clobber (reg:CC FLAGS_REG))]
8831 && ANY_QI_REG_P (operands[0])
8832 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8833 && !(INTVAL (operands[2]) & ~255)
8834 && (INTVAL (operands[2]) & 128)
8835 && GET_MODE (operands[0]) != QImode"
8836 [(parallel [(set (strict_low_part (match_dup 0))
8837 (ior:QI (match_dup 1)
8839 (clobber (reg:CC FLAGS_REG))])]
8840 "operands[0] = gen_lowpart (QImode, operands[0]);
8841 operands[1] = gen_lowpart (QImode, operands[1]);
8842 operands[2] = gen_lowpart (QImode, operands[2]);")
8844 ;; Logical XOR instructions
8846 ;; %%% This used to optimize known byte-wide and operations to memory.
8847 ;; If this is considered useful, it should be done with splitters.
8849 (define_expand "xordi3"
8850 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8851 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8852 (match_operand:DI 2 "x86_64_general_operand" "")))
8853 (clobber (reg:CC FLAGS_REG))]
8855 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8857 (define_insn "*xordi_1_rex64"
8858 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8859 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8860 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8861 (clobber (reg:CC FLAGS_REG))]
8863 && ix86_binary_operator_ok (XOR, DImode, operands)"
8865 xor{q}\t{%2, %0|%0, %2}
8866 xor{q}\t{%2, %0|%0, %2}"
8867 [(set_attr "type" "alu")
8868 (set_attr "mode" "DI,DI")])
8870 (define_insn "*xordi_2_rex64"
8871 [(set (reg FLAGS_REG)
8872 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8873 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8875 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8876 (xor:DI (match_dup 1) (match_dup 2)))]
8878 && ix86_match_ccmode (insn, CCNOmode)
8879 && ix86_binary_operator_ok (XOR, DImode, operands)"
8881 xor{q}\t{%2, %0|%0, %2}
8882 xor{q}\t{%2, %0|%0, %2}"
8883 [(set_attr "type" "alu")
8884 (set_attr "mode" "DI,DI")])
8886 (define_insn "*xordi_3_rex64"
8887 [(set (reg FLAGS_REG)
8888 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8889 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8891 (clobber (match_scratch:DI 0 "=r"))]
8893 && ix86_match_ccmode (insn, CCNOmode)
8894 && ix86_binary_operator_ok (XOR, DImode, operands)"
8895 "xor{q}\t{%2, %0|%0, %2}"
8896 [(set_attr "type" "alu")
8897 (set_attr "mode" "DI")])
8899 (define_expand "xorsi3"
8900 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8901 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8902 (match_operand:SI 2 "general_operand" "")))
8903 (clobber (reg:CC FLAGS_REG))]
8905 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8907 (define_insn "*xorsi_1"
8908 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8909 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8910 (match_operand:SI 2 "general_operand" "ri,rm")))
8911 (clobber (reg:CC FLAGS_REG))]
8912 "ix86_binary_operator_ok (XOR, SImode, operands)"
8913 "xor{l}\t{%2, %0|%0, %2}"
8914 [(set_attr "type" "alu")
8915 (set_attr "mode" "SI")])
8917 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8918 ;; Add speccase for immediates
8919 (define_insn "*xorsi_1_zext"
8920 [(set (match_operand:DI 0 "register_operand" "=r")
8922 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8923 (match_operand:SI 2 "general_operand" "rim"))))
8924 (clobber (reg:CC FLAGS_REG))]
8925 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8926 "xor{l}\t{%2, %k0|%k0, %2}"
8927 [(set_attr "type" "alu")
8928 (set_attr "mode" "SI")])
8930 (define_insn "*xorsi_1_zext_imm"
8931 [(set (match_operand:DI 0 "register_operand" "=r")
8932 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8933 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8934 (clobber (reg:CC FLAGS_REG))]
8935 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8936 "xor{l}\t{%2, %k0|%k0, %2}"
8937 [(set_attr "type" "alu")
8938 (set_attr "mode" "SI")])
8940 (define_insn "*xorsi_2"
8941 [(set (reg FLAGS_REG)
8942 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8943 (match_operand:SI 2 "general_operand" "rim,ri"))
8945 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8946 (xor:SI (match_dup 1) (match_dup 2)))]
8947 "ix86_match_ccmode (insn, CCNOmode)
8948 && ix86_binary_operator_ok (XOR, SImode, operands)"
8949 "xor{l}\t{%2, %0|%0, %2}"
8950 [(set_attr "type" "alu")
8951 (set_attr "mode" "SI")])
8953 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8954 ;; ??? Special case for immediate operand is missing - it is tricky.
8955 (define_insn "*xorsi_2_zext"
8956 [(set (reg FLAGS_REG)
8957 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8958 (match_operand:SI 2 "general_operand" "rim"))
8960 (set (match_operand:DI 0 "register_operand" "=r")
8961 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8962 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8963 && ix86_binary_operator_ok (XOR, SImode, operands)"
8964 "xor{l}\t{%2, %k0|%k0, %2}"
8965 [(set_attr "type" "alu")
8966 (set_attr "mode" "SI")])
8968 (define_insn "*xorsi_2_zext_imm"
8969 [(set (reg FLAGS_REG)
8970 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8971 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8973 (set (match_operand:DI 0 "register_operand" "=r")
8974 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8975 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8976 && ix86_binary_operator_ok (XOR, SImode, operands)"
8977 "xor{l}\t{%2, %k0|%k0, %2}"
8978 [(set_attr "type" "alu")
8979 (set_attr "mode" "SI")])
8981 (define_insn "*xorsi_3"
8982 [(set (reg FLAGS_REG)
8983 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8984 (match_operand:SI 2 "general_operand" "rim"))
8986 (clobber (match_scratch:SI 0 "=r"))]
8987 "ix86_match_ccmode (insn, CCNOmode)
8988 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8989 "xor{l}\t{%2, %0|%0, %2}"
8990 [(set_attr "type" "alu")
8991 (set_attr "mode" "SI")])
8993 (define_expand "xorhi3"
8994 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8995 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8996 (match_operand:HI 2 "general_operand" "")))
8997 (clobber (reg:CC FLAGS_REG))]
8998 "TARGET_HIMODE_MATH"
8999 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9001 (define_insn "*xorhi_1"
9002 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9003 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9004 (match_operand:HI 2 "general_operand" "rmi,ri")))
9005 (clobber (reg:CC FLAGS_REG))]
9006 "ix86_binary_operator_ok (XOR, HImode, operands)"
9007 "xor{w}\t{%2, %0|%0, %2}"
9008 [(set_attr "type" "alu")
9009 (set_attr "mode" "HI")])
9011 (define_insn "*xorhi_2"
9012 [(set (reg FLAGS_REG)
9013 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9014 (match_operand:HI 2 "general_operand" "rim,ri"))
9016 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9017 (xor:HI (match_dup 1) (match_dup 2)))]
9018 "ix86_match_ccmode (insn, CCNOmode)
9019 && ix86_binary_operator_ok (XOR, HImode, operands)"
9020 "xor{w}\t{%2, %0|%0, %2}"
9021 [(set_attr "type" "alu")
9022 (set_attr "mode" "HI")])
9024 (define_insn "*xorhi_3"
9025 [(set (reg FLAGS_REG)
9026 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9027 (match_operand:HI 2 "general_operand" "rim"))
9029 (clobber (match_scratch:HI 0 "=r"))]
9030 "ix86_match_ccmode (insn, CCNOmode)
9031 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9032 "xor{w}\t{%2, %0|%0, %2}"
9033 [(set_attr "type" "alu")
9034 (set_attr "mode" "HI")])
9036 (define_expand "xorqi3"
9037 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9038 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9039 (match_operand:QI 2 "general_operand" "")))
9040 (clobber (reg:CC FLAGS_REG))]
9041 "TARGET_QIMODE_MATH"
9042 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9044 ;; %%% Potential partial reg stall on alternative 2. What to do?
9045 (define_insn "*xorqi_1"
9046 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9047 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9048 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9049 (clobber (reg:CC FLAGS_REG))]
9050 "ix86_binary_operator_ok (XOR, QImode, operands)"
9052 xor{b}\t{%2, %0|%0, %2}
9053 xor{b}\t{%2, %0|%0, %2}
9054 xor{l}\t{%k2, %k0|%k0, %k2}"
9055 [(set_attr "type" "alu")
9056 (set_attr "mode" "QI,QI,SI")])
9058 (define_insn "*xorqi_1_slp"
9059 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9060 (xor:QI (match_dup 0)
9061 (match_operand:QI 1 "general_operand" "qi,qmi")))
9062 (clobber (reg:CC FLAGS_REG))]
9063 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9064 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9065 "xor{b}\t{%1, %0|%0, %1}"
9066 [(set_attr "type" "alu1")
9067 (set_attr "mode" "QI")])
9069 (define_insn "xorqi_ext_0"
9070 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9075 (match_operand 1 "ext_register_operand" "0")
9078 (match_operand 2 "const_int_operand" "n")))
9079 (clobber (reg:CC FLAGS_REG))]
9080 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9081 "xor{b}\t{%2, %h0|%h0, %2}"
9082 [(set_attr "type" "alu")
9083 (set_attr "length_immediate" "1")
9084 (set_attr "mode" "QI")])
9086 (define_insn "*xorqi_ext_1"
9087 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9092 (match_operand 1 "ext_register_operand" "0")
9096 (match_operand:QI 2 "general_operand" "Qm"))))
9097 (clobber (reg:CC FLAGS_REG))]
9099 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9100 "xor{b}\t{%2, %h0|%h0, %2}"
9101 [(set_attr "type" "alu")
9102 (set_attr "length_immediate" "0")
9103 (set_attr "mode" "QI")])
9105 (define_insn "*xorqi_ext_1_rex64"
9106 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9111 (match_operand 1 "ext_register_operand" "0")
9115 (match_operand 2 "ext_register_operand" "Q"))))
9116 (clobber (reg:CC FLAGS_REG))]
9118 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9119 "xor{b}\t{%2, %h0|%h0, %2}"
9120 [(set_attr "type" "alu")
9121 (set_attr "length_immediate" "0")
9122 (set_attr "mode" "QI")])
9124 (define_insn "*xorqi_ext_2"
9125 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9129 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9132 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9135 (clobber (reg:CC FLAGS_REG))]
9136 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9137 "xor{b}\t{%h2, %h0|%h0, %h2}"
9138 [(set_attr "type" "alu")
9139 (set_attr "length_immediate" "0")
9140 (set_attr "mode" "QI")])
9142 (define_insn "*xorqi_cc_1"
9143 [(set (reg FLAGS_REG)
9145 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9146 (match_operand:QI 2 "general_operand" "qim,qi"))
9148 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9149 (xor:QI (match_dup 1) (match_dup 2)))]
9150 "ix86_match_ccmode (insn, CCNOmode)
9151 && ix86_binary_operator_ok (XOR, QImode, operands)"
9152 "xor{b}\t{%2, %0|%0, %2}"
9153 [(set_attr "type" "alu")
9154 (set_attr "mode" "QI")])
9156 (define_insn "*xorqi_2_slp"
9157 [(set (reg FLAGS_REG)
9158 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9159 (match_operand:QI 1 "general_operand" "qim,qi"))
9161 (set (strict_low_part (match_dup 0))
9162 (xor:QI (match_dup 0) (match_dup 1)))]
9163 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9164 && ix86_match_ccmode (insn, CCNOmode)
9165 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9166 "xor{b}\t{%1, %0|%0, %1}"
9167 [(set_attr "type" "alu1")
9168 (set_attr "mode" "QI")])
9170 (define_insn "*xorqi_cc_2"
9171 [(set (reg FLAGS_REG)
9173 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9174 (match_operand:QI 2 "general_operand" "qim"))
9176 (clobber (match_scratch:QI 0 "=q"))]
9177 "ix86_match_ccmode (insn, CCNOmode)
9178 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9179 "xor{b}\t{%2, %0|%0, %2}"
9180 [(set_attr "type" "alu")
9181 (set_attr "mode" "QI")])
9183 (define_insn "*xorqi_cc_ext_1"
9184 [(set (reg FLAGS_REG)
9188 (match_operand 1 "ext_register_operand" "0")
9191 (match_operand:QI 2 "general_operand" "qmn"))
9193 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9197 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9199 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9200 "xor{b}\t{%2, %h0|%h0, %2}"
9201 [(set_attr "type" "alu")
9202 (set_attr "mode" "QI")])
9204 (define_insn "*xorqi_cc_ext_1_rex64"
9205 [(set (reg FLAGS_REG)
9209 (match_operand 1 "ext_register_operand" "0")
9212 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9214 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9218 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9220 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9221 "xor{b}\t{%2, %h0|%h0, %2}"
9222 [(set_attr "type" "alu")
9223 (set_attr "mode" "QI")])
9225 (define_expand "xorqi_cc_ext_1"
9227 (set (reg:CCNO FLAGS_REG)
9231 (match_operand 1 "ext_register_operand" "")
9234 (match_operand:QI 2 "general_operand" ""))
9236 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9240 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9246 [(set (match_operand 0 "register_operand" "")
9247 (xor (match_operand 1 "register_operand" "")
9248 (match_operand 2 "const_int_operand" "")))
9249 (clobber (reg:CC FLAGS_REG))]
9251 && QI_REG_P (operands[0])
9252 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9253 && !(INTVAL (operands[2]) & ~(255 << 8))
9254 && GET_MODE (operands[0]) != QImode"
9255 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9256 (xor:SI (zero_extract:SI (match_dup 1)
9257 (const_int 8) (const_int 8))
9259 (clobber (reg:CC FLAGS_REG))])]
9260 "operands[0] = gen_lowpart (SImode, operands[0]);
9261 operands[1] = gen_lowpart (SImode, operands[1]);
9262 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9264 ;; Since XOR can be encoded with sign extended immediate, this is only
9265 ;; profitable when 7th bit is set.
9267 [(set (match_operand 0 "register_operand" "")
9268 (xor (match_operand 1 "general_operand" "")
9269 (match_operand 2 "const_int_operand" "")))
9270 (clobber (reg:CC FLAGS_REG))]
9272 && ANY_QI_REG_P (operands[0])
9273 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9274 && !(INTVAL (operands[2]) & ~255)
9275 && (INTVAL (operands[2]) & 128)
9276 && GET_MODE (operands[0]) != QImode"
9277 [(parallel [(set (strict_low_part (match_dup 0))
9278 (xor:QI (match_dup 1)
9280 (clobber (reg:CC FLAGS_REG))])]
9281 "operands[0] = gen_lowpart (QImode, operands[0]);
9282 operands[1] = gen_lowpart (QImode, operands[1]);
9283 operands[2] = gen_lowpart (QImode, operands[2]);")
9285 ;; Negation instructions
9287 (define_expand "negti2"
9288 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9289 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9290 (clobber (reg:CC FLAGS_REG))])]
9292 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9294 (define_insn "*negti2_1"
9295 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9296 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9297 (clobber (reg:CC FLAGS_REG))]
9299 && ix86_unary_operator_ok (NEG, TImode, operands)"
9303 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9304 (neg:TI (match_operand:TI 1 "general_operand" "")))
9305 (clobber (reg:CC FLAGS_REG))]
9306 "TARGET_64BIT && reload_completed"
9308 [(set (reg:CCZ FLAGS_REG)
9309 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9310 (set (match_dup 0) (neg:DI (match_dup 2)))])
9313 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9316 (clobber (reg:CC FLAGS_REG))])
9319 (neg:DI (match_dup 1)))
9320 (clobber (reg:CC FLAGS_REG))])]
9321 "split_ti (operands+1, 1, operands+2, operands+3);
9322 split_ti (operands+0, 1, operands+0, operands+1);")
9324 (define_expand "negdi2"
9325 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9326 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9327 (clobber (reg:CC FLAGS_REG))])]
9329 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9331 (define_insn "*negdi2_1"
9332 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9333 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9334 (clobber (reg:CC FLAGS_REG))]
9336 && ix86_unary_operator_ok (NEG, DImode, operands)"
9340 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9341 (neg:DI (match_operand:DI 1 "general_operand" "")))
9342 (clobber (reg:CC FLAGS_REG))]
9343 "!TARGET_64BIT && reload_completed"
9345 [(set (reg:CCZ FLAGS_REG)
9346 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9347 (set (match_dup 0) (neg:SI (match_dup 2)))])
9350 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9353 (clobber (reg:CC FLAGS_REG))])
9356 (neg:SI (match_dup 1)))
9357 (clobber (reg:CC FLAGS_REG))])]
9358 "split_di (operands+1, 1, operands+2, operands+3);
9359 split_di (operands+0, 1, operands+0, operands+1);")
9361 (define_insn "*negdi2_1_rex64"
9362 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9363 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9364 (clobber (reg:CC FLAGS_REG))]
9365 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9367 [(set_attr "type" "negnot")
9368 (set_attr "mode" "DI")])
9370 ;; The problem with neg is that it does not perform (compare x 0),
9371 ;; it really performs (compare 0 x), which leaves us with the zero
9372 ;; flag being the only useful item.
9374 (define_insn "*negdi2_cmpz_rex64"
9375 [(set (reg:CCZ FLAGS_REG)
9376 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9378 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9379 (neg:DI (match_dup 1)))]
9380 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9382 [(set_attr "type" "negnot")
9383 (set_attr "mode" "DI")])
9386 (define_expand "negsi2"
9387 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9388 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9389 (clobber (reg:CC FLAGS_REG))])]
9391 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9393 (define_insn "*negsi2_1"
9394 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9395 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9396 (clobber (reg:CC FLAGS_REG))]
9397 "ix86_unary_operator_ok (NEG, SImode, operands)"
9399 [(set_attr "type" "negnot")
9400 (set_attr "mode" "SI")])
9402 ;; Combine is quite creative about this pattern.
9403 (define_insn "*negsi2_1_zext"
9404 [(set (match_operand:DI 0 "register_operand" "=r")
9405 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9408 (clobber (reg:CC FLAGS_REG))]
9409 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9411 [(set_attr "type" "negnot")
9412 (set_attr "mode" "SI")])
9414 ;; The problem with neg is that it does not perform (compare x 0),
9415 ;; it really performs (compare 0 x), which leaves us with the zero
9416 ;; flag being the only useful item.
9418 (define_insn "*negsi2_cmpz"
9419 [(set (reg:CCZ FLAGS_REG)
9420 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9422 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9423 (neg:SI (match_dup 1)))]
9424 "ix86_unary_operator_ok (NEG, SImode, operands)"
9426 [(set_attr "type" "negnot")
9427 (set_attr "mode" "SI")])
9429 (define_insn "*negsi2_cmpz_zext"
9430 [(set (reg:CCZ FLAGS_REG)
9431 (compare:CCZ (lshiftrt:DI
9433 (match_operand:DI 1 "register_operand" "0")
9437 (set (match_operand:DI 0 "register_operand" "=r")
9438 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9441 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9443 [(set_attr "type" "negnot")
9444 (set_attr "mode" "SI")])
9446 (define_expand "neghi2"
9447 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9448 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9449 (clobber (reg:CC FLAGS_REG))])]
9450 "TARGET_HIMODE_MATH"
9451 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9453 (define_insn "*neghi2_1"
9454 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9455 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9456 (clobber (reg:CC FLAGS_REG))]
9457 "ix86_unary_operator_ok (NEG, HImode, operands)"
9459 [(set_attr "type" "negnot")
9460 (set_attr "mode" "HI")])
9462 (define_insn "*neghi2_cmpz"
9463 [(set (reg:CCZ FLAGS_REG)
9464 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9466 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9467 (neg:HI (match_dup 1)))]
9468 "ix86_unary_operator_ok (NEG, HImode, operands)"
9470 [(set_attr "type" "negnot")
9471 (set_attr "mode" "HI")])
9473 (define_expand "negqi2"
9474 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9475 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9476 (clobber (reg:CC FLAGS_REG))])]
9477 "TARGET_QIMODE_MATH"
9478 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9480 (define_insn "*negqi2_1"
9481 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9482 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9483 (clobber (reg:CC FLAGS_REG))]
9484 "ix86_unary_operator_ok (NEG, QImode, operands)"
9486 [(set_attr "type" "negnot")
9487 (set_attr "mode" "QI")])
9489 (define_insn "*negqi2_cmpz"
9490 [(set (reg:CCZ FLAGS_REG)
9491 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9493 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9494 (neg:QI (match_dup 1)))]
9495 "ix86_unary_operator_ok (NEG, QImode, operands)"
9497 [(set_attr "type" "negnot")
9498 (set_attr "mode" "QI")])
9500 ;; Changing of sign for FP values is doable using integer unit too.
9502 (define_expand "negsf2"
9503 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9504 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9505 "TARGET_80387 || TARGET_SSE_MATH"
9506 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9508 (define_expand "abssf2"
9509 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9510 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9511 "TARGET_80387 || TARGET_SSE_MATH"
9512 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9514 (define_insn "*absnegsf2_mixed"
9515 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#f,x#f,f#x,rm")
9516 (match_operator:SF 3 "absneg_operator"
9517 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#f,0 ,0")]))
9518 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9519 (clobber (reg:CC FLAGS_REG))]
9520 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9521 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9524 (define_insn "*absnegsf2_sse"
9525 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9526 (match_operator:SF 3 "absneg_operator"
9527 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9528 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9529 (clobber (reg:CC FLAGS_REG))]
9531 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9534 (define_insn "*absnegsf2_i387"
9535 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9536 (match_operator:SF 3 "absneg_operator"
9537 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9538 (use (match_operand 2 "" ""))
9539 (clobber (reg:CC FLAGS_REG))]
9540 "TARGET_80387 && !TARGET_SSE_MATH
9541 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9544 (define_expand "copysignsf3"
9545 [(match_operand:SF 0 "register_operand" "")
9546 (match_operand:SF 1 "nonmemory_operand" "")
9547 (match_operand:SF 2 "register_operand" "")]
9550 ix86_expand_copysign (operands);
9554 (define_insn_and_split "copysignsf3_const"
9555 [(set (match_operand:SF 0 "register_operand" "=x")
9557 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9558 (match_operand:SF 2 "register_operand" "0")
9559 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9563 "&& reload_completed"
9566 ix86_split_copysign_const (operands);
9570 (define_insn "copysignsf3_var"
9571 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9573 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9574 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9575 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9576 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9578 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9583 [(set (match_operand:SF 0 "register_operand" "")
9585 [(match_operand:SF 2 "register_operand" "")
9586 (match_operand:SF 3 "register_operand" "")
9587 (match_operand:V4SF 4 "" "")
9588 (match_operand:V4SF 5 "" "")]
9590 (clobber (match_scratch:V4SF 1 ""))]
9591 "TARGET_SSE_MATH && reload_completed"
9594 ix86_split_copysign_var (operands);
9598 (define_expand "negdf2"
9599 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9600 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9601 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9602 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9604 (define_expand "absdf2"
9605 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9606 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9607 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9608 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9610 (define_insn "*absnegdf2_mixed"
9611 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,f#Y,rm")
9612 (match_operator:DF 3 "absneg_operator"
9613 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#f,0 ,0")]))
9614 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9615 (clobber (reg:CC FLAGS_REG))]
9616 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9617 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9620 (define_insn "*absnegdf2_sse"
9621 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9622 (match_operator:DF 3 "absneg_operator"
9623 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9624 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X"))
9625 (clobber (reg:CC FLAGS_REG))]
9626 "TARGET_SSE2 && TARGET_SSE_MATH
9627 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9630 (define_insn "*absnegdf2_i387"
9631 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9632 (match_operator:DF 3 "absneg_operator"
9633 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9634 (use (match_operand 2 "" ""))
9635 (clobber (reg:CC FLAGS_REG))]
9636 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9637 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9640 (define_expand "copysigndf3"
9641 [(match_operand:DF 0 "register_operand" "")
9642 (match_operand:DF 1 "nonmemory_operand" "")
9643 (match_operand:DF 2 "register_operand" "")]
9644 "TARGET_SSE2 && TARGET_SSE_MATH"
9646 ix86_expand_copysign (operands);
9650 (define_insn_and_split "copysigndf3_const"
9651 [(set (match_operand:DF 0 "register_operand" "=x")
9653 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9654 (match_operand:DF 2 "register_operand" "0")
9655 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9657 "TARGET_SSE2 && TARGET_SSE_MATH"
9659 "&& reload_completed"
9662 ix86_split_copysign_const (operands);
9666 (define_insn "copysigndf3_var"
9667 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9669 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9670 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9671 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9672 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9674 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9675 "TARGET_SSE2 && TARGET_SSE_MATH"
9679 [(set (match_operand:DF 0 "register_operand" "")
9681 [(match_operand:DF 2 "register_operand" "")
9682 (match_operand:DF 3 "register_operand" "")
9683 (match_operand:V2DF 4 "" "")
9684 (match_operand:V2DF 5 "" "")]
9686 (clobber (match_scratch:V2DF 1 ""))]
9687 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9690 ix86_split_copysign_var (operands);
9694 (define_expand "negxf2"
9695 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9696 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9698 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9700 (define_expand "absxf2"
9701 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9702 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9704 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9706 (define_insn "*absnegxf2_i387"
9707 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9708 (match_operator:XF 3 "absneg_operator"
9709 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9710 (use (match_operand 2 "" ""))
9711 (clobber (reg:CC FLAGS_REG))]
9713 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9716 ;; Splitters for fp abs and neg.
9719 [(set (match_operand 0 "fp_register_operand" "")
9720 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9721 (use (match_operand 2 "" ""))
9722 (clobber (reg:CC FLAGS_REG))]
9724 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9727 [(set (match_operand 0 "register_operand" "")
9728 (match_operator 3 "absneg_operator"
9729 [(match_operand 1 "register_operand" "")]))
9730 (use (match_operand 2 "nonimmediate_operand" ""))
9731 (clobber (reg:CC FLAGS_REG))]
9732 "reload_completed && SSE_REG_P (operands[0])"
9733 [(set (match_dup 0) (match_dup 3))]
9735 enum machine_mode mode = GET_MODE (operands[0]);
9736 enum machine_mode vmode = GET_MODE (operands[2]);
9739 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9740 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9741 if (operands_match_p (operands[0], operands[2]))
9744 operands[1] = operands[2];
9747 if (GET_CODE (operands[3]) == ABS)
9748 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9750 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9755 [(set (match_operand:SF 0 "register_operand" "")
9756 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9757 (use (match_operand:V4SF 2 "" ""))
9758 (clobber (reg:CC FLAGS_REG))]
9760 [(parallel [(set (match_dup 0) (match_dup 1))
9761 (clobber (reg:CC FLAGS_REG))])]
9764 operands[0] = gen_lowpart (SImode, operands[0]);
9765 if (GET_CODE (operands[1]) == ABS)
9767 tmp = gen_int_mode (0x7fffffff, SImode);
9768 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9772 tmp = gen_int_mode (0x80000000, SImode);
9773 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9779 [(set (match_operand:DF 0 "register_operand" "")
9780 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9781 (use (match_operand 2 "" ""))
9782 (clobber (reg:CC FLAGS_REG))]
9784 [(parallel [(set (match_dup 0) (match_dup 1))
9785 (clobber (reg:CC FLAGS_REG))])]
9790 tmp = gen_lowpart (DImode, operands[0]);
9791 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9794 if (GET_CODE (operands[1]) == ABS)
9797 tmp = gen_rtx_NOT (DImode, tmp);
9801 operands[0] = gen_highpart (SImode, operands[0]);
9802 if (GET_CODE (operands[1]) == ABS)
9804 tmp = gen_int_mode (0x7fffffff, SImode);
9805 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9809 tmp = gen_int_mode (0x80000000, SImode);
9810 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9817 [(set (match_operand:XF 0 "register_operand" "")
9818 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9819 (use (match_operand 2 "" ""))
9820 (clobber (reg:CC FLAGS_REG))]
9822 [(parallel [(set (match_dup 0) (match_dup 1))
9823 (clobber (reg:CC FLAGS_REG))])]
9826 operands[0] = gen_rtx_REG (SImode,
9827 true_regnum (operands[0])
9828 + (TARGET_64BIT ? 1 : 2));
9829 if (GET_CODE (operands[1]) == ABS)
9831 tmp = GEN_INT (0x7fff);
9832 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9836 tmp = GEN_INT (0x8000);
9837 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9843 [(set (match_operand 0 "memory_operand" "")
9844 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9845 (use (match_operand 2 "" ""))
9846 (clobber (reg:CC FLAGS_REG))]
9848 [(parallel [(set (match_dup 0) (match_dup 1))
9849 (clobber (reg:CC FLAGS_REG))])]
9851 enum machine_mode mode = GET_MODE (operands[0]);
9852 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9855 operands[0] = adjust_address (operands[0], QImode, size - 1);
9856 if (GET_CODE (operands[1]) == ABS)
9858 tmp = gen_int_mode (0x7f, QImode);
9859 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9863 tmp = gen_int_mode (0x80, QImode);
9864 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9869 ;; Conditionalize these after reload. If they match before reload, we
9870 ;; lose the clobber and ability to use integer instructions.
9872 (define_insn "*negsf2_1"
9873 [(set (match_operand:SF 0 "register_operand" "=f")
9874 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9875 "TARGET_80387 && reload_completed"
9877 [(set_attr "type" "fsgn")
9878 (set_attr "mode" "SF")])
9880 (define_insn "*negdf2_1"
9881 [(set (match_operand:DF 0 "register_operand" "=f")
9882 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9883 "TARGET_80387 && reload_completed"
9885 [(set_attr "type" "fsgn")
9886 (set_attr "mode" "DF")])
9888 (define_insn "*negxf2_1"
9889 [(set (match_operand:XF 0 "register_operand" "=f")
9890 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9891 "TARGET_80387 && reload_completed"
9893 [(set_attr "type" "fsgn")
9894 (set_attr "mode" "XF")])
9896 (define_insn "*abssf2_1"
9897 [(set (match_operand:SF 0 "register_operand" "=f")
9898 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9899 "TARGET_80387 && reload_completed"
9901 [(set_attr "type" "fsgn")
9902 (set_attr "mode" "SF")])
9904 (define_insn "*absdf2_1"
9905 [(set (match_operand:DF 0 "register_operand" "=f")
9906 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9907 "TARGET_80387 && reload_completed"
9909 [(set_attr "type" "fsgn")
9910 (set_attr "mode" "DF")])
9912 (define_insn "*absxf2_1"
9913 [(set (match_operand:XF 0 "register_operand" "=f")
9914 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9915 "TARGET_80387 && reload_completed"
9917 [(set_attr "type" "fsgn")
9918 (set_attr "mode" "DF")])
9920 (define_insn "*negextendsfdf2"
9921 [(set (match_operand:DF 0 "register_operand" "=f")
9922 (neg:DF (float_extend:DF
9923 (match_operand:SF 1 "register_operand" "0"))))]
9924 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9926 [(set_attr "type" "fsgn")
9927 (set_attr "mode" "DF")])
9929 (define_insn "*negextenddfxf2"
9930 [(set (match_operand:XF 0 "register_operand" "=f")
9931 (neg:XF (float_extend:XF
9932 (match_operand:DF 1 "register_operand" "0"))))]
9935 [(set_attr "type" "fsgn")
9936 (set_attr "mode" "XF")])
9938 (define_insn "*negextendsfxf2"
9939 [(set (match_operand:XF 0 "register_operand" "=f")
9940 (neg:XF (float_extend:XF
9941 (match_operand:SF 1 "register_operand" "0"))))]
9944 [(set_attr "type" "fsgn")
9945 (set_attr "mode" "XF")])
9947 (define_insn "*absextendsfdf2"
9948 [(set (match_operand:DF 0 "register_operand" "=f")
9949 (abs:DF (float_extend:DF
9950 (match_operand:SF 1 "register_operand" "0"))))]
9951 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9953 [(set_attr "type" "fsgn")
9954 (set_attr "mode" "DF")])
9956 (define_insn "*absextenddfxf2"
9957 [(set (match_operand:XF 0 "register_operand" "=f")
9958 (abs:XF (float_extend:XF
9959 (match_operand:DF 1 "register_operand" "0"))))]
9962 [(set_attr "type" "fsgn")
9963 (set_attr "mode" "XF")])
9965 (define_insn "*absextendsfxf2"
9966 [(set (match_operand:XF 0 "register_operand" "=f")
9967 (abs:XF (float_extend:XF
9968 (match_operand:SF 1 "register_operand" "0"))))]
9971 [(set_attr "type" "fsgn")
9972 (set_attr "mode" "XF")])
9974 ;; One complement instructions
9976 (define_expand "one_cmpldi2"
9977 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9978 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9980 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9982 (define_insn "*one_cmpldi2_1_rex64"
9983 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9984 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9985 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9987 [(set_attr "type" "negnot")
9988 (set_attr "mode" "DI")])
9990 (define_insn "*one_cmpldi2_2_rex64"
9991 [(set (reg FLAGS_REG)
9992 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9994 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9995 (not:DI (match_dup 1)))]
9996 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9997 && ix86_unary_operator_ok (NOT, DImode, operands)"
9999 [(set_attr "type" "alu1")
10000 (set_attr "mode" "DI")])
10003 [(set (match_operand 0 "flags_reg_operand" "")
10004 (match_operator 2 "compare_operator"
10005 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10007 (set (match_operand:DI 1 "nonimmediate_operand" "")
10008 (not:DI (match_dup 3)))]
10009 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10010 [(parallel [(set (match_dup 0)
10012 [(xor:DI (match_dup 3) (const_int -1))
10015 (xor:DI (match_dup 3) (const_int -1)))])]
10018 (define_expand "one_cmplsi2"
10019 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10020 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10022 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10024 (define_insn "*one_cmplsi2_1"
10025 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10026 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10027 "ix86_unary_operator_ok (NOT, SImode, operands)"
10029 [(set_attr "type" "negnot")
10030 (set_attr "mode" "SI")])
10032 ;; ??? Currently never generated - xor is used instead.
10033 (define_insn "*one_cmplsi2_1_zext"
10034 [(set (match_operand:DI 0 "register_operand" "=r")
10035 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10036 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10038 [(set_attr "type" "negnot")
10039 (set_attr "mode" "SI")])
10041 (define_insn "*one_cmplsi2_2"
10042 [(set (reg FLAGS_REG)
10043 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10045 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10046 (not:SI (match_dup 1)))]
10047 "ix86_match_ccmode (insn, CCNOmode)
10048 && ix86_unary_operator_ok (NOT, SImode, operands)"
10050 [(set_attr "type" "alu1")
10051 (set_attr "mode" "SI")])
10054 [(set (match_operand 0 "flags_reg_operand" "")
10055 (match_operator 2 "compare_operator"
10056 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10058 (set (match_operand:SI 1 "nonimmediate_operand" "")
10059 (not:SI (match_dup 3)))]
10060 "ix86_match_ccmode (insn, CCNOmode)"
10061 [(parallel [(set (match_dup 0)
10062 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10065 (xor:SI (match_dup 3) (const_int -1)))])]
10068 ;; ??? Currently never generated - xor is used instead.
10069 (define_insn "*one_cmplsi2_2_zext"
10070 [(set (reg FLAGS_REG)
10071 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10073 (set (match_operand:DI 0 "register_operand" "=r")
10074 (zero_extend:DI (not:SI (match_dup 1))))]
10075 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10076 && ix86_unary_operator_ok (NOT, SImode, operands)"
10078 [(set_attr "type" "alu1")
10079 (set_attr "mode" "SI")])
10082 [(set (match_operand 0 "flags_reg_operand" "")
10083 (match_operator 2 "compare_operator"
10084 [(not:SI (match_operand:SI 3 "register_operand" ""))
10086 (set (match_operand:DI 1 "register_operand" "")
10087 (zero_extend:DI (not:SI (match_dup 3))))]
10088 "ix86_match_ccmode (insn, CCNOmode)"
10089 [(parallel [(set (match_dup 0)
10090 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10093 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10096 (define_expand "one_cmplhi2"
10097 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10098 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10099 "TARGET_HIMODE_MATH"
10100 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10102 (define_insn "*one_cmplhi2_1"
10103 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10104 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10105 "ix86_unary_operator_ok (NOT, HImode, operands)"
10107 [(set_attr "type" "negnot")
10108 (set_attr "mode" "HI")])
10110 (define_insn "*one_cmplhi2_2"
10111 [(set (reg FLAGS_REG)
10112 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10114 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10115 (not:HI (match_dup 1)))]
10116 "ix86_match_ccmode (insn, CCNOmode)
10117 && ix86_unary_operator_ok (NEG, HImode, operands)"
10119 [(set_attr "type" "alu1")
10120 (set_attr "mode" "HI")])
10123 [(set (match_operand 0 "flags_reg_operand" "")
10124 (match_operator 2 "compare_operator"
10125 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10127 (set (match_operand:HI 1 "nonimmediate_operand" "")
10128 (not:HI (match_dup 3)))]
10129 "ix86_match_ccmode (insn, CCNOmode)"
10130 [(parallel [(set (match_dup 0)
10131 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10134 (xor:HI (match_dup 3) (const_int -1)))])]
10137 ;; %%% Potential partial reg stall on alternative 1. What to do?
10138 (define_expand "one_cmplqi2"
10139 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10140 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10141 "TARGET_QIMODE_MATH"
10142 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10144 (define_insn "*one_cmplqi2_1"
10145 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10146 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10147 "ix86_unary_operator_ok (NOT, QImode, operands)"
10151 [(set_attr "type" "negnot")
10152 (set_attr "mode" "QI,SI")])
10154 (define_insn "*one_cmplqi2_2"
10155 [(set (reg FLAGS_REG)
10156 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10158 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10159 (not:QI (match_dup 1)))]
10160 "ix86_match_ccmode (insn, CCNOmode)
10161 && ix86_unary_operator_ok (NOT, QImode, operands)"
10163 [(set_attr "type" "alu1")
10164 (set_attr "mode" "QI")])
10167 [(set (match_operand 0 "flags_reg_operand" "")
10168 (match_operator 2 "compare_operator"
10169 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10171 (set (match_operand:QI 1 "nonimmediate_operand" "")
10172 (not:QI (match_dup 3)))]
10173 "ix86_match_ccmode (insn, CCNOmode)"
10174 [(parallel [(set (match_dup 0)
10175 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10178 (xor:QI (match_dup 3) (const_int -1)))])]
10181 ;; Arithmetic shift instructions
10183 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10184 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10185 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10186 ;; from the assembler input.
10188 ;; This instruction shifts the target reg/mem as usual, but instead of
10189 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10190 ;; is a left shift double, bits are taken from the high order bits of
10191 ;; reg, else if the insn is a shift right double, bits are taken from the
10192 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10193 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10195 ;; Since sh[lr]d does not change the `reg' operand, that is done
10196 ;; separately, making all shifts emit pairs of shift double and normal
10197 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10198 ;; support a 63 bit shift, each shift where the count is in a reg expands
10199 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10201 ;; If the shift count is a constant, we need never emit more than one
10202 ;; shift pair, instead using moves and sign extension for counts greater
10205 (define_expand "ashlti3"
10206 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10207 (ashift:TI (match_operand:TI 1 "register_operand" "")
10208 (match_operand:QI 2 "nonmemory_operand" "")))
10209 (clobber (reg:CC FLAGS_REG))])]
10212 if (! immediate_operand (operands[2], QImode))
10214 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10217 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10221 (define_insn "ashlti3_1"
10222 [(set (match_operand:TI 0 "register_operand" "=r")
10223 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10224 (match_operand:QI 2 "register_operand" "c")))
10225 (clobber (match_scratch:DI 3 "=&r"))
10226 (clobber (reg:CC FLAGS_REG))]
10229 [(set_attr "type" "multi")])
10231 (define_insn "*ashlti3_2"
10232 [(set (match_operand:TI 0 "register_operand" "=r")
10233 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10234 (match_operand:QI 2 "immediate_operand" "O")))
10235 (clobber (reg:CC FLAGS_REG))]
10238 [(set_attr "type" "multi")])
10241 [(set (match_operand:TI 0 "register_operand" "")
10242 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10243 (match_operand:QI 2 "register_operand" "")))
10244 (clobber (match_scratch:DI 3 ""))
10245 (clobber (reg:CC FLAGS_REG))]
10246 "TARGET_64BIT && reload_completed"
10248 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10251 [(set (match_operand:TI 0 "register_operand" "")
10252 (ashift:TI (match_operand:TI 1 "register_operand" "")
10253 (match_operand:QI 2 "immediate_operand" "")))
10254 (clobber (reg:CC FLAGS_REG))]
10255 "TARGET_64BIT && reload_completed"
10257 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10259 (define_insn "x86_64_shld"
10260 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10261 (ior:DI (ashift:DI (match_dup 0)
10262 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10263 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10264 (minus:QI (const_int 64) (match_dup 2)))))
10265 (clobber (reg:CC FLAGS_REG))]
10268 shld{q}\t{%2, %1, %0|%0, %1, %2}
10269 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10270 [(set_attr "type" "ishift")
10271 (set_attr "prefix_0f" "1")
10272 (set_attr "mode" "DI")
10273 (set_attr "athlon_decode" "vector")])
10275 (define_expand "x86_64_shift_adj"
10276 [(set (reg:CCZ FLAGS_REG)
10277 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10280 (set (match_operand:DI 0 "register_operand" "")
10281 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10282 (match_operand:DI 1 "register_operand" "")
10285 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10286 (match_operand:DI 3 "register_operand" "r")
10291 (define_expand "ashldi3"
10292 [(set (match_operand:DI 0 "shiftdi_operand" "")
10293 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10294 (match_operand:QI 2 "nonmemory_operand" "")))]
10296 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10298 (define_insn "*ashldi3_1_rex64"
10299 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10300 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10301 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10302 (clobber (reg:CC FLAGS_REG))]
10303 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10305 switch (get_attr_type (insn))
10308 gcc_assert (operands[2] == const1_rtx);
10309 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10310 return "add{q}\t{%0, %0|%0, %0}";
10313 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10314 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10315 operands[1] = gen_rtx_MULT (DImode, operands[1],
10316 GEN_INT (1 << INTVAL (operands[2])));
10317 return "lea{q}\t{%a1, %0|%0, %a1}";
10320 if (REG_P (operands[2]))
10321 return "sal{q}\t{%b2, %0|%0, %b2}";
10322 else if (operands[2] == const1_rtx
10323 && (TARGET_SHIFT1 || optimize_size))
10324 return "sal{q}\t%0";
10326 return "sal{q}\t{%2, %0|%0, %2}";
10329 [(set (attr "type")
10330 (cond [(eq_attr "alternative" "1")
10331 (const_string "lea")
10332 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10334 (match_operand 0 "register_operand" ""))
10335 (match_operand 2 "const1_operand" ""))
10336 (const_string "alu")
10338 (const_string "ishift")))
10339 (set_attr "mode" "DI")])
10341 ;; Convert lea to the lea pattern to avoid flags dependency.
10343 [(set (match_operand:DI 0 "register_operand" "")
10344 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10345 (match_operand:QI 2 "immediate_operand" "")))
10346 (clobber (reg:CC FLAGS_REG))]
10347 "TARGET_64BIT && reload_completed
10348 && true_regnum (operands[0]) != true_regnum (operands[1])"
10349 [(set (match_dup 0)
10350 (mult:DI (match_dup 1)
10352 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10354 ;; This pattern can't accept a variable shift count, since shifts by
10355 ;; zero don't affect the flags. We assume that shifts by constant
10356 ;; zero are optimized away.
10357 (define_insn "*ashldi3_cmp_rex64"
10358 [(set (reg FLAGS_REG)
10360 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10361 (match_operand:QI 2 "immediate_operand" "e"))
10363 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10364 (ashift:DI (match_dup 1) (match_dup 2)))]
10365 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10366 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10368 switch (get_attr_type (insn))
10371 gcc_assert (operands[2] == const1_rtx);
10372 return "add{q}\t{%0, %0|%0, %0}";
10375 if (REG_P (operands[2]))
10376 return "sal{q}\t{%b2, %0|%0, %b2}";
10377 else if (operands[2] == const1_rtx
10378 && (TARGET_SHIFT1 || optimize_size))
10379 return "sal{q}\t%0";
10381 return "sal{q}\t{%2, %0|%0, %2}";
10384 [(set (attr "type")
10385 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10387 (match_operand 0 "register_operand" ""))
10388 (match_operand 2 "const1_operand" ""))
10389 (const_string "alu")
10391 (const_string "ishift")))
10392 (set_attr "mode" "DI")])
10394 (define_insn "*ashldi3_1"
10395 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10396 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10397 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10398 (clobber (reg:CC FLAGS_REG))]
10401 [(set_attr "type" "multi")])
10403 ;; By default we don't ask for a scratch register, because when DImode
10404 ;; values are manipulated, registers are already at a premium. But if
10405 ;; we have one handy, we won't turn it away.
10407 [(match_scratch:SI 3 "r")
10408 (parallel [(set (match_operand:DI 0 "register_operand" "")
10409 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10410 (match_operand:QI 2 "nonmemory_operand" "")))
10411 (clobber (reg:CC FLAGS_REG))])
10413 "!TARGET_64BIT && TARGET_CMOVE"
10415 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10418 [(set (match_operand:DI 0 "register_operand" "")
10419 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10420 (match_operand:QI 2 "nonmemory_operand" "")))
10421 (clobber (reg:CC FLAGS_REG))]
10422 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10423 ? flow2_completed : reload_completed)"
10425 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10427 (define_insn "x86_shld_1"
10428 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10429 (ior:SI (ashift:SI (match_dup 0)
10430 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10431 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10432 (minus:QI (const_int 32) (match_dup 2)))))
10433 (clobber (reg:CC FLAGS_REG))]
10436 shld{l}\t{%2, %1, %0|%0, %1, %2}
10437 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10438 [(set_attr "type" "ishift")
10439 (set_attr "prefix_0f" "1")
10440 (set_attr "mode" "SI")
10441 (set_attr "pent_pair" "np")
10442 (set_attr "athlon_decode" "vector")])
10444 (define_expand "x86_shift_adj_1"
10445 [(set (reg:CCZ FLAGS_REG)
10446 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10449 (set (match_operand:SI 0 "register_operand" "")
10450 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10451 (match_operand:SI 1 "register_operand" "")
10454 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10455 (match_operand:SI 3 "register_operand" "r")
10460 (define_expand "x86_shift_adj_2"
10461 [(use (match_operand:SI 0 "register_operand" ""))
10462 (use (match_operand:SI 1 "register_operand" ""))
10463 (use (match_operand:QI 2 "register_operand" ""))]
10466 rtx label = gen_label_rtx ();
10469 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10471 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10472 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10473 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10474 gen_rtx_LABEL_REF (VOIDmode, label),
10476 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10477 JUMP_LABEL (tmp) = label;
10479 emit_move_insn (operands[0], operands[1]);
10480 ix86_expand_clear (operands[1]);
10482 emit_label (label);
10483 LABEL_NUSES (label) = 1;
10488 (define_expand "ashlsi3"
10489 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10490 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10491 (match_operand:QI 2 "nonmemory_operand" "")))
10492 (clobber (reg:CC FLAGS_REG))]
10494 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10496 (define_insn "*ashlsi3_1"
10497 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10498 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10499 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10500 (clobber (reg:CC FLAGS_REG))]
10501 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10503 switch (get_attr_type (insn))
10506 gcc_assert (operands[2] == const1_rtx);
10507 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10508 return "add{l}\t{%0, %0|%0, %0}";
10514 if (REG_P (operands[2]))
10515 return "sal{l}\t{%b2, %0|%0, %b2}";
10516 else if (operands[2] == const1_rtx
10517 && (TARGET_SHIFT1 || optimize_size))
10518 return "sal{l}\t%0";
10520 return "sal{l}\t{%2, %0|%0, %2}";
10523 [(set (attr "type")
10524 (cond [(eq_attr "alternative" "1")
10525 (const_string "lea")
10526 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10528 (match_operand 0 "register_operand" ""))
10529 (match_operand 2 "const1_operand" ""))
10530 (const_string "alu")
10532 (const_string "ishift")))
10533 (set_attr "mode" "SI")])
10535 ;; Convert lea to the lea pattern to avoid flags dependency.
10537 [(set (match_operand 0 "register_operand" "")
10538 (ashift (match_operand 1 "index_register_operand" "")
10539 (match_operand:QI 2 "const_int_operand" "")))
10540 (clobber (reg:CC FLAGS_REG))]
10542 && true_regnum (operands[0]) != true_regnum (operands[1])
10543 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10547 enum machine_mode mode = GET_MODE (operands[0]);
10549 if (GET_MODE_SIZE (mode) < 4)
10550 operands[0] = gen_lowpart (SImode, operands[0]);
10552 operands[1] = gen_lowpart (Pmode, operands[1]);
10553 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10555 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10556 if (Pmode != SImode)
10557 pat = gen_rtx_SUBREG (SImode, pat, 0);
10558 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10562 ;; Rare case of shifting RSP is handled by generating move and shift
10564 [(set (match_operand 0 "register_operand" "")
10565 (ashift (match_operand 1 "register_operand" "")
10566 (match_operand:QI 2 "const_int_operand" "")))
10567 (clobber (reg:CC FLAGS_REG))]
10569 && true_regnum (operands[0]) != true_regnum (operands[1])"
10573 emit_move_insn (operands[0], operands[1]);
10574 pat = gen_rtx_SET (VOIDmode, operands[0],
10575 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10576 operands[0], operands[2]));
10577 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10578 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10582 (define_insn "*ashlsi3_1_zext"
10583 [(set (match_operand:DI 0 "register_operand" "=r,r")
10584 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10585 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10586 (clobber (reg:CC FLAGS_REG))]
10587 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10589 switch (get_attr_type (insn))
10592 gcc_assert (operands[2] == const1_rtx);
10593 return "add{l}\t{%k0, %k0|%k0, %k0}";
10599 if (REG_P (operands[2]))
10600 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10601 else if (operands[2] == const1_rtx
10602 && (TARGET_SHIFT1 || optimize_size))
10603 return "sal{l}\t%k0";
10605 return "sal{l}\t{%2, %k0|%k0, %2}";
10608 [(set (attr "type")
10609 (cond [(eq_attr "alternative" "1")
10610 (const_string "lea")
10611 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10613 (match_operand 2 "const1_operand" ""))
10614 (const_string "alu")
10616 (const_string "ishift")))
10617 (set_attr "mode" "SI")])
10619 ;; Convert lea to the lea pattern to avoid flags dependency.
10621 [(set (match_operand:DI 0 "register_operand" "")
10622 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10623 (match_operand:QI 2 "const_int_operand" ""))))
10624 (clobber (reg:CC FLAGS_REG))]
10625 "TARGET_64BIT && reload_completed
10626 && true_regnum (operands[0]) != true_regnum (operands[1])"
10627 [(set (match_dup 0) (zero_extend:DI
10628 (subreg:SI (mult:SI (match_dup 1)
10629 (match_dup 2)) 0)))]
10631 operands[1] = gen_lowpart (Pmode, operands[1]);
10632 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10635 ;; This pattern can't accept a variable shift count, since shifts by
10636 ;; zero don't affect the flags. We assume that shifts by constant
10637 ;; zero are optimized away.
10638 (define_insn "*ashlsi3_cmp"
10639 [(set (reg FLAGS_REG)
10641 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10642 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10644 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10645 (ashift:SI (match_dup 1) (match_dup 2)))]
10646 "ix86_match_ccmode (insn, CCGOCmode)
10647 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10649 switch (get_attr_type (insn))
10652 gcc_assert (operands[2] == const1_rtx);
10653 return "add{l}\t{%0, %0|%0, %0}";
10656 if (REG_P (operands[2]))
10657 return "sal{l}\t{%b2, %0|%0, %b2}";
10658 else if (operands[2] == const1_rtx
10659 && (TARGET_SHIFT1 || optimize_size))
10660 return "sal{l}\t%0";
10662 return "sal{l}\t{%2, %0|%0, %2}";
10665 [(set (attr "type")
10666 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10668 (match_operand 0 "register_operand" ""))
10669 (match_operand 2 "const1_operand" ""))
10670 (const_string "alu")
10672 (const_string "ishift")))
10673 (set_attr "mode" "SI")])
10675 (define_insn "*ashlsi3_cmp_zext"
10676 [(set (reg FLAGS_REG)
10678 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10679 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10681 (set (match_operand:DI 0 "register_operand" "=r")
10682 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10683 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10684 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10686 switch (get_attr_type (insn))
10689 gcc_assert (operands[2] == const1_rtx);
10690 return "add{l}\t{%k0, %k0|%k0, %k0}";
10693 if (REG_P (operands[2]))
10694 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10695 else if (operands[2] == const1_rtx
10696 && (TARGET_SHIFT1 || optimize_size))
10697 return "sal{l}\t%k0";
10699 return "sal{l}\t{%2, %k0|%k0, %2}";
10702 [(set (attr "type")
10703 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10705 (match_operand 2 "const1_operand" ""))
10706 (const_string "alu")
10708 (const_string "ishift")))
10709 (set_attr "mode" "SI")])
10711 (define_expand "ashlhi3"
10712 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10713 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10714 (match_operand:QI 2 "nonmemory_operand" "")))
10715 (clobber (reg:CC FLAGS_REG))]
10716 "TARGET_HIMODE_MATH"
10717 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10719 (define_insn "*ashlhi3_1_lea"
10720 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10721 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10722 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10723 (clobber (reg:CC FLAGS_REG))]
10724 "!TARGET_PARTIAL_REG_STALL
10725 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10727 switch (get_attr_type (insn))
10732 gcc_assert (operands[2] == const1_rtx);
10733 return "add{w}\t{%0, %0|%0, %0}";
10736 if (REG_P (operands[2]))
10737 return "sal{w}\t{%b2, %0|%0, %b2}";
10738 else if (operands[2] == const1_rtx
10739 && (TARGET_SHIFT1 || optimize_size))
10740 return "sal{w}\t%0";
10742 return "sal{w}\t{%2, %0|%0, %2}";
10745 [(set (attr "type")
10746 (cond [(eq_attr "alternative" "1")
10747 (const_string "lea")
10748 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10750 (match_operand 0 "register_operand" ""))
10751 (match_operand 2 "const1_operand" ""))
10752 (const_string "alu")
10754 (const_string "ishift")))
10755 (set_attr "mode" "HI,SI")])
10757 (define_insn "*ashlhi3_1"
10758 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10759 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10760 (match_operand:QI 2 "nonmemory_operand" "cI")))
10761 (clobber (reg:CC FLAGS_REG))]
10762 "TARGET_PARTIAL_REG_STALL
10763 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10765 switch (get_attr_type (insn))
10768 gcc_assert (operands[2] == const1_rtx);
10769 return "add{w}\t{%0, %0|%0, %0}";
10772 if (REG_P (operands[2]))
10773 return "sal{w}\t{%b2, %0|%0, %b2}";
10774 else if (operands[2] == const1_rtx
10775 && (TARGET_SHIFT1 || optimize_size))
10776 return "sal{w}\t%0";
10778 return "sal{w}\t{%2, %0|%0, %2}";
10781 [(set (attr "type")
10782 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10784 (match_operand 0 "register_operand" ""))
10785 (match_operand 2 "const1_operand" ""))
10786 (const_string "alu")
10788 (const_string "ishift")))
10789 (set_attr "mode" "HI")])
10791 ;; This pattern can't accept a variable shift count, since shifts by
10792 ;; zero don't affect the flags. We assume that shifts by constant
10793 ;; zero are optimized away.
10794 (define_insn "*ashlhi3_cmp"
10795 [(set (reg FLAGS_REG)
10797 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10798 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10800 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10801 (ashift:HI (match_dup 1) (match_dup 2)))]
10802 "ix86_match_ccmode (insn, CCGOCmode)
10803 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10805 switch (get_attr_type (insn))
10808 gcc_assert (operands[2] == const1_rtx);
10809 return "add{w}\t{%0, %0|%0, %0}";
10812 if (REG_P (operands[2]))
10813 return "sal{w}\t{%b2, %0|%0, %b2}";
10814 else if (operands[2] == const1_rtx
10815 && (TARGET_SHIFT1 || optimize_size))
10816 return "sal{w}\t%0";
10818 return "sal{w}\t{%2, %0|%0, %2}";
10821 [(set (attr "type")
10822 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10824 (match_operand 0 "register_operand" ""))
10825 (match_operand 2 "const1_operand" ""))
10826 (const_string "alu")
10828 (const_string "ishift")))
10829 (set_attr "mode" "HI")])
10831 (define_expand "ashlqi3"
10832 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10833 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10834 (match_operand:QI 2 "nonmemory_operand" "")))
10835 (clobber (reg:CC FLAGS_REG))]
10836 "TARGET_QIMODE_MATH"
10837 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10839 ;; %%% Potential partial reg stall on alternative 2. What to do?
10841 (define_insn "*ashlqi3_1_lea"
10842 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10843 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10844 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10845 (clobber (reg:CC FLAGS_REG))]
10846 "!TARGET_PARTIAL_REG_STALL
10847 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10849 switch (get_attr_type (insn))
10854 gcc_assert (operands[2] == const1_rtx);
10855 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10856 return "add{l}\t{%k0, %k0|%k0, %k0}";
10858 return "add{b}\t{%0, %0|%0, %0}";
10861 if (REG_P (operands[2]))
10863 if (get_attr_mode (insn) == MODE_SI)
10864 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10866 return "sal{b}\t{%b2, %0|%0, %b2}";
10868 else if (operands[2] == const1_rtx
10869 && (TARGET_SHIFT1 || optimize_size))
10871 if (get_attr_mode (insn) == MODE_SI)
10872 return "sal{l}\t%0";
10874 return "sal{b}\t%0";
10878 if (get_attr_mode (insn) == MODE_SI)
10879 return "sal{l}\t{%2, %k0|%k0, %2}";
10881 return "sal{b}\t{%2, %0|%0, %2}";
10885 [(set (attr "type")
10886 (cond [(eq_attr "alternative" "2")
10887 (const_string "lea")
10888 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10890 (match_operand 0 "register_operand" ""))
10891 (match_operand 2 "const1_operand" ""))
10892 (const_string "alu")
10894 (const_string "ishift")))
10895 (set_attr "mode" "QI,SI,SI")])
10897 (define_insn "*ashlqi3_1"
10898 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10899 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10900 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10901 (clobber (reg:CC FLAGS_REG))]
10902 "TARGET_PARTIAL_REG_STALL
10903 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10905 switch (get_attr_type (insn))
10908 gcc_assert (operands[2] == const1_rtx);
10909 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10910 return "add{l}\t{%k0, %k0|%k0, %k0}";
10912 return "add{b}\t{%0, %0|%0, %0}";
10915 if (REG_P (operands[2]))
10917 if (get_attr_mode (insn) == MODE_SI)
10918 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10920 return "sal{b}\t{%b2, %0|%0, %b2}";
10922 else if (operands[2] == const1_rtx
10923 && (TARGET_SHIFT1 || optimize_size))
10925 if (get_attr_mode (insn) == MODE_SI)
10926 return "sal{l}\t%0";
10928 return "sal{b}\t%0";
10932 if (get_attr_mode (insn) == MODE_SI)
10933 return "sal{l}\t{%2, %k0|%k0, %2}";
10935 return "sal{b}\t{%2, %0|%0, %2}";
10939 [(set (attr "type")
10940 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10942 (match_operand 0 "register_operand" ""))
10943 (match_operand 2 "const1_operand" ""))
10944 (const_string "alu")
10946 (const_string "ishift")))
10947 (set_attr "mode" "QI,SI")])
10949 ;; This pattern can't accept a variable shift count, since shifts by
10950 ;; zero don't affect the flags. We assume that shifts by constant
10951 ;; zero are optimized away.
10952 (define_insn "*ashlqi3_cmp"
10953 [(set (reg FLAGS_REG)
10955 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10956 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10958 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10959 (ashift:QI (match_dup 1) (match_dup 2)))]
10960 "ix86_match_ccmode (insn, CCGOCmode)
10961 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10963 switch (get_attr_type (insn))
10966 gcc_assert (operands[2] == const1_rtx);
10967 return "add{b}\t{%0, %0|%0, %0}";
10970 if (REG_P (operands[2]))
10971 return "sal{b}\t{%b2, %0|%0, %b2}";
10972 else if (operands[2] == const1_rtx
10973 && (TARGET_SHIFT1 || optimize_size))
10974 return "sal{b}\t%0";
10976 return "sal{b}\t{%2, %0|%0, %2}";
10979 [(set (attr "type")
10980 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10982 (match_operand 0 "register_operand" ""))
10983 (match_operand 2 "const1_operand" ""))
10984 (const_string "alu")
10986 (const_string "ishift")))
10987 (set_attr "mode" "QI")])
10989 ;; See comment above `ashldi3' about how this works.
10991 (define_expand "ashrti3"
10992 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10993 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10994 (match_operand:QI 2 "nonmemory_operand" "")))
10995 (clobber (reg:CC FLAGS_REG))])]
10998 if (! immediate_operand (operands[2], QImode))
11000 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11003 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11007 (define_insn "ashrti3_1"
11008 [(set (match_operand:TI 0 "register_operand" "=r")
11009 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11010 (match_operand:QI 2 "register_operand" "c")))
11011 (clobber (match_scratch:DI 3 "=&r"))
11012 (clobber (reg:CC FLAGS_REG))]
11015 [(set_attr "type" "multi")])
11017 (define_insn "*ashrti3_2"
11018 [(set (match_operand:TI 0 "register_operand" "=r")
11019 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11020 (match_operand:QI 2 "immediate_operand" "O")))
11021 (clobber (reg:CC FLAGS_REG))]
11024 [(set_attr "type" "multi")])
11027 [(set (match_operand:TI 0 "register_operand" "")
11028 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11029 (match_operand:QI 2 "register_operand" "")))
11030 (clobber (match_scratch:DI 3 ""))
11031 (clobber (reg:CC FLAGS_REG))]
11032 "TARGET_64BIT && reload_completed"
11034 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11037 [(set (match_operand:TI 0 "register_operand" "")
11038 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11039 (match_operand:QI 2 "immediate_operand" "")))
11040 (clobber (reg:CC FLAGS_REG))]
11041 "TARGET_64BIT && reload_completed"
11043 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11045 (define_insn "x86_64_shrd"
11046 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11047 (ior:DI (ashiftrt:DI (match_dup 0)
11048 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11049 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11050 (minus:QI (const_int 64) (match_dup 2)))))
11051 (clobber (reg:CC FLAGS_REG))]
11054 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11055 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11056 [(set_attr "type" "ishift")
11057 (set_attr "prefix_0f" "1")
11058 (set_attr "mode" "DI")
11059 (set_attr "athlon_decode" "vector")])
11061 (define_expand "ashrdi3"
11062 [(set (match_operand:DI 0 "shiftdi_operand" "")
11063 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11064 (match_operand:QI 2 "nonmemory_operand" "")))]
11066 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11068 (define_insn "*ashrdi3_63_rex64"
11069 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11070 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11071 (match_operand:DI 2 "const_int_operand" "i,i")))
11072 (clobber (reg:CC FLAGS_REG))]
11073 "TARGET_64BIT && INTVAL (operands[2]) == 63
11074 && (TARGET_USE_CLTD || optimize_size)
11075 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11078 sar{q}\t{%2, %0|%0, %2}"
11079 [(set_attr "type" "imovx,ishift")
11080 (set_attr "prefix_0f" "0,*")
11081 (set_attr "length_immediate" "0,*")
11082 (set_attr "modrm" "0,1")
11083 (set_attr "mode" "DI")])
11085 (define_insn "*ashrdi3_1_one_bit_rex64"
11086 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11087 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11088 (match_operand:QI 2 "const1_operand" "")))
11089 (clobber (reg:CC FLAGS_REG))]
11090 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11091 && (TARGET_SHIFT1 || optimize_size)"
11093 [(set_attr "type" "ishift")
11094 (set (attr "length")
11095 (if_then_else (match_operand:DI 0 "register_operand" "")
11097 (const_string "*")))])
11099 (define_insn "*ashrdi3_1_rex64"
11100 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11101 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11102 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11103 (clobber (reg:CC FLAGS_REG))]
11104 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11106 sar{q}\t{%2, %0|%0, %2}
11107 sar{q}\t{%b2, %0|%0, %b2}"
11108 [(set_attr "type" "ishift")
11109 (set_attr "mode" "DI")])
11111 ;; This pattern can't accept a variable shift count, since shifts by
11112 ;; zero don't affect the flags. We assume that shifts by constant
11113 ;; zero are optimized away.
11114 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11115 [(set (reg FLAGS_REG)
11117 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11118 (match_operand:QI 2 "const1_operand" ""))
11120 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11121 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11122 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11123 && (TARGET_SHIFT1 || optimize_size)
11124 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11126 [(set_attr "type" "ishift")
11127 (set (attr "length")
11128 (if_then_else (match_operand:DI 0 "register_operand" "")
11130 (const_string "*")))])
11132 ;; This pattern can't accept a variable shift count, since shifts by
11133 ;; zero don't affect the flags. We assume that shifts by constant
11134 ;; zero are optimized away.
11135 (define_insn "*ashrdi3_cmp_rex64"
11136 [(set (reg FLAGS_REG)
11138 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11139 (match_operand:QI 2 "const_int_operand" "n"))
11141 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11142 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11143 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11144 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11145 "sar{q}\t{%2, %0|%0, %2}"
11146 [(set_attr "type" "ishift")
11147 (set_attr "mode" "DI")])
11149 (define_insn "*ashrdi3_1"
11150 [(set (match_operand:DI 0 "register_operand" "=r")
11151 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11152 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11153 (clobber (reg:CC FLAGS_REG))]
11156 [(set_attr "type" "multi")])
11158 ;; By default we don't ask for a scratch register, because when DImode
11159 ;; values are manipulated, registers are already at a premium. But if
11160 ;; we have one handy, we won't turn it away.
11162 [(match_scratch:SI 3 "r")
11163 (parallel [(set (match_operand:DI 0 "register_operand" "")
11164 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11165 (match_operand:QI 2 "nonmemory_operand" "")))
11166 (clobber (reg:CC FLAGS_REG))])
11168 "!TARGET_64BIT && TARGET_CMOVE"
11170 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11173 [(set (match_operand:DI 0 "register_operand" "")
11174 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11175 (match_operand:QI 2 "nonmemory_operand" "")))
11176 (clobber (reg:CC FLAGS_REG))]
11177 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11178 ? flow2_completed : reload_completed)"
11180 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11182 (define_insn "x86_shrd_1"
11183 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11184 (ior:SI (ashiftrt:SI (match_dup 0)
11185 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11186 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11187 (minus:QI (const_int 32) (match_dup 2)))))
11188 (clobber (reg:CC FLAGS_REG))]
11191 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11192 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11193 [(set_attr "type" "ishift")
11194 (set_attr "prefix_0f" "1")
11195 (set_attr "pent_pair" "np")
11196 (set_attr "mode" "SI")])
11198 (define_expand "x86_shift_adj_3"
11199 [(use (match_operand:SI 0 "register_operand" ""))
11200 (use (match_operand:SI 1 "register_operand" ""))
11201 (use (match_operand:QI 2 "register_operand" ""))]
11204 rtx label = gen_label_rtx ();
11207 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11209 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11210 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11211 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11212 gen_rtx_LABEL_REF (VOIDmode, label),
11214 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11215 JUMP_LABEL (tmp) = label;
11217 emit_move_insn (operands[0], operands[1]);
11218 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11220 emit_label (label);
11221 LABEL_NUSES (label) = 1;
11226 (define_insn "ashrsi3_31"
11227 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11228 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11229 (match_operand:SI 2 "const_int_operand" "i,i")))
11230 (clobber (reg:CC FLAGS_REG))]
11231 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11232 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11235 sar{l}\t{%2, %0|%0, %2}"
11236 [(set_attr "type" "imovx,ishift")
11237 (set_attr "prefix_0f" "0,*")
11238 (set_attr "length_immediate" "0,*")
11239 (set_attr "modrm" "0,1")
11240 (set_attr "mode" "SI")])
11242 (define_insn "*ashrsi3_31_zext"
11243 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11244 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11245 (match_operand:SI 2 "const_int_operand" "i,i"))))
11246 (clobber (reg:CC FLAGS_REG))]
11247 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11248 && INTVAL (operands[2]) == 31
11249 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11252 sar{l}\t{%2, %k0|%k0, %2}"
11253 [(set_attr "type" "imovx,ishift")
11254 (set_attr "prefix_0f" "0,*")
11255 (set_attr "length_immediate" "0,*")
11256 (set_attr "modrm" "0,1")
11257 (set_attr "mode" "SI")])
11259 (define_expand "ashrsi3"
11260 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11261 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11262 (match_operand:QI 2 "nonmemory_operand" "")))
11263 (clobber (reg:CC FLAGS_REG))]
11265 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11267 (define_insn "*ashrsi3_1_one_bit"
11268 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11269 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11270 (match_operand:QI 2 "const1_operand" "")))
11271 (clobber (reg:CC FLAGS_REG))]
11272 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11273 && (TARGET_SHIFT1 || optimize_size)"
11275 [(set_attr "type" "ishift")
11276 (set (attr "length")
11277 (if_then_else (match_operand:SI 0 "register_operand" "")
11279 (const_string "*")))])
11281 (define_insn "*ashrsi3_1_one_bit_zext"
11282 [(set (match_operand:DI 0 "register_operand" "=r")
11283 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11284 (match_operand:QI 2 "const1_operand" ""))))
11285 (clobber (reg:CC FLAGS_REG))]
11286 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11287 && (TARGET_SHIFT1 || optimize_size)"
11289 [(set_attr "type" "ishift")
11290 (set_attr "length" "2")])
11292 (define_insn "*ashrsi3_1"
11293 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11294 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11295 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11296 (clobber (reg:CC FLAGS_REG))]
11297 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11299 sar{l}\t{%2, %0|%0, %2}
11300 sar{l}\t{%b2, %0|%0, %b2}"
11301 [(set_attr "type" "ishift")
11302 (set_attr "mode" "SI")])
11304 (define_insn "*ashrsi3_1_zext"
11305 [(set (match_operand:DI 0 "register_operand" "=r,r")
11306 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11307 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11308 (clobber (reg:CC FLAGS_REG))]
11309 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11311 sar{l}\t{%2, %k0|%k0, %2}
11312 sar{l}\t{%b2, %k0|%k0, %b2}"
11313 [(set_attr "type" "ishift")
11314 (set_attr "mode" "SI")])
11316 ;; This pattern can't accept a variable shift count, since shifts by
11317 ;; zero don't affect the flags. We assume that shifts by constant
11318 ;; zero are optimized away.
11319 (define_insn "*ashrsi3_one_bit_cmp"
11320 [(set (reg FLAGS_REG)
11322 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11323 (match_operand:QI 2 "const1_operand" ""))
11325 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11326 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11327 "ix86_match_ccmode (insn, CCGOCmode)
11328 && (TARGET_SHIFT1 || optimize_size)
11329 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11331 [(set_attr "type" "ishift")
11332 (set (attr "length")
11333 (if_then_else (match_operand:SI 0 "register_operand" "")
11335 (const_string "*")))])
11337 (define_insn "*ashrsi3_one_bit_cmp_zext"
11338 [(set (reg FLAGS_REG)
11340 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11341 (match_operand:QI 2 "const1_operand" ""))
11343 (set (match_operand:DI 0 "register_operand" "=r")
11344 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11345 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11346 && (TARGET_SHIFT1 || optimize_size)
11347 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11349 [(set_attr "type" "ishift")
11350 (set_attr "length" "2")])
11352 ;; This pattern can't accept a variable shift count, since shifts by
11353 ;; zero don't affect the flags. We assume that shifts by constant
11354 ;; zero are optimized away.
11355 (define_insn "*ashrsi3_cmp"
11356 [(set (reg FLAGS_REG)
11358 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11359 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11361 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11362 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11363 "ix86_match_ccmode (insn, CCGOCmode)
11364 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11365 "sar{l}\t{%2, %0|%0, %2}"
11366 [(set_attr "type" "ishift")
11367 (set_attr "mode" "SI")])
11369 (define_insn "*ashrsi3_cmp_zext"
11370 [(set (reg FLAGS_REG)
11372 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11373 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11375 (set (match_operand:DI 0 "register_operand" "=r")
11376 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11377 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11378 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11379 "sar{l}\t{%2, %k0|%k0, %2}"
11380 [(set_attr "type" "ishift")
11381 (set_attr "mode" "SI")])
11383 (define_expand "ashrhi3"
11384 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11385 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11386 (match_operand:QI 2 "nonmemory_operand" "")))
11387 (clobber (reg:CC FLAGS_REG))]
11388 "TARGET_HIMODE_MATH"
11389 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11391 (define_insn "*ashrhi3_1_one_bit"
11392 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11393 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11394 (match_operand:QI 2 "const1_operand" "")))
11395 (clobber (reg:CC FLAGS_REG))]
11396 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11397 && (TARGET_SHIFT1 || optimize_size)"
11399 [(set_attr "type" "ishift")
11400 (set (attr "length")
11401 (if_then_else (match_operand 0 "register_operand" "")
11403 (const_string "*")))])
11405 (define_insn "*ashrhi3_1"
11406 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11407 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11408 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11409 (clobber (reg:CC FLAGS_REG))]
11410 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11412 sar{w}\t{%2, %0|%0, %2}
11413 sar{w}\t{%b2, %0|%0, %b2}"
11414 [(set_attr "type" "ishift")
11415 (set_attr "mode" "HI")])
11417 ;; This pattern can't accept a variable shift count, since shifts by
11418 ;; zero don't affect the flags. We assume that shifts by constant
11419 ;; zero are optimized away.
11420 (define_insn "*ashrhi3_one_bit_cmp"
11421 [(set (reg FLAGS_REG)
11423 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11424 (match_operand:QI 2 "const1_operand" ""))
11426 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11427 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11428 "ix86_match_ccmode (insn, CCGOCmode)
11429 && (TARGET_SHIFT1 || optimize_size)
11430 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11432 [(set_attr "type" "ishift")
11433 (set (attr "length")
11434 (if_then_else (match_operand 0 "register_operand" "")
11436 (const_string "*")))])
11438 ;; This pattern can't accept a variable shift count, since shifts by
11439 ;; zero don't affect the flags. We assume that shifts by constant
11440 ;; zero are optimized away.
11441 (define_insn "*ashrhi3_cmp"
11442 [(set (reg FLAGS_REG)
11444 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11445 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11447 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11448 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11449 "ix86_match_ccmode (insn, CCGOCmode)
11450 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11451 "sar{w}\t{%2, %0|%0, %2}"
11452 [(set_attr "type" "ishift")
11453 (set_attr "mode" "HI")])
11455 (define_expand "ashrqi3"
11456 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11457 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11458 (match_operand:QI 2 "nonmemory_operand" "")))
11459 (clobber (reg:CC FLAGS_REG))]
11460 "TARGET_QIMODE_MATH"
11461 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11463 (define_insn "*ashrqi3_1_one_bit"
11464 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11465 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11466 (match_operand:QI 2 "const1_operand" "")))
11467 (clobber (reg:CC FLAGS_REG))]
11468 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11469 && (TARGET_SHIFT1 || optimize_size)"
11471 [(set_attr "type" "ishift")
11472 (set (attr "length")
11473 (if_then_else (match_operand 0 "register_operand" "")
11475 (const_string "*")))])
11477 (define_insn "*ashrqi3_1_one_bit_slp"
11478 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11479 (ashiftrt:QI (match_dup 0)
11480 (match_operand:QI 1 "const1_operand" "")))
11481 (clobber (reg:CC FLAGS_REG))]
11482 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11483 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11484 && (TARGET_SHIFT1 || optimize_size)"
11486 [(set_attr "type" "ishift1")
11487 (set (attr "length")
11488 (if_then_else (match_operand 0 "register_operand" "")
11490 (const_string "*")))])
11492 (define_insn "*ashrqi3_1"
11493 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11494 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11495 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11496 (clobber (reg:CC FLAGS_REG))]
11497 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11499 sar{b}\t{%2, %0|%0, %2}
11500 sar{b}\t{%b2, %0|%0, %b2}"
11501 [(set_attr "type" "ishift")
11502 (set_attr "mode" "QI")])
11504 (define_insn "*ashrqi3_1_slp"
11505 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11506 (ashiftrt:QI (match_dup 0)
11507 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11508 (clobber (reg:CC FLAGS_REG))]
11509 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11510 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11512 sar{b}\t{%1, %0|%0, %1}
11513 sar{b}\t{%b1, %0|%0, %b1}"
11514 [(set_attr "type" "ishift1")
11515 (set_attr "mode" "QI")])
11517 ;; This pattern can't accept a variable shift count, since shifts by
11518 ;; zero don't affect the flags. We assume that shifts by constant
11519 ;; zero are optimized away.
11520 (define_insn "*ashrqi3_one_bit_cmp"
11521 [(set (reg FLAGS_REG)
11523 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11524 (match_operand:QI 2 "const1_operand" "I"))
11526 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11527 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11528 "ix86_match_ccmode (insn, CCGOCmode)
11529 && (TARGET_SHIFT1 || optimize_size)
11530 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11532 [(set_attr "type" "ishift")
11533 (set (attr "length")
11534 (if_then_else (match_operand 0 "register_operand" "")
11536 (const_string "*")))])
11538 ;; This pattern can't accept a variable shift count, since shifts by
11539 ;; zero don't affect the flags. We assume that shifts by constant
11540 ;; zero are optimized away.
11541 (define_insn "*ashrqi3_cmp"
11542 [(set (reg FLAGS_REG)
11544 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11545 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11547 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11548 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11549 "ix86_match_ccmode (insn, CCGOCmode)
11550 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11551 "sar{b}\t{%2, %0|%0, %2}"
11552 [(set_attr "type" "ishift")
11553 (set_attr "mode" "QI")])
11555 ;; Logical shift instructions
11557 ;; See comment above `ashldi3' about how this works.
11559 (define_expand "lshrti3"
11560 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11561 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11562 (match_operand:QI 2 "nonmemory_operand" "")))
11563 (clobber (reg:CC FLAGS_REG))])]
11566 if (! immediate_operand (operands[2], QImode))
11568 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11571 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11575 (define_insn "lshrti3_1"
11576 [(set (match_operand:TI 0 "register_operand" "=r")
11577 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11578 (match_operand:QI 2 "register_operand" "c")))
11579 (clobber (match_scratch:DI 3 "=&r"))
11580 (clobber (reg:CC FLAGS_REG))]
11583 [(set_attr "type" "multi")])
11585 (define_insn "*lshrti3_2"
11586 [(set (match_operand:TI 0 "register_operand" "=r")
11587 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11588 (match_operand:QI 2 "immediate_operand" "O")))
11589 (clobber (reg:CC FLAGS_REG))]
11592 [(set_attr "type" "multi")])
11595 [(set (match_operand:TI 0 "register_operand" "")
11596 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11597 (match_operand:QI 2 "register_operand" "")))
11598 (clobber (match_scratch:DI 3 ""))
11599 (clobber (reg:CC FLAGS_REG))]
11600 "TARGET_64BIT && reload_completed"
11602 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11605 [(set (match_operand:TI 0 "register_operand" "")
11606 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11607 (match_operand:QI 2 "immediate_operand" "")))
11608 (clobber (reg:CC FLAGS_REG))]
11609 "TARGET_64BIT && reload_completed"
11611 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11613 (define_expand "lshrdi3"
11614 [(set (match_operand:DI 0 "shiftdi_operand" "")
11615 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11616 (match_operand:QI 2 "nonmemory_operand" "")))]
11618 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11620 (define_insn "*lshrdi3_1_one_bit_rex64"
11621 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11622 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11623 (match_operand:QI 2 "const1_operand" "")))
11624 (clobber (reg:CC FLAGS_REG))]
11625 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11626 && (TARGET_SHIFT1 || optimize_size)"
11628 [(set_attr "type" "ishift")
11629 (set (attr "length")
11630 (if_then_else (match_operand:DI 0 "register_operand" "")
11632 (const_string "*")))])
11634 (define_insn "*lshrdi3_1_rex64"
11635 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11636 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11637 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11638 (clobber (reg:CC FLAGS_REG))]
11639 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11641 shr{q}\t{%2, %0|%0, %2}
11642 shr{q}\t{%b2, %0|%0, %b2}"
11643 [(set_attr "type" "ishift")
11644 (set_attr "mode" "DI")])
11646 ;; This pattern can't accept a variable shift count, since shifts by
11647 ;; zero don't affect the flags. We assume that shifts by constant
11648 ;; zero are optimized away.
11649 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11650 [(set (reg FLAGS_REG)
11652 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11653 (match_operand:QI 2 "const1_operand" ""))
11655 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11656 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11657 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11658 && (TARGET_SHIFT1 || optimize_size)
11659 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11661 [(set_attr "type" "ishift")
11662 (set (attr "length")
11663 (if_then_else (match_operand:DI 0 "register_operand" "")
11665 (const_string "*")))])
11667 ;; This pattern can't accept a variable shift count, since shifts by
11668 ;; zero don't affect the flags. We assume that shifts by constant
11669 ;; zero are optimized away.
11670 (define_insn "*lshrdi3_cmp_rex64"
11671 [(set (reg FLAGS_REG)
11673 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11674 (match_operand:QI 2 "const_int_operand" "e"))
11676 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11677 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11678 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11679 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11680 "shr{q}\t{%2, %0|%0, %2}"
11681 [(set_attr "type" "ishift")
11682 (set_attr "mode" "DI")])
11684 (define_insn "*lshrdi3_1"
11685 [(set (match_operand:DI 0 "register_operand" "=r")
11686 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11687 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11688 (clobber (reg:CC FLAGS_REG))]
11691 [(set_attr "type" "multi")])
11693 ;; By default we don't ask for a scratch register, because when DImode
11694 ;; values are manipulated, registers are already at a premium. But if
11695 ;; we have one handy, we won't turn it away.
11697 [(match_scratch:SI 3 "r")
11698 (parallel [(set (match_operand:DI 0 "register_operand" "")
11699 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11700 (match_operand:QI 2 "nonmemory_operand" "")))
11701 (clobber (reg:CC FLAGS_REG))])
11703 "!TARGET_64BIT && TARGET_CMOVE"
11705 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11708 [(set (match_operand:DI 0 "register_operand" "")
11709 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11710 (match_operand:QI 2 "nonmemory_operand" "")))
11711 (clobber (reg:CC FLAGS_REG))]
11712 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11713 ? flow2_completed : reload_completed)"
11715 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11717 (define_expand "lshrsi3"
11718 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11719 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11720 (match_operand:QI 2 "nonmemory_operand" "")))
11721 (clobber (reg:CC FLAGS_REG))]
11723 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11725 (define_insn "*lshrsi3_1_one_bit"
11726 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11727 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11728 (match_operand:QI 2 "const1_operand" "")))
11729 (clobber (reg:CC FLAGS_REG))]
11730 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11731 && (TARGET_SHIFT1 || optimize_size)"
11733 [(set_attr "type" "ishift")
11734 (set (attr "length")
11735 (if_then_else (match_operand:SI 0 "register_operand" "")
11737 (const_string "*")))])
11739 (define_insn "*lshrsi3_1_one_bit_zext"
11740 [(set (match_operand:DI 0 "register_operand" "=r")
11741 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11742 (match_operand:QI 2 "const1_operand" "")))
11743 (clobber (reg:CC FLAGS_REG))]
11744 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11745 && (TARGET_SHIFT1 || optimize_size)"
11747 [(set_attr "type" "ishift")
11748 (set_attr "length" "2")])
11750 (define_insn "*lshrsi3_1"
11751 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11752 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11753 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11754 (clobber (reg:CC FLAGS_REG))]
11755 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11757 shr{l}\t{%2, %0|%0, %2}
11758 shr{l}\t{%b2, %0|%0, %b2}"
11759 [(set_attr "type" "ishift")
11760 (set_attr "mode" "SI")])
11762 (define_insn "*lshrsi3_1_zext"
11763 [(set (match_operand:DI 0 "register_operand" "=r,r")
11765 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11766 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11767 (clobber (reg:CC FLAGS_REG))]
11768 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11770 shr{l}\t{%2, %k0|%k0, %2}
11771 shr{l}\t{%b2, %k0|%k0, %b2}"
11772 [(set_attr "type" "ishift")
11773 (set_attr "mode" "SI")])
11775 ;; This pattern can't accept a variable shift count, since shifts by
11776 ;; zero don't affect the flags. We assume that shifts by constant
11777 ;; zero are optimized away.
11778 (define_insn "*lshrsi3_one_bit_cmp"
11779 [(set (reg FLAGS_REG)
11781 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11782 (match_operand:QI 2 "const1_operand" ""))
11784 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11785 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11786 "ix86_match_ccmode (insn, CCGOCmode)
11787 && (TARGET_SHIFT1 || optimize_size)
11788 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11790 [(set_attr "type" "ishift")
11791 (set (attr "length")
11792 (if_then_else (match_operand:SI 0 "register_operand" "")
11794 (const_string "*")))])
11796 (define_insn "*lshrsi3_cmp_one_bit_zext"
11797 [(set (reg FLAGS_REG)
11799 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11800 (match_operand:QI 2 "const1_operand" ""))
11802 (set (match_operand:DI 0 "register_operand" "=r")
11803 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11804 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11805 && (TARGET_SHIFT1 || optimize_size)
11806 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11808 [(set_attr "type" "ishift")
11809 (set_attr "length" "2")])
11811 ;; This pattern can't accept a variable shift count, since shifts by
11812 ;; zero don't affect the flags. We assume that shifts by constant
11813 ;; zero are optimized away.
11814 (define_insn "*lshrsi3_cmp"
11815 [(set (reg FLAGS_REG)
11817 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11818 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11820 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11821 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11822 "ix86_match_ccmode (insn, CCGOCmode)
11823 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11824 "shr{l}\t{%2, %0|%0, %2}"
11825 [(set_attr "type" "ishift")
11826 (set_attr "mode" "SI")])
11828 (define_insn "*lshrsi3_cmp_zext"
11829 [(set (reg FLAGS_REG)
11831 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11832 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11834 (set (match_operand:DI 0 "register_operand" "=r")
11835 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11836 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11837 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11838 "shr{l}\t{%2, %k0|%k0, %2}"
11839 [(set_attr "type" "ishift")
11840 (set_attr "mode" "SI")])
11842 (define_expand "lshrhi3"
11843 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11844 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11845 (match_operand:QI 2 "nonmemory_operand" "")))
11846 (clobber (reg:CC FLAGS_REG))]
11847 "TARGET_HIMODE_MATH"
11848 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11850 (define_insn "*lshrhi3_1_one_bit"
11851 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11852 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11853 (match_operand:QI 2 "const1_operand" "")))
11854 (clobber (reg:CC FLAGS_REG))]
11855 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11856 && (TARGET_SHIFT1 || optimize_size)"
11858 [(set_attr "type" "ishift")
11859 (set (attr "length")
11860 (if_then_else (match_operand 0 "register_operand" "")
11862 (const_string "*")))])
11864 (define_insn "*lshrhi3_1"
11865 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11866 (lshiftrt:HI (match_operand:HI 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 (LSHIFTRT, HImode, operands)"
11871 shr{w}\t{%2, %0|%0, %2}
11872 shr{w}\t{%b2, %0|%0, %b2}"
11873 [(set_attr "type" "ishift")
11874 (set_attr "mode" "HI")])
11876 ;; This pattern can't accept a variable shift count, since shifts by
11877 ;; zero don't affect the flags. We assume that shifts by constant
11878 ;; zero are optimized away.
11879 (define_insn "*lshrhi3_one_bit_cmp"
11880 [(set (reg FLAGS_REG)
11882 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11883 (match_operand:QI 2 "const1_operand" ""))
11885 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11886 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11887 "ix86_match_ccmode (insn, CCGOCmode)
11888 && (TARGET_SHIFT1 || optimize_size)
11889 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11891 [(set_attr "type" "ishift")
11892 (set (attr "length")
11893 (if_then_else (match_operand:SI 0 "register_operand" "")
11895 (const_string "*")))])
11897 ;; This pattern can't accept a variable shift count, since shifts by
11898 ;; zero don't affect the flags. We assume that shifts by constant
11899 ;; zero are optimized away.
11900 (define_insn "*lshrhi3_cmp"
11901 [(set (reg FLAGS_REG)
11903 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11904 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11906 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11907 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11908 "ix86_match_ccmode (insn, CCGOCmode)
11909 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11910 "shr{w}\t{%2, %0|%0, %2}"
11911 [(set_attr "type" "ishift")
11912 (set_attr "mode" "HI")])
11914 (define_expand "lshrqi3"
11915 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11916 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11917 (match_operand:QI 2 "nonmemory_operand" "")))
11918 (clobber (reg:CC FLAGS_REG))]
11919 "TARGET_QIMODE_MATH"
11920 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11922 (define_insn "*lshrqi3_1_one_bit"
11923 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11924 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11925 (match_operand:QI 2 "const1_operand" "")))
11926 (clobber (reg:CC FLAGS_REG))]
11927 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11928 && (TARGET_SHIFT1 || optimize_size)"
11930 [(set_attr "type" "ishift")
11931 (set (attr "length")
11932 (if_then_else (match_operand 0 "register_operand" "")
11934 (const_string "*")))])
11936 (define_insn "*lshrqi3_1_one_bit_slp"
11937 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11938 (lshiftrt:QI (match_dup 0)
11939 (match_operand:QI 1 "const1_operand" "")))
11940 (clobber (reg:CC FLAGS_REG))]
11941 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11942 && (TARGET_SHIFT1 || optimize_size)"
11944 [(set_attr "type" "ishift1")
11945 (set (attr "length")
11946 (if_then_else (match_operand 0 "register_operand" "")
11948 (const_string "*")))])
11950 (define_insn "*lshrqi3_1"
11951 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11952 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11953 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11954 (clobber (reg:CC FLAGS_REG))]
11955 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11957 shr{b}\t{%2, %0|%0, %2}
11958 shr{b}\t{%b2, %0|%0, %b2}"
11959 [(set_attr "type" "ishift")
11960 (set_attr "mode" "QI")])
11962 (define_insn "*lshrqi3_1_slp"
11963 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11964 (lshiftrt:QI (match_dup 0)
11965 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11966 (clobber (reg:CC FLAGS_REG))]
11967 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11968 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11970 shr{b}\t{%1, %0|%0, %1}
11971 shr{b}\t{%b1, %0|%0, %b1}"
11972 [(set_attr "type" "ishift1")
11973 (set_attr "mode" "QI")])
11975 ;; This pattern can't accept a variable shift count, since shifts by
11976 ;; zero don't affect the flags. We assume that shifts by constant
11977 ;; zero are optimized away.
11978 (define_insn "*lshrqi2_one_bit_cmp"
11979 [(set (reg FLAGS_REG)
11981 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11982 (match_operand:QI 2 "const1_operand" ""))
11984 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11985 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11986 "ix86_match_ccmode (insn, CCGOCmode)
11987 && (TARGET_SHIFT1 || optimize_size)
11988 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11990 [(set_attr "type" "ishift")
11991 (set (attr "length")
11992 (if_then_else (match_operand:SI 0 "register_operand" "")
11994 (const_string "*")))])
11996 ;; This pattern can't accept a variable shift count, since shifts by
11997 ;; zero don't affect the flags. We assume that shifts by constant
11998 ;; zero are optimized away.
11999 (define_insn "*lshrqi2_cmp"
12000 [(set (reg FLAGS_REG)
12002 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12003 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12005 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12006 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12007 "ix86_match_ccmode (insn, CCGOCmode)
12008 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12009 "shr{b}\t{%2, %0|%0, %2}"
12010 [(set_attr "type" "ishift")
12011 (set_attr "mode" "QI")])
12013 ;; Rotate instructions
12015 (define_expand "rotldi3"
12016 [(set (match_operand:DI 0 "shiftdi_operand" "")
12017 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12018 (match_operand:QI 2 "nonmemory_operand" "")))
12019 (clobber (reg:CC FLAGS_REG))]
12024 ix86_expand_binary_operator (ROTATE, DImode, operands);
12027 if (!const_1_to_31_operand (operands[2], VOIDmode))
12029 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12033 ;; Implement rotation using two double-precision shift instructions
12034 ;; and a scratch register.
12035 (define_insn_and_split "ix86_rotldi3"
12036 [(set (match_operand:DI 0 "register_operand" "=r")
12037 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12038 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12039 (clobber (reg:CC FLAGS_REG))
12040 (clobber (match_scratch:SI 3 "=&r"))]
12043 "&& reload_completed"
12044 [(set (match_dup 3) (match_dup 4))
12046 [(set (match_dup 4)
12047 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12048 (lshiftrt:SI (match_dup 5)
12049 (minus:QI (const_int 32) (match_dup 2)))))
12050 (clobber (reg:CC FLAGS_REG))])
12052 [(set (match_dup 5)
12053 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12054 (lshiftrt:SI (match_dup 3)
12055 (minus:QI (const_int 32) (match_dup 2)))))
12056 (clobber (reg:CC FLAGS_REG))])]
12057 "split_di (operands, 1, operands + 4, operands + 5);")
12059 (define_insn "*rotlsi3_1_one_bit_rex64"
12060 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12061 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12062 (match_operand:QI 2 "const1_operand" "")))
12063 (clobber (reg:CC FLAGS_REG))]
12064 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12065 && (TARGET_SHIFT1 || optimize_size)"
12067 [(set_attr "type" "rotate")
12068 (set (attr "length")
12069 (if_then_else (match_operand:DI 0 "register_operand" "")
12071 (const_string "*")))])
12073 (define_insn "*rotldi3_1_rex64"
12074 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12075 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12076 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12077 (clobber (reg:CC FLAGS_REG))]
12078 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12080 rol{q}\t{%2, %0|%0, %2}
12081 rol{q}\t{%b2, %0|%0, %b2}"
12082 [(set_attr "type" "rotate")
12083 (set_attr "mode" "DI")])
12085 (define_expand "rotlsi3"
12086 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12087 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12088 (match_operand:QI 2 "nonmemory_operand" "")))
12089 (clobber (reg:CC FLAGS_REG))]
12091 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12093 (define_insn "*rotlsi3_1_one_bit"
12094 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12095 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12096 (match_operand:QI 2 "const1_operand" "")))
12097 (clobber (reg:CC FLAGS_REG))]
12098 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12099 && (TARGET_SHIFT1 || optimize_size)"
12101 [(set_attr "type" "rotate")
12102 (set (attr "length")
12103 (if_then_else (match_operand:SI 0 "register_operand" "")
12105 (const_string "*")))])
12107 (define_insn "*rotlsi3_1_one_bit_zext"
12108 [(set (match_operand:DI 0 "register_operand" "=r")
12110 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12111 (match_operand:QI 2 "const1_operand" ""))))
12112 (clobber (reg:CC FLAGS_REG))]
12113 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12114 && (TARGET_SHIFT1 || optimize_size)"
12116 [(set_attr "type" "rotate")
12117 (set_attr "length" "2")])
12119 (define_insn "*rotlsi3_1"
12120 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12121 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12122 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12123 (clobber (reg:CC FLAGS_REG))]
12124 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12126 rol{l}\t{%2, %0|%0, %2}
12127 rol{l}\t{%b2, %0|%0, %b2}"
12128 [(set_attr "type" "rotate")
12129 (set_attr "mode" "SI")])
12131 (define_insn "*rotlsi3_1_zext"
12132 [(set (match_operand:DI 0 "register_operand" "=r,r")
12134 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12135 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12136 (clobber (reg:CC FLAGS_REG))]
12137 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12139 rol{l}\t{%2, %k0|%k0, %2}
12140 rol{l}\t{%b2, %k0|%k0, %b2}"
12141 [(set_attr "type" "rotate")
12142 (set_attr "mode" "SI")])
12144 (define_expand "rotlhi3"
12145 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12146 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12147 (match_operand:QI 2 "nonmemory_operand" "")))
12148 (clobber (reg:CC FLAGS_REG))]
12149 "TARGET_HIMODE_MATH"
12150 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12152 (define_insn "*rotlhi3_1_one_bit"
12153 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12154 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12155 (match_operand:QI 2 "const1_operand" "")))
12156 (clobber (reg:CC FLAGS_REG))]
12157 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12158 && (TARGET_SHIFT1 || optimize_size)"
12160 [(set_attr "type" "rotate")
12161 (set (attr "length")
12162 (if_then_else (match_operand 0 "register_operand" "")
12164 (const_string "*")))])
12166 (define_insn "*rotlhi3_1"
12167 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12168 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12169 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12170 (clobber (reg:CC FLAGS_REG))]
12171 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12173 rol{w}\t{%2, %0|%0, %2}
12174 rol{w}\t{%b2, %0|%0, %b2}"
12175 [(set_attr "type" "rotate")
12176 (set_attr "mode" "HI")])
12178 (define_expand "rotlqi3"
12179 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12180 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12181 (match_operand:QI 2 "nonmemory_operand" "")))
12182 (clobber (reg:CC FLAGS_REG))]
12183 "TARGET_QIMODE_MATH"
12184 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12186 (define_insn "*rotlqi3_1_one_bit_slp"
12187 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12188 (rotate:QI (match_dup 0)
12189 (match_operand:QI 1 "const1_operand" "")))
12190 (clobber (reg:CC FLAGS_REG))]
12191 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12192 && (TARGET_SHIFT1 || optimize_size)"
12194 [(set_attr "type" "rotate1")
12195 (set (attr "length")
12196 (if_then_else (match_operand 0 "register_operand" "")
12198 (const_string "*")))])
12200 (define_insn "*rotlqi3_1_one_bit"
12201 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12202 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12203 (match_operand:QI 2 "const1_operand" "")))
12204 (clobber (reg:CC FLAGS_REG))]
12205 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12206 && (TARGET_SHIFT1 || optimize_size)"
12208 [(set_attr "type" "rotate")
12209 (set (attr "length")
12210 (if_then_else (match_operand 0 "register_operand" "")
12212 (const_string "*")))])
12214 (define_insn "*rotlqi3_1_slp"
12215 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12216 (rotate:QI (match_dup 0)
12217 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12218 (clobber (reg:CC FLAGS_REG))]
12219 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12220 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12222 rol{b}\t{%1, %0|%0, %1}
12223 rol{b}\t{%b1, %0|%0, %b1}"
12224 [(set_attr "type" "rotate1")
12225 (set_attr "mode" "QI")])
12227 (define_insn "*rotlqi3_1"
12228 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12229 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12230 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12231 (clobber (reg:CC FLAGS_REG))]
12232 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12234 rol{b}\t{%2, %0|%0, %2}
12235 rol{b}\t{%b2, %0|%0, %b2}"
12236 [(set_attr "type" "rotate")
12237 (set_attr "mode" "QI")])
12239 (define_expand "rotrdi3"
12240 [(set (match_operand:DI 0 "shiftdi_operand" "")
12241 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12242 (match_operand:QI 2 "nonmemory_operand" "")))
12243 (clobber (reg:CC FLAGS_REG))]
12248 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12251 if (!const_1_to_31_operand (operands[2], VOIDmode))
12253 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12257 ;; Implement rotation using two double-precision shift instructions
12258 ;; and a scratch register.
12259 (define_insn_and_split "ix86_rotrdi3"
12260 [(set (match_operand:DI 0 "register_operand" "=r")
12261 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12262 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12263 (clobber (reg:CC FLAGS_REG))
12264 (clobber (match_scratch:SI 3 "=&r"))]
12267 "&& reload_completed"
12268 [(set (match_dup 3) (match_dup 4))
12270 [(set (match_dup 4)
12271 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12272 (ashift:SI (match_dup 5)
12273 (minus:QI (const_int 32) (match_dup 2)))))
12274 (clobber (reg:CC FLAGS_REG))])
12276 [(set (match_dup 5)
12277 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12278 (ashift:SI (match_dup 3)
12279 (minus:QI (const_int 32) (match_dup 2)))))
12280 (clobber (reg:CC FLAGS_REG))])]
12281 "split_di (operands, 1, operands + 4, operands + 5);")
12283 (define_insn "*rotrdi3_1_one_bit_rex64"
12284 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12285 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12286 (match_operand:QI 2 "const1_operand" "")))
12287 (clobber (reg:CC FLAGS_REG))]
12288 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12289 && (TARGET_SHIFT1 || optimize_size)"
12291 [(set_attr "type" "rotate")
12292 (set (attr "length")
12293 (if_then_else (match_operand:DI 0 "register_operand" "")
12295 (const_string "*")))])
12297 (define_insn "*rotrdi3_1_rex64"
12298 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12299 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12300 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12301 (clobber (reg:CC FLAGS_REG))]
12302 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12304 ror{q}\t{%2, %0|%0, %2}
12305 ror{q}\t{%b2, %0|%0, %b2}"
12306 [(set_attr "type" "rotate")
12307 (set_attr "mode" "DI")])
12309 (define_expand "rotrsi3"
12310 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12311 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12312 (match_operand:QI 2 "nonmemory_operand" "")))
12313 (clobber (reg:CC FLAGS_REG))]
12315 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12317 (define_insn "*rotrsi3_1_one_bit"
12318 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12319 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12320 (match_operand:QI 2 "const1_operand" "")))
12321 (clobber (reg:CC FLAGS_REG))]
12322 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12323 && (TARGET_SHIFT1 || optimize_size)"
12325 [(set_attr "type" "rotate")
12326 (set (attr "length")
12327 (if_then_else (match_operand:SI 0 "register_operand" "")
12329 (const_string "*")))])
12331 (define_insn "*rotrsi3_1_one_bit_zext"
12332 [(set (match_operand:DI 0 "register_operand" "=r")
12334 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12335 (match_operand:QI 2 "const1_operand" ""))))
12336 (clobber (reg:CC FLAGS_REG))]
12337 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12338 && (TARGET_SHIFT1 || optimize_size)"
12340 [(set_attr "type" "rotate")
12341 (set (attr "length")
12342 (if_then_else (match_operand:SI 0 "register_operand" "")
12344 (const_string "*")))])
12346 (define_insn "*rotrsi3_1"
12347 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12348 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12349 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12350 (clobber (reg:CC FLAGS_REG))]
12351 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12353 ror{l}\t{%2, %0|%0, %2}
12354 ror{l}\t{%b2, %0|%0, %b2}"
12355 [(set_attr "type" "rotate")
12356 (set_attr "mode" "SI")])
12358 (define_insn "*rotrsi3_1_zext"
12359 [(set (match_operand:DI 0 "register_operand" "=r,r")
12361 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12362 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12363 (clobber (reg:CC FLAGS_REG))]
12364 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12366 ror{l}\t{%2, %k0|%k0, %2}
12367 ror{l}\t{%b2, %k0|%k0, %b2}"
12368 [(set_attr "type" "rotate")
12369 (set_attr "mode" "SI")])
12371 (define_expand "rotrhi3"
12372 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12373 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12374 (match_operand:QI 2 "nonmemory_operand" "")))
12375 (clobber (reg:CC FLAGS_REG))]
12376 "TARGET_HIMODE_MATH"
12377 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12379 (define_insn "*rotrhi3_one_bit"
12380 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12381 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12382 (match_operand:QI 2 "const1_operand" "")))
12383 (clobber (reg:CC FLAGS_REG))]
12384 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12385 && (TARGET_SHIFT1 || optimize_size)"
12387 [(set_attr "type" "rotate")
12388 (set (attr "length")
12389 (if_then_else (match_operand 0 "register_operand" "")
12391 (const_string "*")))])
12393 (define_insn "*rotrhi3"
12394 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12395 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12396 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12397 (clobber (reg:CC FLAGS_REG))]
12398 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12400 ror{w}\t{%2, %0|%0, %2}
12401 ror{w}\t{%b2, %0|%0, %b2}"
12402 [(set_attr "type" "rotate")
12403 (set_attr "mode" "HI")])
12405 (define_expand "rotrqi3"
12406 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12407 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12408 (match_operand:QI 2 "nonmemory_operand" "")))
12409 (clobber (reg:CC FLAGS_REG))]
12410 "TARGET_QIMODE_MATH"
12411 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12413 (define_insn "*rotrqi3_1_one_bit"
12414 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12415 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12416 (match_operand:QI 2 "const1_operand" "")))
12417 (clobber (reg:CC FLAGS_REG))]
12418 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12419 && (TARGET_SHIFT1 || optimize_size)"
12421 [(set_attr "type" "rotate")
12422 (set (attr "length")
12423 (if_then_else (match_operand 0 "register_operand" "")
12425 (const_string "*")))])
12427 (define_insn "*rotrqi3_1_one_bit_slp"
12428 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12429 (rotatert:QI (match_dup 0)
12430 (match_operand:QI 1 "const1_operand" "")))
12431 (clobber (reg:CC FLAGS_REG))]
12432 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12433 && (TARGET_SHIFT1 || optimize_size)"
12435 [(set_attr "type" "rotate1")
12436 (set (attr "length")
12437 (if_then_else (match_operand 0 "register_operand" "")
12439 (const_string "*")))])
12441 (define_insn "*rotrqi3_1"
12442 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12443 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12444 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12445 (clobber (reg:CC FLAGS_REG))]
12446 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12448 ror{b}\t{%2, %0|%0, %2}
12449 ror{b}\t{%b2, %0|%0, %b2}"
12450 [(set_attr "type" "rotate")
12451 (set_attr "mode" "QI")])
12453 (define_insn "*rotrqi3_1_slp"
12454 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12455 (rotatert:QI (match_dup 0)
12456 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12457 (clobber (reg:CC FLAGS_REG))]
12458 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12459 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12461 ror{b}\t{%1, %0|%0, %1}
12462 ror{b}\t{%b1, %0|%0, %b1}"
12463 [(set_attr "type" "rotate1")
12464 (set_attr "mode" "QI")])
12466 ;; Bit set / bit test instructions
12468 (define_expand "extv"
12469 [(set (match_operand:SI 0 "register_operand" "")
12470 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12471 (match_operand:SI 2 "immediate_operand" "")
12472 (match_operand:SI 3 "immediate_operand" "")))]
12475 /* Handle extractions from %ah et al. */
12476 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12479 /* From mips.md: extract_bit_field doesn't verify that our source
12480 matches the predicate, so check it again here. */
12481 if (! ext_register_operand (operands[1], VOIDmode))
12485 (define_expand "extzv"
12486 [(set (match_operand:SI 0 "register_operand" "")
12487 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12488 (match_operand:SI 2 "immediate_operand" "")
12489 (match_operand:SI 3 "immediate_operand" "")))]
12492 /* Handle extractions from %ah et al. */
12493 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12496 /* From mips.md: extract_bit_field doesn't verify that our source
12497 matches the predicate, so check it again here. */
12498 if (! ext_register_operand (operands[1], VOIDmode))
12502 (define_expand "insv"
12503 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12504 (match_operand 1 "immediate_operand" "")
12505 (match_operand 2 "immediate_operand" ""))
12506 (match_operand 3 "register_operand" ""))]
12509 /* Handle extractions from %ah et al. */
12510 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12513 /* From mips.md: insert_bit_field doesn't verify that our source
12514 matches the predicate, so check it again here. */
12515 if (! ext_register_operand (operands[0], VOIDmode))
12519 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12521 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12526 ;; %%% bts, btr, btc, bt.
12527 ;; In general these instructions are *slow* when applied to memory,
12528 ;; since they enforce atomic operation. When applied to registers,
12529 ;; it depends on the cpu implementation. They're never faster than
12530 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12531 ;; no point. But in 64-bit, we can't hold the relevant immediates
12532 ;; within the instruction itself, so operating on bits in the high
12533 ;; 32-bits of a register becomes easier.
12535 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12536 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12537 ;; negdf respectively, so they can never be disabled entirely.
12539 (define_insn "*btsq"
12540 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12542 (match_operand:DI 1 "const_0_to_63_operand" ""))
12544 (clobber (reg:CC FLAGS_REG))]
12545 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12547 [(set_attr "type" "alu1")])
12549 (define_insn "*btrq"
12550 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12552 (match_operand:DI 1 "const_0_to_63_operand" ""))
12554 (clobber (reg:CC FLAGS_REG))]
12555 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12557 [(set_attr "type" "alu1")])
12559 (define_insn "*btcq"
12560 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12562 (match_operand:DI 1 "const_0_to_63_operand" ""))
12563 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12564 (clobber (reg:CC FLAGS_REG))]
12565 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12567 [(set_attr "type" "alu1")])
12569 ;; Allow Nocona to avoid these instructions if a register is available.
12572 [(match_scratch:DI 2 "r")
12573 (parallel [(set (zero_extract:DI
12574 (match_operand:DI 0 "register_operand" "")
12576 (match_operand:DI 1 "const_0_to_63_operand" ""))
12578 (clobber (reg:CC FLAGS_REG))])]
12579 "TARGET_64BIT && !TARGET_USE_BT"
12582 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12585 if (HOST_BITS_PER_WIDE_INT >= 64)
12586 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12587 else if (i < HOST_BITS_PER_WIDE_INT)
12588 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12590 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12592 op1 = immed_double_const (lo, hi, DImode);
12595 emit_move_insn (operands[2], op1);
12599 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12604 [(match_scratch:DI 2 "r")
12605 (parallel [(set (zero_extract:DI
12606 (match_operand:DI 0 "register_operand" "")
12608 (match_operand:DI 1 "const_0_to_63_operand" ""))
12610 (clobber (reg:CC FLAGS_REG))])]
12611 "TARGET_64BIT && !TARGET_USE_BT"
12614 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12617 if (HOST_BITS_PER_WIDE_INT >= 64)
12618 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12619 else if (i < HOST_BITS_PER_WIDE_INT)
12620 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12622 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12624 op1 = immed_double_const (~lo, ~hi, DImode);
12627 emit_move_insn (operands[2], op1);
12631 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12636 [(match_scratch:DI 2 "r")
12637 (parallel [(set (zero_extract:DI
12638 (match_operand:DI 0 "register_operand" "")
12640 (match_operand:DI 1 "const_0_to_63_operand" ""))
12641 (not:DI (zero_extract:DI
12642 (match_dup 0) (const_int 1) (match_dup 1))))
12643 (clobber (reg:CC FLAGS_REG))])]
12644 "TARGET_64BIT && !TARGET_USE_BT"
12647 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12650 if (HOST_BITS_PER_WIDE_INT >= 64)
12651 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12652 else if (i < HOST_BITS_PER_WIDE_INT)
12653 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12655 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12657 op1 = immed_double_const (lo, hi, DImode);
12660 emit_move_insn (operands[2], op1);
12664 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12668 ;; Store-flag instructions.
12670 ;; For all sCOND expanders, also expand the compare or test insn that
12671 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12673 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12674 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12675 ;; way, which can later delete the movzx if only QImode is needed.
12677 (define_expand "seq"
12678 [(set (match_operand:QI 0 "register_operand" "")
12679 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12681 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12683 (define_expand "sne"
12684 [(set (match_operand:QI 0 "register_operand" "")
12685 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12687 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12689 (define_expand "sgt"
12690 [(set (match_operand:QI 0 "register_operand" "")
12691 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12693 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12695 (define_expand "sgtu"
12696 [(set (match_operand:QI 0 "register_operand" "")
12697 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12699 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12701 (define_expand "slt"
12702 [(set (match_operand:QI 0 "register_operand" "")
12703 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12705 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12707 (define_expand "sltu"
12708 [(set (match_operand:QI 0 "register_operand" "")
12709 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12711 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12713 (define_expand "sge"
12714 [(set (match_operand:QI 0 "register_operand" "")
12715 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12717 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12719 (define_expand "sgeu"
12720 [(set (match_operand:QI 0 "register_operand" "")
12721 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12723 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12725 (define_expand "sle"
12726 [(set (match_operand:QI 0 "register_operand" "")
12727 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12729 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12731 (define_expand "sleu"
12732 [(set (match_operand:QI 0 "register_operand" "")
12733 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12735 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12737 (define_expand "sunordered"
12738 [(set (match_operand:QI 0 "register_operand" "")
12739 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12740 "TARGET_80387 || TARGET_SSE"
12741 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12743 (define_expand "sordered"
12744 [(set (match_operand:QI 0 "register_operand" "")
12745 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12747 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12749 (define_expand "suneq"
12750 [(set (match_operand:QI 0 "register_operand" "")
12751 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12752 "TARGET_80387 || TARGET_SSE"
12753 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12755 (define_expand "sunge"
12756 [(set (match_operand:QI 0 "register_operand" "")
12757 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12758 "TARGET_80387 || TARGET_SSE"
12759 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12761 (define_expand "sungt"
12762 [(set (match_operand:QI 0 "register_operand" "")
12763 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12764 "TARGET_80387 || TARGET_SSE"
12765 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12767 (define_expand "sunle"
12768 [(set (match_operand:QI 0 "register_operand" "")
12769 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12770 "TARGET_80387 || TARGET_SSE"
12771 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12773 (define_expand "sunlt"
12774 [(set (match_operand:QI 0 "register_operand" "")
12775 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12776 "TARGET_80387 || TARGET_SSE"
12777 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12779 (define_expand "sltgt"
12780 [(set (match_operand:QI 0 "register_operand" "")
12781 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12782 "TARGET_80387 || TARGET_SSE"
12783 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12785 (define_insn "*setcc_1"
12786 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12787 (match_operator:QI 1 "ix86_comparison_operator"
12788 [(reg FLAGS_REG) (const_int 0)]))]
12791 [(set_attr "type" "setcc")
12792 (set_attr "mode" "QI")])
12794 (define_insn "*setcc_2"
12795 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12796 (match_operator:QI 1 "ix86_comparison_operator"
12797 [(reg FLAGS_REG) (const_int 0)]))]
12800 [(set_attr "type" "setcc")
12801 (set_attr "mode" "QI")])
12803 ;; In general it is not safe to assume too much about CCmode registers,
12804 ;; so simplify-rtx stops when it sees a second one. Under certain
12805 ;; conditions this is safe on x86, so help combine not create
12812 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12813 (ne:QI (match_operator 1 "ix86_comparison_operator"
12814 [(reg FLAGS_REG) (const_int 0)])
12817 [(set (match_dup 0) (match_dup 1))]
12819 PUT_MODE (operands[1], QImode);
12823 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12824 (ne:QI (match_operator 1 "ix86_comparison_operator"
12825 [(reg FLAGS_REG) (const_int 0)])
12828 [(set (match_dup 0) (match_dup 1))]
12830 PUT_MODE (operands[1], QImode);
12834 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12835 (eq:QI (match_operator 1 "ix86_comparison_operator"
12836 [(reg FLAGS_REG) (const_int 0)])
12839 [(set (match_dup 0) (match_dup 1))]
12841 rtx new_op1 = copy_rtx (operands[1]);
12842 operands[1] = new_op1;
12843 PUT_MODE (new_op1, QImode);
12844 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12845 GET_MODE (XEXP (new_op1, 0))));
12847 /* Make sure that (a) the CCmode we have for the flags is strong
12848 enough for the reversed compare or (b) we have a valid FP compare. */
12849 if (! ix86_comparison_operator (new_op1, VOIDmode))
12854 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12855 (eq:QI (match_operator 1 "ix86_comparison_operator"
12856 [(reg FLAGS_REG) (const_int 0)])
12859 [(set (match_dup 0) (match_dup 1))]
12861 rtx new_op1 = copy_rtx (operands[1]);
12862 operands[1] = new_op1;
12863 PUT_MODE (new_op1, QImode);
12864 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12865 GET_MODE (XEXP (new_op1, 0))));
12867 /* Make sure that (a) the CCmode we have for the flags is strong
12868 enough for the reversed compare or (b) we have a valid FP compare. */
12869 if (! ix86_comparison_operator (new_op1, VOIDmode))
12873 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12874 ;; subsequent logical operations are used to imitate conditional moves.
12875 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12878 (define_insn "*sse_setccsf"
12879 [(set (match_operand:SF 0 "register_operand" "=x")
12880 (match_operator:SF 1 "sse_comparison_operator"
12881 [(match_operand:SF 2 "register_operand" "0")
12882 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12884 "cmp%D1ss\t{%3, %0|%0, %3}"
12885 [(set_attr "type" "ssecmp")
12886 (set_attr "mode" "SF")])
12888 (define_insn "*sse_setccdf"
12889 [(set (match_operand:DF 0 "register_operand" "=Y")
12890 (match_operator:DF 1 "sse_comparison_operator"
12891 [(match_operand:DF 2 "register_operand" "0")
12892 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12894 "cmp%D1sd\t{%3, %0|%0, %3}"
12895 [(set_attr "type" "ssecmp")
12896 (set_attr "mode" "DF")])
12898 ;; Basic conditional jump instructions.
12899 ;; We ignore the overflow flag for signed branch instructions.
12901 ;; For all bCOND expanders, also expand the compare or test insn that
12902 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12904 (define_expand "beq"
12906 (if_then_else (match_dup 1)
12907 (label_ref (match_operand 0 "" ""))
12910 "ix86_expand_branch (EQ, operands[0]); DONE;")
12912 (define_expand "bne"
12914 (if_then_else (match_dup 1)
12915 (label_ref (match_operand 0 "" ""))
12918 "ix86_expand_branch (NE, operands[0]); DONE;")
12920 (define_expand "bgt"
12922 (if_then_else (match_dup 1)
12923 (label_ref (match_operand 0 "" ""))
12926 "ix86_expand_branch (GT, operands[0]); DONE;")
12928 (define_expand "bgtu"
12930 (if_then_else (match_dup 1)
12931 (label_ref (match_operand 0 "" ""))
12934 "ix86_expand_branch (GTU, operands[0]); DONE;")
12936 (define_expand "blt"
12938 (if_then_else (match_dup 1)
12939 (label_ref (match_operand 0 "" ""))
12942 "ix86_expand_branch (LT, operands[0]); DONE;")
12944 (define_expand "bltu"
12946 (if_then_else (match_dup 1)
12947 (label_ref (match_operand 0 "" ""))
12950 "ix86_expand_branch (LTU, operands[0]); DONE;")
12952 (define_expand "bge"
12954 (if_then_else (match_dup 1)
12955 (label_ref (match_operand 0 "" ""))
12958 "ix86_expand_branch (GE, operands[0]); DONE;")
12960 (define_expand "bgeu"
12962 (if_then_else (match_dup 1)
12963 (label_ref (match_operand 0 "" ""))
12966 "ix86_expand_branch (GEU, operands[0]); DONE;")
12968 (define_expand "ble"
12970 (if_then_else (match_dup 1)
12971 (label_ref (match_operand 0 "" ""))
12974 "ix86_expand_branch (LE, operands[0]); DONE;")
12976 (define_expand "bleu"
12978 (if_then_else (match_dup 1)
12979 (label_ref (match_operand 0 "" ""))
12982 "ix86_expand_branch (LEU, operands[0]); DONE;")
12984 (define_expand "bunordered"
12986 (if_then_else (match_dup 1)
12987 (label_ref (match_operand 0 "" ""))
12989 "TARGET_80387 || TARGET_SSE_MATH"
12990 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12992 (define_expand "bordered"
12994 (if_then_else (match_dup 1)
12995 (label_ref (match_operand 0 "" ""))
12997 "TARGET_80387 || TARGET_SSE_MATH"
12998 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13000 (define_expand "buneq"
13002 (if_then_else (match_dup 1)
13003 (label_ref (match_operand 0 "" ""))
13005 "TARGET_80387 || TARGET_SSE_MATH"
13006 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13008 (define_expand "bunge"
13010 (if_then_else (match_dup 1)
13011 (label_ref (match_operand 0 "" ""))
13013 "TARGET_80387 || TARGET_SSE_MATH"
13014 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13016 (define_expand "bungt"
13018 (if_then_else (match_dup 1)
13019 (label_ref (match_operand 0 "" ""))
13021 "TARGET_80387 || TARGET_SSE_MATH"
13022 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13024 (define_expand "bunle"
13026 (if_then_else (match_dup 1)
13027 (label_ref (match_operand 0 "" ""))
13029 "TARGET_80387 || TARGET_SSE_MATH"
13030 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13032 (define_expand "bunlt"
13034 (if_then_else (match_dup 1)
13035 (label_ref (match_operand 0 "" ""))
13037 "TARGET_80387 || TARGET_SSE_MATH"
13038 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13040 (define_expand "bltgt"
13042 (if_then_else (match_dup 1)
13043 (label_ref (match_operand 0 "" ""))
13045 "TARGET_80387 || TARGET_SSE_MATH"
13046 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13048 (define_insn "*jcc_1"
13050 (if_then_else (match_operator 1 "ix86_comparison_operator"
13051 [(reg FLAGS_REG) (const_int 0)])
13052 (label_ref (match_operand 0 "" ""))
13056 [(set_attr "type" "ibr")
13057 (set_attr "modrm" "0")
13058 (set (attr "length")
13059 (if_then_else (and (ge (minus (match_dup 0) (pc))
13061 (lt (minus (match_dup 0) (pc))
13066 (define_insn "*jcc_2"
13068 (if_then_else (match_operator 1 "ix86_comparison_operator"
13069 [(reg FLAGS_REG) (const_int 0)])
13071 (label_ref (match_operand 0 "" ""))))]
13074 [(set_attr "type" "ibr")
13075 (set_attr "modrm" "0")
13076 (set (attr "length")
13077 (if_then_else (and (ge (minus (match_dup 0) (pc))
13079 (lt (minus (match_dup 0) (pc))
13084 ;; In general it is not safe to assume too much about CCmode registers,
13085 ;; so simplify-rtx stops when it sees a second one. Under certain
13086 ;; conditions this is safe on x86, so help combine not create
13094 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13095 [(reg FLAGS_REG) (const_int 0)])
13097 (label_ref (match_operand 1 "" ""))
13101 (if_then_else (match_dup 0)
13102 (label_ref (match_dup 1))
13105 PUT_MODE (operands[0], VOIDmode);
13110 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13111 [(reg FLAGS_REG) (const_int 0)])
13113 (label_ref (match_operand 1 "" ""))
13117 (if_then_else (match_dup 0)
13118 (label_ref (match_dup 1))
13121 rtx new_op0 = copy_rtx (operands[0]);
13122 operands[0] = new_op0;
13123 PUT_MODE (new_op0, VOIDmode);
13124 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13125 GET_MODE (XEXP (new_op0, 0))));
13127 /* Make sure that (a) the CCmode we have for the flags is strong
13128 enough for the reversed compare or (b) we have a valid FP compare. */
13129 if (! ix86_comparison_operator (new_op0, VOIDmode))
13133 ;; Define combination compare-and-branch fp compare instructions to use
13134 ;; during early optimization. Splitting the operation apart early makes
13135 ;; for bad code when we want to reverse the operation.
13137 (define_insn "*fp_jcc_1_mixed"
13139 (if_then_else (match_operator 0 "comparison_operator"
13140 [(match_operand 1 "register_operand" "f#x,x#f")
13141 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13142 (label_ref (match_operand 3 "" ""))
13144 (clobber (reg:CCFP FPSR_REG))
13145 (clobber (reg:CCFP FLAGS_REG))]
13146 "TARGET_MIX_SSE_I387
13147 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13148 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13149 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13152 (define_insn "*fp_jcc_1_sse"
13154 (if_then_else (match_operator 0 "comparison_operator"
13155 [(match_operand 1 "register_operand" "x")
13156 (match_operand 2 "nonimmediate_operand" "xm")])
13157 (label_ref (match_operand 3 "" ""))
13159 (clobber (reg:CCFP FPSR_REG))
13160 (clobber (reg:CCFP FLAGS_REG))]
13162 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13163 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13164 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13167 (define_insn "*fp_jcc_1_387"
13169 (if_then_else (match_operator 0 "comparison_operator"
13170 [(match_operand 1 "register_operand" "f")
13171 (match_operand 2 "register_operand" "f")])
13172 (label_ref (match_operand 3 "" ""))
13174 (clobber (reg:CCFP FPSR_REG))
13175 (clobber (reg:CCFP FLAGS_REG))]
13176 "TARGET_CMOVE && TARGET_80387
13177 && FLOAT_MODE_P (GET_MODE (operands[1]))
13178 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13179 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13182 (define_insn "*fp_jcc_2_mixed"
13184 (if_then_else (match_operator 0 "comparison_operator"
13185 [(match_operand 1 "register_operand" "f#x,x#f")
13186 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13188 (label_ref (match_operand 3 "" ""))))
13189 (clobber (reg:CCFP FPSR_REG))
13190 (clobber (reg:CCFP FLAGS_REG))]
13191 "TARGET_MIX_SSE_I387
13192 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13193 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13194 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13197 (define_insn "*fp_jcc_2_sse"
13199 (if_then_else (match_operator 0 "comparison_operator"
13200 [(match_operand 1 "register_operand" "x")
13201 (match_operand 2 "nonimmediate_operand" "xm")])
13203 (label_ref (match_operand 3 "" ""))))
13204 (clobber (reg:CCFP FPSR_REG))
13205 (clobber (reg:CCFP FLAGS_REG))]
13207 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13208 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13209 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13212 (define_insn "*fp_jcc_2_387"
13214 (if_then_else (match_operator 0 "comparison_operator"
13215 [(match_operand 1 "register_operand" "f")
13216 (match_operand 2 "register_operand" "f")])
13218 (label_ref (match_operand 3 "" ""))))
13219 (clobber (reg:CCFP FPSR_REG))
13220 (clobber (reg:CCFP FLAGS_REG))]
13221 "TARGET_CMOVE && TARGET_80387
13222 && FLOAT_MODE_P (GET_MODE (operands[1]))
13223 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13224 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13227 (define_insn "*fp_jcc_3_387"
13229 (if_then_else (match_operator 0 "comparison_operator"
13230 [(match_operand 1 "register_operand" "f")
13231 (match_operand 2 "nonimmediate_operand" "fm")])
13232 (label_ref (match_operand 3 "" ""))
13234 (clobber (reg:CCFP FPSR_REG))
13235 (clobber (reg:CCFP FLAGS_REG))
13236 (clobber (match_scratch:HI 4 "=a"))]
13238 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13239 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13240 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13241 && SELECT_CC_MODE (GET_CODE (operands[0]),
13242 operands[1], operands[2]) == CCFPmode
13243 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13246 (define_insn "*fp_jcc_4_387"
13248 (if_then_else (match_operator 0 "comparison_operator"
13249 [(match_operand 1 "register_operand" "f")
13250 (match_operand 2 "nonimmediate_operand" "fm")])
13252 (label_ref (match_operand 3 "" ""))))
13253 (clobber (reg:CCFP FPSR_REG))
13254 (clobber (reg:CCFP FLAGS_REG))
13255 (clobber (match_scratch:HI 4 "=a"))]
13257 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13258 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13259 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13260 && SELECT_CC_MODE (GET_CODE (operands[0]),
13261 operands[1], operands[2]) == CCFPmode
13262 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13265 (define_insn "*fp_jcc_5_387"
13267 (if_then_else (match_operator 0 "comparison_operator"
13268 [(match_operand 1 "register_operand" "f")
13269 (match_operand 2 "register_operand" "f")])
13270 (label_ref (match_operand 3 "" ""))
13272 (clobber (reg:CCFP FPSR_REG))
13273 (clobber (reg:CCFP FLAGS_REG))
13274 (clobber (match_scratch:HI 4 "=a"))]
13276 && FLOAT_MODE_P (GET_MODE (operands[1]))
13277 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13278 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13281 (define_insn "*fp_jcc_6_387"
13283 (if_then_else (match_operator 0 "comparison_operator"
13284 [(match_operand 1 "register_operand" "f")
13285 (match_operand 2 "register_operand" "f")])
13287 (label_ref (match_operand 3 "" ""))))
13288 (clobber (reg:CCFP FPSR_REG))
13289 (clobber (reg:CCFP FLAGS_REG))
13290 (clobber (match_scratch:HI 4 "=a"))]
13292 && FLOAT_MODE_P (GET_MODE (operands[1]))
13293 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13294 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13297 (define_insn "*fp_jcc_7_387"
13299 (if_then_else (match_operator 0 "comparison_operator"
13300 [(match_operand 1 "register_operand" "f")
13301 (match_operand 2 "const0_operand" "X")])
13302 (label_ref (match_operand 3 "" ""))
13304 (clobber (reg:CCFP FPSR_REG))
13305 (clobber (reg:CCFP FLAGS_REG))
13306 (clobber (match_scratch:HI 4 "=a"))]
13308 && FLOAT_MODE_P (GET_MODE (operands[1]))
13309 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13310 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13311 && SELECT_CC_MODE (GET_CODE (operands[0]),
13312 operands[1], operands[2]) == CCFPmode
13313 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13316 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13317 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13318 ;; with a precedence over other operators and is always put in the first
13319 ;; place. Swap condition and operands to match ficom instruction.
13321 (define_insn "*fp_jcc_8<mode>_387"
13323 (if_then_else (match_operator 0 "comparison_operator"
13324 [(match_operator 1 "float_operator"
13325 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13326 (match_operand 3 "register_operand" "f,f")])
13327 (label_ref (match_operand 4 "" ""))
13329 (clobber (reg:CCFP FPSR_REG))
13330 (clobber (reg:CCFP FLAGS_REG))
13331 (clobber (match_scratch:HI 5 "=a,a"))]
13332 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13333 && FLOAT_MODE_P (GET_MODE (operands[3]))
13334 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13335 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13336 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13337 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13342 (if_then_else (match_operator 0 "comparison_operator"
13343 [(match_operand 1 "register_operand" "")
13344 (match_operand 2 "nonimmediate_operand" "")])
13345 (match_operand 3 "" "")
13346 (match_operand 4 "" "")))
13347 (clobber (reg:CCFP FPSR_REG))
13348 (clobber (reg:CCFP FLAGS_REG))]
13352 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13353 operands[3], operands[4], NULL_RTX, NULL_RTX);
13359 (if_then_else (match_operator 0 "comparison_operator"
13360 [(match_operand 1 "register_operand" "")
13361 (match_operand 2 "general_operand" "")])
13362 (match_operand 3 "" "")
13363 (match_operand 4 "" "")))
13364 (clobber (reg:CCFP FPSR_REG))
13365 (clobber (reg:CCFP FLAGS_REG))
13366 (clobber (match_scratch:HI 5 "=a"))]
13370 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13371 operands[3], operands[4], operands[5], NULL_RTX);
13377 (if_then_else (match_operator 0 "comparison_operator"
13378 [(match_operator 1 "float_operator"
13379 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13380 (match_operand 3 "register_operand" "")])
13381 (match_operand 4 "" "")
13382 (match_operand 5 "" "")))
13383 (clobber (reg:CCFP FPSR_REG))
13384 (clobber (reg:CCFP FLAGS_REG))
13385 (clobber (match_scratch:HI 6 "=a"))]
13389 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13390 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13391 operands[3], operands[7],
13392 operands[4], operands[5], operands[6], NULL_RTX);
13396 ;; %%% Kill this when reload knows how to do it.
13399 (if_then_else (match_operator 0 "comparison_operator"
13400 [(match_operator 1 "float_operator"
13401 [(match_operand:X87MODEI12 2 "register_operand" "")])
13402 (match_operand 3 "register_operand" "")])
13403 (match_operand 4 "" "")
13404 (match_operand 5 "" "")))
13405 (clobber (reg:CCFP FPSR_REG))
13406 (clobber (reg:CCFP FLAGS_REG))
13407 (clobber (match_scratch:HI 6 "=a"))]
13411 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13412 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13413 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13414 operands[3], operands[7],
13415 operands[4], operands[5], operands[6], operands[2]);
13419 ;; Unconditional and other jump instructions
13421 (define_insn "jump"
13423 (label_ref (match_operand 0 "" "")))]
13426 [(set_attr "type" "ibr")
13427 (set (attr "length")
13428 (if_then_else (and (ge (minus (match_dup 0) (pc))
13430 (lt (minus (match_dup 0) (pc))
13434 (set_attr "modrm" "0")])
13436 (define_expand "indirect_jump"
13437 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13441 (define_insn "*indirect_jump"
13442 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13445 [(set_attr "type" "ibr")
13446 (set_attr "length_immediate" "0")])
13448 (define_insn "*indirect_jump_rtx64"
13449 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13452 [(set_attr "type" "ibr")
13453 (set_attr "length_immediate" "0")])
13455 (define_expand "tablejump"
13456 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13457 (use (label_ref (match_operand 1 "" "")))])]
13460 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13461 relative. Convert the relative address to an absolute address. */
13465 enum rtx_code code;
13471 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13473 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13477 op1 = pic_offset_table_rtx;
13482 op0 = pic_offset_table_rtx;
13486 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13491 (define_insn "*tablejump_1"
13492 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13493 (use (label_ref (match_operand 1 "" "")))]
13496 [(set_attr "type" "ibr")
13497 (set_attr "length_immediate" "0")])
13499 (define_insn "*tablejump_1_rtx64"
13500 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13501 (use (label_ref (match_operand 1 "" "")))]
13504 [(set_attr "type" "ibr")
13505 (set_attr "length_immediate" "0")])
13507 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13510 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13511 (set (match_operand:QI 1 "register_operand" "")
13512 (match_operator:QI 2 "ix86_comparison_operator"
13513 [(reg FLAGS_REG) (const_int 0)]))
13514 (set (match_operand 3 "q_regs_operand" "")
13515 (zero_extend (match_dup 1)))]
13516 "(peep2_reg_dead_p (3, operands[1])
13517 || operands_match_p (operands[1], operands[3]))
13518 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13519 [(set (match_dup 4) (match_dup 0))
13520 (set (strict_low_part (match_dup 5))
13523 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13524 operands[5] = gen_lowpart (QImode, operands[3]);
13525 ix86_expand_clear (operands[3]);
13528 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13531 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13532 (set (match_operand:QI 1 "register_operand" "")
13533 (match_operator:QI 2 "ix86_comparison_operator"
13534 [(reg FLAGS_REG) (const_int 0)]))
13535 (parallel [(set (match_operand 3 "q_regs_operand" "")
13536 (zero_extend (match_dup 1)))
13537 (clobber (reg:CC FLAGS_REG))])]
13538 "(peep2_reg_dead_p (3, operands[1])
13539 || operands_match_p (operands[1], operands[3]))
13540 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13541 [(set (match_dup 4) (match_dup 0))
13542 (set (strict_low_part (match_dup 5))
13545 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13546 operands[5] = gen_lowpart (QImode, operands[3]);
13547 ix86_expand_clear (operands[3]);
13550 ;; Call instructions.
13552 ;; The predicates normally associated with named expanders are not properly
13553 ;; checked for calls. This is a bug in the generic code, but it isn't that
13554 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13556 ;; Call subroutine returning no value.
13558 (define_expand "call_pop"
13559 [(parallel [(call (match_operand:QI 0 "" "")
13560 (match_operand:SI 1 "" ""))
13561 (set (reg:SI SP_REG)
13562 (plus:SI (reg:SI SP_REG)
13563 (match_operand:SI 3 "" "")))])]
13566 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13570 (define_insn "*call_pop_0"
13571 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13572 (match_operand:SI 1 "" ""))
13573 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13574 (match_operand:SI 2 "immediate_operand" "")))]
13577 if (SIBLING_CALL_P (insn))
13580 return "call\t%P0";
13582 [(set_attr "type" "call")])
13584 (define_insn "*call_pop_1"
13585 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13586 (match_operand:SI 1 "" ""))
13587 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13588 (match_operand:SI 2 "immediate_operand" "i")))]
13591 if (constant_call_address_operand (operands[0], Pmode))
13593 if (SIBLING_CALL_P (insn))
13596 return "call\t%P0";
13598 if (SIBLING_CALL_P (insn))
13601 return "call\t%A0";
13603 [(set_attr "type" "call")])
13605 (define_expand "call"
13606 [(call (match_operand:QI 0 "" "")
13607 (match_operand 1 "" ""))
13608 (use (match_operand 2 "" ""))]
13611 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13615 (define_expand "sibcall"
13616 [(call (match_operand:QI 0 "" "")
13617 (match_operand 1 "" ""))
13618 (use (match_operand 2 "" ""))]
13621 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13625 (define_insn "*call_0"
13626 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13627 (match_operand 1 "" ""))]
13630 if (SIBLING_CALL_P (insn))
13633 return "call\t%P0";
13635 [(set_attr "type" "call")])
13637 (define_insn "*call_1"
13638 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13639 (match_operand 1 "" ""))]
13640 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13642 if (constant_call_address_operand (operands[0], Pmode))
13643 return "call\t%P0";
13644 return "call\t%A0";
13646 [(set_attr "type" "call")])
13648 (define_insn "*sibcall_1"
13649 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13650 (match_operand 1 "" ""))]
13651 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13653 if (constant_call_address_operand (operands[0], Pmode))
13657 [(set_attr "type" "call")])
13659 (define_insn "*call_1_rex64"
13660 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13661 (match_operand 1 "" ""))]
13662 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13664 if (constant_call_address_operand (operands[0], Pmode))
13665 return "call\t%P0";
13666 return "call\t%A0";
13668 [(set_attr "type" "call")])
13670 (define_insn "*sibcall_1_rex64"
13671 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13672 (match_operand 1 "" ""))]
13673 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13675 [(set_attr "type" "call")])
13677 (define_insn "*sibcall_1_rex64_v"
13678 [(call (mem:QI (reg:DI 40))
13679 (match_operand 0 "" ""))]
13680 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13682 [(set_attr "type" "call")])
13685 ;; Call subroutine, returning value in operand 0
13687 (define_expand "call_value_pop"
13688 [(parallel [(set (match_operand 0 "" "")
13689 (call (match_operand:QI 1 "" "")
13690 (match_operand:SI 2 "" "")))
13691 (set (reg:SI SP_REG)
13692 (plus:SI (reg:SI SP_REG)
13693 (match_operand:SI 4 "" "")))])]
13696 ix86_expand_call (operands[0], operands[1], operands[2],
13697 operands[3], operands[4], 0);
13701 (define_expand "call_value"
13702 [(set (match_operand 0 "" "")
13703 (call (match_operand:QI 1 "" "")
13704 (match_operand:SI 2 "" "")))
13705 (use (match_operand:SI 3 "" ""))]
13706 ;; Operand 2 not used on the i386.
13709 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13713 (define_expand "sibcall_value"
13714 [(set (match_operand 0 "" "")
13715 (call (match_operand:QI 1 "" "")
13716 (match_operand:SI 2 "" "")))
13717 (use (match_operand:SI 3 "" ""))]
13718 ;; Operand 2 not used on the i386.
13721 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13725 ;; Call subroutine returning any type.
13727 (define_expand "untyped_call"
13728 [(parallel [(call (match_operand 0 "" "")
13730 (match_operand 1 "" "")
13731 (match_operand 2 "" "")])]
13736 /* In order to give reg-stack an easier job in validating two
13737 coprocessor registers as containing a possible return value,
13738 simply pretend the untyped call returns a complex long double
13741 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13742 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13743 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13746 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13748 rtx set = XVECEXP (operands[2], 0, i);
13749 emit_move_insn (SET_DEST (set), SET_SRC (set));
13752 /* The optimizer does not know that the call sets the function value
13753 registers we stored in the result block. We avoid problems by
13754 claiming that all hard registers are used and clobbered at this
13756 emit_insn (gen_blockage (const0_rtx));
13761 ;; Prologue and epilogue instructions
13763 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13764 ;; all of memory. This blocks insns from being moved across this point.
13766 (define_insn "blockage"
13767 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13770 [(set_attr "length" "0")])
13772 ;; Insn emitted into the body of a function to return from a function.
13773 ;; This is only done if the function's epilogue is known to be simple.
13774 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13776 (define_expand "return"
13778 "ix86_can_use_return_insn_p ()"
13780 if (current_function_pops_args)
13782 rtx popc = GEN_INT (current_function_pops_args);
13783 emit_jump_insn (gen_return_pop_internal (popc));
13788 (define_insn "return_internal"
13792 [(set_attr "length" "1")
13793 (set_attr "length_immediate" "0")
13794 (set_attr "modrm" "0")])
13796 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13797 ;; instruction Athlon and K8 have.
13799 (define_insn "return_internal_long"
13801 (unspec [(const_int 0)] UNSPEC_REP)]
13804 [(set_attr "length" "1")
13805 (set_attr "length_immediate" "0")
13806 (set_attr "prefix_rep" "1")
13807 (set_attr "modrm" "0")])
13809 (define_insn "return_pop_internal"
13811 (use (match_operand:SI 0 "const_int_operand" ""))]
13814 [(set_attr "length" "3")
13815 (set_attr "length_immediate" "2")
13816 (set_attr "modrm" "0")])
13818 (define_insn "return_indirect_internal"
13820 (use (match_operand:SI 0 "register_operand" "r"))]
13823 [(set_attr "type" "ibr")
13824 (set_attr "length_immediate" "0")])
13830 [(set_attr "length" "1")
13831 (set_attr "length_immediate" "0")
13832 (set_attr "modrm" "0")])
13834 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13835 ;; branch prediction penalty for the third jump in a 16-byte
13838 (define_insn "align"
13839 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13842 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13843 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13845 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13846 The align insn is used to avoid 3 jump instructions in the row to improve
13847 branch prediction and the benefits hardly outweight the cost of extra 8
13848 nops on the average inserted by full alignment pseudo operation. */
13852 [(set_attr "length" "16")])
13854 (define_expand "prologue"
13857 "ix86_expand_prologue (); DONE;")
13859 (define_insn "set_got"
13860 [(set (match_operand:SI 0 "register_operand" "=r")
13861 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13862 (clobber (reg:CC FLAGS_REG))]
13864 { return output_set_got (operands[0], NULL_RTX); }
13865 [(set_attr "type" "multi")
13866 (set_attr "length" "12")])
13868 (define_insn "set_got_labelled"
13869 [(set (match_operand:SI 0 "register_operand" "=r")
13870 (unspec:SI [(label_ref (match_operand 1 "" ""))]
13872 (clobber (reg:CC FLAGS_REG))]
13874 { return output_set_got (operands[0], operands[1]); }
13875 [(set_attr "type" "multi")
13876 (set_attr "length" "12")])
13878 (define_insn "set_got_rex64"
13879 [(set (match_operand:DI 0 "register_operand" "=r")
13880 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13882 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13883 [(set_attr "type" "lea")
13884 (set_attr "length" "6")])
13886 (define_expand "epilogue"
13889 "ix86_expand_epilogue (1); DONE;")
13891 (define_expand "sibcall_epilogue"
13894 "ix86_expand_epilogue (0); DONE;")
13896 (define_expand "eh_return"
13897 [(use (match_operand 0 "register_operand" ""))]
13900 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13902 /* Tricky bit: we write the address of the handler to which we will
13903 be returning into someone else's stack frame, one word below the
13904 stack address we wish to restore. */
13905 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13906 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13907 tmp = gen_rtx_MEM (Pmode, tmp);
13908 emit_move_insn (tmp, ra);
13910 if (Pmode == SImode)
13911 emit_jump_insn (gen_eh_return_si (sa));
13913 emit_jump_insn (gen_eh_return_di (sa));
13918 (define_insn_and_split "eh_return_si"
13920 (unspec [(match_operand:SI 0 "register_operand" "c")]
13921 UNSPEC_EH_RETURN))]
13926 "ix86_expand_epilogue (2); DONE;")
13928 (define_insn_and_split "eh_return_di"
13930 (unspec [(match_operand:DI 0 "register_operand" "c")]
13931 UNSPEC_EH_RETURN))]
13936 "ix86_expand_epilogue (2); DONE;")
13938 (define_insn "leave"
13939 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13940 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13941 (clobber (mem:BLK (scratch)))]
13944 [(set_attr "type" "leave")])
13946 (define_insn "leave_rex64"
13947 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13948 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13949 (clobber (mem:BLK (scratch)))]
13952 [(set_attr "type" "leave")])
13954 (define_expand "ffssi2"
13956 [(set (match_operand:SI 0 "register_operand" "")
13957 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13958 (clobber (match_scratch:SI 2 ""))
13959 (clobber (reg:CC FLAGS_REG))])]
13963 (define_insn_and_split "*ffs_cmove"
13964 [(set (match_operand:SI 0 "register_operand" "=r")
13965 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13966 (clobber (match_scratch:SI 2 "=&r"))
13967 (clobber (reg:CC FLAGS_REG))]
13970 "&& reload_completed"
13971 [(set (match_dup 2) (const_int -1))
13972 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13973 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13974 (set (match_dup 0) (if_then_else:SI
13975 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13978 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13979 (clobber (reg:CC FLAGS_REG))])]
13982 (define_insn_and_split "*ffs_no_cmove"
13983 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13984 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13985 (clobber (match_scratch:SI 2 "=&q"))
13986 (clobber (reg:CC FLAGS_REG))]
13990 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13991 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13992 (set (strict_low_part (match_dup 3))
13993 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13994 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13995 (clobber (reg:CC FLAGS_REG))])
13996 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13997 (clobber (reg:CC FLAGS_REG))])
13998 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13999 (clobber (reg:CC FLAGS_REG))])]
14001 operands[3] = gen_lowpart (QImode, operands[2]);
14002 ix86_expand_clear (operands[2]);
14005 (define_insn "*ffssi_1"
14006 [(set (reg:CCZ FLAGS_REG)
14007 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14009 (set (match_operand:SI 0 "register_operand" "=r")
14010 (ctz:SI (match_dup 1)))]
14012 "bsf{l}\t{%1, %0|%0, %1}"
14013 [(set_attr "prefix_0f" "1")])
14015 (define_expand "ffsdi2"
14017 [(set (match_operand:DI 0 "register_operand" "")
14018 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14019 (clobber (match_scratch:DI 2 ""))
14020 (clobber (reg:CC FLAGS_REG))])]
14021 "TARGET_64BIT && TARGET_CMOVE"
14024 (define_insn_and_split "*ffs_rex64"
14025 [(set (match_operand:DI 0 "register_operand" "=r")
14026 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14027 (clobber (match_scratch:DI 2 "=&r"))
14028 (clobber (reg:CC FLAGS_REG))]
14029 "TARGET_64BIT && TARGET_CMOVE"
14031 "&& reload_completed"
14032 [(set (match_dup 2) (const_int -1))
14033 (parallel [(set (reg:CCZ FLAGS_REG)
14034 (compare:CCZ (match_dup 1) (const_int 0)))
14035 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14036 (set (match_dup 0) (if_then_else:DI
14037 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14040 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14041 (clobber (reg:CC FLAGS_REG))])]
14044 (define_insn "*ffsdi_1"
14045 [(set (reg:CCZ FLAGS_REG)
14046 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14048 (set (match_operand:DI 0 "register_operand" "=r")
14049 (ctz:DI (match_dup 1)))]
14051 "bsf{q}\t{%1, %0|%0, %1}"
14052 [(set_attr "prefix_0f" "1")])
14054 (define_insn "ctzsi2"
14055 [(set (match_operand:SI 0 "register_operand" "=r")
14056 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14057 (clobber (reg:CC FLAGS_REG))]
14059 "bsf{l}\t{%1, %0|%0, %1}"
14060 [(set_attr "prefix_0f" "1")])
14062 (define_insn "ctzdi2"
14063 [(set (match_operand:DI 0 "register_operand" "=r")
14064 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14065 (clobber (reg:CC FLAGS_REG))]
14067 "bsf{q}\t{%1, %0|%0, %1}"
14068 [(set_attr "prefix_0f" "1")])
14070 (define_expand "clzsi2"
14072 [(set (match_operand:SI 0 "register_operand" "")
14073 (minus:SI (const_int 31)
14074 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14075 (clobber (reg:CC FLAGS_REG))])
14077 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14078 (clobber (reg:CC FLAGS_REG))])]
14082 (define_insn "*bsr"
14083 [(set (match_operand:SI 0 "register_operand" "=r")
14084 (minus:SI (const_int 31)
14085 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14086 (clobber (reg:CC FLAGS_REG))]
14088 "bsr{l}\t{%1, %0|%0, %1}"
14089 [(set_attr "prefix_0f" "1")])
14091 (define_expand "clzdi2"
14093 [(set (match_operand:DI 0 "register_operand" "")
14094 (minus:DI (const_int 63)
14095 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14096 (clobber (reg:CC FLAGS_REG))])
14098 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14099 (clobber (reg:CC FLAGS_REG))])]
14103 (define_insn "*bsr_rex64"
14104 [(set (match_operand:DI 0 "register_operand" "=r")
14105 (minus:DI (const_int 63)
14106 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14107 (clobber (reg:CC FLAGS_REG))]
14109 "bsr{q}\t{%1, %0|%0, %1}"
14110 [(set_attr "prefix_0f" "1")])
14112 ;; Thread-local storage patterns for ELF.
14114 ;; Note that these code sequences must appear exactly as shown
14115 ;; in order to allow linker relaxation.
14117 (define_insn "*tls_global_dynamic_32_gnu"
14118 [(set (match_operand:SI 0 "register_operand" "=a")
14119 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14120 (match_operand:SI 2 "tls_symbolic_operand" "")
14121 (match_operand:SI 3 "call_insn_operand" "")]
14123 (clobber (match_scratch:SI 4 "=d"))
14124 (clobber (match_scratch:SI 5 "=c"))
14125 (clobber (reg:CC FLAGS_REG))]
14126 "!TARGET_64BIT && TARGET_GNU_TLS"
14127 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14128 [(set_attr "type" "multi")
14129 (set_attr "length" "12")])
14131 (define_insn "*tls_global_dynamic_32_sun"
14132 [(set (match_operand:SI 0 "register_operand" "=a")
14133 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14134 (match_operand:SI 2 "tls_symbolic_operand" "")
14135 (match_operand:SI 3 "call_insn_operand" "")]
14137 (clobber (match_scratch:SI 4 "=d"))
14138 (clobber (match_scratch:SI 5 "=c"))
14139 (clobber (reg:CC FLAGS_REG))]
14140 "!TARGET_64BIT && TARGET_SUN_TLS"
14141 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14142 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14143 [(set_attr "type" "multi")
14144 (set_attr "length" "14")])
14146 (define_expand "tls_global_dynamic_32"
14147 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14150 (match_operand:SI 1 "tls_symbolic_operand" "")
14153 (clobber (match_scratch:SI 4 ""))
14154 (clobber (match_scratch:SI 5 ""))
14155 (clobber (reg:CC FLAGS_REG))])]
14159 operands[2] = pic_offset_table_rtx;
14162 operands[2] = gen_reg_rtx (Pmode);
14163 emit_insn (gen_set_got (operands[2]));
14165 if (TARGET_GNU2_TLS)
14167 emit_insn (gen_tls_dynamic_gnu2_32
14168 (operands[0], operands[1], operands[2]));
14171 operands[3] = ix86_tls_get_addr ();
14174 (define_insn "*tls_global_dynamic_64"
14175 [(set (match_operand:DI 0 "register_operand" "=a")
14176 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14177 (match_operand:DI 3 "" "")))
14178 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14181 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14182 [(set_attr "type" "multi")
14183 (set_attr "length" "16")])
14185 (define_expand "tls_global_dynamic_64"
14186 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14187 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14188 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14192 if (TARGET_GNU2_TLS)
14194 emit_insn (gen_tls_dynamic_gnu2_64
14195 (operands[0], operands[1]));
14198 operands[2] = ix86_tls_get_addr ();
14201 (define_insn "*tls_local_dynamic_base_32_gnu"
14202 [(set (match_operand:SI 0 "register_operand" "=a")
14203 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14204 (match_operand:SI 2 "call_insn_operand" "")]
14205 UNSPEC_TLS_LD_BASE))
14206 (clobber (match_scratch:SI 3 "=d"))
14207 (clobber (match_scratch:SI 4 "=c"))
14208 (clobber (reg:CC FLAGS_REG))]
14209 "!TARGET_64BIT && TARGET_GNU_TLS"
14210 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14211 [(set_attr "type" "multi")
14212 (set_attr "length" "11")])
14214 (define_insn "*tls_local_dynamic_base_32_sun"
14215 [(set (match_operand:SI 0 "register_operand" "=a")
14216 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14217 (match_operand:SI 2 "call_insn_operand" "")]
14218 UNSPEC_TLS_LD_BASE))
14219 (clobber (match_scratch:SI 3 "=d"))
14220 (clobber (match_scratch:SI 4 "=c"))
14221 (clobber (reg:CC FLAGS_REG))]
14222 "!TARGET_64BIT && TARGET_SUN_TLS"
14223 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14224 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14225 [(set_attr "type" "multi")
14226 (set_attr "length" "13")])
14228 (define_expand "tls_local_dynamic_base_32"
14229 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14230 (unspec:SI [(match_dup 1) (match_dup 2)]
14231 UNSPEC_TLS_LD_BASE))
14232 (clobber (match_scratch:SI 3 ""))
14233 (clobber (match_scratch:SI 4 ""))
14234 (clobber (reg:CC FLAGS_REG))])]
14238 operands[1] = pic_offset_table_rtx;
14241 operands[1] = gen_reg_rtx (Pmode);
14242 emit_insn (gen_set_got (operands[1]));
14244 if (TARGET_GNU2_TLS)
14246 emit_insn (gen_tls_dynamic_gnu2_32
14247 (operands[0], ix86_tls_module_base (), operands[1]));
14250 operands[2] = ix86_tls_get_addr ();
14253 (define_insn "*tls_local_dynamic_base_64"
14254 [(set (match_operand:DI 0 "register_operand" "=a")
14255 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14256 (match_operand:DI 2 "" "")))
14257 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14259 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14260 [(set_attr "type" "multi")
14261 (set_attr "length" "12")])
14263 (define_expand "tls_local_dynamic_base_64"
14264 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14265 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14266 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14269 if (TARGET_GNU2_TLS)
14271 emit_insn (gen_tls_dynamic_gnu2_64
14272 (operands[0], ix86_tls_module_base ()));
14275 operands[1] = ix86_tls_get_addr ();
14278 ;; Local dynamic of a single variable is a lose. Show combine how
14279 ;; to convert that back to global dynamic.
14281 (define_insn_and_split "*tls_local_dynamic_32_once"
14282 [(set (match_operand:SI 0 "register_operand" "=a")
14283 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14284 (match_operand:SI 2 "call_insn_operand" "")]
14285 UNSPEC_TLS_LD_BASE)
14286 (const:SI (unspec:SI
14287 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14289 (clobber (match_scratch:SI 4 "=d"))
14290 (clobber (match_scratch:SI 5 "=c"))
14291 (clobber (reg:CC FLAGS_REG))]
14295 [(parallel [(set (match_dup 0)
14296 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14298 (clobber (match_dup 4))
14299 (clobber (match_dup 5))
14300 (clobber (reg:CC FLAGS_REG))])]
14303 ;; Load and add the thread base pointer from %gs:0.
14305 (define_insn "*load_tp_si"
14306 [(set (match_operand:SI 0 "register_operand" "=r")
14307 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14309 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14310 [(set_attr "type" "imov")
14311 (set_attr "modrm" "0")
14312 (set_attr "length" "7")
14313 (set_attr "memory" "load")
14314 (set_attr "imm_disp" "false")])
14316 (define_insn "*add_tp_si"
14317 [(set (match_operand:SI 0 "register_operand" "=r")
14318 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14319 (match_operand:SI 1 "register_operand" "0")))
14320 (clobber (reg:CC FLAGS_REG))]
14322 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14323 [(set_attr "type" "alu")
14324 (set_attr "modrm" "0")
14325 (set_attr "length" "7")
14326 (set_attr "memory" "load")
14327 (set_attr "imm_disp" "false")])
14329 (define_insn "*load_tp_di"
14330 [(set (match_operand:DI 0 "register_operand" "=r")
14331 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14333 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14334 [(set_attr "type" "imov")
14335 (set_attr "modrm" "0")
14336 (set_attr "length" "7")
14337 (set_attr "memory" "load")
14338 (set_attr "imm_disp" "false")])
14340 (define_insn "*add_tp_di"
14341 [(set (match_operand:DI 0 "register_operand" "=r")
14342 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14343 (match_operand:DI 1 "register_operand" "0")))
14344 (clobber (reg:CC FLAGS_REG))]
14346 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14347 [(set_attr "type" "alu")
14348 (set_attr "modrm" "0")
14349 (set_attr "length" "7")
14350 (set_attr "memory" "load")
14351 (set_attr "imm_disp" "false")])
14353 ;; GNU2 TLS patterns can be split.
14355 (define_expand "tls_dynamic_gnu2_32"
14356 [(set (match_dup 3)
14357 (plus:SI (match_operand:SI 2 "register_operand" "")
14359 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14362 [(set (match_operand:SI 0 "register_operand" "")
14363 (unspec:SI [(match_dup 1) (match_dup 3)
14364 (match_dup 2) (reg:SI SP_REG)]
14366 (clobber (reg:CC FLAGS_REG))])]
14367 "!TARGET_64BIT && TARGET_GNU2_TLS"
14369 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14370 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14373 (define_insn "*tls_dynamic_lea_32"
14374 [(set (match_operand:SI 0 "register_operand" "=r")
14375 (plus:SI (match_operand:SI 1 "register_operand" "b")
14377 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14378 UNSPEC_TLSDESC))))]
14379 "!TARGET_64BIT && TARGET_GNU2_TLS"
14380 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14381 [(set_attr "type" "lea")
14382 (set_attr "mode" "SI")
14383 (set_attr "length" "6")
14384 (set_attr "length_address" "4")])
14386 (define_insn "*tls_dynamic_call_32"
14387 [(set (match_operand:SI 0 "register_operand" "=a")
14388 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14389 (match_operand:SI 2 "register_operand" "0")
14390 ;; we have to make sure %ebx still points to the GOT
14391 (match_operand:SI 3 "register_operand" "b")
14394 (clobber (reg:CC FLAGS_REG))]
14395 "!TARGET_64BIT && TARGET_GNU2_TLS"
14396 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14397 [(set_attr "type" "call")
14398 (set_attr "length" "2")
14399 (set_attr "length_address" "0")])
14401 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14402 [(set (match_operand:SI 0 "register_operand" "=&a")
14404 (plus:SI (match_operand:SI 3 "tp_or_register_operand" "ir")
14405 (unspec:SI [(match_operand:SI 4 "tls_modbase_operand" "")
14406 (match_operand:SI 5 "" "")
14407 (match_operand:SI 2 "register_operand" "b")
14410 (const:SI (unspec:SI
14411 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14413 (clobber (reg:CC FLAGS_REG))]
14414 "!TARGET_64BIT && TARGET_GNU2_TLS"
14418 [(set (match_dup 0)
14419 (plus:SI (match_dup 3)
14421 (clobber (reg:CC FLAGS_REG))])]
14423 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14424 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14427 (define_expand "tls_dynamic_gnu2_64"
14428 [(set (match_dup 2)
14429 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14432 [(set (match_operand:DI 0 "register_operand" "")
14433 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14435 (clobber (reg:CC FLAGS_REG))])]
14436 "TARGET_64BIT && TARGET_GNU2_TLS"
14438 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14439 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14442 (define_insn "*tls_dynamic_lea_64"
14443 [(set (match_operand:DI 0 "register_operand" "=r")
14444 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14446 "TARGET_64BIT && TARGET_GNU2_TLS"
14447 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14448 [(set_attr "type" "lea")
14449 (set_attr "mode" "DI")
14450 (set_attr "length" "7")
14451 (set_attr "length_address" "4")])
14453 (define_insn "*tls_dynamic_call_64"
14454 [(set (match_operand:DI 0 "register_operand" "=a")
14455 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14456 (match_operand:DI 2 "register_operand" "0")
14459 (clobber (reg:CC FLAGS_REG))]
14460 "TARGET_64BIT && TARGET_GNU2_TLS"
14461 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14462 [(set_attr "type" "call")
14463 (set_attr "length" "2")
14464 (set_attr "length_address" "0")])
14466 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14467 [(set (match_operand:DI 0 "register_operand" "=&a")
14469 (plus:DI (match_operand:DI 2 "tp_or_register_operand" "ir")
14470 (unspec:DI [(match_operand:DI 3 "tls_modbase_operand" "")
14471 (match_operand:DI 4 "" "")
14474 (const:DI (unspec:DI
14475 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14477 (clobber (reg:CC FLAGS_REG))]
14478 "TARGET_64BIT && TARGET_GNU2_TLS"
14482 [(set (match_dup 0)
14483 (plus:DI (match_dup 2)
14485 (clobber (reg:CC FLAGS_REG))])]
14487 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14488 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14493 ;; These patterns match the binary 387 instructions for addM3, subM3,
14494 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14495 ;; SFmode. The first is the normal insn, the second the same insn but
14496 ;; with one operand a conversion, and the third the same insn but with
14497 ;; the other operand a conversion. The conversion may be SFmode or
14498 ;; SImode if the target mode DFmode, but only SImode if the target mode
14501 ;; Gcc is slightly more smart about handling normal two address instructions
14502 ;; so use special patterns for add and mull.
14504 (define_insn "*fop_sf_comm_mixed"
14505 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14506 (match_operator:SF 3 "binary_fp_operator"
14507 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14508 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14509 "TARGET_MIX_SSE_I387
14510 && COMMUTATIVE_ARITH_P (operands[3])
14511 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14512 "* return output_387_binary_op (insn, operands);"
14513 [(set (attr "type")
14514 (if_then_else (eq_attr "alternative" "1")
14515 (if_then_else (match_operand:SF 3 "mult_operator" "")
14516 (const_string "ssemul")
14517 (const_string "sseadd"))
14518 (if_then_else (match_operand:SF 3 "mult_operator" "")
14519 (const_string "fmul")
14520 (const_string "fop"))))
14521 (set_attr "mode" "SF")])
14523 (define_insn "*fop_sf_comm_sse"
14524 [(set (match_operand:SF 0 "register_operand" "=x")
14525 (match_operator:SF 3 "binary_fp_operator"
14526 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14527 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14529 && COMMUTATIVE_ARITH_P (operands[3])
14530 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14531 "* return output_387_binary_op (insn, operands);"
14532 [(set (attr "type")
14533 (if_then_else (match_operand:SF 3 "mult_operator" "")
14534 (const_string "ssemul")
14535 (const_string "sseadd")))
14536 (set_attr "mode" "SF")])
14538 (define_insn "*fop_sf_comm_i387"
14539 [(set (match_operand:SF 0 "register_operand" "=f")
14540 (match_operator:SF 3 "binary_fp_operator"
14541 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14542 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14544 && COMMUTATIVE_ARITH_P (operands[3])
14545 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14546 "* return output_387_binary_op (insn, operands);"
14547 [(set (attr "type")
14548 (if_then_else (match_operand:SF 3 "mult_operator" "")
14549 (const_string "fmul")
14550 (const_string "fop")))
14551 (set_attr "mode" "SF")])
14553 (define_insn "*fop_sf_1_mixed"
14554 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14555 (match_operator:SF 3 "binary_fp_operator"
14556 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14557 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14558 "TARGET_MIX_SSE_I387
14559 && !COMMUTATIVE_ARITH_P (operands[3])
14560 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14561 "* return output_387_binary_op (insn, operands);"
14562 [(set (attr "type")
14563 (cond [(and (eq_attr "alternative" "2")
14564 (match_operand:SF 3 "mult_operator" ""))
14565 (const_string "ssemul")
14566 (and (eq_attr "alternative" "2")
14567 (match_operand:SF 3 "div_operator" ""))
14568 (const_string "ssediv")
14569 (eq_attr "alternative" "2")
14570 (const_string "sseadd")
14571 (match_operand:SF 3 "mult_operator" "")
14572 (const_string "fmul")
14573 (match_operand:SF 3 "div_operator" "")
14574 (const_string "fdiv")
14576 (const_string "fop")))
14577 (set_attr "mode" "SF")])
14579 (define_insn "*fop_sf_1_sse"
14580 [(set (match_operand:SF 0 "register_operand" "=x")
14581 (match_operator:SF 3 "binary_fp_operator"
14582 [(match_operand:SF 1 "register_operand" "0")
14583 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14585 && !COMMUTATIVE_ARITH_P (operands[3])"
14586 "* return output_387_binary_op (insn, operands);"
14587 [(set (attr "type")
14588 (cond [(match_operand:SF 3 "mult_operator" "")
14589 (const_string "ssemul")
14590 (match_operand:SF 3 "div_operator" "")
14591 (const_string "ssediv")
14593 (const_string "sseadd")))
14594 (set_attr "mode" "SF")])
14596 ;; This pattern is not fully shadowed by the pattern above.
14597 (define_insn "*fop_sf_1_i387"
14598 [(set (match_operand:SF 0 "register_operand" "=f,f")
14599 (match_operator:SF 3 "binary_fp_operator"
14600 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14601 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14602 "TARGET_80387 && !TARGET_SSE_MATH
14603 && !COMMUTATIVE_ARITH_P (operands[3])
14604 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14605 "* return output_387_binary_op (insn, operands);"
14606 [(set (attr "type")
14607 (cond [(match_operand:SF 3 "mult_operator" "")
14608 (const_string "fmul")
14609 (match_operand:SF 3 "div_operator" "")
14610 (const_string "fdiv")
14612 (const_string "fop")))
14613 (set_attr "mode" "SF")])
14615 ;; ??? Add SSE splitters for these!
14616 (define_insn "*fop_sf_2<mode>_i387"
14617 [(set (match_operand:SF 0 "register_operand" "=f,f")
14618 (match_operator:SF 3 "binary_fp_operator"
14619 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14620 (match_operand:SF 2 "register_operand" "0,0")]))]
14621 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14622 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14623 [(set (attr "type")
14624 (cond [(match_operand:SF 3 "mult_operator" "")
14625 (const_string "fmul")
14626 (match_operand:SF 3 "div_operator" "")
14627 (const_string "fdiv")
14629 (const_string "fop")))
14630 (set_attr "fp_int_src" "true")
14631 (set_attr "mode" "<MODE>")])
14633 (define_insn "*fop_sf_3<mode>_i387"
14634 [(set (match_operand:SF 0 "register_operand" "=f,f")
14635 (match_operator:SF 3 "binary_fp_operator"
14636 [(match_operand:SF 1 "register_operand" "0,0")
14637 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14638 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14639 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14640 [(set (attr "type")
14641 (cond [(match_operand:SF 3 "mult_operator" "")
14642 (const_string "fmul")
14643 (match_operand:SF 3 "div_operator" "")
14644 (const_string "fdiv")
14646 (const_string "fop")))
14647 (set_attr "fp_int_src" "true")
14648 (set_attr "mode" "<MODE>")])
14650 (define_insn "*fop_df_comm_mixed"
14651 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14652 (match_operator:DF 3 "binary_fp_operator"
14653 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14654 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14655 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14656 && COMMUTATIVE_ARITH_P (operands[3])
14657 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14658 "* return output_387_binary_op (insn, operands);"
14659 [(set (attr "type")
14660 (if_then_else (eq_attr "alternative" "1")
14661 (if_then_else (match_operand:SF 3 "mult_operator" "")
14662 (const_string "ssemul")
14663 (const_string "sseadd"))
14664 (if_then_else (match_operand:SF 3 "mult_operator" "")
14665 (const_string "fmul")
14666 (const_string "fop"))))
14667 (set_attr "mode" "DF")])
14669 (define_insn "*fop_df_comm_sse"
14670 [(set (match_operand:DF 0 "register_operand" "=Y")
14671 (match_operator:DF 3 "binary_fp_operator"
14672 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14673 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14674 "TARGET_SSE2 && TARGET_SSE_MATH
14675 && COMMUTATIVE_ARITH_P (operands[3])
14676 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14677 "* return output_387_binary_op (insn, operands);"
14678 [(set (attr "type")
14679 (if_then_else (match_operand:SF 3 "mult_operator" "")
14680 (const_string "ssemul")
14681 (const_string "sseadd")))
14682 (set_attr "mode" "DF")])
14684 (define_insn "*fop_df_comm_i387"
14685 [(set (match_operand:DF 0 "register_operand" "=f")
14686 (match_operator:DF 3 "binary_fp_operator"
14687 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14688 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14690 && COMMUTATIVE_ARITH_P (operands[3])
14691 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14692 "* return output_387_binary_op (insn, operands);"
14693 [(set (attr "type")
14694 (if_then_else (match_operand:SF 3 "mult_operator" "")
14695 (const_string "fmul")
14696 (const_string "fop")))
14697 (set_attr "mode" "DF")])
14699 (define_insn "*fop_df_1_mixed"
14700 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14701 (match_operator:DF 3 "binary_fp_operator"
14702 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14703 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14704 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14705 && !COMMUTATIVE_ARITH_P (operands[3])
14706 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14707 "* return output_387_binary_op (insn, operands);"
14708 [(set (attr "type")
14709 (cond [(and (eq_attr "alternative" "2")
14710 (match_operand:SF 3 "mult_operator" ""))
14711 (const_string "ssemul")
14712 (and (eq_attr "alternative" "2")
14713 (match_operand:SF 3 "div_operator" ""))
14714 (const_string "ssediv")
14715 (eq_attr "alternative" "2")
14716 (const_string "sseadd")
14717 (match_operand:DF 3 "mult_operator" "")
14718 (const_string "fmul")
14719 (match_operand:DF 3 "div_operator" "")
14720 (const_string "fdiv")
14722 (const_string "fop")))
14723 (set_attr "mode" "DF")])
14725 (define_insn "*fop_df_1_sse"
14726 [(set (match_operand:DF 0 "register_operand" "=Y")
14727 (match_operator:DF 3 "binary_fp_operator"
14728 [(match_operand:DF 1 "register_operand" "0")
14729 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14730 "TARGET_SSE2 && TARGET_SSE_MATH
14731 && !COMMUTATIVE_ARITH_P (operands[3])"
14732 "* return output_387_binary_op (insn, operands);"
14733 [(set_attr "mode" "DF")
14735 (cond [(match_operand:SF 3 "mult_operator" "")
14736 (const_string "ssemul")
14737 (match_operand:SF 3 "div_operator" "")
14738 (const_string "ssediv")
14740 (const_string "sseadd")))])
14742 ;; This pattern is not fully shadowed by the pattern above.
14743 (define_insn "*fop_df_1_i387"
14744 [(set (match_operand:DF 0 "register_operand" "=f,f")
14745 (match_operator:DF 3 "binary_fp_operator"
14746 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14747 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14748 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14749 && !COMMUTATIVE_ARITH_P (operands[3])
14750 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14751 "* return output_387_binary_op (insn, operands);"
14752 [(set (attr "type")
14753 (cond [(match_operand:DF 3 "mult_operator" "")
14754 (const_string "fmul")
14755 (match_operand:DF 3 "div_operator" "")
14756 (const_string "fdiv")
14758 (const_string "fop")))
14759 (set_attr "mode" "DF")])
14761 ;; ??? Add SSE splitters for these!
14762 (define_insn "*fop_df_2<mode>_i387"
14763 [(set (match_operand:DF 0 "register_operand" "=f,f")
14764 (match_operator:DF 3 "binary_fp_operator"
14765 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14766 (match_operand:DF 2 "register_operand" "0,0")]))]
14767 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14768 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14769 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14770 [(set (attr "type")
14771 (cond [(match_operand:DF 3 "mult_operator" "")
14772 (const_string "fmul")
14773 (match_operand:DF 3 "div_operator" "")
14774 (const_string "fdiv")
14776 (const_string "fop")))
14777 (set_attr "fp_int_src" "true")
14778 (set_attr "mode" "<MODE>")])
14780 (define_insn "*fop_df_3<mode>_i387"
14781 [(set (match_operand:DF 0 "register_operand" "=f,f")
14782 (match_operator:DF 3 "binary_fp_operator"
14783 [(match_operand:DF 1 "register_operand" "0,0")
14784 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14785 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14786 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14787 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14788 [(set (attr "type")
14789 (cond [(match_operand:DF 3 "mult_operator" "")
14790 (const_string "fmul")
14791 (match_operand:DF 3 "div_operator" "")
14792 (const_string "fdiv")
14794 (const_string "fop")))
14795 (set_attr "fp_int_src" "true")
14796 (set_attr "mode" "<MODE>")])
14798 (define_insn "*fop_df_4_i387"
14799 [(set (match_operand:DF 0 "register_operand" "=f,f")
14800 (match_operator:DF 3 "binary_fp_operator"
14801 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14802 (match_operand:DF 2 "register_operand" "0,f")]))]
14803 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14804 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14805 "* return output_387_binary_op (insn, operands);"
14806 [(set (attr "type")
14807 (cond [(match_operand:DF 3 "mult_operator" "")
14808 (const_string "fmul")
14809 (match_operand:DF 3 "div_operator" "")
14810 (const_string "fdiv")
14812 (const_string "fop")))
14813 (set_attr "mode" "SF")])
14815 (define_insn "*fop_df_5_i387"
14816 [(set (match_operand:DF 0 "register_operand" "=f,f")
14817 (match_operator:DF 3 "binary_fp_operator"
14818 [(match_operand:DF 1 "register_operand" "0,f")
14820 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14821 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14822 "* return output_387_binary_op (insn, operands);"
14823 [(set (attr "type")
14824 (cond [(match_operand:DF 3 "mult_operator" "")
14825 (const_string "fmul")
14826 (match_operand:DF 3 "div_operator" "")
14827 (const_string "fdiv")
14829 (const_string "fop")))
14830 (set_attr "mode" "SF")])
14832 (define_insn "*fop_df_6_i387"
14833 [(set (match_operand:DF 0 "register_operand" "=f,f")
14834 (match_operator:DF 3 "binary_fp_operator"
14836 (match_operand:SF 1 "register_operand" "0,f"))
14838 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14839 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14840 "* return output_387_binary_op (insn, operands);"
14841 [(set (attr "type")
14842 (cond [(match_operand:DF 3 "mult_operator" "")
14843 (const_string "fmul")
14844 (match_operand:DF 3 "div_operator" "")
14845 (const_string "fdiv")
14847 (const_string "fop")))
14848 (set_attr "mode" "SF")])
14850 (define_insn "*fop_xf_comm_i387"
14851 [(set (match_operand:XF 0 "register_operand" "=f")
14852 (match_operator:XF 3 "binary_fp_operator"
14853 [(match_operand:XF 1 "register_operand" "%0")
14854 (match_operand:XF 2 "register_operand" "f")]))]
14856 && COMMUTATIVE_ARITH_P (operands[3])"
14857 "* return output_387_binary_op (insn, operands);"
14858 [(set (attr "type")
14859 (if_then_else (match_operand:XF 3 "mult_operator" "")
14860 (const_string "fmul")
14861 (const_string "fop")))
14862 (set_attr "mode" "XF")])
14864 (define_insn "*fop_xf_1_i387"
14865 [(set (match_operand:XF 0 "register_operand" "=f,f")
14866 (match_operator:XF 3 "binary_fp_operator"
14867 [(match_operand:XF 1 "register_operand" "0,f")
14868 (match_operand:XF 2 "register_operand" "f,0")]))]
14870 && !COMMUTATIVE_ARITH_P (operands[3])"
14871 "* return output_387_binary_op (insn, operands);"
14872 [(set (attr "type")
14873 (cond [(match_operand:XF 3 "mult_operator" "")
14874 (const_string "fmul")
14875 (match_operand:XF 3 "div_operator" "")
14876 (const_string "fdiv")
14878 (const_string "fop")))
14879 (set_attr "mode" "XF")])
14881 (define_insn "*fop_xf_2<mode>_i387"
14882 [(set (match_operand:XF 0 "register_operand" "=f,f")
14883 (match_operator:XF 3 "binary_fp_operator"
14884 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14885 (match_operand:XF 2 "register_operand" "0,0")]))]
14886 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14887 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14888 [(set (attr "type")
14889 (cond [(match_operand:XF 3 "mult_operator" "")
14890 (const_string "fmul")
14891 (match_operand:XF 3 "div_operator" "")
14892 (const_string "fdiv")
14894 (const_string "fop")))
14895 (set_attr "fp_int_src" "true")
14896 (set_attr "mode" "<MODE>")])
14898 (define_insn "*fop_xf_3<mode>_i387"
14899 [(set (match_operand:XF 0 "register_operand" "=f,f")
14900 (match_operator:XF 3 "binary_fp_operator"
14901 [(match_operand:XF 1 "register_operand" "0,0")
14902 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14903 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14904 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14905 [(set (attr "type")
14906 (cond [(match_operand:XF 3 "mult_operator" "")
14907 (const_string "fmul")
14908 (match_operand:XF 3 "div_operator" "")
14909 (const_string "fdiv")
14911 (const_string "fop")))
14912 (set_attr "fp_int_src" "true")
14913 (set_attr "mode" "<MODE>")])
14915 (define_insn "*fop_xf_4_i387"
14916 [(set (match_operand:XF 0 "register_operand" "=f,f")
14917 (match_operator:XF 3 "binary_fp_operator"
14918 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14919 (match_operand:XF 2 "register_operand" "0,f")]))]
14921 "* return output_387_binary_op (insn, operands);"
14922 [(set (attr "type")
14923 (cond [(match_operand:XF 3 "mult_operator" "")
14924 (const_string "fmul")
14925 (match_operand:XF 3 "div_operator" "")
14926 (const_string "fdiv")
14928 (const_string "fop")))
14929 (set_attr "mode" "SF")])
14931 (define_insn "*fop_xf_5_i387"
14932 [(set (match_operand:XF 0 "register_operand" "=f,f")
14933 (match_operator:XF 3 "binary_fp_operator"
14934 [(match_operand:XF 1 "register_operand" "0,f")
14936 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14938 "* return output_387_binary_op (insn, operands);"
14939 [(set (attr "type")
14940 (cond [(match_operand:XF 3 "mult_operator" "")
14941 (const_string "fmul")
14942 (match_operand:XF 3 "div_operator" "")
14943 (const_string "fdiv")
14945 (const_string "fop")))
14946 (set_attr "mode" "SF")])
14948 (define_insn "*fop_xf_6_i387"
14949 [(set (match_operand:XF 0 "register_operand" "=f,f")
14950 (match_operator:XF 3 "binary_fp_operator"
14952 (match_operand 1 "register_operand" "0,f"))
14954 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14956 "* return output_387_binary_op (insn, operands);"
14957 [(set (attr "type")
14958 (cond [(match_operand:XF 3 "mult_operator" "")
14959 (const_string "fmul")
14960 (match_operand:XF 3 "div_operator" "")
14961 (const_string "fdiv")
14963 (const_string "fop")))
14964 (set_attr "mode" "SF")])
14967 [(set (match_operand 0 "register_operand" "")
14968 (match_operator 3 "binary_fp_operator"
14969 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14970 (match_operand 2 "register_operand" "")]))]
14971 "TARGET_80387 && reload_completed
14972 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14975 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14976 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14977 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14978 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14979 GET_MODE (operands[3]),
14982 ix86_free_from_memory (GET_MODE (operands[1]));
14987 [(set (match_operand 0 "register_operand" "")
14988 (match_operator 3 "binary_fp_operator"
14989 [(match_operand 1 "register_operand" "")
14990 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14991 "TARGET_80387 && reload_completed
14992 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14995 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14996 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14997 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14998 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14999 GET_MODE (operands[3]),
15002 ix86_free_from_memory (GET_MODE (operands[2]));
15006 ;; FPU special functions.
15008 (define_expand "sqrtsf2"
15009 [(set (match_operand:SF 0 "register_operand" "")
15010 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15011 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15013 if (!TARGET_SSE_MATH)
15014 operands[1] = force_reg (SFmode, operands[1]);
15017 (define_insn "*sqrtsf2_mixed"
15018 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15019 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15020 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15023 sqrtss\t{%1, %0|%0, %1}"
15024 [(set_attr "type" "fpspc,sse")
15025 (set_attr "mode" "SF,SF")
15026 (set_attr "athlon_decode" "direct,*")])
15028 (define_insn "*sqrtsf2_sse"
15029 [(set (match_operand:SF 0 "register_operand" "=x")
15030 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15032 "sqrtss\t{%1, %0|%0, %1}"
15033 [(set_attr "type" "sse")
15034 (set_attr "mode" "SF")
15035 (set_attr "athlon_decode" "*")])
15037 (define_insn "*sqrtsf2_i387"
15038 [(set (match_operand:SF 0 "register_operand" "=f")
15039 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15040 "TARGET_USE_FANCY_MATH_387"
15042 [(set_attr "type" "fpspc")
15043 (set_attr "mode" "SF")
15044 (set_attr "athlon_decode" "direct")])
15046 (define_expand "sqrtdf2"
15047 [(set (match_operand:DF 0 "register_operand" "")
15048 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15049 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15051 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15052 operands[1] = force_reg (DFmode, operands[1]);
15055 (define_insn "*sqrtdf2_mixed"
15056 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15057 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15058 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15061 sqrtsd\t{%1, %0|%0, %1}"
15062 [(set_attr "type" "fpspc,sse")
15063 (set_attr "mode" "DF,DF")
15064 (set_attr "athlon_decode" "direct,*")])
15066 (define_insn "*sqrtdf2_sse"
15067 [(set (match_operand:DF 0 "register_operand" "=Y")
15068 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15069 "TARGET_SSE2 && TARGET_SSE_MATH"
15070 "sqrtsd\t{%1, %0|%0, %1}"
15071 [(set_attr "type" "sse")
15072 (set_attr "mode" "DF")
15073 (set_attr "athlon_decode" "*")])
15075 (define_insn "*sqrtdf2_i387"
15076 [(set (match_operand:DF 0 "register_operand" "=f")
15077 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15078 "TARGET_USE_FANCY_MATH_387"
15080 [(set_attr "type" "fpspc")
15081 (set_attr "mode" "DF")
15082 (set_attr "athlon_decode" "direct")])
15084 (define_insn "*sqrtextendsfdf2_i387"
15085 [(set (match_operand:DF 0 "register_operand" "=f")
15086 (sqrt:DF (float_extend:DF
15087 (match_operand:SF 1 "register_operand" "0"))))]
15088 "TARGET_USE_FANCY_MATH_387
15089 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15091 [(set_attr "type" "fpspc")
15092 (set_attr "mode" "DF")
15093 (set_attr "athlon_decode" "direct")])
15095 (define_insn "sqrtxf2"
15096 [(set (match_operand:XF 0 "register_operand" "=f")
15097 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15098 "TARGET_USE_FANCY_MATH_387
15099 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15101 [(set_attr "type" "fpspc")
15102 (set_attr "mode" "XF")
15103 (set_attr "athlon_decode" "direct")])
15105 (define_insn "*sqrtextendsfxf2_i387"
15106 [(set (match_operand:XF 0 "register_operand" "=f")
15107 (sqrt:XF (float_extend:XF
15108 (match_operand:SF 1 "register_operand" "0"))))]
15109 "TARGET_USE_FANCY_MATH_387"
15111 [(set_attr "type" "fpspc")
15112 (set_attr "mode" "XF")
15113 (set_attr "athlon_decode" "direct")])
15115 (define_insn "*sqrtextenddfxf2_i387"
15116 [(set (match_operand:XF 0 "register_operand" "=f")
15117 (sqrt:XF (float_extend:XF
15118 (match_operand:DF 1 "register_operand" "0"))))]
15119 "TARGET_USE_FANCY_MATH_387"
15121 [(set_attr "type" "fpspc")
15122 (set_attr "mode" "XF")
15123 (set_attr "athlon_decode" "direct")])
15125 (define_insn "fpremxf4"
15126 [(set (match_operand:XF 0 "register_operand" "=f")
15127 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15128 (match_operand:XF 3 "register_operand" "1")]
15130 (set (match_operand:XF 1 "register_operand" "=u")
15131 (unspec:XF [(match_dup 2) (match_dup 3)]
15133 (set (reg:CCFP FPSR_REG)
15134 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15135 "TARGET_USE_FANCY_MATH_387
15136 && flag_unsafe_math_optimizations"
15138 [(set_attr "type" "fpspc")
15139 (set_attr "mode" "XF")])
15141 (define_expand "fmodsf3"
15142 [(use (match_operand:SF 0 "register_operand" ""))
15143 (use (match_operand:SF 1 "register_operand" ""))
15144 (use (match_operand:SF 2 "register_operand" ""))]
15145 "TARGET_USE_FANCY_MATH_387
15146 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15147 && flag_unsafe_math_optimizations"
15149 rtx label = gen_label_rtx ();
15151 rtx op1 = gen_reg_rtx (XFmode);
15152 rtx op2 = gen_reg_rtx (XFmode);
15154 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15155 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15157 emit_label (label);
15159 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15160 ix86_emit_fp_unordered_jump (label);
15162 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15166 (define_expand "fmoddf3"
15167 [(use (match_operand:DF 0 "register_operand" ""))
15168 (use (match_operand:DF 1 "register_operand" ""))
15169 (use (match_operand:DF 2 "register_operand" ""))]
15170 "TARGET_USE_FANCY_MATH_387
15171 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15172 && flag_unsafe_math_optimizations"
15174 rtx label = gen_label_rtx ();
15176 rtx op1 = gen_reg_rtx (XFmode);
15177 rtx op2 = gen_reg_rtx (XFmode);
15179 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15180 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15182 emit_label (label);
15184 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15185 ix86_emit_fp_unordered_jump (label);
15187 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15191 (define_expand "fmodxf3"
15192 [(use (match_operand:XF 0 "register_operand" ""))
15193 (use (match_operand:XF 1 "register_operand" ""))
15194 (use (match_operand:XF 2 "register_operand" ""))]
15195 "TARGET_USE_FANCY_MATH_387
15196 && flag_unsafe_math_optimizations"
15198 rtx label = gen_label_rtx ();
15200 emit_label (label);
15202 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15203 operands[1], operands[2]));
15204 ix86_emit_fp_unordered_jump (label);
15206 emit_move_insn (operands[0], operands[1]);
15210 (define_insn "fprem1xf4"
15211 [(set (match_operand:XF 0 "register_operand" "=f")
15212 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15213 (match_operand:XF 3 "register_operand" "1")]
15215 (set (match_operand:XF 1 "register_operand" "=u")
15216 (unspec:XF [(match_dup 2) (match_dup 3)]
15218 (set (reg:CCFP FPSR_REG)
15219 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15220 "TARGET_USE_FANCY_MATH_387
15221 && flag_unsafe_math_optimizations"
15223 [(set_attr "type" "fpspc")
15224 (set_attr "mode" "XF")])
15226 (define_expand "dremsf3"
15227 [(use (match_operand:SF 0 "register_operand" ""))
15228 (use (match_operand:SF 1 "register_operand" ""))
15229 (use (match_operand:SF 2 "register_operand" ""))]
15230 "TARGET_USE_FANCY_MATH_387
15231 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15232 && flag_unsafe_math_optimizations"
15234 rtx label = gen_label_rtx ();
15236 rtx op1 = gen_reg_rtx (XFmode);
15237 rtx op2 = gen_reg_rtx (XFmode);
15239 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15240 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15242 emit_label (label);
15244 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15245 ix86_emit_fp_unordered_jump (label);
15247 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15251 (define_expand "dremdf3"
15252 [(use (match_operand:DF 0 "register_operand" ""))
15253 (use (match_operand:DF 1 "register_operand" ""))
15254 (use (match_operand:DF 2 "register_operand" ""))]
15255 "TARGET_USE_FANCY_MATH_387
15256 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15257 && flag_unsafe_math_optimizations"
15259 rtx label = gen_label_rtx ();
15261 rtx op1 = gen_reg_rtx (XFmode);
15262 rtx op2 = gen_reg_rtx (XFmode);
15264 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15265 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15267 emit_label (label);
15269 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15270 ix86_emit_fp_unordered_jump (label);
15272 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15276 (define_expand "dremxf3"
15277 [(use (match_operand:XF 0 "register_operand" ""))
15278 (use (match_operand:XF 1 "register_operand" ""))
15279 (use (match_operand:XF 2 "register_operand" ""))]
15280 "TARGET_USE_FANCY_MATH_387
15281 && flag_unsafe_math_optimizations"
15283 rtx label = gen_label_rtx ();
15285 emit_label (label);
15287 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15288 operands[1], operands[2]));
15289 ix86_emit_fp_unordered_jump (label);
15291 emit_move_insn (operands[0], operands[1]);
15295 (define_insn "*sindf2"
15296 [(set (match_operand:DF 0 "register_operand" "=f")
15297 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15298 "TARGET_USE_FANCY_MATH_387
15299 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15300 && flag_unsafe_math_optimizations"
15302 [(set_attr "type" "fpspc")
15303 (set_attr "mode" "DF")])
15305 (define_insn "*sinsf2"
15306 [(set (match_operand:SF 0 "register_operand" "=f")
15307 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15308 "TARGET_USE_FANCY_MATH_387
15309 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15310 && flag_unsafe_math_optimizations"
15312 [(set_attr "type" "fpspc")
15313 (set_attr "mode" "SF")])
15315 (define_insn "*sinextendsfdf2"
15316 [(set (match_operand:DF 0 "register_operand" "=f")
15317 (unspec:DF [(float_extend:DF
15318 (match_operand:SF 1 "register_operand" "0"))]
15320 "TARGET_USE_FANCY_MATH_387
15321 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15322 && flag_unsafe_math_optimizations"
15324 [(set_attr "type" "fpspc")
15325 (set_attr "mode" "DF")])
15327 (define_insn "*sinxf2"
15328 [(set (match_operand:XF 0 "register_operand" "=f")
15329 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15330 "TARGET_USE_FANCY_MATH_387
15331 && flag_unsafe_math_optimizations"
15333 [(set_attr "type" "fpspc")
15334 (set_attr "mode" "XF")])
15336 (define_insn "*cosdf2"
15337 [(set (match_operand:DF 0 "register_operand" "=f")
15338 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15339 "TARGET_USE_FANCY_MATH_387
15340 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15341 && flag_unsafe_math_optimizations"
15343 [(set_attr "type" "fpspc")
15344 (set_attr "mode" "DF")])
15346 (define_insn "*cossf2"
15347 [(set (match_operand:SF 0 "register_operand" "=f")
15348 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15349 "TARGET_USE_FANCY_MATH_387
15350 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15351 && flag_unsafe_math_optimizations"
15353 [(set_attr "type" "fpspc")
15354 (set_attr "mode" "SF")])
15356 (define_insn "*cosextendsfdf2"
15357 [(set (match_operand:DF 0 "register_operand" "=f")
15358 (unspec:DF [(float_extend:DF
15359 (match_operand:SF 1 "register_operand" "0"))]
15361 "TARGET_USE_FANCY_MATH_387
15362 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15363 && flag_unsafe_math_optimizations"
15365 [(set_attr "type" "fpspc")
15366 (set_attr "mode" "DF")])
15368 (define_insn "*cosxf2"
15369 [(set (match_operand:XF 0 "register_operand" "=f")
15370 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15371 "TARGET_USE_FANCY_MATH_387
15372 && flag_unsafe_math_optimizations"
15374 [(set_attr "type" "fpspc")
15375 (set_attr "mode" "XF")])
15377 ;; With sincos pattern defined, sin and cos builtin function will be
15378 ;; expanded to sincos pattern with one of its outputs left unused.
15379 ;; Cse pass will detected, if two sincos patterns can be combined,
15380 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15381 ;; depending on the unused output.
15383 (define_insn "sincosdf3"
15384 [(set (match_operand:DF 0 "register_operand" "=f")
15385 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15386 UNSPEC_SINCOS_COS))
15387 (set (match_operand:DF 1 "register_operand" "=u")
15388 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15389 "TARGET_USE_FANCY_MATH_387
15390 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15391 && flag_unsafe_math_optimizations"
15393 [(set_attr "type" "fpspc")
15394 (set_attr "mode" "DF")])
15397 [(set (match_operand:DF 0 "register_operand" "")
15398 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15399 UNSPEC_SINCOS_COS))
15400 (set (match_operand:DF 1 "register_operand" "")
15401 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15402 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15403 && !reload_completed && !reload_in_progress"
15404 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15408 [(set (match_operand:DF 0 "register_operand" "")
15409 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15410 UNSPEC_SINCOS_COS))
15411 (set (match_operand:DF 1 "register_operand" "")
15412 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15413 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15414 && !reload_completed && !reload_in_progress"
15415 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15418 (define_insn "sincossf3"
15419 [(set (match_operand:SF 0 "register_operand" "=f")
15420 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15421 UNSPEC_SINCOS_COS))
15422 (set (match_operand:SF 1 "register_operand" "=u")
15423 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15424 "TARGET_USE_FANCY_MATH_387
15425 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15426 && flag_unsafe_math_optimizations"
15428 [(set_attr "type" "fpspc")
15429 (set_attr "mode" "SF")])
15432 [(set (match_operand:SF 0 "register_operand" "")
15433 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15434 UNSPEC_SINCOS_COS))
15435 (set (match_operand:SF 1 "register_operand" "")
15436 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15437 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15438 && !reload_completed && !reload_in_progress"
15439 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15443 [(set (match_operand:SF 0 "register_operand" "")
15444 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15445 UNSPEC_SINCOS_COS))
15446 (set (match_operand:SF 1 "register_operand" "")
15447 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15448 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15449 && !reload_completed && !reload_in_progress"
15450 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15453 (define_insn "*sincosextendsfdf3"
15454 [(set (match_operand:DF 0 "register_operand" "=f")
15455 (unspec:DF [(float_extend:DF
15456 (match_operand:SF 2 "register_operand" "0"))]
15457 UNSPEC_SINCOS_COS))
15458 (set (match_operand:DF 1 "register_operand" "=u")
15459 (unspec:DF [(float_extend:DF
15460 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15461 "TARGET_USE_FANCY_MATH_387
15462 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15463 && flag_unsafe_math_optimizations"
15465 [(set_attr "type" "fpspc")
15466 (set_attr "mode" "DF")])
15469 [(set (match_operand:DF 0 "register_operand" "")
15470 (unspec:DF [(float_extend:DF
15471 (match_operand:SF 2 "register_operand" ""))]
15472 UNSPEC_SINCOS_COS))
15473 (set (match_operand:DF 1 "register_operand" "")
15474 (unspec:DF [(float_extend:DF
15475 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15476 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15477 && !reload_completed && !reload_in_progress"
15478 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15479 (match_dup 2))] UNSPEC_SIN))]
15483 [(set (match_operand:DF 0 "register_operand" "")
15484 (unspec:DF [(float_extend:DF
15485 (match_operand:SF 2 "register_operand" ""))]
15486 UNSPEC_SINCOS_COS))
15487 (set (match_operand:DF 1 "register_operand" "")
15488 (unspec:DF [(float_extend:DF
15489 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15490 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15491 && !reload_completed && !reload_in_progress"
15492 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15493 (match_dup 2))] UNSPEC_COS))]
15496 (define_insn "sincosxf3"
15497 [(set (match_operand:XF 0 "register_operand" "=f")
15498 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15499 UNSPEC_SINCOS_COS))
15500 (set (match_operand:XF 1 "register_operand" "=u")
15501 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15502 "TARGET_USE_FANCY_MATH_387
15503 && flag_unsafe_math_optimizations"
15505 [(set_attr "type" "fpspc")
15506 (set_attr "mode" "XF")])
15509 [(set (match_operand:XF 0 "register_operand" "")
15510 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15511 UNSPEC_SINCOS_COS))
15512 (set (match_operand:XF 1 "register_operand" "")
15513 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15514 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15515 && !reload_completed && !reload_in_progress"
15516 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15520 [(set (match_operand:XF 0 "register_operand" "")
15521 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15522 UNSPEC_SINCOS_COS))
15523 (set (match_operand:XF 1 "register_operand" "")
15524 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15525 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15526 && !reload_completed && !reload_in_progress"
15527 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15530 (define_insn "*tandf3_1"
15531 [(set (match_operand:DF 0 "register_operand" "=f")
15532 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15534 (set (match_operand:DF 1 "register_operand" "=u")
15535 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15536 "TARGET_USE_FANCY_MATH_387
15537 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15538 && flag_unsafe_math_optimizations"
15540 [(set_attr "type" "fpspc")
15541 (set_attr "mode" "DF")])
15543 ;; optimize sequence: fptan
15546 ;; into fptan insn.
15549 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15550 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15552 (set (match_operand:DF 1 "register_operand" "")
15553 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15555 (match_operand:DF 3 "immediate_operand" ""))]
15556 "standard_80387_constant_p (operands[3]) == 2"
15557 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15558 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15561 (define_expand "tandf2"
15562 [(parallel [(set (match_dup 2)
15563 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15565 (set (match_operand:DF 0 "register_operand" "")
15566 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15567 "TARGET_USE_FANCY_MATH_387
15568 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15569 && flag_unsafe_math_optimizations"
15571 operands[2] = gen_reg_rtx (DFmode);
15574 (define_insn "*tansf3_1"
15575 [(set (match_operand:SF 0 "register_operand" "=f")
15576 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15578 (set (match_operand:SF 1 "register_operand" "=u")
15579 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15580 "TARGET_USE_FANCY_MATH_387
15581 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15582 && flag_unsafe_math_optimizations"
15584 [(set_attr "type" "fpspc")
15585 (set_attr "mode" "SF")])
15587 ;; optimize sequence: fptan
15590 ;; into fptan insn.
15593 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15594 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15596 (set (match_operand:SF 1 "register_operand" "")
15597 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15599 (match_operand:SF 3 "immediate_operand" ""))]
15600 "standard_80387_constant_p (operands[3]) == 2"
15601 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15602 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15605 (define_expand "tansf2"
15606 [(parallel [(set (match_dup 2)
15607 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15609 (set (match_operand:SF 0 "register_operand" "")
15610 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15611 "TARGET_USE_FANCY_MATH_387
15612 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15613 && flag_unsafe_math_optimizations"
15615 operands[2] = gen_reg_rtx (SFmode);
15618 (define_insn "*tanxf3_1"
15619 [(set (match_operand:XF 0 "register_operand" "=f")
15620 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15622 (set (match_operand:XF 1 "register_operand" "=u")
15623 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15624 "TARGET_USE_FANCY_MATH_387
15625 && flag_unsafe_math_optimizations"
15627 [(set_attr "type" "fpspc")
15628 (set_attr "mode" "XF")])
15630 ;; optimize sequence: fptan
15633 ;; into fptan insn.
15636 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15637 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15639 (set (match_operand:XF 1 "register_operand" "")
15640 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15642 (match_operand:XF 3 "immediate_operand" ""))]
15643 "standard_80387_constant_p (operands[3]) == 2"
15644 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15645 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15648 (define_expand "tanxf2"
15649 [(parallel [(set (match_dup 2)
15650 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15652 (set (match_operand:XF 0 "register_operand" "")
15653 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15654 "TARGET_USE_FANCY_MATH_387
15655 && flag_unsafe_math_optimizations"
15657 operands[2] = gen_reg_rtx (XFmode);
15660 (define_insn "atan2df3_1"
15661 [(set (match_operand:DF 0 "register_operand" "=f")
15662 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15663 (match_operand:DF 1 "register_operand" "u")]
15665 (clobber (match_scratch:DF 3 "=1"))]
15666 "TARGET_USE_FANCY_MATH_387
15667 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15668 && flag_unsafe_math_optimizations"
15670 [(set_attr "type" "fpspc")
15671 (set_attr "mode" "DF")])
15673 (define_expand "atan2df3"
15674 [(use (match_operand:DF 0 "register_operand" ""))
15675 (use (match_operand:DF 2 "register_operand" ""))
15676 (use (match_operand:DF 1 "register_operand" ""))]
15677 "TARGET_USE_FANCY_MATH_387
15678 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15679 && flag_unsafe_math_optimizations"
15681 rtx copy = gen_reg_rtx (DFmode);
15682 emit_move_insn (copy, operands[1]);
15683 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15687 (define_expand "atandf2"
15688 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15689 (unspec:DF [(match_dup 2)
15690 (match_operand:DF 1 "register_operand" "")]
15692 (clobber (match_scratch:DF 3 ""))])]
15693 "TARGET_USE_FANCY_MATH_387
15694 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15695 && flag_unsafe_math_optimizations"
15697 operands[2] = gen_reg_rtx (DFmode);
15698 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15701 (define_insn "atan2sf3_1"
15702 [(set (match_operand:SF 0 "register_operand" "=f")
15703 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15704 (match_operand:SF 1 "register_operand" "u")]
15706 (clobber (match_scratch:SF 3 "=1"))]
15707 "TARGET_USE_FANCY_MATH_387
15708 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15709 && flag_unsafe_math_optimizations"
15711 [(set_attr "type" "fpspc")
15712 (set_attr "mode" "SF")])
15714 (define_expand "atan2sf3"
15715 [(use (match_operand:SF 0 "register_operand" ""))
15716 (use (match_operand:SF 2 "register_operand" ""))
15717 (use (match_operand:SF 1 "register_operand" ""))]
15718 "TARGET_USE_FANCY_MATH_387
15719 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15720 && flag_unsafe_math_optimizations"
15722 rtx copy = gen_reg_rtx (SFmode);
15723 emit_move_insn (copy, operands[1]);
15724 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15728 (define_expand "atansf2"
15729 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15730 (unspec:SF [(match_dup 2)
15731 (match_operand:SF 1 "register_operand" "")]
15733 (clobber (match_scratch:SF 3 ""))])]
15734 "TARGET_USE_FANCY_MATH_387
15735 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15736 && flag_unsafe_math_optimizations"
15738 operands[2] = gen_reg_rtx (SFmode);
15739 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15742 (define_insn "atan2xf3_1"
15743 [(set (match_operand:XF 0 "register_operand" "=f")
15744 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15745 (match_operand:XF 1 "register_operand" "u")]
15747 (clobber (match_scratch:XF 3 "=1"))]
15748 "TARGET_USE_FANCY_MATH_387
15749 && flag_unsafe_math_optimizations"
15751 [(set_attr "type" "fpspc")
15752 (set_attr "mode" "XF")])
15754 (define_expand "atan2xf3"
15755 [(use (match_operand:XF 0 "register_operand" ""))
15756 (use (match_operand:XF 2 "register_operand" ""))
15757 (use (match_operand:XF 1 "register_operand" ""))]
15758 "TARGET_USE_FANCY_MATH_387
15759 && flag_unsafe_math_optimizations"
15761 rtx copy = gen_reg_rtx (XFmode);
15762 emit_move_insn (copy, operands[1]);
15763 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15767 (define_expand "atanxf2"
15768 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15769 (unspec:XF [(match_dup 2)
15770 (match_operand:XF 1 "register_operand" "")]
15772 (clobber (match_scratch:XF 3 ""))])]
15773 "TARGET_USE_FANCY_MATH_387
15774 && flag_unsafe_math_optimizations"
15776 operands[2] = gen_reg_rtx (XFmode);
15777 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15780 (define_expand "asindf2"
15781 [(set (match_dup 2)
15782 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15783 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15784 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15785 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15786 (parallel [(set (match_dup 7)
15787 (unspec:XF [(match_dup 6) (match_dup 2)]
15789 (clobber (match_scratch:XF 8 ""))])
15790 (set (match_operand:DF 0 "register_operand" "")
15791 (float_truncate:DF (match_dup 7)))]
15792 "TARGET_USE_FANCY_MATH_387
15793 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15794 && flag_unsafe_math_optimizations"
15798 for (i=2; i<8; i++)
15799 operands[i] = gen_reg_rtx (XFmode);
15801 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15804 (define_expand "asinsf2"
15805 [(set (match_dup 2)
15806 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15807 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15808 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15809 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15810 (parallel [(set (match_dup 7)
15811 (unspec:XF [(match_dup 6) (match_dup 2)]
15813 (clobber (match_scratch:XF 8 ""))])
15814 (set (match_operand:SF 0 "register_operand" "")
15815 (float_truncate:SF (match_dup 7)))]
15816 "TARGET_USE_FANCY_MATH_387
15817 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15818 && flag_unsafe_math_optimizations"
15822 for (i=2; i<8; i++)
15823 operands[i] = gen_reg_rtx (XFmode);
15825 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15828 (define_expand "asinxf2"
15829 [(set (match_dup 2)
15830 (mult:XF (match_operand:XF 1 "register_operand" "")
15832 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15833 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15834 (parallel [(set (match_operand:XF 0 "register_operand" "")
15835 (unspec:XF [(match_dup 5) (match_dup 1)]
15837 (clobber (match_scratch:XF 6 ""))])]
15838 "TARGET_USE_FANCY_MATH_387
15839 && flag_unsafe_math_optimizations"
15843 for (i=2; i<6; i++)
15844 operands[i] = gen_reg_rtx (XFmode);
15846 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15849 (define_expand "acosdf2"
15850 [(set (match_dup 2)
15851 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15852 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15853 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15854 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15855 (parallel [(set (match_dup 7)
15856 (unspec:XF [(match_dup 2) (match_dup 6)]
15858 (clobber (match_scratch:XF 8 ""))])
15859 (set (match_operand:DF 0 "register_operand" "")
15860 (float_truncate:DF (match_dup 7)))]
15861 "TARGET_USE_FANCY_MATH_387
15862 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15863 && flag_unsafe_math_optimizations"
15867 for (i=2; i<8; i++)
15868 operands[i] = gen_reg_rtx (XFmode);
15870 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15873 (define_expand "acossf2"
15874 [(set (match_dup 2)
15875 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15876 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15877 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15878 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15879 (parallel [(set (match_dup 7)
15880 (unspec:XF [(match_dup 2) (match_dup 6)]
15882 (clobber (match_scratch:XF 8 ""))])
15883 (set (match_operand:SF 0 "register_operand" "")
15884 (float_truncate:SF (match_dup 7)))]
15885 "TARGET_USE_FANCY_MATH_387
15886 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15887 && flag_unsafe_math_optimizations"
15891 for (i=2; i<8; i++)
15892 operands[i] = gen_reg_rtx (XFmode);
15894 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15897 (define_expand "acosxf2"
15898 [(set (match_dup 2)
15899 (mult:XF (match_operand:XF 1 "register_operand" "")
15901 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15902 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15903 (parallel [(set (match_operand:XF 0 "register_operand" "")
15904 (unspec:XF [(match_dup 1) (match_dup 5)]
15906 (clobber (match_scratch:XF 6 ""))])]
15907 "TARGET_USE_FANCY_MATH_387
15908 && flag_unsafe_math_optimizations"
15912 for (i=2; i<6; i++)
15913 operands[i] = gen_reg_rtx (XFmode);
15915 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15918 (define_insn "fyl2x_xf3"
15919 [(set (match_operand:XF 0 "register_operand" "=f")
15920 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15921 (match_operand:XF 1 "register_operand" "u")]
15923 (clobber (match_scratch:XF 3 "=1"))]
15924 "TARGET_USE_FANCY_MATH_387
15925 && flag_unsafe_math_optimizations"
15927 [(set_attr "type" "fpspc")
15928 (set_attr "mode" "XF")])
15930 (define_expand "logsf2"
15931 [(set (match_dup 2)
15932 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15933 (parallel [(set (match_dup 4)
15934 (unspec:XF [(match_dup 2)
15935 (match_dup 3)] UNSPEC_FYL2X))
15936 (clobber (match_scratch:XF 5 ""))])
15937 (set (match_operand:SF 0 "register_operand" "")
15938 (float_truncate:SF (match_dup 4)))]
15939 "TARGET_USE_FANCY_MATH_387
15940 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15941 && flag_unsafe_math_optimizations"
15945 operands[2] = gen_reg_rtx (XFmode);
15946 operands[3] = gen_reg_rtx (XFmode);
15947 operands[4] = gen_reg_rtx (XFmode);
15949 temp = standard_80387_constant_rtx (4); /* fldln2 */
15950 emit_move_insn (operands[3], temp);
15953 (define_expand "logdf2"
15954 [(set (match_dup 2)
15955 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15956 (parallel [(set (match_dup 4)
15957 (unspec:XF [(match_dup 2)
15958 (match_dup 3)] UNSPEC_FYL2X))
15959 (clobber (match_scratch:XF 5 ""))])
15960 (set (match_operand:DF 0 "register_operand" "")
15961 (float_truncate:DF (match_dup 4)))]
15962 "TARGET_USE_FANCY_MATH_387
15963 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15964 && flag_unsafe_math_optimizations"
15968 operands[2] = gen_reg_rtx (XFmode);
15969 operands[3] = gen_reg_rtx (XFmode);
15970 operands[4] = gen_reg_rtx (XFmode);
15972 temp = standard_80387_constant_rtx (4); /* fldln2 */
15973 emit_move_insn (operands[3], temp);
15976 (define_expand "logxf2"
15977 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15978 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15979 (match_dup 2)] UNSPEC_FYL2X))
15980 (clobber (match_scratch:XF 3 ""))])]
15981 "TARGET_USE_FANCY_MATH_387
15982 && flag_unsafe_math_optimizations"
15986 operands[2] = gen_reg_rtx (XFmode);
15987 temp = standard_80387_constant_rtx (4); /* fldln2 */
15988 emit_move_insn (operands[2], temp);
15991 (define_expand "log10sf2"
15992 [(set (match_dup 2)
15993 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15994 (parallel [(set (match_dup 4)
15995 (unspec:XF [(match_dup 2)
15996 (match_dup 3)] UNSPEC_FYL2X))
15997 (clobber (match_scratch:XF 5 ""))])
15998 (set (match_operand:SF 0 "register_operand" "")
15999 (float_truncate:SF (match_dup 4)))]
16000 "TARGET_USE_FANCY_MATH_387
16001 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16002 && flag_unsafe_math_optimizations"
16006 operands[2] = gen_reg_rtx (XFmode);
16007 operands[3] = gen_reg_rtx (XFmode);
16008 operands[4] = gen_reg_rtx (XFmode);
16010 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16011 emit_move_insn (operands[3], temp);
16014 (define_expand "log10df2"
16015 [(set (match_dup 2)
16016 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16017 (parallel [(set (match_dup 4)
16018 (unspec:XF [(match_dup 2)
16019 (match_dup 3)] UNSPEC_FYL2X))
16020 (clobber (match_scratch:XF 5 ""))])
16021 (set (match_operand:DF 0 "register_operand" "")
16022 (float_truncate:DF (match_dup 4)))]
16023 "TARGET_USE_FANCY_MATH_387
16024 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16025 && flag_unsafe_math_optimizations"
16029 operands[2] = gen_reg_rtx (XFmode);
16030 operands[3] = gen_reg_rtx (XFmode);
16031 operands[4] = gen_reg_rtx (XFmode);
16033 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16034 emit_move_insn (operands[3], temp);
16037 (define_expand "log10xf2"
16038 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16039 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16040 (match_dup 2)] UNSPEC_FYL2X))
16041 (clobber (match_scratch:XF 3 ""))])]
16042 "TARGET_USE_FANCY_MATH_387
16043 && flag_unsafe_math_optimizations"
16047 operands[2] = gen_reg_rtx (XFmode);
16048 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16049 emit_move_insn (operands[2], temp);
16052 (define_expand "log2sf2"
16053 [(set (match_dup 2)
16054 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16055 (parallel [(set (match_dup 4)
16056 (unspec:XF [(match_dup 2)
16057 (match_dup 3)] UNSPEC_FYL2X))
16058 (clobber (match_scratch:XF 5 ""))])
16059 (set (match_operand:SF 0 "register_operand" "")
16060 (float_truncate:SF (match_dup 4)))]
16061 "TARGET_USE_FANCY_MATH_387
16062 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16063 && flag_unsafe_math_optimizations"
16065 operands[2] = gen_reg_rtx (XFmode);
16066 operands[3] = gen_reg_rtx (XFmode);
16067 operands[4] = gen_reg_rtx (XFmode);
16069 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16072 (define_expand "log2df2"
16073 [(set (match_dup 2)
16074 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16075 (parallel [(set (match_dup 4)
16076 (unspec:XF [(match_dup 2)
16077 (match_dup 3)] UNSPEC_FYL2X))
16078 (clobber (match_scratch:XF 5 ""))])
16079 (set (match_operand:DF 0 "register_operand" "")
16080 (float_truncate:DF (match_dup 4)))]
16081 "TARGET_USE_FANCY_MATH_387
16082 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16083 && flag_unsafe_math_optimizations"
16085 operands[2] = gen_reg_rtx (XFmode);
16086 operands[3] = gen_reg_rtx (XFmode);
16087 operands[4] = gen_reg_rtx (XFmode);
16089 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16092 (define_expand "log2xf2"
16093 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16094 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16095 (match_dup 2)] UNSPEC_FYL2X))
16096 (clobber (match_scratch:XF 3 ""))])]
16097 "TARGET_USE_FANCY_MATH_387
16098 && flag_unsafe_math_optimizations"
16100 operands[2] = gen_reg_rtx (XFmode);
16101 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16104 (define_insn "fyl2xp1_xf3"
16105 [(set (match_operand:XF 0 "register_operand" "=f")
16106 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16107 (match_operand:XF 1 "register_operand" "u")]
16109 (clobber (match_scratch:XF 3 "=1"))]
16110 "TARGET_USE_FANCY_MATH_387
16111 && flag_unsafe_math_optimizations"
16113 [(set_attr "type" "fpspc")
16114 (set_attr "mode" "XF")])
16116 (define_expand "log1psf2"
16117 [(use (match_operand:SF 0 "register_operand" ""))
16118 (use (match_operand:SF 1 "register_operand" ""))]
16119 "TARGET_USE_FANCY_MATH_387
16120 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16121 && flag_unsafe_math_optimizations"
16123 rtx op0 = gen_reg_rtx (XFmode);
16124 rtx op1 = gen_reg_rtx (XFmode);
16126 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16127 ix86_emit_i387_log1p (op0, op1);
16128 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16132 (define_expand "log1pdf2"
16133 [(use (match_operand:DF 0 "register_operand" ""))
16134 (use (match_operand:DF 1 "register_operand" ""))]
16135 "TARGET_USE_FANCY_MATH_387
16136 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16137 && flag_unsafe_math_optimizations"
16139 rtx op0 = gen_reg_rtx (XFmode);
16140 rtx op1 = gen_reg_rtx (XFmode);
16142 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16143 ix86_emit_i387_log1p (op0, op1);
16144 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16148 (define_expand "log1pxf2"
16149 [(use (match_operand:XF 0 "register_operand" ""))
16150 (use (match_operand:XF 1 "register_operand" ""))]
16151 "TARGET_USE_FANCY_MATH_387
16152 && flag_unsafe_math_optimizations"
16154 ix86_emit_i387_log1p (operands[0], operands[1]);
16158 (define_insn "*fxtractxf3"
16159 [(set (match_operand:XF 0 "register_operand" "=f")
16160 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16161 UNSPEC_XTRACT_FRACT))
16162 (set (match_operand:XF 1 "register_operand" "=u")
16163 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16164 "TARGET_USE_FANCY_MATH_387
16165 && flag_unsafe_math_optimizations"
16167 [(set_attr "type" "fpspc")
16168 (set_attr "mode" "XF")])
16170 (define_expand "logbsf2"
16171 [(set (match_dup 2)
16172 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16173 (parallel [(set (match_dup 3)
16174 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16176 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16177 (set (match_operand:SF 0 "register_operand" "")
16178 (float_truncate:SF (match_dup 4)))]
16179 "TARGET_USE_FANCY_MATH_387
16180 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16181 && flag_unsafe_math_optimizations"
16183 operands[2] = gen_reg_rtx (XFmode);
16184 operands[3] = gen_reg_rtx (XFmode);
16185 operands[4] = gen_reg_rtx (XFmode);
16188 (define_expand "logbdf2"
16189 [(set (match_dup 2)
16190 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16191 (parallel [(set (match_dup 3)
16192 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16194 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16195 (set (match_operand:DF 0 "register_operand" "")
16196 (float_truncate:DF (match_dup 4)))]
16197 "TARGET_USE_FANCY_MATH_387
16198 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16199 && flag_unsafe_math_optimizations"
16201 operands[2] = gen_reg_rtx (XFmode);
16202 operands[3] = gen_reg_rtx (XFmode);
16203 operands[4] = gen_reg_rtx (XFmode);
16206 (define_expand "logbxf2"
16207 [(parallel [(set (match_dup 2)
16208 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16209 UNSPEC_XTRACT_FRACT))
16210 (set (match_operand:XF 0 "register_operand" "")
16211 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16212 "TARGET_USE_FANCY_MATH_387
16213 && flag_unsafe_math_optimizations"
16215 operands[2] = gen_reg_rtx (XFmode);
16218 (define_expand "ilogbsi2"
16219 [(parallel [(set (match_dup 2)
16220 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16221 UNSPEC_XTRACT_FRACT))
16222 (set (match_operand:XF 3 "register_operand" "")
16223 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16224 (parallel [(set (match_operand:SI 0 "register_operand" "")
16225 (fix:SI (match_dup 3)))
16226 (clobber (reg:CC FLAGS_REG))])]
16227 "TARGET_USE_FANCY_MATH_387
16228 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16229 && flag_unsafe_math_optimizations"
16231 operands[2] = gen_reg_rtx (XFmode);
16232 operands[3] = gen_reg_rtx (XFmode);
16235 (define_insn "*f2xm1xf2"
16236 [(set (match_operand:XF 0 "register_operand" "=f")
16237 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16239 "TARGET_USE_FANCY_MATH_387
16240 && flag_unsafe_math_optimizations"
16242 [(set_attr "type" "fpspc")
16243 (set_attr "mode" "XF")])
16245 (define_insn "*fscalexf4"
16246 [(set (match_operand:XF 0 "register_operand" "=f")
16247 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16248 (match_operand:XF 3 "register_operand" "1")]
16249 UNSPEC_FSCALE_FRACT))
16250 (set (match_operand:XF 1 "register_operand" "=u")
16251 (unspec:XF [(match_dup 2) (match_dup 3)]
16252 UNSPEC_FSCALE_EXP))]
16253 "TARGET_USE_FANCY_MATH_387
16254 && flag_unsafe_math_optimizations"
16256 [(set_attr "type" "fpspc")
16257 (set_attr "mode" "XF")])
16259 (define_expand "expsf2"
16260 [(set (match_dup 2)
16261 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16262 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16263 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16264 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16265 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16266 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16267 (parallel [(set (match_dup 10)
16268 (unspec:XF [(match_dup 9) (match_dup 5)]
16269 UNSPEC_FSCALE_FRACT))
16270 (set (match_dup 11)
16271 (unspec:XF [(match_dup 9) (match_dup 5)]
16272 UNSPEC_FSCALE_EXP))])
16273 (set (match_operand:SF 0 "register_operand" "")
16274 (float_truncate:SF (match_dup 10)))]
16275 "TARGET_USE_FANCY_MATH_387
16276 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16277 && flag_unsafe_math_optimizations"
16282 for (i=2; i<12; i++)
16283 operands[i] = gen_reg_rtx (XFmode);
16284 temp = standard_80387_constant_rtx (5); /* fldl2e */
16285 emit_move_insn (operands[3], temp);
16286 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16289 (define_expand "expdf2"
16290 [(set (match_dup 2)
16291 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16292 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16293 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16294 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16295 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16296 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16297 (parallel [(set (match_dup 10)
16298 (unspec:XF [(match_dup 9) (match_dup 5)]
16299 UNSPEC_FSCALE_FRACT))
16300 (set (match_dup 11)
16301 (unspec:XF [(match_dup 9) (match_dup 5)]
16302 UNSPEC_FSCALE_EXP))])
16303 (set (match_operand:DF 0 "register_operand" "")
16304 (float_truncate:DF (match_dup 10)))]
16305 "TARGET_USE_FANCY_MATH_387
16306 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16307 && flag_unsafe_math_optimizations"
16312 for (i=2; i<12; i++)
16313 operands[i] = gen_reg_rtx (XFmode);
16314 temp = standard_80387_constant_rtx (5); /* fldl2e */
16315 emit_move_insn (operands[3], temp);
16316 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16319 (define_expand "expxf2"
16320 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16322 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16323 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16324 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16325 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16326 (parallel [(set (match_operand:XF 0 "register_operand" "")
16327 (unspec:XF [(match_dup 8) (match_dup 4)]
16328 UNSPEC_FSCALE_FRACT))
16330 (unspec:XF [(match_dup 8) (match_dup 4)]
16331 UNSPEC_FSCALE_EXP))])]
16332 "TARGET_USE_FANCY_MATH_387
16333 && flag_unsafe_math_optimizations"
16338 for (i=2; i<10; i++)
16339 operands[i] = gen_reg_rtx (XFmode);
16340 temp = standard_80387_constant_rtx (5); /* fldl2e */
16341 emit_move_insn (operands[2], temp);
16342 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16345 (define_expand "exp10sf2"
16346 [(set (match_dup 2)
16347 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16348 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16349 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16350 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16351 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16352 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16353 (parallel [(set (match_dup 10)
16354 (unspec:XF [(match_dup 9) (match_dup 5)]
16355 UNSPEC_FSCALE_FRACT))
16356 (set (match_dup 11)
16357 (unspec:XF [(match_dup 9) (match_dup 5)]
16358 UNSPEC_FSCALE_EXP))])
16359 (set (match_operand:SF 0 "register_operand" "")
16360 (float_truncate:SF (match_dup 10)))]
16361 "TARGET_USE_FANCY_MATH_387
16362 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16363 && flag_unsafe_math_optimizations"
16368 for (i=2; i<12; i++)
16369 operands[i] = gen_reg_rtx (XFmode);
16370 temp = standard_80387_constant_rtx (6); /* fldl2t */
16371 emit_move_insn (operands[3], temp);
16372 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16375 (define_expand "exp10df2"
16376 [(set (match_dup 2)
16377 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16378 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16379 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16380 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16381 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16382 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16383 (parallel [(set (match_dup 10)
16384 (unspec:XF [(match_dup 9) (match_dup 5)]
16385 UNSPEC_FSCALE_FRACT))
16386 (set (match_dup 11)
16387 (unspec:XF [(match_dup 9) (match_dup 5)]
16388 UNSPEC_FSCALE_EXP))])
16389 (set (match_operand:DF 0 "register_operand" "")
16390 (float_truncate:DF (match_dup 10)))]
16391 "TARGET_USE_FANCY_MATH_387
16392 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16393 && flag_unsafe_math_optimizations"
16398 for (i=2; i<12; i++)
16399 operands[i] = gen_reg_rtx (XFmode);
16400 temp = standard_80387_constant_rtx (6); /* fldl2t */
16401 emit_move_insn (operands[3], temp);
16402 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16405 (define_expand "exp10xf2"
16406 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16408 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16409 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16410 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16411 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16412 (parallel [(set (match_operand:XF 0 "register_operand" "")
16413 (unspec:XF [(match_dup 8) (match_dup 4)]
16414 UNSPEC_FSCALE_FRACT))
16416 (unspec:XF [(match_dup 8) (match_dup 4)]
16417 UNSPEC_FSCALE_EXP))])]
16418 "TARGET_USE_FANCY_MATH_387
16419 && flag_unsafe_math_optimizations"
16424 for (i=2; i<10; i++)
16425 operands[i] = gen_reg_rtx (XFmode);
16426 temp = standard_80387_constant_rtx (6); /* fldl2t */
16427 emit_move_insn (operands[2], temp);
16428 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16431 (define_expand "exp2sf2"
16432 [(set (match_dup 2)
16433 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16434 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16435 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16436 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16437 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16438 (parallel [(set (match_dup 8)
16439 (unspec:XF [(match_dup 7) (match_dup 3)]
16440 UNSPEC_FSCALE_FRACT))
16442 (unspec:XF [(match_dup 7) (match_dup 3)]
16443 UNSPEC_FSCALE_EXP))])
16444 (set (match_operand:SF 0 "register_operand" "")
16445 (float_truncate:SF (match_dup 8)))]
16446 "TARGET_USE_FANCY_MATH_387
16447 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16448 && flag_unsafe_math_optimizations"
16452 for (i=2; i<10; i++)
16453 operands[i] = gen_reg_rtx (XFmode);
16454 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16457 (define_expand "exp2df2"
16458 [(set (match_dup 2)
16459 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16460 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16461 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16462 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16463 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16464 (parallel [(set (match_dup 8)
16465 (unspec:XF [(match_dup 7) (match_dup 3)]
16466 UNSPEC_FSCALE_FRACT))
16468 (unspec:XF [(match_dup 7) (match_dup 3)]
16469 UNSPEC_FSCALE_EXP))])
16470 (set (match_operand:DF 0 "register_operand" "")
16471 (float_truncate:DF (match_dup 8)))]
16472 "TARGET_USE_FANCY_MATH_387
16473 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16474 && flag_unsafe_math_optimizations"
16478 for (i=2; i<10; i++)
16479 operands[i] = gen_reg_rtx (XFmode);
16480 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16483 (define_expand "exp2xf2"
16484 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16485 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16486 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16487 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16488 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16489 (parallel [(set (match_operand:XF 0 "register_operand" "")
16490 (unspec:XF [(match_dup 7) (match_dup 3)]
16491 UNSPEC_FSCALE_FRACT))
16493 (unspec:XF [(match_dup 7) (match_dup 3)]
16494 UNSPEC_FSCALE_EXP))])]
16495 "TARGET_USE_FANCY_MATH_387
16496 && flag_unsafe_math_optimizations"
16500 for (i=2; i<9; i++)
16501 operands[i] = gen_reg_rtx (XFmode);
16502 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16505 (define_expand "expm1df2"
16506 [(set (match_dup 2)
16507 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16508 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16509 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16510 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16511 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16512 (parallel [(set (match_dup 8)
16513 (unspec:XF [(match_dup 7) (match_dup 5)]
16514 UNSPEC_FSCALE_FRACT))
16516 (unspec:XF [(match_dup 7) (match_dup 5)]
16517 UNSPEC_FSCALE_EXP))])
16518 (parallel [(set (match_dup 11)
16519 (unspec:XF [(match_dup 10) (match_dup 9)]
16520 UNSPEC_FSCALE_FRACT))
16521 (set (match_dup 12)
16522 (unspec:XF [(match_dup 10) (match_dup 9)]
16523 UNSPEC_FSCALE_EXP))])
16524 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16525 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16526 (set (match_operand:DF 0 "register_operand" "")
16527 (float_truncate:DF (match_dup 14)))]
16528 "TARGET_USE_FANCY_MATH_387
16529 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16530 && flag_unsafe_math_optimizations"
16535 for (i=2; i<15; i++)
16536 operands[i] = gen_reg_rtx (XFmode);
16537 temp = standard_80387_constant_rtx (5); /* fldl2e */
16538 emit_move_insn (operands[3], temp);
16539 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16542 (define_expand "expm1sf2"
16543 [(set (match_dup 2)
16544 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16545 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16546 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16547 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16548 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16549 (parallel [(set (match_dup 8)
16550 (unspec:XF [(match_dup 7) (match_dup 5)]
16551 UNSPEC_FSCALE_FRACT))
16553 (unspec:XF [(match_dup 7) (match_dup 5)]
16554 UNSPEC_FSCALE_EXP))])
16555 (parallel [(set (match_dup 11)
16556 (unspec:XF [(match_dup 10) (match_dup 9)]
16557 UNSPEC_FSCALE_FRACT))
16558 (set (match_dup 12)
16559 (unspec:XF [(match_dup 10) (match_dup 9)]
16560 UNSPEC_FSCALE_EXP))])
16561 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16562 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16563 (set (match_operand:SF 0 "register_operand" "")
16564 (float_truncate:SF (match_dup 14)))]
16565 "TARGET_USE_FANCY_MATH_387
16566 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16567 && flag_unsafe_math_optimizations"
16572 for (i=2; i<15; i++)
16573 operands[i] = gen_reg_rtx (XFmode);
16574 temp = standard_80387_constant_rtx (5); /* fldl2e */
16575 emit_move_insn (operands[3], temp);
16576 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16579 (define_expand "expm1xf2"
16580 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16582 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16583 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16584 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16585 (parallel [(set (match_dup 7)
16586 (unspec:XF [(match_dup 6) (match_dup 4)]
16587 UNSPEC_FSCALE_FRACT))
16589 (unspec:XF [(match_dup 6) (match_dup 4)]
16590 UNSPEC_FSCALE_EXP))])
16591 (parallel [(set (match_dup 10)
16592 (unspec:XF [(match_dup 9) (match_dup 8)]
16593 UNSPEC_FSCALE_FRACT))
16594 (set (match_dup 11)
16595 (unspec:XF [(match_dup 9) (match_dup 8)]
16596 UNSPEC_FSCALE_EXP))])
16597 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16598 (set (match_operand:XF 0 "register_operand" "")
16599 (plus:XF (match_dup 12) (match_dup 7)))]
16600 "TARGET_USE_FANCY_MATH_387
16601 && flag_unsafe_math_optimizations"
16606 for (i=2; i<13; i++)
16607 operands[i] = gen_reg_rtx (XFmode);
16608 temp = standard_80387_constant_rtx (5); /* fldl2e */
16609 emit_move_insn (operands[2], temp);
16610 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16613 (define_expand "ldexpdf3"
16614 [(set (match_dup 3)
16615 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16617 (float:XF (match_operand:SI 2 "register_operand" "")))
16618 (parallel [(set (match_dup 5)
16619 (unspec:XF [(match_dup 3) (match_dup 4)]
16620 UNSPEC_FSCALE_FRACT))
16622 (unspec:XF [(match_dup 3) (match_dup 4)]
16623 UNSPEC_FSCALE_EXP))])
16624 (set (match_operand:DF 0 "register_operand" "")
16625 (float_truncate:DF (match_dup 5)))]
16626 "TARGET_USE_FANCY_MATH_387
16627 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16628 && flag_unsafe_math_optimizations"
16632 for (i=3; i<7; i++)
16633 operands[i] = gen_reg_rtx (XFmode);
16636 (define_expand "ldexpsf3"
16637 [(set (match_dup 3)
16638 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16640 (float:XF (match_operand:SI 2 "register_operand" "")))
16641 (parallel [(set (match_dup 5)
16642 (unspec:XF [(match_dup 3) (match_dup 4)]
16643 UNSPEC_FSCALE_FRACT))
16645 (unspec:XF [(match_dup 3) (match_dup 4)]
16646 UNSPEC_FSCALE_EXP))])
16647 (set (match_operand:SF 0 "register_operand" "")
16648 (float_truncate:SF (match_dup 5)))]
16649 "TARGET_USE_FANCY_MATH_387
16650 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16651 && flag_unsafe_math_optimizations"
16655 for (i=3; i<7; i++)
16656 operands[i] = gen_reg_rtx (XFmode);
16659 (define_expand "ldexpxf3"
16660 [(set (match_dup 3)
16661 (float:XF (match_operand:SI 2 "register_operand" "")))
16662 (parallel [(set (match_operand:XF 0 " register_operand" "")
16663 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16665 UNSPEC_FSCALE_FRACT))
16667 (unspec:XF [(match_dup 1) (match_dup 3)]
16668 UNSPEC_FSCALE_EXP))])]
16669 "TARGET_USE_FANCY_MATH_387
16670 && flag_unsafe_math_optimizations"
16674 for (i=3; i<5; i++)
16675 operands[i] = gen_reg_rtx (XFmode);
16679 (define_insn "frndintxf2"
16680 [(set (match_operand:XF 0 "register_operand" "=f")
16681 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16683 "TARGET_USE_FANCY_MATH_387
16684 && flag_unsafe_math_optimizations"
16686 [(set_attr "type" "fpspc")
16687 (set_attr "mode" "XF")])
16689 (define_expand "rintdf2"
16690 [(use (match_operand:DF 0 "register_operand" ""))
16691 (use (match_operand:DF 1 "register_operand" ""))]
16692 "TARGET_USE_FANCY_MATH_387
16693 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16694 && flag_unsafe_math_optimizations"
16696 rtx op0 = gen_reg_rtx (XFmode);
16697 rtx op1 = gen_reg_rtx (XFmode);
16699 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16700 emit_insn (gen_frndintxf2 (op0, op1));
16702 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16706 (define_expand "rintsf2"
16707 [(use (match_operand:SF 0 "register_operand" ""))
16708 (use (match_operand:SF 1 "register_operand" ""))]
16709 "TARGET_USE_FANCY_MATH_387
16710 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16711 && flag_unsafe_math_optimizations"
16713 rtx op0 = gen_reg_rtx (XFmode);
16714 rtx op1 = gen_reg_rtx (XFmode);
16716 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16717 emit_insn (gen_frndintxf2 (op0, op1));
16719 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16723 (define_expand "rintxf2"
16724 [(use (match_operand:XF 0 "register_operand" ""))
16725 (use (match_operand:XF 1 "register_operand" ""))]
16726 "TARGET_USE_FANCY_MATH_387
16727 && flag_unsafe_math_optimizations"
16729 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16733 (define_insn_and_split "*fistdi2_1"
16734 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16735 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16737 "TARGET_USE_FANCY_MATH_387
16738 && flag_unsafe_math_optimizations
16739 && !(reload_completed || reload_in_progress)"
16744 if (memory_operand (operands[0], VOIDmode))
16745 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16748 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16749 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16754 [(set_attr "type" "fpspc")
16755 (set_attr "mode" "DI")])
16757 (define_insn "fistdi2"
16758 [(set (match_operand:DI 0 "memory_operand" "=m")
16759 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16761 (clobber (match_scratch:XF 2 "=&1f"))]
16762 "TARGET_USE_FANCY_MATH_387
16763 && flag_unsafe_math_optimizations"
16764 "* return output_fix_trunc (insn, operands, 0);"
16765 [(set_attr "type" "fpspc")
16766 (set_attr "mode" "DI")])
16768 (define_insn "fistdi2_with_temp"
16769 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16770 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16772 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16773 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16774 "TARGET_USE_FANCY_MATH_387
16775 && flag_unsafe_math_optimizations"
16777 [(set_attr "type" "fpspc")
16778 (set_attr "mode" "DI")])
16781 [(set (match_operand:DI 0 "register_operand" "")
16782 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16784 (clobber (match_operand:DI 2 "memory_operand" ""))
16785 (clobber (match_scratch 3 ""))]
16787 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16788 (clobber (match_dup 3))])
16789 (set (match_dup 0) (match_dup 2))]
16793 [(set (match_operand:DI 0 "memory_operand" "")
16794 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16796 (clobber (match_operand:DI 2 "memory_operand" ""))
16797 (clobber (match_scratch 3 ""))]
16799 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16800 (clobber (match_dup 3))])]
16803 (define_insn_and_split "*fist<mode>2_1"
16804 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16805 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16807 "TARGET_USE_FANCY_MATH_387
16808 && flag_unsafe_math_optimizations
16809 && !(reload_completed || reload_in_progress)"
16814 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16815 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16819 [(set_attr "type" "fpspc")
16820 (set_attr "mode" "<MODE>")])
16822 (define_insn "fist<mode>2"
16823 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16824 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16826 "TARGET_USE_FANCY_MATH_387
16827 && flag_unsafe_math_optimizations"
16828 "* return output_fix_trunc (insn, operands, 0);"
16829 [(set_attr "type" "fpspc")
16830 (set_attr "mode" "<MODE>")])
16832 (define_insn "fist<mode>2_with_temp"
16833 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16834 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16836 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16837 "TARGET_USE_FANCY_MATH_387
16838 && flag_unsafe_math_optimizations"
16840 [(set_attr "type" "fpspc")
16841 (set_attr "mode" "<MODE>")])
16844 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16845 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16847 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16849 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16851 (set (match_dup 0) (match_dup 2))]
16855 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16856 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16858 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16860 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16864 (define_expand "lrint<mode>2"
16865 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16866 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16868 "TARGET_USE_FANCY_MATH_387
16869 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16870 && flag_unsafe_math_optimizations"
16873 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16874 (define_insn_and_split "frndintxf2_floor"
16875 [(set (match_operand:XF 0 "register_operand" "=f")
16876 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16877 UNSPEC_FRNDINT_FLOOR))
16878 (clobber (reg:CC FLAGS_REG))]
16879 "TARGET_USE_FANCY_MATH_387
16880 && flag_unsafe_math_optimizations
16881 && !(reload_completed || reload_in_progress)"
16886 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16888 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16889 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16891 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16892 operands[2], operands[3]));
16895 [(set_attr "type" "frndint")
16896 (set_attr "i387_cw" "floor")
16897 (set_attr "mode" "XF")])
16899 (define_insn "frndintxf2_floor_i387"
16900 [(set (match_operand:XF 0 "register_operand" "=f")
16901 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16902 UNSPEC_FRNDINT_FLOOR))
16903 (use (match_operand:HI 2 "memory_operand" "m"))
16904 (use (match_operand:HI 3 "memory_operand" "m"))]
16905 "TARGET_USE_FANCY_MATH_387
16906 && flag_unsafe_math_optimizations"
16907 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16908 [(set_attr "type" "frndint")
16909 (set_attr "i387_cw" "floor")
16910 (set_attr "mode" "XF")])
16912 (define_expand "floorxf2"
16913 [(use (match_operand:XF 0 "register_operand" ""))
16914 (use (match_operand:XF 1 "register_operand" ""))]
16915 "TARGET_USE_FANCY_MATH_387
16916 && flag_unsafe_math_optimizations"
16918 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16922 (define_expand "floordf2"
16923 [(use (match_operand:DF 0 "register_operand" ""))
16924 (use (match_operand:DF 1 "register_operand" ""))]
16925 "TARGET_USE_FANCY_MATH_387
16926 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16927 && flag_unsafe_math_optimizations"
16929 rtx op0 = gen_reg_rtx (XFmode);
16930 rtx op1 = gen_reg_rtx (XFmode);
16932 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16933 emit_insn (gen_frndintxf2_floor (op0, op1));
16935 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16939 (define_expand "floorsf2"
16940 [(use (match_operand:SF 0 "register_operand" ""))
16941 (use (match_operand:SF 1 "register_operand" ""))]
16942 "TARGET_USE_FANCY_MATH_387
16943 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16944 && flag_unsafe_math_optimizations"
16946 rtx op0 = gen_reg_rtx (XFmode);
16947 rtx op1 = gen_reg_rtx (XFmode);
16949 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16950 emit_insn (gen_frndintxf2_floor (op0, op1));
16952 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16956 (define_insn_and_split "*fist<mode>2_floor_1"
16957 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16958 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16959 UNSPEC_FIST_FLOOR))
16960 (clobber (reg:CC FLAGS_REG))]
16961 "TARGET_USE_FANCY_MATH_387
16962 && flag_unsafe_math_optimizations
16963 && !(reload_completed || reload_in_progress)"
16968 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16970 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16971 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16972 if (memory_operand (operands[0], VOIDmode))
16973 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16974 operands[2], operands[3]));
16977 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16978 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16979 operands[2], operands[3],
16984 [(set_attr "type" "fistp")
16985 (set_attr "i387_cw" "floor")
16986 (set_attr "mode" "<MODE>")])
16988 (define_insn "fistdi2_floor"
16989 [(set (match_operand:DI 0 "memory_operand" "=m")
16990 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16991 UNSPEC_FIST_FLOOR))
16992 (use (match_operand:HI 2 "memory_operand" "m"))
16993 (use (match_operand:HI 3 "memory_operand" "m"))
16994 (clobber (match_scratch:XF 4 "=&1f"))]
16995 "TARGET_USE_FANCY_MATH_387
16996 && flag_unsafe_math_optimizations"
16997 "* return output_fix_trunc (insn, operands, 0);"
16998 [(set_attr "type" "fistp")
16999 (set_attr "i387_cw" "floor")
17000 (set_attr "mode" "DI")])
17002 (define_insn "fistdi2_floor_with_temp"
17003 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17004 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17005 UNSPEC_FIST_FLOOR))
17006 (use (match_operand:HI 2 "memory_operand" "m,m"))
17007 (use (match_operand:HI 3 "memory_operand" "m,m"))
17008 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17009 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17010 "TARGET_USE_FANCY_MATH_387
17011 && flag_unsafe_math_optimizations"
17013 [(set_attr "type" "fistp")
17014 (set_attr "i387_cw" "floor")
17015 (set_attr "mode" "DI")])
17018 [(set (match_operand:DI 0 "register_operand" "")
17019 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17020 UNSPEC_FIST_FLOOR))
17021 (use (match_operand:HI 2 "memory_operand" ""))
17022 (use (match_operand:HI 3 "memory_operand" ""))
17023 (clobber (match_operand:DI 4 "memory_operand" ""))
17024 (clobber (match_scratch 5 ""))]
17026 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17027 (use (match_dup 2))
17028 (use (match_dup 3))
17029 (clobber (match_dup 5))])
17030 (set (match_dup 0) (match_dup 4))]
17034 [(set (match_operand:DI 0 "memory_operand" "")
17035 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17036 UNSPEC_FIST_FLOOR))
17037 (use (match_operand:HI 2 "memory_operand" ""))
17038 (use (match_operand:HI 3 "memory_operand" ""))
17039 (clobber (match_operand:DI 4 "memory_operand" ""))
17040 (clobber (match_scratch 5 ""))]
17042 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17043 (use (match_dup 2))
17044 (use (match_dup 3))
17045 (clobber (match_dup 5))])]
17048 (define_insn "fist<mode>2_floor"
17049 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17050 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17051 UNSPEC_FIST_FLOOR))
17052 (use (match_operand:HI 2 "memory_operand" "m"))
17053 (use (match_operand:HI 3 "memory_operand" "m"))]
17054 "TARGET_USE_FANCY_MATH_387
17055 && flag_unsafe_math_optimizations"
17056 "* return output_fix_trunc (insn, operands, 0);"
17057 [(set_attr "type" "fistp")
17058 (set_attr "i387_cw" "floor")
17059 (set_attr "mode" "<MODE>")])
17061 (define_insn "fist<mode>2_floor_with_temp"
17062 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17063 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17064 UNSPEC_FIST_FLOOR))
17065 (use (match_operand:HI 2 "memory_operand" "m,m"))
17066 (use (match_operand:HI 3 "memory_operand" "m,m"))
17067 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17068 "TARGET_USE_FANCY_MATH_387
17069 && flag_unsafe_math_optimizations"
17071 [(set_attr "type" "fistp")
17072 (set_attr "i387_cw" "floor")
17073 (set_attr "mode" "<MODE>")])
17076 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17077 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17078 UNSPEC_FIST_FLOOR))
17079 (use (match_operand:HI 2 "memory_operand" ""))
17080 (use (match_operand:HI 3 "memory_operand" ""))
17081 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17083 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17084 UNSPEC_FIST_FLOOR))
17085 (use (match_dup 2))
17086 (use (match_dup 3))])
17087 (set (match_dup 0) (match_dup 4))]
17091 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17092 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17093 UNSPEC_FIST_FLOOR))
17094 (use (match_operand:HI 2 "memory_operand" ""))
17095 (use (match_operand:HI 3 "memory_operand" ""))
17096 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17098 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17099 UNSPEC_FIST_FLOOR))
17100 (use (match_dup 2))
17101 (use (match_dup 3))])]
17104 (define_expand "lfloor<mode>2"
17105 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17106 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17107 UNSPEC_FIST_FLOOR))
17108 (clobber (reg:CC FLAGS_REG))])]
17109 "TARGET_USE_FANCY_MATH_387
17110 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17111 && flag_unsafe_math_optimizations"
17114 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17115 (define_insn_and_split "frndintxf2_ceil"
17116 [(set (match_operand:XF 0 "register_operand" "=f")
17117 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17118 UNSPEC_FRNDINT_CEIL))
17119 (clobber (reg:CC FLAGS_REG))]
17120 "TARGET_USE_FANCY_MATH_387
17121 && flag_unsafe_math_optimizations
17122 && !(reload_completed || reload_in_progress)"
17127 ix86_optimize_mode_switching[I387_CEIL] = 1;
17129 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17130 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17132 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17133 operands[2], operands[3]));
17136 [(set_attr "type" "frndint")
17137 (set_attr "i387_cw" "ceil")
17138 (set_attr "mode" "XF")])
17140 (define_insn "frndintxf2_ceil_i387"
17141 [(set (match_operand:XF 0 "register_operand" "=f")
17142 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17143 UNSPEC_FRNDINT_CEIL))
17144 (use (match_operand:HI 2 "memory_operand" "m"))
17145 (use (match_operand:HI 3 "memory_operand" "m"))]
17146 "TARGET_USE_FANCY_MATH_387
17147 && flag_unsafe_math_optimizations"
17148 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17149 [(set_attr "type" "frndint")
17150 (set_attr "i387_cw" "ceil")
17151 (set_attr "mode" "XF")])
17153 (define_expand "ceilxf2"
17154 [(use (match_operand:XF 0 "register_operand" ""))
17155 (use (match_operand:XF 1 "register_operand" ""))]
17156 "TARGET_USE_FANCY_MATH_387
17157 && flag_unsafe_math_optimizations"
17159 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17163 (define_expand "ceildf2"
17164 [(use (match_operand:DF 0 "register_operand" ""))
17165 (use (match_operand:DF 1 "register_operand" ""))]
17166 "TARGET_USE_FANCY_MATH_387
17167 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17168 && flag_unsafe_math_optimizations"
17170 rtx op0 = gen_reg_rtx (XFmode);
17171 rtx op1 = gen_reg_rtx (XFmode);
17173 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17174 emit_insn (gen_frndintxf2_ceil (op0, op1));
17176 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17180 (define_expand "ceilsf2"
17181 [(use (match_operand:SF 0 "register_operand" ""))
17182 (use (match_operand:SF 1 "register_operand" ""))]
17183 "TARGET_USE_FANCY_MATH_387
17184 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17185 && flag_unsafe_math_optimizations"
17187 rtx op0 = gen_reg_rtx (XFmode);
17188 rtx op1 = gen_reg_rtx (XFmode);
17190 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17191 emit_insn (gen_frndintxf2_ceil (op0, op1));
17193 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17197 (define_insn_and_split "*fist<mode>2_ceil_1"
17198 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17199 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17201 (clobber (reg:CC FLAGS_REG))]
17202 "TARGET_USE_FANCY_MATH_387
17203 && flag_unsafe_math_optimizations
17204 && !(reload_completed || reload_in_progress)"
17209 ix86_optimize_mode_switching[I387_CEIL] = 1;
17211 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17212 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17213 if (memory_operand (operands[0], VOIDmode))
17214 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17215 operands[2], operands[3]));
17218 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17219 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17220 operands[2], operands[3],
17225 [(set_attr "type" "fistp")
17226 (set_attr "i387_cw" "ceil")
17227 (set_attr "mode" "<MODE>")])
17229 (define_insn "fistdi2_ceil"
17230 [(set (match_operand:DI 0 "memory_operand" "=m")
17231 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17233 (use (match_operand:HI 2 "memory_operand" "m"))
17234 (use (match_operand:HI 3 "memory_operand" "m"))
17235 (clobber (match_scratch:XF 4 "=&1f"))]
17236 "TARGET_USE_FANCY_MATH_387
17237 && flag_unsafe_math_optimizations"
17238 "* return output_fix_trunc (insn, operands, 0);"
17239 [(set_attr "type" "fistp")
17240 (set_attr "i387_cw" "ceil")
17241 (set_attr "mode" "DI")])
17243 (define_insn "fistdi2_ceil_with_temp"
17244 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17245 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17247 (use (match_operand:HI 2 "memory_operand" "m,m"))
17248 (use (match_operand:HI 3 "memory_operand" "m,m"))
17249 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17250 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17251 "TARGET_USE_FANCY_MATH_387
17252 && flag_unsafe_math_optimizations"
17254 [(set_attr "type" "fistp")
17255 (set_attr "i387_cw" "ceil")
17256 (set_attr "mode" "DI")])
17259 [(set (match_operand:DI 0 "register_operand" "")
17260 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17262 (use (match_operand:HI 2 "memory_operand" ""))
17263 (use (match_operand:HI 3 "memory_operand" ""))
17264 (clobber (match_operand:DI 4 "memory_operand" ""))
17265 (clobber (match_scratch 5 ""))]
17267 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17268 (use (match_dup 2))
17269 (use (match_dup 3))
17270 (clobber (match_dup 5))])
17271 (set (match_dup 0) (match_dup 4))]
17275 [(set (match_operand:DI 0 "memory_operand" "")
17276 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17278 (use (match_operand:HI 2 "memory_operand" ""))
17279 (use (match_operand:HI 3 "memory_operand" ""))
17280 (clobber (match_operand:DI 4 "memory_operand" ""))
17281 (clobber (match_scratch 5 ""))]
17283 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17284 (use (match_dup 2))
17285 (use (match_dup 3))
17286 (clobber (match_dup 5))])]
17289 (define_insn "fist<mode>2_ceil"
17290 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17291 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17293 (use (match_operand:HI 2 "memory_operand" "m"))
17294 (use (match_operand:HI 3 "memory_operand" "m"))]
17295 "TARGET_USE_FANCY_MATH_387
17296 && flag_unsafe_math_optimizations"
17297 "* return output_fix_trunc (insn, operands, 0);"
17298 [(set_attr "type" "fistp")
17299 (set_attr "i387_cw" "ceil")
17300 (set_attr "mode" "<MODE>")])
17302 (define_insn "fist<mode>2_ceil_with_temp"
17303 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17304 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17306 (use (match_operand:HI 2 "memory_operand" "m,m"))
17307 (use (match_operand:HI 3 "memory_operand" "m,m"))
17308 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17309 "TARGET_USE_FANCY_MATH_387
17310 && flag_unsafe_math_optimizations"
17312 [(set_attr "type" "fistp")
17313 (set_attr "i387_cw" "ceil")
17314 (set_attr "mode" "<MODE>")])
17317 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17318 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17320 (use (match_operand:HI 2 "memory_operand" ""))
17321 (use (match_operand:HI 3 "memory_operand" ""))
17322 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17324 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17326 (use (match_dup 2))
17327 (use (match_dup 3))])
17328 (set (match_dup 0) (match_dup 4))]
17332 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17333 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17335 (use (match_operand:HI 2 "memory_operand" ""))
17336 (use (match_operand:HI 3 "memory_operand" ""))
17337 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17339 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17341 (use (match_dup 2))
17342 (use (match_dup 3))])]
17345 (define_expand "lceil<mode>2"
17346 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17347 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17349 (clobber (reg:CC FLAGS_REG))])]
17350 "TARGET_USE_FANCY_MATH_387
17351 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17352 && flag_unsafe_math_optimizations"
17355 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17356 (define_insn_and_split "frndintxf2_trunc"
17357 [(set (match_operand:XF 0 "register_operand" "=f")
17358 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17359 UNSPEC_FRNDINT_TRUNC))
17360 (clobber (reg:CC FLAGS_REG))]
17361 "TARGET_USE_FANCY_MATH_387
17362 && flag_unsafe_math_optimizations
17363 && !(reload_completed || reload_in_progress)"
17368 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17370 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17371 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17373 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17374 operands[2], operands[3]));
17377 [(set_attr "type" "frndint")
17378 (set_attr "i387_cw" "trunc")
17379 (set_attr "mode" "XF")])
17381 (define_insn "frndintxf2_trunc_i387"
17382 [(set (match_operand:XF 0 "register_operand" "=f")
17383 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17384 UNSPEC_FRNDINT_TRUNC))
17385 (use (match_operand:HI 2 "memory_operand" "m"))
17386 (use (match_operand:HI 3 "memory_operand" "m"))]
17387 "TARGET_USE_FANCY_MATH_387
17388 && flag_unsafe_math_optimizations"
17389 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17390 [(set_attr "type" "frndint")
17391 (set_attr "i387_cw" "trunc")
17392 (set_attr "mode" "XF")])
17394 (define_expand "btruncxf2"
17395 [(use (match_operand:XF 0 "register_operand" ""))
17396 (use (match_operand:XF 1 "register_operand" ""))]
17397 "TARGET_USE_FANCY_MATH_387
17398 && flag_unsafe_math_optimizations"
17400 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17404 (define_expand "btruncdf2"
17405 [(use (match_operand:DF 0 "register_operand" ""))
17406 (use (match_operand:DF 1 "register_operand" ""))]
17407 "TARGET_USE_FANCY_MATH_387
17408 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17409 && flag_unsafe_math_optimizations"
17411 rtx op0 = gen_reg_rtx (XFmode);
17412 rtx op1 = gen_reg_rtx (XFmode);
17414 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17415 emit_insn (gen_frndintxf2_trunc (op0, op1));
17417 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17421 (define_expand "btruncsf2"
17422 [(use (match_operand:SF 0 "register_operand" ""))
17423 (use (match_operand:SF 1 "register_operand" ""))]
17424 "TARGET_USE_FANCY_MATH_387
17425 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17426 && flag_unsafe_math_optimizations"
17428 rtx op0 = gen_reg_rtx (XFmode);
17429 rtx op1 = gen_reg_rtx (XFmode);
17431 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17432 emit_insn (gen_frndintxf2_trunc (op0, op1));
17434 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17438 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17439 (define_insn_and_split "frndintxf2_mask_pm"
17440 [(set (match_operand:XF 0 "register_operand" "=f")
17441 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17442 UNSPEC_FRNDINT_MASK_PM))
17443 (clobber (reg:CC FLAGS_REG))]
17444 "TARGET_USE_FANCY_MATH_387
17445 && flag_unsafe_math_optimizations
17446 && !(reload_completed || reload_in_progress)"
17451 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17453 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17454 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17456 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17457 operands[2], operands[3]));
17460 [(set_attr "type" "frndint")
17461 (set_attr "i387_cw" "mask_pm")
17462 (set_attr "mode" "XF")])
17464 (define_insn "frndintxf2_mask_pm_i387"
17465 [(set (match_operand:XF 0 "register_operand" "=f")
17466 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17467 UNSPEC_FRNDINT_MASK_PM))
17468 (use (match_operand:HI 2 "memory_operand" "m"))
17469 (use (match_operand:HI 3 "memory_operand" "m"))]
17470 "TARGET_USE_FANCY_MATH_387
17471 && flag_unsafe_math_optimizations"
17472 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17473 [(set_attr "type" "frndint")
17474 (set_attr "i387_cw" "mask_pm")
17475 (set_attr "mode" "XF")])
17477 (define_expand "nearbyintxf2"
17478 [(use (match_operand:XF 0 "register_operand" ""))
17479 (use (match_operand:XF 1 "register_operand" ""))]
17480 "TARGET_USE_FANCY_MATH_387
17481 && flag_unsafe_math_optimizations"
17483 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17488 (define_expand "nearbyintdf2"
17489 [(use (match_operand:DF 0 "register_operand" ""))
17490 (use (match_operand:DF 1 "register_operand" ""))]
17491 "TARGET_USE_FANCY_MATH_387
17492 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17493 && flag_unsafe_math_optimizations"
17495 rtx op0 = gen_reg_rtx (XFmode);
17496 rtx op1 = gen_reg_rtx (XFmode);
17498 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17499 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17501 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17505 (define_expand "nearbyintsf2"
17506 [(use (match_operand:SF 0 "register_operand" ""))
17507 (use (match_operand:SF 1 "register_operand" ""))]
17508 "TARGET_USE_FANCY_MATH_387
17509 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17510 && flag_unsafe_math_optimizations"
17512 rtx op0 = gen_reg_rtx (XFmode);
17513 rtx op1 = gen_reg_rtx (XFmode);
17515 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17516 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17518 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17523 ;; Block operation instructions
17526 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17529 [(set_attr "type" "cld")])
17531 (define_expand "movmemsi"
17532 [(use (match_operand:BLK 0 "memory_operand" ""))
17533 (use (match_operand:BLK 1 "memory_operand" ""))
17534 (use (match_operand:SI 2 "nonmemory_operand" ""))
17535 (use (match_operand:SI 3 "const_int_operand" ""))]
17536 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17538 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17544 (define_expand "movmemdi"
17545 [(use (match_operand:BLK 0 "memory_operand" ""))
17546 (use (match_operand:BLK 1 "memory_operand" ""))
17547 (use (match_operand:DI 2 "nonmemory_operand" ""))
17548 (use (match_operand:DI 3 "const_int_operand" ""))]
17551 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17557 ;; Most CPUs don't like single string operations
17558 ;; Handle this case here to simplify previous expander.
17560 (define_expand "strmov"
17561 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17562 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17563 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17564 (clobber (reg:CC FLAGS_REG))])
17565 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17566 (clobber (reg:CC FLAGS_REG))])]
17569 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17571 /* If .md ever supports :P for Pmode, these can be directly
17572 in the pattern above. */
17573 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17574 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17576 if (TARGET_SINGLE_STRINGOP || optimize_size)
17578 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17579 operands[2], operands[3],
17580 operands[5], operands[6]));
17584 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17587 (define_expand "strmov_singleop"
17588 [(parallel [(set (match_operand 1 "memory_operand" "")
17589 (match_operand 3 "memory_operand" ""))
17590 (set (match_operand 0 "register_operand" "")
17591 (match_operand 4 "" ""))
17592 (set (match_operand 2 "register_operand" "")
17593 (match_operand 5 "" ""))
17594 (use (reg:SI DIRFLAG_REG))])]
17595 "TARGET_SINGLE_STRINGOP || optimize_size"
17598 (define_insn "*strmovdi_rex_1"
17599 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17600 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17601 (set (match_operand:DI 0 "register_operand" "=D")
17602 (plus:DI (match_dup 2)
17604 (set (match_operand:DI 1 "register_operand" "=S")
17605 (plus:DI (match_dup 3)
17607 (use (reg:SI DIRFLAG_REG))]
17608 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17610 [(set_attr "type" "str")
17611 (set_attr "mode" "DI")
17612 (set_attr "memory" "both")])
17614 (define_insn "*strmovsi_1"
17615 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17616 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17617 (set (match_operand:SI 0 "register_operand" "=D")
17618 (plus:SI (match_dup 2)
17620 (set (match_operand:SI 1 "register_operand" "=S")
17621 (plus:SI (match_dup 3)
17623 (use (reg:SI DIRFLAG_REG))]
17624 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17626 [(set_attr "type" "str")
17627 (set_attr "mode" "SI")
17628 (set_attr "memory" "both")])
17630 (define_insn "*strmovsi_rex_1"
17631 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17632 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17633 (set (match_operand:DI 0 "register_operand" "=D")
17634 (plus:DI (match_dup 2)
17636 (set (match_operand:DI 1 "register_operand" "=S")
17637 (plus:DI (match_dup 3)
17639 (use (reg:SI DIRFLAG_REG))]
17640 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17642 [(set_attr "type" "str")
17643 (set_attr "mode" "SI")
17644 (set_attr "memory" "both")])
17646 (define_insn "*strmovhi_1"
17647 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17648 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17649 (set (match_operand:SI 0 "register_operand" "=D")
17650 (plus:SI (match_dup 2)
17652 (set (match_operand:SI 1 "register_operand" "=S")
17653 (plus:SI (match_dup 3)
17655 (use (reg:SI DIRFLAG_REG))]
17656 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17658 [(set_attr "type" "str")
17659 (set_attr "memory" "both")
17660 (set_attr "mode" "HI")])
17662 (define_insn "*strmovhi_rex_1"
17663 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17664 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17665 (set (match_operand:DI 0 "register_operand" "=D")
17666 (plus:DI (match_dup 2)
17668 (set (match_operand:DI 1 "register_operand" "=S")
17669 (plus:DI (match_dup 3)
17671 (use (reg:SI DIRFLAG_REG))]
17672 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17674 [(set_attr "type" "str")
17675 (set_attr "memory" "both")
17676 (set_attr "mode" "HI")])
17678 (define_insn "*strmovqi_1"
17679 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17680 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17681 (set (match_operand:SI 0 "register_operand" "=D")
17682 (plus:SI (match_dup 2)
17684 (set (match_operand:SI 1 "register_operand" "=S")
17685 (plus:SI (match_dup 3)
17687 (use (reg:SI DIRFLAG_REG))]
17688 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17690 [(set_attr "type" "str")
17691 (set_attr "memory" "both")
17692 (set_attr "mode" "QI")])
17694 (define_insn "*strmovqi_rex_1"
17695 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17696 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17697 (set (match_operand:DI 0 "register_operand" "=D")
17698 (plus:DI (match_dup 2)
17700 (set (match_operand:DI 1 "register_operand" "=S")
17701 (plus:DI (match_dup 3)
17703 (use (reg:SI DIRFLAG_REG))]
17704 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17706 [(set_attr "type" "str")
17707 (set_attr "memory" "both")
17708 (set_attr "mode" "QI")])
17710 (define_expand "rep_mov"
17711 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17712 (set (match_operand 0 "register_operand" "")
17713 (match_operand 5 "" ""))
17714 (set (match_operand 2 "register_operand" "")
17715 (match_operand 6 "" ""))
17716 (set (match_operand 1 "memory_operand" "")
17717 (match_operand 3 "memory_operand" ""))
17718 (use (match_dup 4))
17719 (use (reg:SI DIRFLAG_REG))])]
17723 (define_insn "*rep_movdi_rex64"
17724 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17725 (set (match_operand:DI 0 "register_operand" "=D")
17726 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17728 (match_operand:DI 3 "register_operand" "0")))
17729 (set (match_operand:DI 1 "register_operand" "=S")
17730 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17731 (match_operand:DI 4 "register_operand" "1")))
17732 (set (mem:BLK (match_dup 3))
17733 (mem:BLK (match_dup 4)))
17734 (use (match_dup 5))
17735 (use (reg:SI DIRFLAG_REG))]
17737 "{rep\;movsq|rep movsq}"
17738 [(set_attr "type" "str")
17739 (set_attr "prefix_rep" "1")
17740 (set_attr "memory" "both")
17741 (set_attr "mode" "DI")])
17743 (define_insn "*rep_movsi"
17744 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17745 (set (match_operand:SI 0 "register_operand" "=D")
17746 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17748 (match_operand:SI 3 "register_operand" "0")))
17749 (set (match_operand:SI 1 "register_operand" "=S")
17750 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17751 (match_operand:SI 4 "register_operand" "1")))
17752 (set (mem:BLK (match_dup 3))
17753 (mem:BLK (match_dup 4)))
17754 (use (match_dup 5))
17755 (use (reg:SI DIRFLAG_REG))]
17757 "{rep\;movsl|rep movsd}"
17758 [(set_attr "type" "str")
17759 (set_attr "prefix_rep" "1")
17760 (set_attr "memory" "both")
17761 (set_attr "mode" "SI")])
17763 (define_insn "*rep_movsi_rex64"
17764 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17765 (set (match_operand:DI 0 "register_operand" "=D")
17766 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17768 (match_operand:DI 3 "register_operand" "0")))
17769 (set (match_operand:DI 1 "register_operand" "=S")
17770 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17771 (match_operand:DI 4 "register_operand" "1")))
17772 (set (mem:BLK (match_dup 3))
17773 (mem:BLK (match_dup 4)))
17774 (use (match_dup 5))
17775 (use (reg:SI DIRFLAG_REG))]
17777 "{rep\;movsl|rep movsd}"
17778 [(set_attr "type" "str")
17779 (set_attr "prefix_rep" "1")
17780 (set_attr "memory" "both")
17781 (set_attr "mode" "SI")])
17783 (define_insn "*rep_movqi"
17784 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17785 (set (match_operand:SI 0 "register_operand" "=D")
17786 (plus:SI (match_operand:SI 3 "register_operand" "0")
17787 (match_operand:SI 5 "register_operand" "2")))
17788 (set (match_operand:SI 1 "register_operand" "=S")
17789 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17790 (set (mem:BLK (match_dup 3))
17791 (mem:BLK (match_dup 4)))
17792 (use (match_dup 5))
17793 (use (reg:SI DIRFLAG_REG))]
17795 "{rep\;movsb|rep movsb}"
17796 [(set_attr "type" "str")
17797 (set_attr "prefix_rep" "1")
17798 (set_attr "memory" "both")
17799 (set_attr "mode" "SI")])
17801 (define_insn "*rep_movqi_rex64"
17802 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17803 (set (match_operand:DI 0 "register_operand" "=D")
17804 (plus:DI (match_operand:DI 3 "register_operand" "0")
17805 (match_operand:DI 5 "register_operand" "2")))
17806 (set (match_operand:DI 1 "register_operand" "=S")
17807 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17808 (set (mem:BLK (match_dup 3))
17809 (mem:BLK (match_dup 4)))
17810 (use (match_dup 5))
17811 (use (reg:SI DIRFLAG_REG))]
17813 "{rep\;movsb|rep movsb}"
17814 [(set_attr "type" "str")
17815 (set_attr "prefix_rep" "1")
17816 (set_attr "memory" "both")
17817 (set_attr "mode" "SI")])
17819 (define_expand "setmemsi"
17820 [(use (match_operand:BLK 0 "memory_operand" ""))
17821 (use (match_operand:SI 1 "nonmemory_operand" ""))
17822 (use (match_operand 2 "const_int_operand" ""))
17823 (use (match_operand 3 "const_int_operand" ""))]
17826 /* If value to set is not zero, use the library routine. */
17827 if (operands[2] != const0_rtx)
17830 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17836 (define_expand "setmemdi"
17837 [(use (match_operand:BLK 0 "memory_operand" ""))
17838 (use (match_operand:DI 1 "nonmemory_operand" ""))
17839 (use (match_operand 2 "const_int_operand" ""))
17840 (use (match_operand 3 "const_int_operand" ""))]
17843 /* If value to set is not zero, use the library routine. */
17844 if (operands[2] != const0_rtx)
17847 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17853 ;; Most CPUs don't like single string operations
17854 ;; Handle this case here to simplify previous expander.
17856 (define_expand "strset"
17857 [(set (match_operand 1 "memory_operand" "")
17858 (match_operand 2 "register_operand" ""))
17859 (parallel [(set (match_operand 0 "register_operand" "")
17861 (clobber (reg:CC FLAGS_REG))])]
17864 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17865 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17867 /* If .md ever supports :P for Pmode, this can be directly
17868 in the pattern above. */
17869 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17870 GEN_INT (GET_MODE_SIZE (GET_MODE
17872 if (TARGET_SINGLE_STRINGOP || optimize_size)
17874 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17880 (define_expand "strset_singleop"
17881 [(parallel [(set (match_operand 1 "memory_operand" "")
17882 (match_operand 2 "register_operand" ""))
17883 (set (match_operand 0 "register_operand" "")
17884 (match_operand 3 "" ""))
17885 (use (reg:SI DIRFLAG_REG))])]
17886 "TARGET_SINGLE_STRINGOP || optimize_size"
17889 (define_insn "*strsetdi_rex_1"
17890 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17891 (match_operand:DI 2 "register_operand" "a"))
17892 (set (match_operand:DI 0 "register_operand" "=D")
17893 (plus:DI (match_dup 1)
17895 (use (reg:SI DIRFLAG_REG))]
17896 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17898 [(set_attr "type" "str")
17899 (set_attr "memory" "store")
17900 (set_attr "mode" "DI")])
17902 (define_insn "*strsetsi_1"
17903 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17904 (match_operand:SI 2 "register_operand" "a"))
17905 (set (match_operand:SI 0 "register_operand" "=D")
17906 (plus:SI (match_dup 1)
17908 (use (reg:SI DIRFLAG_REG))]
17909 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17911 [(set_attr "type" "str")
17912 (set_attr "memory" "store")
17913 (set_attr "mode" "SI")])
17915 (define_insn "*strsetsi_rex_1"
17916 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17917 (match_operand:SI 2 "register_operand" "a"))
17918 (set (match_operand:DI 0 "register_operand" "=D")
17919 (plus:DI (match_dup 1)
17921 (use (reg:SI DIRFLAG_REG))]
17922 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17924 [(set_attr "type" "str")
17925 (set_attr "memory" "store")
17926 (set_attr "mode" "SI")])
17928 (define_insn "*strsethi_1"
17929 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17930 (match_operand:HI 2 "register_operand" "a"))
17931 (set (match_operand:SI 0 "register_operand" "=D")
17932 (plus:SI (match_dup 1)
17934 (use (reg:SI DIRFLAG_REG))]
17935 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17937 [(set_attr "type" "str")
17938 (set_attr "memory" "store")
17939 (set_attr "mode" "HI")])
17941 (define_insn "*strsethi_rex_1"
17942 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17943 (match_operand:HI 2 "register_operand" "a"))
17944 (set (match_operand:DI 0 "register_operand" "=D")
17945 (plus:DI (match_dup 1)
17947 (use (reg:SI DIRFLAG_REG))]
17948 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17950 [(set_attr "type" "str")
17951 (set_attr "memory" "store")
17952 (set_attr "mode" "HI")])
17954 (define_insn "*strsetqi_1"
17955 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17956 (match_operand:QI 2 "register_operand" "a"))
17957 (set (match_operand:SI 0 "register_operand" "=D")
17958 (plus:SI (match_dup 1)
17960 (use (reg:SI DIRFLAG_REG))]
17961 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17963 [(set_attr "type" "str")
17964 (set_attr "memory" "store")
17965 (set_attr "mode" "QI")])
17967 (define_insn "*strsetqi_rex_1"
17968 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17969 (match_operand:QI 2 "register_operand" "a"))
17970 (set (match_operand:DI 0 "register_operand" "=D")
17971 (plus:DI (match_dup 1)
17973 (use (reg:SI DIRFLAG_REG))]
17974 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17976 [(set_attr "type" "str")
17977 (set_attr "memory" "store")
17978 (set_attr "mode" "QI")])
17980 (define_expand "rep_stos"
17981 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17982 (set (match_operand 0 "register_operand" "")
17983 (match_operand 4 "" ""))
17984 (set (match_operand 2 "memory_operand" "") (const_int 0))
17985 (use (match_operand 3 "register_operand" ""))
17986 (use (match_dup 1))
17987 (use (reg:SI DIRFLAG_REG))])]
17991 (define_insn "*rep_stosdi_rex64"
17992 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17993 (set (match_operand:DI 0 "register_operand" "=D")
17994 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17996 (match_operand:DI 3 "register_operand" "0")))
17997 (set (mem:BLK (match_dup 3))
17999 (use (match_operand:DI 2 "register_operand" "a"))
18000 (use (match_dup 4))
18001 (use (reg:SI DIRFLAG_REG))]
18003 "{rep\;stosq|rep stosq}"
18004 [(set_attr "type" "str")
18005 (set_attr "prefix_rep" "1")
18006 (set_attr "memory" "store")
18007 (set_attr "mode" "DI")])
18009 (define_insn "*rep_stossi"
18010 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18011 (set (match_operand:SI 0 "register_operand" "=D")
18012 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18014 (match_operand:SI 3 "register_operand" "0")))
18015 (set (mem:BLK (match_dup 3))
18017 (use (match_operand:SI 2 "register_operand" "a"))
18018 (use (match_dup 4))
18019 (use (reg:SI DIRFLAG_REG))]
18021 "{rep\;stosl|rep stosd}"
18022 [(set_attr "type" "str")
18023 (set_attr "prefix_rep" "1")
18024 (set_attr "memory" "store")
18025 (set_attr "mode" "SI")])
18027 (define_insn "*rep_stossi_rex64"
18028 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18029 (set (match_operand:DI 0 "register_operand" "=D")
18030 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18032 (match_operand:DI 3 "register_operand" "0")))
18033 (set (mem:BLK (match_dup 3))
18035 (use (match_operand:SI 2 "register_operand" "a"))
18036 (use (match_dup 4))
18037 (use (reg:SI DIRFLAG_REG))]
18039 "{rep\;stosl|rep stosd}"
18040 [(set_attr "type" "str")
18041 (set_attr "prefix_rep" "1")
18042 (set_attr "memory" "store")
18043 (set_attr "mode" "SI")])
18045 (define_insn "*rep_stosqi"
18046 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18047 (set (match_operand:SI 0 "register_operand" "=D")
18048 (plus:SI (match_operand:SI 3 "register_operand" "0")
18049 (match_operand:SI 4 "register_operand" "1")))
18050 (set (mem:BLK (match_dup 3))
18052 (use (match_operand:QI 2 "register_operand" "a"))
18053 (use (match_dup 4))
18054 (use (reg:SI DIRFLAG_REG))]
18056 "{rep\;stosb|rep stosb}"
18057 [(set_attr "type" "str")
18058 (set_attr "prefix_rep" "1")
18059 (set_attr "memory" "store")
18060 (set_attr "mode" "QI")])
18062 (define_insn "*rep_stosqi_rex64"
18063 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18064 (set (match_operand:DI 0 "register_operand" "=D")
18065 (plus:DI (match_operand:DI 3 "register_operand" "0")
18066 (match_operand:DI 4 "register_operand" "1")))
18067 (set (mem:BLK (match_dup 3))
18069 (use (match_operand:QI 2 "register_operand" "a"))
18070 (use (match_dup 4))
18071 (use (reg:SI DIRFLAG_REG))]
18073 "{rep\;stosb|rep stosb}"
18074 [(set_attr "type" "str")
18075 (set_attr "prefix_rep" "1")
18076 (set_attr "memory" "store")
18077 (set_attr "mode" "QI")])
18079 (define_expand "cmpstrnsi"
18080 [(set (match_operand:SI 0 "register_operand" "")
18081 (compare:SI (match_operand:BLK 1 "general_operand" "")
18082 (match_operand:BLK 2 "general_operand" "")))
18083 (use (match_operand 3 "general_operand" ""))
18084 (use (match_operand 4 "immediate_operand" ""))]
18085 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18087 rtx addr1, addr2, out, outlow, count, countreg, align;
18089 /* Can't use this if the user has appropriated esi or edi. */
18090 if (global_regs[4] || global_regs[5])
18094 if (GET_CODE (out) != REG)
18095 out = gen_reg_rtx (SImode);
18097 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18098 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18099 if (addr1 != XEXP (operands[1], 0))
18100 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18101 if (addr2 != XEXP (operands[2], 0))
18102 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18104 count = operands[3];
18105 countreg = ix86_zero_extend_to_Pmode (count);
18107 /* %%% Iff we are testing strict equality, we can use known alignment
18108 to good advantage. This may be possible with combine, particularly
18109 once cc0 is dead. */
18110 align = operands[4];
18112 emit_insn (gen_cld ());
18113 if (GET_CODE (count) == CONST_INT)
18115 if (INTVAL (count) == 0)
18117 emit_move_insn (operands[0], const0_rtx);
18120 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18121 operands[1], operands[2]));
18126 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18128 emit_insn (gen_cmpsi_1 (countreg, countreg));
18129 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18130 operands[1], operands[2]));
18133 outlow = gen_lowpart (QImode, out);
18134 emit_insn (gen_cmpintqi (outlow));
18135 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18137 if (operands[0] != out)
18138 emit_move_insn (operands[0], out);
18143 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18145 (define_expand "cmpintqi"
18146 [(set (match_dup 1)
18147 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18149 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18150 (parallel [(set (match_operand:QI 0 "register_operand" "")
18151 (minus:QI (match_dup 1)
18153 (clobber (reg:CC FLAGS_REG))])]
18155 "operands[1] = gen_reg_rtx (QImode);
18156 operands[2] = gen_reg_rtx (QImode);")
18158 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18159 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18161 (define_expand "cmpstrnqi_nz_1"
18162 [(parallel [(set (reg:CC FLAGS_REG)
18163 (compare:CC (match_operand 4 "memory_operand" "")
18164 (match_operand 5 "memory_operand" "")))
18165 (use (match_operand 2 "register_operand" ""))
18166 (use (match_operand:SI 3 "immediate_operand" ""))
18167 (use (reg:SI DIRFLAG_REG))
18168 (clobber (match_operand 0 "register_operand" ""))
18169 (clobber (match_operand 1 "register_operand" ""))
18170 (clobber (match_dup 2))])]
18174 (define_insn "*cmpstrnqi_nz_1"
18175 [(set (reg:CC FLAGS_REG)
18176 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18177 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18178 (use (match_operand:SI 6 "register_operand" "2"))
18179 (use (match_operand:SI 3 "immediate_operand" "i"))
18180 (use (reg:SI DIRFLAG_REG))
18181 (clobber (match_operand:SI 0 "register_operand" "=S"))
18182 (clobber (match_operand:SI 1 "register_operand" "=D"))
18183 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18186 [(set_attr "type" "str")
18187 (set_attr "mode" "QI")
18188 (set_attr "prefix_rep" "1")])
18190 (define_insn "*cmpstrnqi_nz_rex_1"
18191 [(set (reg:CC FLAGS_REG)
18192 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18193 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18194 (use (match_operand:DI 6 "register_operand" "2"))
18195 (use (match_operand:SI 3 "immediate_operand" "i"))
18196 (use (reg:SI DIRFLAG_REG))
18197 (clobber (match_operand:DI 0 "register_operand" "=S"))
18198 (clobber (match_operand:DI 1 "register_operand" "=D"))
18199 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18202 [(set_attr "type" "str")
18203 (set_attr "mode" "QI")
18204 (set_attr "prefix_rep" "1")])
18206 ;; The same, but the count is not known to not be zero.
18208 (define_expand "cmpstrnqi_1"
18209 [(parallel [(set (reg:CC FLAGS_REG)
18210 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18212 (compare:CC (match_operand 4 "memory_operand" "")
18213 (match_operand 5 "memory_operand" ""))
18215 (use (match_operand:SI 3 "immediate_operand" ""))
18216 (use (reg:CC FLAGS_REG))
18217 (use (reg:SI DIRFLAG_REG))
18218 (clobber (match_operand 0 "register_operand" ""))
18219 (clobber (match_operand 1 "register_operand" ""))
18220 (clobber (match_dup 2))])]
18224 (define_insn "*cmpstrnqi_1"
18225 [(set (reg:CC FLAGS_REG)
18226 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18228 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18229 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18231 (use (match_operand:SI 3 "immediate_operand" "i"))
18232 (use (reg:CC FLAGS_REG))
18233 (use (reg:SI DIRFLAG_REG))
18234 (clobber (match_operand:SI 0 "register_operand" "=S"))
18235 (clobber (match_operand:SI 1 "register_operand" "=D"))
18236 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18239 [(set_attr "type" "str")
18240 (set_attr "mode" "QI")
18241 (set_attr "prefix_rep" "1")])
18243 (define_insn "*cmpstrnqi_rex_1"
18244 [(set (reg:CC FLAGS_REG)
18245 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18247 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18248 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18250 (use (match_operand:SI 3 "immediate_operand" "i"))
18251 (use (reg:CC FLAGS_REG))
18252 (use (reg:SI DIRFLAG_REG))
18253 (clobber (match_operand:DI 0 "register_operand" "=S"))
18254 (clobber (match_operand:DI 1 "register_operand" "=D"))
18255 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18258 [(set_attr "type" "str")
18259 (set_attr "mode" "QI")
18260 (set_attr "prefix_rep" "1")])
18262 (define_expand "strlensi"
18263 [(set (match_operand:SI 0 "register_operand" "")
18264 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18265 (match_operand:QI 2 "immediate_operand" "")
18266 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18269 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18275 (define_expand "strlendi"
18276 [(set (match_operand:DI 0 "register_operand" "")
18277 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18278 (match_operand:QI 2 "immediate_operand" "")
18279 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18282 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18288 (define_expand "strlenqi_1"
18289 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18290 (use (reg:SI DIRFLAG_REG))
18291 (clobber (match_operand 1 "register_operand" ""))
18292 (clobber (reg:CC FLAGS_REG))])]
18296 (define_insn "*strlenqi_1"
18297 [(set (match_operand:SI 0 "register_operand" "=&c")
18298 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18299 (match_operand:QI 2 "register_operand" "a")
18300 (match_operand:SI 3 "immediate_operand" "i")
18301 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18302 (use (reg:SI DIRFLAG_REG))
18303 (clobber (match_operand:SI 1 "register_operand" "=D"))
18304 (clobber (reg:CC FLAGS_REG))]
18307 [(set_attr "type" "str")
18308 (set_attr "mode" "QI")
18309 (set_attr "prefix_rep" "1")])
18311 (define_insn "*strlenqi_rex_1"
18312 [(set (match_operand:DI 0 "register_operand" "=&c")
18313 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18314 (match_operand:QI 2 "register_operand" "a")
18315 (match_operand:DI 3 "immediate_operand" "i")
18316 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18317 (use (reg:SI DIRFLAG_REG))
18318 (clobber (match_operand:DI 1 "register_operand" "=D"))
18319 (clobber (reg:CC FLAGS_REG))]
18322 [(set_attr "type" "str")
18323 (set_attr "mode" "QI")
18324 (set_attr "prefix_rep" "1")])
18326 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18327 ;; handled in combine, but it is not currently up to the task.
18328 ;; When used for their truth value, the cmpstrn* expanders generate
18337 ;; The intermediate three instructions are unnecessary.
18339 ;; This one handles cmpstrn*_nz_1...
18342 (set (reg:CC FLAGS_REG)
18343 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18344 (mem:BLK (match_operand 5 "register_operand" ""))))
18345 (use (match_operand 6 "register_operand" ""))
18346 (use (match_operand:SI 3 "immediate_operand" ""))
18347 (use (reg:SI DIRFLAG_REG))
18348 (clobber (match_operand 0 "register_operand" ""))
18349 (clobber (match_operand 1 "register_operand" ""))
18350 (clobber (match_operand 2 "register_operand" ""))])
18351 (set (match_operand:QI 7 "register_operand" "")
18352 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18353 (set (match_operand:QI 8 "register_operand" "")
18354 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18355 (set (reg FLAGS_REG)
18356 (compare (match_dup 7) (match_dup 8)))
18358 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18360 (set (reg:CC FLAGS_REG)
18361 (compare:CC (mem:BLK (match_dup 4))
18362 (mem:BLK (match_dup 5))))
18363 (use (match_dup 6))
18364 (use (match_dup 3))
18365 (use (reg:SI DIRFLAG_REG))
18366 (clobber (match_dup 0))
18367 (clobber (match_dup 1))
18368 (clobber (match_dup 2))])]
18371 ;; ...and this one handles cmpstrn*_1.
18374 (set (reg:CC FLAGS_REG)
18375 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18377 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18378 (mem:BLK (match_operand 5 "register_operand" "")))
18380 (use (match_operand:SI 3 "immediate_operand" ""))
18381 (use (reg:CC FLAGS_REG))
18382 (use (reg:SI DIRFLAG_REG))
18383 (clobber (match_operand 0 "register_operand" ""))
18384 (clobber (match_operand 1 "register_operand" ""))
18385 (clobber (match_operand 2 "register_operand" ""))])
18386 (set (match_operand:QI 7 "register_operand" "")
18387 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18388 (set (match_operand:QI 8 "register_operand" "")
18389 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18390 (set (reg FLAGS_REG)
18391 (compare (match_dup 7) (match_dup 8)))
18393 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18395 (set (reg:CC FLAGS_REG)
18396 (if_then_else:CC (ne (match_dup 6)
18398 (compare:CC (mem:BLK (match_dup 4))
18399 (mem:BLK (match_dup 5)))
18401 (use (match_dup 3))
18402 (use (reg:CC FLAGS_REG))
18403 (use (reg:SI DIRFLAG_REG))
18404 (clobber (match_dup 0))
18405 (clobber (match_dup 1))
18406 (clobber (match_dup 2))])]
18411 ;; Conditional move instructions.
18413 (define_expand "movdicc"
18414 [(set (match_operand:DI 0 "register_operand" "")
18415 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18416 (match_operand:DI 2 "general_operand" "")
18417 (match_operand:DI 3 "general_operand" "")))]
18419 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18421 (define_insn "x86_movdicc_0_m1_rex64"
18422 [(set (match_operand:DI 0 "register_operand" "=r")
18423 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18426 (clobber (reg:CC FLAGS_REG))]
18429 ; Since we don't have the proper number of operands for an alu insn,
18430 ; fill in all the blanks.
18431 [(set_attr "type" "alu")
18432 (set_attr "pent_pair" "pu")
18433 (set_attr "memory" "none")
18434 (set_attr "imm_disp" "false")
18435 (set_attr "mode" "DI")
18436 (set_attr "length_immediate" "0")])
18438 (define_insn "*movdicc_c_rex64"
18439 [(set (match_operand:DI 0 "register_operand" "=r,r")
18440 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18441 [(reg FLAGS_REG) (const_int 0)])
18442 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18443 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18444 "TARGET_64BIT && TARGET_CMOVE
18445 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18447 cmov%O2%C1\t{%2, %0|%0, %2}
18448 cmov%O2%c1\t{%3, %0|%0, %3}"
18449 [(set_attr "type" "icmov")
18450 (set_attr "mode" "DI")])
18452 (define_expand "movsicc"
18453 [(set (match_operand:SI 0 "register_operand" "")
18454 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18455 (match_operand:SI 2 "general_operand" "")
18456 (match_operand:SI 3 "general_operand" "")))]
18458 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18460 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18461 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18462 ;; So just document what we're doing explicitly.
18464 (define_insn "x86_movsicc_0_m1"
18465 [(set (match_operand:SI 0 "register_operand" "=r")
18466 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18469 (clobber (reg:CC FLAGS_REG))]
18472 ; Since we don't have the proper number of operands for an alu insn,
18473 ; fill in all the blanks.
18474 [(set_attr "type" "alu")
18475 (set_attr "pent_pair" "pu")
18476 (set_attr "memory" "none")
18477 (set_attr "imm_disp" "false")
18478 (set_attr "mode" "SI")
18479 (set_attr "length_immediate" "0")])
18481 (define_insn "*movsicc_noc"
18482 [(set (match_operand:SI 0 "register_operand" "=r,r")
18483 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18484 [(reg FLAGS_REG) (const_int 0)])
18485 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18486 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18488 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18490 cmov%O2%C1\t{%2, %0|%0, %2}
18491 cmov%O2%c1\t{%3, %0|%0, %3}"
18492 [(set_attr "type" "icmov")
18493 (set_attr "mode" "SI")])
18495 (define_expand "movhicc"
18496 [(set (match_operand:HI 0 "register_operand" "")
18497 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18498 (match_operand:HI 2 "general_operand" "")
18499 (match_operand:HI 3 "general_operand" "")))]
18500 "TARGET_HIMODE_MATH"
18501 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18503 (define_insn "*movhicc_noc"
18504 [(set (match_operand:HI 0 "register_operand" "=r,r")
18505 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18506 [(reg FLAGS_REG) (const_int 0)])
18507 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18508 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18510 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18512 cmov%O2%C1\t{%2, %0|%0, %2}
18513 cmov%O2%c1\t{%3, %0|%0, %3}"
18514 [(set_attr "type" "icmov")
18515 (set_attr "mode" "HI")])
18517 (define_expand "movqicc"
18518 [(set (match_operand:QI 0 "register_operand" "")
18519 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18520 (match_operand:QI 2 "general_operand" "")
18521 (match_operand:QI 3 "general_operand" "")))]
18522 "TARGET_QIMODE_MATH"
18523 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18525 (define_insn_and_split "*movqicc_noc"
18526 [(set (match_operand:QI 0 "register_operand" "=r,r")
18527 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18528 [(match_operand 4 "flags_reg_operand" "")
18530 (match_operand:QI 2 "register_operand" "r,0")
18531 (match_operand:QI 3 "register_operand" "0,r")))]
18532 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18534 "&& reload_completed"
18535 [(set (match_dup 0)
18536 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18539 "operands[0] = gen_lowpart (SImode, operands[0]);
18540 operands[2] = gen_lowpart (SImode, operands[2]);
18541 operands[3] = gen_lowpart (SImode, operands[3]);"
18542 [(set_attr "type" "icmov")
18543 (set_attr "mode" "SI")])
18545 (define_expand "movsfcc"
18546 [(set (match_operand:SF 0 "register_operand" "")
18547 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18548 (match_operand:SF 2 "register_operand" "")
18549 (match_operand:SF 3 "register_operand" "")))]
18550 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18551 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18553 (define_insn "*movsfcc_1_387"
18554 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18555 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18556 [(reg FLAGS_REG) (const_int 0)])
18557 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18558 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18559 "TARGET_80387 && TARGET_CMOVE
18560 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18562 fcmov%F1\t{%2, %0|%0, %2}
18563 fcmov%f1\t{%3, %0|%0, %3}
18564 cmov%O2%C1\t{%2, %0|%0, %2}
18565 cmov%O2%c1\t{%3, %0|%0, %3}"
18566 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18567 (set_attr "mode" "SF,SF,SI,SI")])
18569 (define_expand "movdfcc"
18570 [(set (match_operand:DF 0 "register_operand" "")
18571 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18572 (match_operand:DF 2 "register_operand" "")
18573 (match_operand:DF 3 "register_operand" "")))]
18574 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18575 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18577 (define_insn "*movdfcc_1"
18578 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18579 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18580 [(reg FLAGS_REG) (const_int 0)])
18581 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18582 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18583 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18584 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18586 fcmov%F1\t{%2, %0|%0, %2}
18587 fcmov%f1\t{%3, %0|%0, %3}
18590 [(set_attr "type" "fcmov,fcmov,multi,multi")
18591 (set_attr "mode" "DF")])
18593 (define_insn "*movdfcc_1_rex64"
18594 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18595 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18596 [(reg FLAGS_REG) (const_int 0)])
18597 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18598 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18599 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18600 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18602 fcmov%F1\t{%2, %0|%0, %2}
18603 fcmov%f1\t{%3, %0|%0, %3}
18604 cmov%O2%C1\t{%2, %0|%0, %2}
18605 cmov%O2%c1\t{%3, %0|%0, %3}"
18606 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18607 (set_attr "mode" "DF")])
18610 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18611 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18612 [(match_operand 4 "flags_reg_operand" "")
18614 (match_operand:DF 2 "nonimmediate_operand" "")
18615 (match_operand:DF 3 "nonimmediate_operand" "")))]
18616 "!TARGET_64BIT && reload_completed"
18617 [(set (match_dup 2)
18618 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18622 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18625 "split_di (operands+2, 1, operands+5, operands+6);
18626 split_di (operands+3, 1, operands+7, operands+8);
18627 split_di (operands, 1, operands+2, operands+3);")
18629 (define_expand "movxfcc"
18630 [(set (match_operand:XF 0 "register_operand" "")
18631 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18632 (match_operand:XF 2 "register_operand" "")
18633 (match_operand:XF 3 "register_operand" "")))]
18634 "TARGET_80387 && TARGET_CMOVE"
18635 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18637 (define_insn "*movxfcc_1"
18638 [(set (match_operand:XF 0 "register_operand" "=f,f")
18639 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18640 [(reg FLAGS_REG) (const_int 0)])
18641 (match_operand:XF 2 "register_operand" "f,0")
18642 (match_operand:XF 3 "register_operand" "0,f")))]
18643 "TARGET_80387 && TARGET_CMOVE"
18645 fcmov%F1\t{%2, %0|%0, %2}
18646 fcmov%f1\t{%3, %0|%0, %3}"
18647 [(set_attr "type" "fcmov")
18648 (set_attr "mode" "XF")])
18650 ;; These versions of the min/max patterns are intentionally ignorant of
18651 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18652 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18653 ;; are undefined in this condition, we're certain this is correct.
18655 (define_insn "sminsf3"
18656 [(set (match_operand:SF 0 "register_operand" "=x")
18657 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18658 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18660 "minss\t{%2, %0|%0, %2}"
18661 [(set_attr "type" "sseadd")
18662 (set_attr "mode" "SF")])
18664 (define_insn "smaxsf3"
18665 [(set (match_operand:SF 0 "register_operand" "=x")
18666 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18667 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18669 "maxss\t{%2, %0|%0, %2}"
18670 [(set_attr "type" "sseadd")
18671 (set_attr "mode" "SF")])
18673 (define_insn "smindf3"
18674 [(set (match_operand:DF 0 "register_operand" "=x")
18675 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18676 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18677 "TARGET_SSE2 && TARGET_SSE_MATH"
18678 "minsd\t{%2, %0|%0, %2}"
18679 [(set_attr "type" "sseadd")
18680 (set_attr "mode" "DF")])
18682 (define_insn "smaxdf3"
18683 [(set (match_operand:DF 0 "register_operand" "=x")
18684 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18685 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18686 "TARGET_SSE2 && TARGET_SSE_MATH"
18687 "maxsd\t{%2, %0|%0, %2}"
18688 [(set_attr "type" "sseadd")
18689 (set_attr "mode" "DF")])
18691 ;; These versions of the min/max patterns implement exactly the operations
18692 ;; min = (op1 < op2 ? op1 : op2)
18693 ;; max = (!(op1 < op2) ? op1 : op2)
18694 ;; Their operands are not commutative, and thus they may be used in the
18695 ;; presence of -0.0 and NaN.
18697 (define_insn "*ieee_sminsf3"
18698 [(set (match_operand:SF 0 "register_operand" "=x")
18699 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18700 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18703 "minss\t{%2, %0|%0, %2}"
18704 [(set_attr "type" "sseadd")
18705 (set_attr "mode" "SF")])
18707 (define_insn "*ieee_smaxsf3"
18708 [(set (match_operand:SF 0 "register_operand" "=x")
18709 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18710 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18713 "maxss\t{%2, %0|%0, %2}"
18714 [(set_attr "type" "sseadd")
18715 (set_attr "mode" "SF")])
18717 (define_insn "*ieee_smindf3"
18718 [(set (match_operand:DF 0 "register_operand" "=x")
18719 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18720 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18722 "TARGET_SSE2 && TARGET_SSE_MATH"
18723 "minsd\t{%2, %0|%0, %2}"
18724 [(set_attr "type" "sseadd")
18725 (set_attr "mode" "DF")])
18727 (define_insn "*ieee_smaxdf3"
18728 [(set (match_operand:DF 0 "register_operand" "=x")
18729 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18730 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18732 "TARGET_SSE2 && TARGET_SSE_MATH"
18733 "maxsd\t{%2, %0|%0, %2}"
18734 [(set_attr "type" "sseadd")
18735 (set_attr "mode" "DF")])
18737 ;; Conditional addition patterns
18738 (define_expand "addqicc"
18739 [(match_operand:QI 0 "register_operand" "")
18740 (match_operand 1 "comparison_operator" "")
18741 (match_operand:QI 2 "register_operand" "")
18742 (match_operand:QI 3 "const_int_operand" "")]
18744 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18746 (define_expand "addhicc"
18747 [(match_operand:HI 0 "register_operand" "")
18748 (match_operand 1 "comparison_operator" "")
18749 (match_operand:HI 2 "register_operand" "")
18750 (match_operand:HI 3 "const_int_operand" "")]
18752 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18754 (define_expand "addsicc"
18755 [(match_operand:SI 0 "register_operand" "")
18756 (match_operand 1 "comparison_operator" "")
18757 (match_operand:SI 2 "register_operand" "")
18758 (match_operand:SI 3 "const_int_operand" "")]
18760 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18762 (define_expand "adddicc"
18763 [(match_operand:DI 0 "register_operand" "")
18764 (match_operand 1 "comparison_operator" "")
18765 (match_operand:DI 2 "register_operand" "")
18766 (match_operand:DI 3 "const_int_operand" "")]
18768 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18771 ;; Misc patterns (?)
18773 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18774 ;; Otherwise there will be nothing to keep
18776 ;; [(set (reg ebp) (reg esp))]
18777 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18778 ;; (clobber (eflags)]
18779 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18781 ;; in proper program order.
18782 (define_insn "pro_epilogue_adjust_stack_1"
18783 [(set (match_operand:SI 0 "register_operand" "=r,r")
18784 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18785 (match_operand:SI 2 "immediate_operand" "i,i")))
18786 (clobber (reg:CC FLAGS_REG))
18787 (clobber (mem:BLK (scratch)))]
18790 switch (get_attr_type (insn))
18793 return "mov{l}\t{%1, %0|%0, %1}";
18796 if (GET_CODE (operands[2]) == CONST_INT
18797 && (INTVAL (operands[2]) == 128
18798 || (INTVAL (operands[2]) < 0
18799 && INTVAL (operands[2]) != -128)))
18801 operands[2] = GEN_INT (-INTVAL (operands[2]));
18802 return "sub{l}\t{%2, %0|%0, %2}";
18804 return "add{l}\t{%2, %0|%0, %2}";
18807 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18808 return "lea{l}\t{%a2, %0|%0, %a2}";
18811 gcc_unreachable ();
18814 [(set (attr "type")
18815 (cond [(eq_attr "alternative" "0")
18816 (const_string "alu")
18817 (match_operand:SI 2 "const0_operand" "")
18818 (const_string "imov")
18820 (const_string "lea")))
18821 (set_attr "mode" "SI")])
18823 (define_insn "pro_epilogue_adjust_stack_rex64"
18824 [(set (match_operand:DI 0 "register_operand" "=r,r")
18825 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18826 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18827 (clobber (reg:CC FLAGS_REG))
18828 (clobber (mem:BLK (scratch)))]
18831 switch (get_attr_type (insn))
18834 return "mov{q}\t{%1, %0|%0, %1}";
18837 if (GET_CODE (operands[2]) == CONST_INT
18838 /* Avoid overflows. */
18839 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18840 && (INTVAL (operands[2]) == 128
18841 || (INTVAL (operands[2]) < 0
18842 && INTVAL (operands[2]) != -128)))
18844 operands[2] = GEN_INT (-INTVAL (operands[2]));
18845 return "sub{q}\t{%2, %0|%0, %2}";
18847 return "add{q}\t{%2, %0|%0, %2}";
18850 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18851 return "lea{q}\t{%a2, %0|%0, %a2}";
18854 gcc_unreachable ();
18857 [(set (attr "type")
18858 (cond [(eq_attr "alternative" "0")
18859 (const_string "alu")
18860 (match_operand:DI 2 "const0_operand" "")
18861 (const_string "imov")
18863 (const_string "lea")))
18864 (set_attr "mode" "DI")])
18866 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18867 [(set (match_operand:DI 0 "register_operand" "=r,r")
18868 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18869 (match_operand:DI 3 "immediate_operand" "i,i")))
18870 (use (match_operand:DI 2 "register_operand" "r,r"))
18871 (clobber (reg:CC FLAGS_REG))
18872 (clobber (mem:BLK (scratch)))]
18875 switch (get_attr_type (insn))
18878 return "add{q}\t{%2, %0|%0, %2}";
18881 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18882 return "lea{q}\t{%a2, %0|%0, %a2}";
18885 gcc_unreachable ();
18888 [(set_attr "type" "alu,lea")
18889 (set_attr "mode" "DI")])
18891 (define_expand "allocate_stack_worker"
18892 [(match_operand:SI 0 "register_operand" "")]
18893 "TARGET_STACK_PROBE"
18895 if (reload_completed)
18898 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18900 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18905 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18907 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18912 (define_insn "allocate_stack_worker_1"
18913 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18914 UNSPECV_STACK_PROBE)
18915 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18916 (clobber (match_scratch:SI 1 "=0"))
18917 (clobber (reg:CC FLAGS_REG))]
18918 "!TARGET_64BIT && TARGET_STACK_PROBE"
18920 [(set_attr "type" "multi")
18921 (set_attr "length" "5")])
18923 (define_expand "allocate_stack_worker_postreload"
18924 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18925 UNSPECV_STACK_PROBE)
18926 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18927 (clobber (match_dup 0))
18928 (clobber (reg:CC FLAGS_REG))])]
18932 (define_insn "allocate_stack_worker_rex64"
18933 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18934 UNSPECV_STACK_PROBE)
18935 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18936 (clobber (match_scratch:DI 1 "=0"))
18937 (clobber (reg:CC FLAGS_REG))]
18938 "TARGET_64BIT && TARGET_STACK_PROBE"
18940 [(set_attr "type" "multi")
18941 (set_attr "length" "5")])
18943 (define_expand "allocate_stack_worker_rex64_postreload"
18944 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18945 UNSPECV_STACK_PROBE)
18946 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18947 (clobber (match_dup 0))
18948 (clobber (reg:CC FLAGS_REG))])]
18952 (define_expand "allocate_stack"
18953 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18954 (minus:SI (reg:SI SP_REG)
18955 (match_operand:SI 1 "general_operand" "")))
18956 (clobber (reg:CC FLAGS_REG))])
18957 (parallel [(set (reg:SI SP_REG)
18958 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18959 (clobber (reg:CC FLAGS_REG))])]
18960 "TARGET_STACK_PROBE"
18962 #ifdef CHECK_STACK_LIMIT
18963 if (GET_CODE (operands[1]) == CONST_INT
18964 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18965 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18969 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18972 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18976 (define_expand "builtin_setjmp_receiver"
18977 [(label_ref (match_operand 0 "" ""))]
18978 "!TARGET_64BIT && flag_pic"
18983 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
18984 rtx label_rtx = gen_label_rtx ();
18985 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18986 emit_label (label_rtx);
18987 xops[0] = xops[1] = picreg;
18988 xops[2] = gen_rtx_CONST (SImode,
18989 gen_rtx_MINUS (SImode,
18990 gen_rtx_LABEL_REF (SImode, label_rtx),
18991 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
18992 ix86_expand_binary_operator (MINUS, SImode, xops);
18995 emit_insn (gen_set_got (pic_offset_table_rtx));
18999 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19002 [(set (match_operand 0 "register_operand" "")
19003 (match_operator 3 "promotable_binary_operator"
19004 [(match_operand 1 "register_operand" "")
19005 (match_operand 2 "aligned_operand" "")]))
19006 (clobber (reg:CC FLAGS_REG))]
19007 "! TARGET_PARTIAL_REG_STALL && reload_completed
19008 && ((GET_MODE (operands[0]) == HImode
19009 && ((!optimize_size && !TARGET_FAST_PREFIX)
19010 || GET_CODE (operands[2]) != CONST_INT
19011 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
19012 || (GET_MODE (operands[0]) == QImode
19013 && (TARGET_PROMOTE_QImode || optimize_size)))"
19014 [(parallel [(set (match_dup 0)
19015 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19016 (clobber (reg:CC FLAGS_REG))])]
19017 "operands[0] = gen_lowpart (SImode, operands[0]);
19018 operands[1] = gen_lowpart (SImode, operands[1]);
19019 if (GET_CODE (operands[3]) != ASHIFT)
19020 operands[2] = gen_lowpart (SImode, operands[2]);
19021 PUT_MODE (operands[3], SImode);")
19023 ; Promote the QImode tests, as i386 has encoding of the AND
19024 ; instruction with 32-bit sign-extended immediate and thus the
19025 ; instruction size is unchanged, except in the %eax case for
19026 ; which it is increased by one byte, hence the ! optimize_size.
19028 [(set (match_operand 0 "flags_reg_operand" "")
19029 (match_operator 2 "compare_operator"
19030 [(and (match_operand 3 "aligned_operand" "")
19031 (match_operand 4 "const_int_operand" ""))
19033 (set (match_operand 1 "register_operand" "")
19034 (and (match_dup 3) (match_dup 4)))]
19035 "! TARGET_PARTIAL_REG_STALL && reload_completed
19036 /* Ensure that the operand will remain sign-extended immediate. */
19037 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19039 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19040 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19041 [(parallel [(set (match_dup 0)
19042 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19045 (and:SI (match_dup 3) (match_dup 4)))])]
19048 = gen_int_mode (INTVAL (operands[4])
19049 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19050 operands[1] = gen_lowpart (SImode, operands[1]);
19051 operands[3] = gen_lowpart (SImode, operands[3]);
19054 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19055 ; the TEST instruction with 32-bit sign-extended immediate and thus
19056 ; the instruction size would at least double, which is not what we
19057 ; want even with ! optimize_size.
19059 [(set (match_operand 0 "flags_reg_operand" "")
19060 (match_operator 1 "compare_operator"
19061 [(and (match_operand:HI 2 "aligned_operand" "")
19062 (match_operand:HI 3 "const_int_operand" ""))
19064 "! TARGET_PARTIAL_REG_STALL && reload_completed
19065 /* Ensure that the operand will remain sign-extended immediate. */
19066 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19067 && ! TARGET_FAST_PREFIX
19068 && ! optimize_size"
19069 [(set (match_dup 0)
19070 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19074 = gen_int_mode (INTVAL (operands[3])
19075 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19076 operands[2] = gen_lowpart (SImode, operands[2]);
19080 [(set (match_operand 0 "register_operand" "")
19081 (neg (match_operand 1 "register_operand" "")))
19082 (clobber (reg:CC FLAGS_REG))]
19083 "! TARGET_PARTIAL_REG_STALL && reload_completed
19084 && (GET_MODE (operands[0]) == HImode
19085 || (GET_MODE (operands[0]) == QImode
19086 && (TARGET_PROMOTE_QImode || optimize_size)))"
19087 [(parallel [(set (match_dup 0)
19088 (neg:SI (match_dup 1)))
19089 (clobber (reg:CC FLAGS_REG))])]
19090 "operands[0] = gen_lowpart (SImode, operands[0]);
19091 operands[1] = gen_lowpart (SImode, operands[1]);")
19094 [(set (match_operand 0 "register_operand" "")
19095 (not (match_operand 1 "register_operand" "")))]
19096 "! TARGET_PARTIAL_REG_STALL && reload_completed
19097 && (GET_MODE (operands[0]) == HImode
19098 || (GET_MODE (operands[0]) == QImode
19099 && (TARGET_PROMOTE_QImode || optimize_size)))"
19100 [(set (match_dup 0)
19101 (not:SI (match_dup 1)))]
19102 "operands[0] = gen_lowpart (SImode, operands[0]);
19103 operands[1] = gen_lowpart (SImode, operands[1]);")
19106 [(set (match_operand 0 "register_operand" "")
19107 (if_then_else (match_operator 1 "comparison_operator"
19108 [(reg FLAGS_REG) (const_int 0)])
19109 (match_operand 2 "register_operand" "")
19110 (match_operand 3 "register_operand" "")))]
19111 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19112 && (GET_MODE (operands[0]) == HImode
19113 || (GET_MODE (operands[0]) == QImode
19114 && (TARGET_PROMOTE_QImode || optimize_size)))"
19115 [(set (match_dup 0)
19116 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19117 "operands[0] = gen_lowpart (SImode, operands[0]);
19118 operands[2] = gen_lowpart (SImode, operands[2]);
19119 operands[3] = gen_lowpart (SImode, operands[3]);")
19122 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19123 ;; transform a complex memory operation into two memory to register operations.
19125 ;; Don't push memory operands
19127 [(set (match_operand:SI 0 "push_operand" "")
19128 (match_operand:SI 1 "memory_operand" ""))
19129 (match_scratch:SI 2 "r")]
19130 "!optimize_size && !TARGET_PUSH_MEMORY
19131 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19132 [(set (match_dup 2) (match_dup 1))
19133 (set (match_dup 0) (match_dup 2))]
19137 [(set (match_operand:DI 0 "push_operand" "")
19138 (match_operand:DI 1 "memory_operand" ""))
19139 (match_scratch:DI 2 "r")]
19140 "!optimize_size && !TARGET_PUSH_MEMORY
19141 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19142 [(set (match_dup 2) (match_dup 1))
19143 (set (match_dup 0) (match_dup 2))]
19146 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19149 [(set (match_operand:SF 0 "push_operand" "")
19150 (match_operand:SF 1 "memory_operand" ""))
19151 (match_scratch:SF 2 "r")]
19152 "!optimize_size && !TARGET_PUSH_MEMORY
19153 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19154 [(set (match_dup 2) (match_dup 1))
19155 (set (match_dup 0) (match_dup 2))]
19159 [(set (match_operand:HI 0 "push_operand" "")
19160 (match_operand:HI 1 "memory_operand" ""))
19161 (match_scratch:HI 2 "r")]
19162 "!optimize_size && !TARGET_PUSH_MEMORY
19163 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19164 [(set (match_dup 2) (match_dup 1))
19165 (set (match_dup 0) (match_dup 2))]
19169 [(set (match_operand:QI 0 "push_operand" "")
19170 (match_operand:QI 1 "memory_operand" ""))
19171 (match_scratch:QI 2 "q")]
19172 "!optimize_size && !TARGET_PUSH_MEMORY
19173 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19174 [(set (match_dup 2) (match_dup 1))
19175 (set (match_dup 0) (match_dup 2))]
19178 ;; Don't move an immediate directly to memory when the instruction
19181 [(match_scratch:SI 1 "r")
19182 (set (match_operand:SI 0 "memory_operand" "")
19185 && ! TARGET_USE_MOV0
19186 && TARGET_SPLIT_LONG_MOVES
19187 && get_attr_length (insn) >= ix86_cost->large_insn
19188 && peep2_regno_dead_p (0, FLAGS_REG)"
19189 [(parallel [(set (match_dup 1) (const_int 0))
19190 (clobber (reg:CC FLAGS_REG))])
19191 (set (match_dup 0) (match_dup 1))]
19195 [(match_scratch:HI 1 "r")
19196 (set (match_operand:HI 0 "memory_operand" "")
19199 && ! TARGET_USE_MOV0
19200 && TARGET_SPLIT_LONG_MOVES
19201 && get_attr_length (insn) >= ix86_cost->large_insn
19202 && peep2_regno_dead_p (0, FLAGS_REG)"
19203 [(parallel [(set (match_dup 2) (const_int 0))
19204 (clobber (reg:CC FLAGS_REG))])
19205 (set (match_dup 0) (match_dup 1))]
19206 "operands[2] = gen_lowpart (SImode, operands[1]);")
19209 [(match_scratch:QI 1 "q")
19210 (set (match_operand:QI 0 "memory_operand" "")
19213 && ! TARGET_USE_MOV0
19214 && TARGET_SPLIT_LONG_MOVES
19215 && get_attr_length (insn) >= ix86_cost->large_insn
19216 && peep2_regno_dead_p (0, FLAGS_REG)"
19217 [(parallel [(set (match_dup 2) (const_int 0))
19218 (clobber (reg:CC FLAGS_REG))])
19219 (set (match_dup 0) (match_dup 1))]
19220 "operands[2] = gen_lowpart (SImode, operands[1]);")
19223 [(match_scratch:SI 2 "r")
19224 (set (match_operand:SI 0 "memory_operand" "")
19225 (match_operand:SI 1 "immediate_operand" ""))]
19227 && get_attr_length (insn) >= ix86_cost->large_insn
19228 && TARGET_SPLIT_LONG_MOVES"
19229 [(set (match_dup 2) (match_dup 1))
19230 (set (match_dup 0) (match_dup 2))]
19234 [(match_scratch:HI 2 "r")
19235 (set (match_operand:HI 0 "memory_operand" "")
19236 (match_operand:HI 1 "immediate_operand" ""))]
19237 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19238 && TARGET_SPLIT_LONG_MOVES"
19239 [(set (match_dup 2) (match_dup 1))
19240 (set (match_dup 0) (match_dup 2))]
19244 [(match_scratch:QI 2 "q")
19245 (set (match_operand:QI 0 "memory_operand" "")
19246 (match_operand:QI 1 "immediate_operand" ""))]
19247 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19248 && TARGET_SPLIT_LONG_MOVES"
19249 [(set (match_dup 2) (match_dup 1))
19250 (set (match_dup 0) (match_dup 2))]
19253 ;; Don't compare memory with zero, load and use a test instead.
19255 [(set (match_operand 0 "flags_reg_operand" "")
19256 (match_operator 1 "compare_operator"
19257 [(match_operand:SI 2 "memory_operand" "")
19259 (match_scratch:SI 3 "r")]
19260 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19261 [(set (match_dup 3) (match_dup 2))
19262 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19265 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19266 ;; Don't split NOTs with a displacement operand, because resulting XOR
19267 ;; will not be pairable anyway.
19269 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19270 ;; represented using a modRM byte. The XOR replacement is long decoded,
19271 ;; so this split helps here as well.
19273 ;; Note: Can't do this as a regular split because we can't get proper
19274 ;; lifetime information then.
19277 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19278 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19280 && peep2_regno_dead_p (0, FLAGS_REG)
19281 && ((TARGET_PENTIUM
19282 && (GET_CODE (operands[0]) != MEM
19283 || !memory_displacement_operand (operands[0], SImode)))
19284 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19285 [(parallel [(set (match_dup 0)
19286 (xor:SI (match_dup 1) (const_int -1)))
19287 (clobber (reg:CC FLAGS_REG))])]
19291 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19292 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19294 && peep2_regno_dead_p (0, FLAGS_REG)
19295 && ((TARGET_PENTIUM
19296 && (GET_CODE (operands[0]) != MEM
19297 || !memory_displacement_operand (operands[0], HImode)))
19298 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19299 [(parallel [(set (match_dup 0)
19300 (xor:HI (match_dup 1) (const_int -1)))
19301 (clobber (reg:CC FLAGS_REG))])]
19305 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19306 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19308 && peep2_regno_dead_p (0, FLAGS_REG)
19309 && ((TARGET_PENTIUM
19310 && (GET_CODE (operands[0]) != MEM
19311 || !memory_displacement_operand (operands[0], QImode)))
19312 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19313 [(parallel [(set (match_dup 0)
19314 (xor:QI (match_dup 1) (const_int -1)))
19315 (clobber (reg:CC FLAGS_REG))])]
19318 ;; Non pairable "test imm, reg" instructions can be translated to
19319 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19320 ;; byte opcode instead of two, have a short form for byte operands),
19321 ;; so do it for other CPUs as well. Given that the value was dead,
19322 ;; this should not create any new dependencies. Pass on the sub-word
19323 ;; versions if we're concerned about partial register stalls.
19326 [(set (match_operand 0 "flags_reg_operand" "")
19327 (match_operator 1 "compare_operator"
19328 [(and:SI (match_operand:SI 2 "register_operand" "")
19329 (match_operand:SI 3 "immediate_operand" ""))
19331 "ix86_match_ccmode (insn, CCNOmode)
19332 && (true_regnum (operands[2]) != 0
19333 || (GET_CODE (operands[3]) == CONST_INT
19334 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19335 && peep2_reg_dead_p (1, operands[2])"
19337 [(set (match_dup 0)
19338 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19341 (and:SI (match_dup 2) (match_dup 3)))])]
19344 ;; We don't need to handle HImode case, because it will be promoted to SImode
19345 ;; on ! TARGET_PARTIAL_REG_STALL
19348 [(set (match_operand 0 "flags_reg_operand" "")
19349 (match_operator 1 "compare_operator"
19350 [(and:QI (match_operand:QI 2 "register_operand" "")
19351 (match_operand:QI 3 "immediate_operand" ""))
19353 "! TARGET_PARTIAL_REG_STALL
19354 && ix86_match_ccmode (insn, CCNOmode)
19355 && true_regnum (operands[2]) != 0
19356 && peep2_reg_dead_p (1, operands[2])"
19358 [(set (match_dup 0)
19359 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19362 (and:QI (match_dup 2) (match_dup 3)))])]
19366 [(set (match_operand 0 "flags_reg_operand" "")
19367 (match_operator 1 "compare_operator"
19370 (match_operand 2 "ext_register_operand" "")
19373 (match_operand 3 "const_int_operand" ""))
19375 "! TARGET_PARTIAL_REG_STALL
19376 && ix86_match_ccmode (insn, CCNOmode)
19377 && true_regnum (operands[2]) != 0
19378 && peep2_reg_dead_p (1, operands[2])"
19379 [(parallel [(set (match_dup 0)
19388 (set (zero_extract:SI (match_dup 2)
19399 ;; Don't do logical operations with memory inputs.
19401 [(match_scratch:SI 2 "r")
19402 (parallel [(set (match_operand:SI 0 "register_operand" "")
19403 (match_operator:SI 3 "arith_or_logical_operator"
19405 (match_operand:SI 1 "memory_operand" "")]))
19406 (clobber (reg:CC FLAGS_REG))])]
19407 "! optimize_size && ! TARGET_READ_MODIFY"
19408 [(set (match_dup 2) (match_dup 1))
19409 (parallel [(set (match_dup 0)
19410 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19411 (clobber (reg:CC FLAGS_REG))])]
19415 [(match_scratch:SI 2 "r")
19416 (parallel [(set (match_operand:SI 0 "register_operand" "")
19417 (match_operator:SI 3 "arith_or_logical_operator"
19418 [(match_operand:SI 1 "memory_operand" "")
19420 (clobber (reg:CC FLAGS_REG))])]
19421 "! optimize_size && ! TARGET_READ_MODIFY"
19422 [(set (match_dup 2) (match_dup 1))
19423 (parallel [(set (match_dup 0)
19424 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19425 (clobber (reg:CC FLAGS_REG))])]
19428 ; Don't do logical operations with memory outputs
19430 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19431 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19432 ; the same decoder scheduling characteristics as the original.
19435 [(match_scratch:SI 2 "r")
19436 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19437 (match_operator:SI 3 "arith_or_logical_operator"
19439 (match_operand:SI 1 "nonmemory_operand" "")]))
19440 (clobber (reg:CC FLAGS_REG))])]
19441 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19442 [(set (match_dup 2) (match_dup 0))
19443 (parallel [(set (match_dup 2)
19444 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19445 (clobber (reg:CC FLAGS_REG))])
19446 (set (match_dup 0) (match_dup 2))]
19450 [(match_scratch:SI 2 "r")
19451 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19452 (match_operator:SI 3 "arith_or_logical_operator"
19453 [(match_operand:SI 1 "nonmemory_operand" "")
19455 (clobber (reg:CC FLAGS_REG))])]
19456 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19457 [(set (match_dup 2) (match_dup 0))
19458 (parallel [(set (match_dup 2)
19459 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19460 (clobber (reg:CC FLAGS_REG))])
19461 (set (match_dup 0) (match_dup 2))]
19464 ;; Attempt to always use XOR for zeroing registers.
19466 [(set (match_operand 0 "register_operand" "")
19467 (match_operand 1 "const0_operand" ""))]
19468 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19469 && (! TARGET_USE_MOV0 || optimize_size)
19470 && GENERAL_REG_P (operands[0])
19471 && peep2_regno_dead_p (0, FLAGS_REG)"
19472 [(parallel [(set (match_dup 0) (const_int 0))
19473 (clobber (reg:CC FLAGS_REG))])]
19475 operands[0] = gen_lowpart (word_mode, operands[0]);
19479 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19481 "(GET_MODE (operands[0]) == QImode
19482 || GET_MODE (operands[0]) == HImode)
19483 && (! TARGET_USE_MOV0 || optimize_size)
19484 && peep2_regno_dead_p (0, FLAGS_REG)"
19485 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19486 (clobber (reg:CC FLAGS_REG))])])
19488 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19490 [(set (match_operand 0 "register_operand" "")
19492 "(GET_MODE (operands[0]) == HImode
19493 || GET_MODE (operands[0]) == SImode
19494 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19495 && (optimize_size || TARGET_PENTIUM)
19496 && peep2_regno_dead_p (0, FLAGS_REG)"
19497 [(parallel [(set (match_dup 0) (const_int -1))
19498 (clobber (reg:CC FLAGS_REG))])]
19499 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19502 ;; Attempt to convert simple leas to adds. These can be created by
19505 [(set (match_operand:SI 0 "register_operand" "")
19506 (plus:SI (match_dup 0)
19507 (match_operand:SI 1 "nonmemory_operand" "")))]
19508 "peep2_regno_dead_p (0, FLAGS_REG)"
19509 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19510 (clobber (reg:CC FLAGS_REG))])]
19514 [(set (match_operand:SI 0 "register_operand" "")
19515 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19516 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19517 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19518 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19519 (clobber (reg:CC FLAGS_REG))])]
19520 "operands[2] = gen_lowpart (SImode, operands[2]);")
19523 [(set (match_operand:DI 0 "register_operand" "")
19524 (plus:DI (match_dup 0)
19525 (match_operand:DI 1 "x86_64_general_operand" "")))]
19526 "peep2_regno_dead_p (0, FLAGS_REG)"
19527 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19528 (clobber (reg:CC FLAGS_REG))])]
19532 [(set (match_operand:SI 0 "register_operand" "")
19533 (mult:SI (match_dup 0)
19534 (match_operand:SI 1 "const_int_operand" "")))]
19535 "exact_log2 (INTVAL (operands[1])) >= 0
19536 && peep2_regno_dead_p (0, FLAGS_REG)"
19537 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19538 (clobber (reg:CC FLAGS_REG))])]
19539 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19542 [(set (match_operand:DI 0 "register_operand" "")
19543 (mult:DI (match_dup 0)
19544 (match_operand:DI 1 "const_int_operand" "")))]
19545 "exact_log2 (INTVAL (operands[1])) >= 0
19546 && peep2_regno_dead_p (0, FLAGS_REG)"
19547 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19548 (clobber (reg:CC FLAGS_REG))])]
19549 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19552 [(set (match_operand:SI 0 "register_operand" "")
19553 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19554 (match_operand:DI 2 "const_int_operand" "")) 0))]
19555 "exact_log2 (INTVAL (operands[2])) >= 0
19556 && REGNO (operands[0]) == REGNO (operands[1])
19557 && peep2_regno_dead_p (0, FLAGS_REG)"
19558 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19559 (clobber (reg:CC FLAGS_REG))])]
19560 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19562 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19563 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19564 ;; many CPUs it is also faster, since special hardware to avoid esp
19565 ;; dependencies is present.
19567 ;; While some of these conversions may be done using splitters, we use peepholes
19568 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19570 ;; Convert prologue esp subtractions to push.
19571 ;; We need register to push. In order to keep verify_flow_info happy we have
19573 ;; - use scratch and clobber it in order to avoid dependencies
19574 ;; - use already live register
19575 ;; We can't use the second way right now, since there is no reliable way how to
19576 ;; verify that given register is live. First choice will also most likely in
19577 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19578 ;; call clobbered registers are dead. We may want to use base pointer as an
19579 ;; alternative when no register is available later.
19582 [(match_scratch:SI 0 "r")
19583 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19584 (clobber (reg:CC FLAGS_REG))
19585 (clobber (mem:BLK (scratch)))])]
19586 "optimize_size || !TARGET_SUB_ESP_4"
19587 [(clobber (match_dup 0))
19588 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19589 (clobber (mem:BLK (scratch)))])])
19592 [(match_scratch:SI 0 "r")
19593 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19594 (clobber (reg:CC FLAGS_REG))
19595 (clobber (mem:BLK (scratch)))])]
19596 "optimize_size || !TARGET_SUB_ESP_8"
19597 [(clobber (match_dup 0))
19598 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19599 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19600 (clobber (mem:BLK (scratch)))])])
19602 ;; Convert esp subtractions to push.
19604 [(match_scratch:SI 0 "r")
19605 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19606 (clobber (reg:CC FLAGS_REG))])]
19607 "optimize_size || !TARGET_SUB_ESP_4"
19608 [(clobber (match_dup 0))
19609 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19612 [(match_scratch:SI 0 "r")
19613 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19614 (clobber (reg:CC FLAGS_REG))])]
19615 "optimize_size || !TARGET_SUB_ESP_8"
19616 [(clobber (match_dup 0))
19617 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19618 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19620 ;; Convert epilogue deallocator to pop.
19622 [(match_scratch:SI 0 "r")
19623 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19624 (clobber (reg:CC FLAGS_REG))
19625 (clobber (mem:BLK (scratch)))])]
19626 "optimize_size || !TARGET_ADD_ESP_4"
19627 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19628 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19629 (clobber (mem:BLK (scratch)))])]
19632 ;; Two pops case is tricky, since pop causes dependency on destination register.
19633 ;; We use two registers if available.
19635 [(match_scratch:SI 0 "r")
19636 (match_scratch:SI 1 "r")
19637 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19638 (clobber (reg:CC FLAGS_REG))
19639 (clobber (mem:BLK (scratch)))])]
19640 "optimize_size || !TARGET_ADD_ESP_8"
19641 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19642 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19643 (clobber (mem:BLK (scratch)))])
19644 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19645 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19649 [(match_scratch:SI 0 "r")
19650 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19651 (clobber (reg:CC FLAGS_REG))
19652 (clobber (mem:BLK (scratch)))])]
19654 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19655 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19656 (clobber (mem:BLK (scratch)))])
19657 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19658 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19661 ;; Convert esp additions to pop.
19663 [(match_scratch:SI 0 "r")
19664 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19665 (clobber (reg:CC FLAGS_REG))])]
19667 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19668 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19671 ;; Two pops case is tricky, since pop causes dependency on destination register.
19672 ;; We use two registers if available.
19674 [(match_scratch:SI 0 "r")
19675 (match_scratch:SI 1 "r")
19676 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19677 (clobber (reg:CC FLAGS_REG))])]
19679 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19680 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19681 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19682 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19686 [(match_scratch:SI 0 "r")
19687 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19688 (clobber (reg:CC FLAGS_REG))])]
19690 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19691 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19692 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19693 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19696 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19697 ;; required and register dies. Similarly for 128 to plus -128.
19699 [(set (match_operand 0 "flags_reg_operand" "")
19700 (match_operator 1 "compare_operator"
19701 [(match_operand 2 "register_operand" "")
19702 (match_operand 3 "const_int_operand" "")]))]
19703 "(INTVAL (operands[3]) == -1
19704 || INTVAL (operands[3]) == 1
19705 || INTVAL (operands[3]) == 128)
19706 && ix86_match_ccmode (insn, CCGCmode)
19707 && peep2_reg_dead_p (1, operands[2])"
19708 [(parallel [(set (match_dup 0)
19709 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19710 (clobber (match_dup 2))])]
19714 [(match_scratch:DI 0 "r")
19715 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19716 (clobber (reg:CC FLAGS_REG))
19717 (clobber (mem:BLK (scratch)))])]
19718 "optimize_size || !TARGET_SUB_ESP_4"
19719 [(clobber (match_dup 0))
19720 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19721 (clobber (mem:BLK (scratch)))])])
19724 [(match_scratch:DI 0 "r")
19725 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19726 (clobber (reg:CC FLAGS_REG))
19727 (clobber (mem:BLK (scratch)))])]
19728 "optimize_size || !TARGET_SUB_ESP_8"
19729 [(clobber (match_dup 0))
19730 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19731 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19732 (clobber (mem:BLK (scratch)))])])
19734 ;; Convert esp subtractions to push.
19736 [(match_scratch:DI 0 "r")
19737 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19738 (clobber (reg:CC FLAGS_REG))])]
19739 "optimize_size || !TARGET_SUB_ESP_4"
19740 [(clobber (match_dup 0))
19741 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19744 [(match_scratch:DI 0 "r")
19745 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19746 (clobber (reg:CC FLAGS_REG))])]
19747 "optimize_size || !TARGET_SUB_ESP_8"
19748 [(clobber (match_dup 0))
19749 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19750 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19752 ;; Convert epilogue deallocator to pop.
19754 [(match_scratch:DI 0 "r")
19755 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19756 (clobber (reg:CC FLAGS_REG))
19757 (clobber (mem:BLK (scratch)))])]
19758 "optimize_size || !TARGET_ADD_ESP_4"
19759 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19760 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19761 (clobber (mem:BLK (scratch)))])]
19764 ;; Two pops case is tricky, since pop causes dependency on destination register.
19765 ;; We use two registers if available.
19767 [(match_scratch:DI 0 "r")
19768 (match_scratch:DI 1 "r")
19769 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19770 (clobber (reg:CC FLAGS_REG))
19771 (clobber (mem:BLK (scratch)))])]
19772 "optimize_size || !TARGET_ADD_ESP_8"
19773 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19774 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19775 (clobber (mem:BLK (scratch)))])
19776 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19777 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19781 [(match_scratch:DI 0 "r")
19782 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19783 (clobber (reg:CC FLAGS_REG))
19784 (clobber (mem:BLK (scratch)))])]
19786 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19787 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19788 (clobber (mem:BLK (scratch)))])
19789 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19790 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19793 ;; Convert esp additions to pop.
19795 [(match_scratch:DI 0 "r")
19796 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19797 (clobber (reg:CC FLAGS_REG))])]
19799 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19800 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19803 ;; Two pops case is tricky, since pop causes dependency on destination register.
19804 ;; We use two registers if available.
19806 [(match_scratch:DI 0 "r")
19807 (match_scratch:DI 1 "r")
19808 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19809 (clobber (reg:CC FLAGS_REG))])]
19811 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19812 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19813 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19814 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19818 [(match_scratch:DI 0 "r")
19819 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19820 (clobber (reg:CC FLAGS_REG))])]
19822 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19823 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19824 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19825 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19828 ;; Convert imul by three, five and nine into lea
19831 [(set (match_operand:SI 0 "register_operand" "")
19832 (mult:SI (match_operand:SI 1 "register_operand" "")
19833 (match_operand:SI 2 "const_int_operand" "")))
19834 (clobber (reg:CC FLAGS_REG))])]
19835 "INTVAL (operands[2]) == 3
19836 || INTVAL (operands[2]) == 5
19837 || INTVAL (operands[2]) == 9"
19838 [(set (match_dup 0)
19839 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19841 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19845 [(set (match_operand:SI 0 "register_operand" "")
19846 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19847 (match_operand:SI 2 "const_int_operand" "")))
19848 (clobber (reg:CC FLAGS_REG))])]
19850 && (INTVAL (operands[2]) == 3
19851 || INTVAL (operands[2]) == 5
19852 || INTVAL (operands[2]) == 9)"
19853 [(set (match_dup 0) (match_dup 1))
19855 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19857 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19861 [(set (match_operand:DI 0 "register_operand" "")
19862 (mult:DI (match_operand:DI 1 "register_operand" "")
19863 (match_operand:DI 2 "const_int_operand" "")))
19864 (clobber (reg:CC FLAGS_REG))])]
19866 && (INTVAL (operands[2]) == 3
19867 || INTVAL (operands[2]) == 5
19868 || INTVAL (operands[2]) == 9)"
19869 [(set (match_dup 0)
19870 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19872 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19876 [(set (match_operand:DI 0 "register_operand" "")
19877 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19878 (match_operand:DI 2 "const_int_operand" "")))
19879 (clobber (reg:CC FLAGS_REG))])]
19882 && (INTVAL (operands[2]) == 3
19883 || INTVAL (operands[2]) == 5
19884 || INTVAL (operands[2]) == 9)"
19885 [(set (match_dup 0) (match_dup 1))
19887 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19889 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19891 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19892 ;; imul $32bit_imm, reg, reg is direct decoded.
19894 [(match_scratch:DI 3 "r")
19895 (parallel [(set (match_operand:DI 0 "register_operand" "")
19896 (mult:DI (match_operand:DI 1 "memory_operand" "")
19897 (match_operand:DI 2 "immediate_operand" "")))
19898 (clobber (reg:CC FLAGS_REG))])]
19899 "TARGET_K8 && !optimize_size
19900 && (GET_CODE (operands[2]) != CONST_INT
19901 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19902 [(set (match_dup 3) (match_dup 1))
19903 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19904 (clobber (reg:CC FLAGS_REG))])]
19908 [(match_scratch:SI 3 "r")
19909 (parallel [(set (match_operand:SI 0 "register_operand" "")
19910 (mult:SI (match_operand:SI 1 "memory_operand" "")
19911 (match_operand:SI 2 "immediate_operand" "")))
19912 (clobber (reg:CC FLAGS_REG))])]
19913 "TARGET_K8 && !optimize_size
19914 && (GET_CODE (operands[2]) != CONST_INT
19915 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19916 [(set (match_dup 3) (match_dup 1))
19917 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19918 (clobber (reg:CC FLAGS_REG))])]
19922 [(match_scratch:SI 3 "r")
19923 (parallel [(set (match_operand:DI 0 "register_operand" "")
19925 (mult:SI (match_operand:SI 1 "memory_operand" "")
19926 (match_operand:SI 2 "immediate_operand" ""))))
19927 (clobber (reg:CC FLAGS_REG))])]
19928 "TARGET_K8 && !optimize_size
19929 && (GET_CODE (operands[2]) != CONST_INT
19930 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19931 [(set (match_dup 3) (match_dup 1))
19932 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19933 (clobber (reg:CC FLAGS_REG))])]
19936 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19937 ;; Convert it into imul reg, reg
19938 ;; It would be better to force assembler to encode instruction using long
19939 ;; immediate, but there is apparently no way to do so.
19941 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19942 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19943 (match_operand:DI 2 "const_int_operand" "")))
19944 (clobber (reg:CC FLAGS_REG))])
19945 (match_scratch:DI 3 "r")]
19946 "TARGET_K8 && !optimize_size
19947 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19948 [(set (match_dup 3) (match_dup 2))
19949 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19950 (clobber (reg:CC FLAGS_REG))])]
19952 if (!rtx_equal_p (operands[0], operands[1]))
19953 emit_move_insn (operands[0], operands[1]);
19957 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19958 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19959 (match_operand:SI 2 "const_int_operand" "")))
19960 (clobber (reg:CC FLAGS_REG))])
19961 (match_scratch:SI 3 "r")]
19962 "TARGET_K8 && !optimize_size
19963 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19964 [(set (match_dup 3) (match_dup 2))
19965 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19966 (clobber (reg:CC FLAGS_REG))])]
19968 if (!rtx_equal_p (operands[0], operands[1]))
19969 emit_move_insn (operands[0], operands[1]);
19973 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19974 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19975 (match_operand:HI 2 "immediate_operand" "")))
19976 (clobber (reg:CC FLAGS_REG))])
19977 (match_scratch:HI 3 "r")]
19978 "TARGET_K8 && !optimize_size"
19979 [(set (match_dup 3) (match_dup 2))
19980 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19981 (clobber (reg:CC FLAGS_REG))])]
19983 if (!rtx_equal_p (operands[0], operands[1]))
19984 emit_move_insn (operands[0], operands[1]);
19987 ;; After splitting up read-modify operations, array accesses with memory
19988 ;; operands might end up in form:
19990 ;; movl 4(%esp), %edx
19992 ;; instead of pre-splitting:
19994 ;; addl 4(%esp), %eax
19996 ;; movl 4(%esp), %edx
19997 ;; leal (%edx,%eax,4), %eax
20000 [(parallel [(set (match_operand 0 "register_operand" "")
20001 (ashift (match_operand 1 "register_operand" "")
20002 (match_operand 2 "const_int_operand" "")))
20003 (clobber (reg:CC FLAGS_REG))])
20004 (set (match_operand 3 "register_operand")
20005 (match_operand 4 "x86_64_general_operand" ""))
20006 (parallel [(set (match_operand 5 "register_operand" "")
20007 (plus (match_operand 6 "register_operand" "")
20008 (match_operand 7 "register_operand" "")))
20009 (clobber (reg:CC FLAGS_REG))])]
20010 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20011 /* Validate MODE for lea. */
20012 && ((!TARGET_PARTIAL_REG_STALL
20013 && (GET_MODE (operands[0]) == QImode
20014 || GET_MODE (operands[0]) == HImode))
20015 || GET_MODE (operands[0]) == SImode
20016 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20017 /* We reorder load and the shift. */
20018 && !rtx_equal_p (operands[1], operands[3])
20019 && !reg_overlap_mentioned_p (operands[0], operands[4])
20020 /* Last PLUS must consist of operand 0 and 3. */
20021 && !rtx_equal_p (operands[0], operands[3])
20022 && (rtx_equal_p (operands[3], operands[6])
20023 || rtx_equal_p (operands[3], operands[7]))
20024 && (rtx_equal_p (operands[0], operands[6])
20025 || rtx_equal_p (operands[0], operands[7]))
20026 /* The intermediate operand 0 must die or be same as output. */
20027 && (rtx_equal_p (operands[0], operands[5])
20028 || peep2_reg_dead_p (3, operands[0]))"
20029 [(set (match_dup 3) (match_dup 4))
20030 (set (match_dup 0) (match_dup 1))]
20032 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20033 int scale = 1 << INTVAL (operands[2]);
20034 rtx index = gen_lowpart (Pmode, operands[1]);
20035 rtx base = gen_lowpart (Pmode, operands[3]);
20036 rtx dest = gen_lowpart (mode, operands[5]);
20038 operands[1] = gen_rtx_PLUS (Pmode, base,
20039 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20041 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20042 operands[0] = dest;
20045 ;; Call-value patterns last so that the wildcard operand does not
20046 ;; disrupt insn-recog's switch tables.
20048 (define_insn "*call_value_pop_0"
20049 [(set (match_operand 0 "" "")
20050 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20051 (match_operand:SI 2 "" "")))
20052 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20053 (match_operand:SI 3 "immediate_operand" "")))]
20056 if (SIBLING_CALL_P (insn))
20059 return "call\t%P1";
20061 [(set_attr "type" "callv")])
20063 (define_insn "*call_value_pop_1"
20064 [(set (match_operand 0 "" "")
20065 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20066 (match_operand:SI 2 "" "")))
20067 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20068 (match_operand:SI 3 "immediate_operand" "i")))]
20071 if (constant_call_address_operand (operands[1], Pmode))
20073 if (SIBLING_CALL_P (insn))
20076 return "call\t%P1";
20078 if (SIBLING_CALL_P (insn))
20081 return "call\t%A1";
20083 [(set_attr "type" "callv")])
20085 (define_insn "*call_value_0"
20086 [(set (match_operand 0 "" "")
20087 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20088 (match_operand:SI 2 "" "")))]
20091 if (SIBLING_CALL_P (insn))
20094 return "call\t%P1";
20096 [(set_attr "type" "callv")])
20098 (define_insn "*call_value_0_rex64"
20099 [(set (match_operand 0 "" "")
20100 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20101 (match_operand:DI 2 "const_int_operand" "")))]
20104 if (SIBLING_CALL_P (insn))
20107 return "call\t%P1";
20109 [(set_attr "type" "callv")])
20111 (define_insn "*call_value_1"
20112 [(set (match_operand 0 "" "")
20113 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20114 (match_operand:SI 2 "" "")))]
20115 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20117 if (constant_call_address_operand (operands[1], Pmode))
20118 return "call\t%P1";
20119 return "call\t%A1";
20121 [(set_attr "type" "callv")])
20123 (define_insn "*sibcall_value_1"
20124 [(set (match_operand 0 "" "")
20125 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20126 (match_operand:SI 2 "" "")))]
20127 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20129 if (constant_call_address_operand (operands[1], Pmode))
20133 [(set_attr "type" "callv")])
20135 (define_insn "*call_value_1_rex64"
20136 [(set (match_operand 0 "" "")
20137 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20138 (match_operand:DI 2 "" "")))]
20139 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20141 if (constant_call_address_operand (operands[1], Pmode))
20142 return "call\t%P1";
20143 return "call\t%A1";
20145 [(set_attr "type" "callv")])
20147 (define_insn "*sibcall_value_1_rex64"
20148 [(set (match_operand 0 "" "")
20149 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20150 (match_operand:DI 2 "" "")))]
20151 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20153 [(set_attr "type" "callv")])
20155 (define_insn "*sibcall_value_1_rex64_v"
20156 [(set (match_operand 0 "" "")
20157 (call (mem:QI (reg:DI 40))
20158 (match_operand:DI 1 "" "")))]
20159 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20161 [(set_attr "type" "callv")])
20163 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20164 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20165 ;; caught for use by garbage collectors and the like. Using an insn that
20166 ;; maps to SIGILL makes it more likely the program will rightfully die.
20167 ;; Keeping with tradition, "6" is in honor of #UD.
20168 (define_insn "trap"
20169 [(trap_if (const_int 1) (const_int 6))]
20172 [(set_attr "length" "2")])
20174 (define_expand "sse_prologue_save"
20175 [(parallel [(set (match_operand:BLK 0 "" "")
20176 (unspec:BLK [(reg:DI 21)
20183 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20184 (use (match_operand:DI 1 "register_operand" ""))
20185 (use (match_operand:DI 2 "immediate_operand" ""))
20186 (use (label_ref:DI (match_operand 3 "" "")))])]
20190 (define_insn "*sse_prologue_save_insn"
20191 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20192 (match_operand:DI 4 "const_int_operand" "n")))
20193 (unspec:BLK [(reg:DI 21)
20200 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20201 (use (match_operand:DI 1 "register_operand" "r"))
20202 (use (match_operand:DI 2 "const_int_operand" "i"))
20203 (use (label_ref:DI (match_operand 3 "" "X")))]
20205 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20206 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20210 operands[0] = gen_rtx_MEM (Pmode,
20211 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20212 output_asm_insn (\"jmp\\t%A1\", operands);
20213 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20215 operands[4] = adjust_address (operands[0], DImode, i*16);
20216 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20217 PUT_MODE (operands[4], TImode);
20218 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20219 output_asm_insn (\"rex\", operands);
20220 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20222 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20223 CODE_LABEL_NUMBER (operands[3]));
20227 [(set_attr "type" "other")
20228 (set_attr "length_immediate" "0")
20229 (set_attr "length_address" "0")
20230 (set_attr "length" "135")
20231 (set_attr "memory" "store")
20232 (set_attr "modrm" "0")
20233 (set_attr "mode" "DI")])
20235 (define_expand "prefetch"
20236 [(prefetch (match_operand 0 "address_operand" "")
20237 (match_operand:SI 1 "const_int_operand" "")
20238 (match_operand:SI 2 "const_int_operand" ""))]
20239 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20241 int rw = INTVAL (operands[1]);
20242 int locality = INTVAL (operands[2]);
20244 gcc_assert (rw == 0 || rw == 1);
20245 gcc_assert (locality >= 0 && locality <= 3);
20246 gcc_assert (GET_MODE (operands[0]) == Pmode
20247 || GET_MODE (operands[0]) == VOIDmode);
20249 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20250 supported by SSE counterpart or the SSE prefetch is not available
20251 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20253 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20254 operands[2] = GEN_INT (3);
20256 operands[1] = const0_rtx;
20259 (define_insn "*prefetch_sse"
20260 [(prefetch (match_operand:SI 0 "address_operand" "p")
20262 (match_operand:SI 1 "const_int_operand" ""))]
20263 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20265 static const char * const patterns[4] = {
20266 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20269 int locality = INTVAL (operands[1]);
20270 gcc_assert (locality >= 0 && locality <= 3);
20272 return patterns[locality];
20274 [(set_attr "type" "sse")
20275 (set_attr "memory" "none")])
20277 (define_insn "*prefetch_sse_rex"
20278 [(prefetch (match_operand:DI 0 "address_operand" "p")
20280 (match_operand:SI 1 "const_int_operand" ""))]
20281 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20283 static const char * const patterns[4] = {
20284 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20287 int locality = INTVAL (operands[1]);
20288 gcc_assert (locality >= 0 && locality <= 3);
20290 return patterns[locality];
20292 [(set_attr "type" "sse")
20293 (set_attr "memory" "none")])
20295 (define_insn "*prefetch_3dnow"
20296 [(prefetch (match_operand:SI 0 "address_operand" "p")
20297 (match_operand:SI 1 "const_int_operand" "n")
20299 "TARGET_3DNOW && !TARGET_64BIT"
20301 if (INTVAL (operands[1]) == 0)
20302 return "prefetch\t%a0";
20304 return "prefetchw\t%a0";
20306 [(set_attr "type" "mmx")
20307 (set_attr "memory" "none")])
20309 (define_insn "*prefetch_3dnow_rex"
20310 [(prefetch (match_operand:DI 0 "address_operand" "p")
20311 (match_operand:SI 1 "const_int_operand" "n")
20313 "TARGET_3DNOW && TARGET_64BIT"
20315 if (INTVAL (operands[1]) == 0)
20316 return "prefetch\t%a0";
20318 return "prefetchw\t%a0";
20320 [(set_attr "type" "mmx")
20321 (set_attr "memory" "none")])
20323 (define_expand "stack_protect_set"
20324 [(match_operand 0 "memory_operand" "")
20325 (match_operand 1 "memory_operand" "")]
20328 #ifdef TARGET_THREAD_SSP_OFFSET
20330 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20331 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20333 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20334 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20337 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20339 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20344 (define_insn "stack_protect_set_si"
20345 [(set (match_operand:SI 0 "memory_operand" "=m")
20346 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20347 (set (match_scratch:SI 2 "=&r") (const_int 0))
20348 (clobber (reg:CC FLAGS_REG))]
20350 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20351 [(set_attr "type" "multi")])
20353 (define_insn "stack_protect_set_di"
20354 [(set (match_operand:DI 0 "memory_operand" "=m")
20355 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20356 (set (match_scratch:DI 2 "=&r") (const_int 0))
20357 (clobber (reg:CC FLAGS_REG))]
20359 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20360 [(set_attr "type" "multi")])
20362 (define_insn "stack_tls_protect_set_si"
20363 [(set (match_operand:SI 0 "memory_operand" "=m")
20364 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20365 (set (match_scratch:SI 2 "=&r") (const_int 0))
20366 (clobber (reg:CC FLAGS_REG))]
20368 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20369 [(set_attr "type" "multi")])
20371 (define_insn "stack_tls_protect_set_di"
20372 [(set (match_operand:DI 0 "memory_operand" "=m")
20373 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20374 (set (match_scratch:DI 2 "=&r") (const_int 0))
20375 (clobber (reg:CC FLAGS_REG))]
20377 "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20378 [(set_attr "type" "multi")])
20380 (define_expand "stack_protect_test"
20381 [(match_operand 0 "memory_operand" "")
20382 (match_operand 1 "memory_operand" "")
20383 (match_operand 2 "" "")]
20386 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20387 ix86_compare_op0 = operands[0];
20388 ix86_compare_op1 = operands[1];
20389 ix86_compare_emitted = flags;
20391 #ifdef TARGET_THREAD_SSP_OFFSET
20393 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20394 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20396 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20397 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20400 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20402 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20404 emit_jump_insn (gen_beq (operands[2]));
20408 (define_insn "stack_protect_test_si"
20409 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20410 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20411 (match_operand:SI 2 "memory_operand" "m")]
20413 (clobber (match_scratch:SI 3 "=&r"))]
20415 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20416 [(set_attr "type" "multi")])
20418 (define_insn "stack_protect_test_di"
20419 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20420 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20421 (match_operand:DI 2 "memory_operand" "m")]
20423 (clobber (match_scratch:DI 3 "=&r"))]
20425 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20426 [(set_attr "type" "multi")])
20428 (define_insn "stack_tls_protect_test_si"
20429 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20430 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20431 (match_operand:SI 2 "const_int_operand" "i")]
20432 UNSPEC_SP_TLS_TEST))
20433 (clobber (match_scratch:SI 3 "=r"))]
20435 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20436 [(set_attr "type" "multi")])
20438 (define_insn "stack_tls_protect_test_di"
20439 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20440 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20441 (match_operand:DI 2 "const_int_operand" "i")]
20442 UNSPEC_SP_TLS_TEST))
20443 (clobber (match_scratch:DI 3 "=r"))]
20445 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20446 [(set_attr "type" "multi")])
20450 (include "sync.md")