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,generic32,generic64"
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 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1516 (and (eq (symbol_ref "optimize_size")
1518 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1521 ;; Avoid partial register stalls when not using QImode arithmetic
1522 (and (eq_attr "type" "imov")
1523 (and (eq_attr "alternative" "0,1")
1524 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1526 (eq (symbol_ref "TARGET_QIMODE_MATH")
1530 (const_string "QI")))])
1532 (define_expand "reload_outqi"
1533 [(parallel [(match_operand:QI 0 "" "=m")
1534 (match_operand:QI 1 "register_operand" "r")
1535 (match_operand:QI 2 "register_operand" "=&q")])]
1539 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1541 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1542 if (! q_regs_operand (op1, QImode))
1544 emit_insn (gen_movqi (op2, op1));
1547 emit_insn (gen_movqi (op0, op1));
1551 (define_insn "*swapqi_1"
1552 [(set (match_operand:QI 0 "register_operand" "+r")
1553 (match_operand:QI 1 "register_operand" "+r"))
1556 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1558 [(set_attr "type" "imov")
1559 (set_attr "mode" "SI")
1560 (set_attr "pent_pair" "np")
1561 (set_attr "athlon_decode" "vector")])
1563 (define_insn "*swapqi_2"
1564 [(set (match_operand:QI 0 "register_operand" "+q")
1565 (match_operand:QI 1 "register_operand" "+q"))
1568 "TARGET_PARTIAL_REG_STALL"
1570 [(set_attr "type" "imov")
1571 (set_attr "mode" "QI")
1572 (set_attr "pent_pair" "np")
1573 (set_attr "athlon_decode" "vector")])
1575 (define_expand "movstrictqi"
1576 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1577 (match_operand:QI 1 "general_operand" ""))]
1578 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1580 /* Don't generate memory->memory moves, go through a register. */
1581 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1582 operands[1] = force_reg (QImode, operands[1]);
1585 (define_insn "*movstrictqi_1"
1586 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1587 (match_operand:QI 1 "general_operand" "*qn,m"))]
1588 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1589 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1590 "mov{b}\t{%1, %0|%0, %1}"
1591 [(set_attr "type" "imov")
1592 (set_attr "mode" "QI")])
1594 (define_insn "*movstrictqi_xor"
1595 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1596 (match_operand:QI 1 "const0_operand" "i"))
1597 (clobber (reg:CC FLAGS_REG))]
1598 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1599 "xor{b}\t{%0, %0|%0, %0}"
1600 [(set_attr "type" "alu1")
1601 (set_attr "mode" "QI")
1602 (set_attr "length_immediate" "0")])
1604 (define_insn "*movsi_extv_1"
1605 [(set (match_operand:SI 0 "register_operand" "=R")
1606 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1610 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1611 [(set_attr "type" "imovx")
1612 (set_attr "mode" "SI")])
1614 (define_insn "*movhi_extv_1"
1615 [(set (match_operand:HI 0 "register_operand" "=R")
1616 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1620 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1621 [(set_attr "type" "imovx")
1622 (set_attr "mode" "SI")])
1624 (define_insn "*movqi_extv_1"
1625 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1626 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1631 switch (get_attr_type (insn))
1634 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1636 return "mov{b}\t{%h1, %0|%0, %h1}";
1640 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1641 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1642 (ne (symbol_ref "TARGET_MOVX")
1644 (const_string "imovx")
1645 (const_string "imov")))
1647 (if_then_else (eq_attr "type" "imovx")
1649 (const_string "QI")))])
1651 (define_insn "*movqi_extv_1_rex64"
1652 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1653 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1658 switch (get_attr_type (insn))
1661 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1663 return "mov{b}\t{%h1, %0|%0, %h1}";
1667 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1668 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1669 (ne (symbol_ref "TARGET_MOVX")
1671 (const_string "imovx")
1672 (const_string "imov")))
1674 (if_then_else (eq_attr "type" "imovx")
1676 (const_string "QI")))])
1678 ;; Stores and loads of ax to arbitrary constant address.
1679 ;; We fake an second form of instruction to force reload to load address
1680 ;; into register when rax is not available
1681 (define_insn "*movabsqi_1_rex64"
1682 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1683 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1684 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1686 movabs{b}\t{%1, %P0|%P0, %1}
1687 mov{b}\t{%1, %a0|%a0, %1}"
1688 [(set_attr "type" "imov")
1689 (set_attr "modrm" "0,*")
1690 (set_attr "length_address" "8,0")
1691 (set_attr "length_immediate" "0,*")
1692 (set_attr "memory" "store")
1693 (set_attr "mode" "QI")])
1695 (define_insn "*movabsqi_2_rex64"
1696 [(set (match_operand:QI 0 "register_operand" "=a,r")
1697 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1698 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1700 movabs{b}\t{%P1, %0|%0, %P1}
1701 mov{b}\t{%a1, %0|%0, %a1}"
1702 [(set_attr "type" "imov")
1703 (set_attr "modrm" "0,*")
1704 (set_attr "length_address" "8,0")
1705 (set_attr "length_immediate" "0")
1706 (set_attr "memory" "load")
1707 (set_attr "mode" "QI")])
1709 (define_insn "*movdi_extzv_1"
1710 [(set (match_operand:DI 0 "register_operand" "=R")
1711 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1715 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1716 [(set_attr "type" "imovx")
1717 (set_attr "mode" "DI")])
1719 (define_insn "*movsi_extzv_1"
1720 [(set (match_operand:SI 0 "register_operand" "=R")
1721 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1725 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1726 [(set_attr "type" "imovx")
1727 (set_attr "mode" "SI")])
1729 (define_insn "*movqi_extzv_2"
1730 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1731 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1736 switch (get_attr_type (insn))
1739 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1741 return "mov{b}\t{%h1, %0|%0, %h1}";
1745 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1746 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1747 (ne (symbol_ref "TARGET_MOVX")
1749 (const_string "imovx")
1750 (const_string "imov")))
1752 (if_then_else (eq_attr "type" "imovx")
1754 (const_string "QI")))])
1756 (define_insn "*movqi_extzv_2_rex64"
1757 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1758 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1763 switch (get_attr_type (insn))
1766 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1768 return "mov{b}\t{%h1, %0|%0, %h1}";
1772 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1773 (ne (symbol_ref "TARGET_MOVX")
1775 (const_string "imovx")
1776 (const_string "imov")))
1778 (if_then_else (eq_attr "type" "imovx")
1780 (const_string "QI")))])
1782 (define_insn "movsi_insv_1"
1783 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1786 (match_operand:SI 1 "general_operand" "Qmn"))]
1788 "mov{b}\t{%b1, %h0|%h0, %b1}"
1789 [(set_attr "type" "imov")
1790 (set_attr "mode" "QI")])
1792 (define_insn "movdi_insv_1_rex64"
1793 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1796 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1798 "mov{b}\t{%b1, %h0|%h0, %b1}"
1799 [(set_attr "type" "imov")
1800 (set_attr "mode" "QI")])
1802 (define_insn "*movqi_insv_2"
1803 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1806 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1809 "mov{b}\t{%h1, %h0|%h0, %h1}"
1810 [(set_attr "type" "imov")
1811 (set_attr "mode" "QI")])
1813 (define_expand "movdi"
1814 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1815 (match_operand:DI 1 "general_operand" ""))]
1817 "ix86_expand_move (DImode, operands); DONE;")
1819 (define_insn "*pushdi"
1820 [(set (match_operand:DI 0 "push_operand" "=<")
1821 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1825 (define_insn "*pushdi2_rex64"
1826 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1827 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1832 [(set_attr "type" "push,multi")
1833 (set_attr "mode" "DI")])
1835 ;; Convert impossible pushes of immediate to existing instructions.
1836 ;; First try to get scratch register and go through it. In case this
1837 ;; fails, push sign extended lower part first and then overwrite
1838 ;; upper part by 32bit move.
1840 [(match_scratch:DI 2 "r")
1841 (set (match_operand:DI 0 "push_operand" "")
1842 (match_operand:DI 1 "immediate_operand" ""))]
1843 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1844 && !x86_64_immediate_operand (operands[1], DImode)"
1845 [(set (match_dup 2) (match_dup 1))
1846 (set (match_dup 0) (match_dup 2))]
1849 ;; We need to define this as both peepholer and splitter for case
1850 ;; peephole2 pass is not run.
1851 ;; "&& 1" is needed to keep it from matching the previous pattern.
1853 [(set (match_operand:DI 0 "push_operand" "")
1854 (match_operand:DI 1 "immediate_operand" ""))]
1855 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1856 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1857 [(set (match_dup 0) (match_dup 1))
1858 (set (match_dup 2) (match_dup 3))]
1859 "split_di (operands + 1, 1, operands + 2, operands + 3);
1860 operands[1] = gen_lowpart (DImode, operands[2]);
1861 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1866 [(set (match_operand:DI 0 "push_operand" "")
1867 (match_operand:DI 1 "immediate_operand" ""))]
1868 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1869 ? flow2_completed : reload_completed)
1870 && !symbolic_operand (operands[1], DImode)
1871 && !x86_64_immediate_operand (operands[1], DImode)"
1872 [(set (match_dup 0) (match_dup 1))
1873 (set (match_dup 2) (match_dup 3))]
1874 "split_di (operands + 1, 1, operands + 2, operands + 3);
1875 operands[1] = gen_lowpart (DImode, operands[2]);
1876 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1880 (define_insn "*pushdi2_prologue_rex64"
1881 [(set (match_operand:DI 0 "push_operand" "=<")
1882 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1883 (clobber (mem:BLK (scratch)))]
1886 [(set_attr "type" "push")
1887 (set_attr "mode" "DI")])
1889 (define_insn "*popdi1_epilogue_rex64"
1890 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1891 (mem:DI (reg:DI SP_REG)))
1892 (set (reg:DI SP_REG)
1893 (plus:DI (reg:DI SP_REG) (const_int 8)))
1894 (clobber (mem:BLK (scratch)))]
1897 [(set_attr "type" "pop")
1898 (set_attr "mode" "DI")])
1900 (define_insn "popdi1"
1901 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1902 (mem:DI (reg:DI SP_REG)))
1903 (set (reg:DI SP_REG)
1904 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1907 [(set_attr "type" "pop")
1908 (set_attr "mode" "DI")])
1910 (define_insn "*movdi_xor_rex64"
1911 [(set (match_operand:DI 0 "register_operand" "=r")
1912 (match_operand:DI 1 "const0_operand" "i"))
1913 (clobber (reg:CC FLAGS_REG))]
1914 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1915 && reload_completed"
1916 "xor{l}\t{%k0, %k0|%k0, %k0}"
1917 [(set_attr "type" "alu1")
1918 (set_attr "mode" "SI")
1919 (set_attr "length_immediate" "0")])
1921 (define_insn "*movdi_or_rex64"
1922 [(set (match_operand:DI 0 "register_operand" "=r")
1923 (match_operand:DI 1 "const_int_operand" "i"))
1924 (clobber (reg:CC FLAGS_REG))]
1925 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1927 && operands[1] == constm1_rtx"
1929 operands[1] = constm1_rtx;
1930 return "or{q}\t{%1, %0|%0, %1}";
1932 [(set_attr "type" "alu1")
1933 (set_attr "mode" "DI")
1934 (set_attr "length_immediate" "1")])
1936 (define_insn "*movdi_2"
1937 [(set (match_operand:DI 0 "nonimmediate_operand"
1938 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1939 (match_operand:DI 1 "general_operand"
1940 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1941 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1946 movq\t{%1, %0|%0, %1}
1947 movq\t{%1, %0|%0, %1}
1949 movq\t{%1, %0|%0, %1}
1950 movdqa\t{%1, %0|%0, %1}
1951 movq\t{%1, %0|%0, %1}
1953 movlps\t{%1, %0|%0, %1}
1954 movaps\t{%1, %0|%0, %1}
1955 movlps\t{%1, %0|%0, %1}"
1956 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1957 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1960 [(set (match_operand:DI 0 "push_operand" "")
1961 (match_operand:DI 1 "general_operand" ""))]
1962 "!TARGET_64BIT && reload_completed
1963 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1965 "ix86_split_long_move (operands); DONE;")
1967 ;; %%% This multiword shite has got to go.
1969 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1970 (match_operand:DI 1 "general_operand" ""))]
1971 "!TARGET_64BIT && reload_completed
1972 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1973 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1975 "ix86_split_long_move (operands); DONE;")
1977 (define_insn "*movdi_1_rex64"
1978 [(set (match_operand:DI 0 "nonimmediate_operand"
1979 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1980 (match_operand:DI 1 "general_operand"
1981 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1982 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1984 switch (get_attr_type (insn))
1987 if (which_alternative == 13)
1988 return "movq2dq\t{%1, %0|%0, %1}";
1990 return "movdq2q\t{%1, %0|%0, %1}";
1992 if (get_attr_mode (insn) == MODE_TI)
1993 return "movdqa\t{%1, %0|%0, %1}";
1996 /* Moves from and into integer register is done using movd opcode with
1998 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1999 return "movd\t{%1, %0|%0, %1}";
2000 return "movq\t{%1, %0|%0, %1}";
2003 return "pxor\t%0, %0";
2007 return "lea{q}\t{%a1, %0|%0, %a1}";
2009 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2010 if (get_attr_mode (insn) == MODE_SI)
2011 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2012 else if (which_alternative == 2)
2013 return "movabs{q}\t{%1, %0|%0, %1}";
2015 return "mov{q}\t{%1, %0|%0, %1}";
2019 (cond [(eq_attr "alternative" "5")
2020 (const_string "mmxadd")
2021 (eq_attr "alternative" "6,7,8")
2022 (const_string "mmxmov")
2023 (eq_attr "alternative" "9")
2024 (const_string "sselog1")
2025 (eq_attr "alternative" "10,11,12")
2026 (const_string "ssemov")
2027 (eq_attr "alternative" "13,14")
2028 (const_string "ssecvt")
2029 (eq_attr "alternative" "4")
2030 (const_string "multi")
2031 (match_operand:DI 1 "pic_32bit_operand" "")
2032 (const_string "lea")
2034 (const_string "imov")))
2035 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2036 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2037 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2039 ;; Stores and loads of ax to arbitrary constant address.
2040 ;; We fake an second form of instruction to force reload to load address
2041 ;; into register when rax is not available
2042 (define_insn "*movabsdi_1_rex64"
2043 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2044 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2045 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2047 movabs{q}\t{%1, %P0|%P0, %1}
2048 mov{q}\t{%1, %a0|%a0, %1}"
2049 [(set_attr "type" "imov")
2050 (set_attr "modrm" "0,*")
2051 (set_attr "length_address" "8,0")
2052 (set_attr "length_immediate" "0,*")
2053 (set_attr "memory" "store")
2054 (set_attr "mode" "DI")])
2056 (define_insn "*movabsdi_2_rex64"
2057 [(set (match_operand:DI 0 "register_operand" "=a,r")
2058 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2059 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2061 movabs{q}\t{%P1, %0|%0, %P1}
2062 mov{q}\t{%a1, %0|%0, %a1}"
2063 [(set_attr "type" "imov")
2064 (set_attr "modrm" "0,*")
2065 (set_attr "length_address" "8,0")
2066 (set_attr "length_immediate" "0")
2067 (set_attr "memory" "load")
2068 (set_attr "mode" "DI")])
2070 ;; Convert impossible stores of immediate to existing instructions.
2071 ;; First try to get scratch register and go through it. In case this
2072 ;; fails, move by 32bit parts.
2074 [(match_scratch:DI 2 "r")
2075 (set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2078 && !x86_64_immediate_operand (operands[1], DImode)"
2079 [(set (match_dup 2) (match_dup 1))
2080 (set (match_dup 0) (match_dup 2))]
2083 ;; We need to define this as both peepholer and splitter for case
2084 ;; peephole2 pass is not run.
2085 ;; "&& 1" is needed to keep it from matching the previous pattern.
2087 [(set (match_operand:DI 0 "memory_operand" "")
2088 (match_operand:DI 1 "immediate_operand" ""))]
2089 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2090 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2091 [(set (match_dup 2) (match_dup 3))
2092 (set (match_dup 4) (match_dup 5))]
2093 "split_di (operands, 2, operands + 2, operands + 4);")
2096 [(set (match_operand:DI 0 "memory_operand" "")
2097 (match_operand:DI 1 "immediate_operand" ""))]
2098 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2099 ? flow2_completed : reload_completed)
2100 && !symbolic_operand (operands[1], DImode)
2101 && !x86_64_immediate_operand (operands[1], DImode)"
2102 [(set (match_dup 2) (match_dup 3))
2103 (set (match_dup 4) (match_dup 5))]
2104 "split_di (operands, 2, operands + 2, operands + 4);")
2106 (define_insn "*swapdi_rex64"
2107 [(set (match_operand:DI 0 "register_operand" "+r")
2108 (match_operand:DI 1 "register_operand" "+r"))
2113 [(set_attr "type" "imov")
2114 (set_attr "mode" "DI")
2115 (set_attr "pent_pair" "np")
2116 (set_attr "athlon_decode" "vector")])
2118 (define_expand "movti"
2119 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2120 (match_operand:TI 1 "nonimmediate_operand" ""))]
2121 "TARGET_SSE || TARGET_64BIT"
2124 ix86_expand_move (TImode, operands);
2126 ix86_expand_vector_move (TImode, operands);
2130 (define_insn "*movti_internal"
2131 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2132 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2133 "TARGET_SSE && !TARGET_64BIT
2134 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2136 switch (which_alternative)
2139 if (get_attr_mode (insn) == MODE_V4SF)
2140 return "xorps\t%0, %0";
2142 return "pxor\t%0, %0";
2145 if (get_attr_mode (insn) == MODE_V4SF)
2146 return "movaps\t{%1, %0|%0, %1}";
2148 return "movdqa\t{%1, %0|%0, %1}";
2153 [(set_attr "type" "sselog1,ssemov,ssemov")
2155 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2156 (ne (symbol_ref "optimize_size") (const_int 0)))
2157 (const_string "V4SF")
2158 (and (eq_attr "alternative" "2")
2159 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2161 (const_string "V4SF")]
2162 (const_string "TI")))])
2164 (define_insn "*movti_rex64"
2165 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2166 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2168 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2170 switch (which_alternative)
2176 if (get_attr_mode (insn) == MODE_V4SF)
2177 return "xorps\t%0, %0";
2179 return "pxor\t%0, %0";
2182 if (get_attr_mode (insn) == MODE_V4SF)
2183 return "movaps\t{%1, %0|%0, %1}";
2185 return "movdqa\t{%1, %0|%0, %1}";
2190 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2192 (cond [(eq_attr "alternative" "2,3")
2194 (ne (symbol_ref "optimize_size")
2196 (const_string "V4SF")
2197 (const_string "TI"))
2198 (eq_attr "alternative" "4")
2200 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2202 (ne (symbol_ref "optimize_size")
2204 (const_string "V4SF")
2205 (const_string "TI"))]
2206 (const_string "DI")))])
2209 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2210 (match_operand:TI 1 "general_operand" ""))]
2211 "reload_completed && !SSE_REG_P (operands[0])
2212 && !SSE_REG_P (operands[1])"
2214 "ix86_split_long_move (operands); DONE;")
2216 (define_expand "movsf"
2217 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2218 (match_operand:SF 1 "general_operand" ""))]
2220 "ix86_expand_move (SFmode, operands); DONE;")
2222 (define_insn "*pushsf"
2223 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2224 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2227 /* Anything else should be already split before reg-stack. */
2228 gcc_assert (which_alternative == 1);
2229 return "push{l}\t%1";
2231 [(set_attr "type" "multi,push,multi")
2232 (set_attr "unit" "i387,*,*")
2233 (set_attr "mode" "SF,SI,SF")])
2235 (define_insn "*pushsf_rex64"
2236 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2237 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2240 /* Anything else should be already split before reg-stack. */
2241 gcc_assert (which_alternative == 1);
2242 return "push{q}\t%q1";
2244 [(set_attr "type" "multi,push,multi")
2245 (set_attr "unit" "i387,*,*")
2246 (set_attr "mode" "SF,DI,SF")])
2249 [(set (match_operand:SF 0 "push_operand" "")
2250 (match_operand:SF 1 "memory_operand" ""))]
2252 && GET_CODE (operands[1]) == MEM
2253 && constant_pool_reference_p (operands[1])"
2256 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2259 ;; %%% Kill this when call knows how to work this out.
2261 [(set (match_operand:SF 0 "push_operand" "")
2262 (match_operand:SF 1 "any_fp_register_operand" ""))]
2264 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2265 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2268 [(set (match_operand:SF 0 "push_operand" "")
2269 (match_operand:SF 1 "any_fp_register_operand" ""))]
2271 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2272 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2274 (define_insn "*movsf_1"
2275 [(set (match_operand:SF 0 "nonimmediate_operand"
2276 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2277 (match_operand:SF 1 "general_operand"
2278 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2279 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2280 && (reload_in_progress || reload_completed
2281 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2282 || GET_CODE (operands[1]) != CONST_DOUBLE
2283 || memory_operand (operands[0], SFmode))"
2285 switch (which_alternative)
2288 return output_387_reg_move (insn, operands);
2291 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2292 return "fstp%z0\t%y0";
2294 return "fst%z0\t%y0";
2297 return standard_80387_constant_opcode (operands[1]);
2301 return "mov{l}\t{%1, %0|%0, %1}";
2303 if (get_attr_mode (insn) == MODE_TI)
2304 return "pxor\t%0, %0";
2306 return "xorps\t%0, %0";
2308 if (get_attr_mode (insn) == MODE_V4SF)
2309 return "movaps\t{%1, %0|%0, %1}";
2311 return "movss\t{%1, %0|%0, %1}";
2314 return "movss\t{%1, %0|%0, %1}";
2318 return "movd\t{%1, %0|%0, %1}";
2321 return "movq\t{%1, %0|%0, %1}";
2327 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2329 (cond [(eq_attr "alternative" "3,4,9,10")
2331 (eq_attr "alternative" "5")
2333 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2335 (ne (symbol_ref "TARGET_SSE2")
2337 (eq (symbol_ref "optimize_size")
2340 (const_string "V4SF"))
2341 /* For architectures resolving dependencies on
2342 whole SSE registers use APS move to break dependency
2343 chains, otherwise use short move to avoid extra work.
2345 Do the same for architectures resolving dependencies on
2346 the parts. While in DF mode it is better to always handle
2347 just register parts, the SF mode is different due to lack
2348 of instructions to load just part of the register. It is
2349 better to maintain the whole registers in single format
2350 to avoid problems on using packed logical operations. */
2351 (eq_attr "alternative" "6")
2353 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2355 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2357 (const_string "V4SF")
2358 (const_string "SF"))
2359 (eq_attr "alternative" "11")
2360 (const_string "DI")]
2361 (const_string "SF")))])
2363 (define_insn "*swapsf"
2364 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2365 (match_operand:SF 1 "fp_register_operand" "+f"))
2368 "reload_completed || TARGET_80387"
2370 if (STACK_TOP_P (operands[0]))
2375 [(set_attr "type" "fxch")
2376 (set_attr "mode" "SF")])
2378 (define_expand "movdf"
2379 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2380 (match_operand:DF 1 "general_operand" ""))]
2382 "ix86_expand_move (DFmode, operands); DONE;")
2384 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2385 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2386 ;; On the average, pushdf using integers can be still shorter. Allow this
2387 ;; pattern for optimize_size too.
2389 (define_insn "*pushdf_nointeger"
2390 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2391 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2392 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2394 /* This insn should be already split before reg-stack. */
2397 [(set_attr "type" "multi")
2398 (set_attr "unit" "i387,*,*,*")
2399 (set_attr "mode" "DF,SI,SI,DF")])
2401 (define_insn "*pushdf_integer"
2402 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2403 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2404 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2406 /* This insn should be already split before reg-stack. */
2409 [(set_attr "type" "multi")
2410 (set_attr "unit" "i387,*,*")
2411 (set_attr "mode" "DF,SI,DF")])
2413 ;; %%% Kill this when call knows how to work this out.
2415 [(set (match_operand:DF 0 "push_operand" "")
2416 (match_operand:DF 1 "any_fp_register_operand" ""))]
2417 "!TARGET_64BIT && reload_completed"
2418 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2419 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2423 [(set (match_operand:DF 0 "push_operand" "")
2424 (match_operand:DF 1 "any_fp_register_operand" ""))]
2425 "TARGET_64BIT && reload_completed"
2426 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2427 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2431 [(set (match_operand:DF 0 "push_operand" "")
2432 (match_operand:DF 1 "general_operand" ""))]
2435 "ix86_split_long_move (operands); DONE;")
2437 ;; Moving is usually shorter when only FP registers are used. This separate
2438 ;; movdf pattern avoids the use of integer registers for FP operations
2439 ;; when optimizing for size.
2441 (define_insn "*movdf_nointeger"
2442 [(set (match_operand:DF 0 "nonimmediate_operand"
2443 "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ")
2444 (match_operand:DF 1 "general_operand"
2445 "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))]
2446 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2447 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2448 && (reload_in_progress || reload_completed
2449 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2450 || GET_CODE (operands[1]) != CONST_DOUBLE
2451 || memory_operand (operands[0], DFmode))"
2453 switch (which_alternative)
2456 return output_387_reg_move (insn, operands);
2459 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2460 return "fstp%z0\t%y0";
2462 return "fst%z0\t%y0";
2465 return standard_80387_constant_opcode (operands[1]);
2471 switch (get_attr_mode (insn))
2474 return "xorps\t%0, %0";
2476 return "xorpd\t%0, %0";
2478 return "pxor\t%0, %0";
2485 switch (get_attr_mode (insn))
2488 return "movaps\t{%1, %0|%0, %1}";
2490 return "movapd\t{%1, %0|%0, %1}";
2492 return "movdqa\t{%1, %0|%0, %1}";
2494 return "movq\t{%1, %0|%0, %1}";
2496 return "movsd\t{%1, %0|%0, %1}";
2498 return "movlpd\t{%1, %0|%0, %1}";
2500 return "movlps\t{%1, %0|%0, %1}";
2509 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2511 (cond [(eq_attr "alternative" "0,1,2")
2513 (eq_attr "alternative" "3,4")
2516 /* For SSE1, we have many fewer alternatives. */
2517 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2518 (cond [(eq_attr "alternative" "5,6")
2519 (const_string "V4SF")
2521 (const_string "V2SF"))
2523 /* xorps is one byte shorter. */
2524 (eq_attr "alternative" "5")
2525 (cond [(ne (symbol_ref "optimize_size")
2527 (const_string "V4SF")
2528 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2532 (const_string "V2DF"))
2534 /* For architectures resolving dependencies on
2535 whole SSE registers use APD move to break dependency
2536 chains, otherwise use short move to avoid extra work.
2538 movaps encodes one byte shorter. */
2539 (eq_attr "alternative" "6")
2541 [(ne (symbol_ref "optimize_size")
2543 (const_string "V4SF")
2544 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2546 (const_string "V2DF")
2548 (const_string "DF"))
2549 /* For architectures resolving dependencies on register
2550 parts we may avoid extra work to zero out upper part
2552 (eq_attr "alternative" "7")
2554 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2556 (const_string "V1DF")
2557 (const_string "DF"))
2559 (const_string "DF")))])
2561 (define_insn "*movdf_integer"
2562 [(set (match_operand:DF 0 "nonimmediate_operand"
2563 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2564 (match_operand:DF 1 "general_operand"
2565 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))]
2566 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2567 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2568 && (reload_in_progress || reload_completed
2569 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2570 || GET_CODE (operands[1]) != CONST_DOUBLE
2571 || memory_operand (operands[0], DFmode))"
2573 switch (which_alternative)
2576 return output_387_reg_move (insn, operands);
2579 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2580 return "fstp%z0\t%y0";
2582 return "fst%z0\t%y0";
2585 return standard_80387_constant_opcode (operands[1]);
2592 switch (get_attr_mode (insn))
2595 return "xorps\t%0, %0";
2597 return "xorpd\t%0, %0";
2599 return "pxor\t%0, %0";
2606 switch (get_attr_mode (insn))
2609 return "movaps\t{%1, %0|%0, %1}";
2611 return "movapd\t{%1, %0|%0, %1}";
2613 return "movdqa\t{%1, %0|%0, %1}";
2615 return "movq\t{%1, %0|%0, %1}";
2617 return "movsd\t{%1, %0|%0, %1}";
2619 return "movlpd\t{%1, %0|%0, %1}";
2621 return "movlps\t{%1, %0|%0, %1}";
2630 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2632 (cond [(eq_attr "alternative" "0,1,2")
2634 (eq_attr "alternative" "3,4")
2637 /* For SSE1, we have many fewer alternatives. */
2638 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2639 (cond [(eq_attr "alternative" "5,6")
2640 (const_string "V4SF")
2642 (const_string "V2SF"))
2644 /* xorps is one byte shorter. */
2645 (eq_attr "alternative" "5")
2646 (cond [(ne (symbol_ref "optimize_size")
2648 (const_string "V4SF")
2649 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2653 (const_string "V2DF"))
2655 /* For architectures resolving dependencies on
2656 whole SSE registers use APD move to break dependency
2657 chains, otherwise use short move to avoid extra work.
2659 movaps encodes one byte shorter. */
2660 (eq_attr "alternative" "6")
2662 [(ne (symbol_ref "optimize_size")
2664 (const_string "V4SF")
2665 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2667 (const_string "V2DF")
2669 (const_string "DF"))
2670 /* For architectures resolving dependencies on register
2671 parts we may avoid extra work to zero out upper part
2673 (eq_attr "alternative" "7")
2675 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2677 (const_string "V1DF")
2678 (const_string "DF"))
2680 (const_string "DF")))])
2683 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2684 (match_operand:DF 1 "general_operand" ""))]
2686 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2687 && ! (ANY_FP_REG_P (operands[0]) ||
2688 (GET_CODE (operands[0]) == SUBREG
2689 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2690 && ! (ANY_FP_REG_P (operands[1]) ||
2691 (GET_CODE (operands[1]) == SUBREG
2692 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2694 "ix86_split_long_move (operands); DONE;")
2696 (define_insn "*swapdf"
2697 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2698 (match_operand:DF 1 "fp_register_operand" "+f"))
2701 "reload_completed || TARGET_80387"
2703 if (STACK_TOP_P (operands[0]))
2708 [(set_attr "type" "fxch")
2709 (set_attr "mode" "DF")])
2711 (define_expand "movxf"
2712 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2713 (match_operand:XF 1 "general_operand" ""))]
2715 "ix86_expand_move (XFmode, operands); DONE;")
2717 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2718 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2719 ;; Pushing using integer instructions is longer except for constants
2720 ;; and direct memory references.
2721 ;; (assuming that any given constant is pushed only once, but this ought to be
2722 ;; handled elsewhere).
2724 (define_insn "*pushxf_nointeger"
2725 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2726 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2729 /* This insn should be already split before reg-stack. */
2732 [(set_attr "type" "multi")
2733 (set_attr "unit" "i387,*,*")
2734 (set_attr "mode" "XF,SI,SI")])
2736 (define_insn "*pushxf_integer"
2737 [(set (match_operand:XF 0 "push_operand" "=<,<")
2738 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2741 /* This insn should be already split before reg-stack. */
2744 [(set_attr "type" "multi")
2745 (set_attr "unit" "i387,*")
2746 (set_attr "mode" "XF,SI")])
2749 [(set (match_operand 0 "push_operand" "")
2750 (match_operand 1 "general_operand" ""))]
2752 && (GET_MODE (operands[0]) == XFmode
2753 || GET_MODE (operands[0]) == DFmode)
2754 && !ANY_FP_REG_P (operands[1])"
2756 "ix86_split_long_move (operands); DONE;")
2759 [(set (match_operand:XF 0 "push_operand" "")
2760 (match_operand:XF 1 "any_fp_register_operand" ""))]
2762 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2763 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2764 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2767 [(set (match_operand:XF 0 "push_operand" "")
2768 (match_operand:XF 1 "any_fp_register_operand" ""))]
2770 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2771 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2772 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774 ;; Do not use integer registers when optimizing for size
2775 (define_insn "*movxf_nointeger"
2776 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2777 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2779 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2780 && (reload_in_progress || reload_completed
2781 || GET_CODE (operands[1]) != CONST_DOUBLE
2782 || memory_operand (operands[0], XFmode))"
2784 switch (which_alternative)
2787 return output_387_reg_move (insn, operands);
2790 /* There is no non-popping store to memory for XFmode. So if
2791 we need one, follow the store with a load. */
2792 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2793 return "fstp%z0\t%y0\;fld%z0\t%y0";
2795 return "fstp%z0\t%y0";
2798 return standard_80387_constant_opcode (operands[1]);
2806 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2807 (set_attr "mode" "XF,XF,XF,SI,SI")])
2809 (define_insn "*movxf_integer"
2810 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2811 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2813 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2814 && (reload_in_progress || reload_completed
2815 || GET_CODE (operands[1]) != CONST_DOUBLE
2816 || memory_operand (operands[0], XFmode))"
2818 switch (which_alternative)
2821 return output_387_reg_move (insn, operands);
2824 /* There is no non-popping store to memory for XFmode. So if
2825 we need one, follow the store with a load. */
2826 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2827 return "fstp%z0\t%y0\;fld%z0\t%y0";
2829 return "fstp%z0\t%y0";
2832 return standard_80387_constant_opcode (operands[1]);
2841 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2842 (set_attr "mode" "XF,XF,XF,SI,SI")])
2845 [(set (match_operand 0 "nonimmediate_operand" "")
2846 (match_operand 1 "general_operand" ""))]
2848 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2849 && GET_MODE (operands[0]) == XFmode
2850 && ! (ANY_FP_REG_P (operands[0]) ||
2851 (GET_CODE (operands[0]) == SUBREG
2852 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2853 && ! (ANY_FP_REG_P (operands[1]) ||
2854 (GET_CODE (operands[1]) == SUBREG
2855 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2857 "ix86_split_long_move (operands); DONE;")
2860 [(set (match_operand 0 "register_operand" "")
2861 (match_operand 1 "memory_operand" ""))]
2863 && GET_CODE (operands[1]) == MEM
2864 && (GET_MODE (operands[0]) == XFmode
2865 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2866 && constant_pool_reference_p (operands[1])"
2867 [(set (match_dup 0) (match_dup 1))]
2869 rtx c = avoid_constant_pool_reference (operands[1]);
2870 rtx r = operands[0];
2872 if (GET_CODE (r) == SUBREG)
2877 if (!standard_sse_constant_p (c))
2880 else if (FP_REG_P (r))
2882 if (!standard_80387_constant_p (c))
2885 else if (MMX_REG_P (r))
2891 (define_insn "swapxf"
2892 [(set (match_operand:XF 0 "register_operand" "+f")
2893 (match_operand:XF 1 "register_operand" "+f"))
2898 if (STACK_TOP_P (operands[0]))
2903 [(set_attr "type" "fxch")
2904 (set_attr "mode" "XF")])
2906 (define_expand "movtf"
2907 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2908 (match_operand:TF 1 "nonimmediate_operand" ""))]
2911 ix86_expand_move (TFmode, operands);
2915 (define_insn "*movtf_internal"
2916 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2917 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2919 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2921 switch (which_alternative)
2927 if (get_attr_mode (insn) == MODE_V4SF)
2928 return "xorps\t%0, %0";
2930 return "pxor\t%0, %0";
2933 if (get_attr_mode (insn) == MODE_V4SF)
2934 return "movaps\t{%1, %0|%0, %1}";
2936 return "movdqa\t{%1, %0|%0, %1}";
2941 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2943 (cond [(eq_attr "alternative" "2,3")
2945 (ne (symbol_ref "optimize_size")
2947 (const_string "V4SF")
2948 (const_string "TI"))
2949 (eq_attr "alternative" "4")
2951 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2953 (ne (symbol_ref "optimize_size")
2955 (const_string "V4SF")
2956 (const_string "TI"))]
2957 (const_string "DI")))])
2960 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2961 (match_operand:TF 1 "general_operand" ""))]
2962 "reload_completed && !SSE_REG_P (operands[0])
2963 && !SSE_REG_P (operands[1])"
2965 "ix86_split_long_move (operands); DONE;")
2967 ;; Zero extension instructions
2969 (define_expand "zero_extendhisi2"
2970 [(set (match_operand:SI 0 "register_operand" "")
2971 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2974 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2976 operands[1] = force_reg (HImode, operands[1]);
2977 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2982 (define_insn "zero_extendhisi2_and"
2983 [(set (match_operand:SI 0 "register_operand" "=r")
2984 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2985 (clobber (reg:CC FLAGS_REG))]
2986 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2988 [(set_attr "type" "alu1")
2989 (set_attr "mode" "SI")])
2992 [(set (match_operand:SI 0 "register_operand" "")
2993 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2994 (clobber (reg:CC FLAGS_REG))]
2995 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2996 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2997 (clobber (reg:CC FLAGS_REG))])]
3000 (define_insn "*zero_extendhisi2_movzwl"
3001 [(set (match_operand:SI 0 "register_operand" "=r")
3002 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3003 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3004 "movz{wl|x}\t{%1, %0|%0, %1}"
3005 [(set_attr "type" "imovx")
3006 (set_attr "mode" "SI")])
3008 (define_expand "zero_extendqihi2"
3010 [(set (match_operand:HI 0 "register_operand" "")
3011 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3012 (clobber (reg:CC FLAGS_REG))])]
3016 (define_insn "*zero_extendqihi2_and"
3017 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3018 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3019 (clobber (reg:CC FLAGS_REG))]
3020 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3022 [(set_attr "type" "alu1")
3023 (set_attr "mode" "HI")])
3025 (define_insn "*zero_extendqihi2_movzbw_and"
3026 [(set (match_operand:HI 0 "register_operand" "=r,r")
3027 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3028 (clobber (reg:CC FLAGS_REG))]
3029 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3031 [(set_attr "type" "imovx,alu1")
3032 (set_attr "mode" "HI")])
3034 ; zero extend to SImode here to avoid partial register stalls
3035 (define_insn "*zero_extendqihi2_movzbl"
3036 [(set (match_operand:HI 0 "register_operand" "=r")
3037 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3038 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3039 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3040 [(set_attr "type" "imovx")
3041 (set_attr "mode" "SI")])
3043 ;; For the movzbw case strip only the clobber
3045 [(set (match_operand:HI 0 "register_operand" "")
3046 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3047 (clobber (reg:CC FLAGS_REG))]
3049 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3050 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3051 [(set (match_operand:HI 0 "register_operand" "")
3052 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3054 ;; When source and destination does not overlap, clear destination
3055 ;; first and then do the movb
3057 [(set (match_operand:HI 0 "register_operand" "")
3058 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3059 (clobber (reg:CC FLAGS_REG))]
3061 && ANY_QI_REG_P (operands[0])
3062 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3063 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3064 [(set (match_dup 0) (const_int 0))
3065 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3066 "operands[2] = gen_lowpart (QImode, operands[0]);")
3068 ;; Rest is handled by single and.
3070 [(set (match_operand:HI 0 "register_operand" "")
3071 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3072 (clobber (reg:CC FLAGS_REG))]
3074 && true_regnum (operands[0]) == true_regnum (operands[1])"
3075 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3076 (clobber (reg:CC FLAGS_REG))])]
3079 (define_expand "zero_extendqisi2"
3081 [(set (match_operand:SI 0 "register_operand" "")
3082 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3083 (clobber (reg:CC FLAGS_REG))])]
3087 (define_insn "*zero_extendqisi2_and"
3088 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3089 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3090 (clobber (reg:CC FLAGS_REG))]
3091 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3093 [(set_attr "type" "alu1")
3094 (set_attr "mode" "SI")])
3096 (define_insn "*zero_extendqisi2_movzbw_and"
3097 [(set (match_operand:SI 0 "register_operand" "=r,r")
3098 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3099 (clobber (reg:CC FLAGS_REG))]
3100 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3102 [(set_attr "type" "imovx,alu1")
3103 (set_attr "mode" "SI")])
3105 (define_insn "*zero_extendqisi2_movzbw"
3106 [(set (match_operand:SI 0 "register_operand" "=r")
3107 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3108 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3109 "movz{bl|x}\t{%1, %0|%0, %1}"
3110 [(set_attr "type" "imovx")
3111 (set_attr "mode" "SI")])
3113 ;; For the movzbl case strip only the clobber
3115 [(set (match_operand:SI 0 "register_operand" "")
3116 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3117 (clobber (reg:CC FLAGS_REG))]
3119 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3120 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3122 (zero_extend:SI (match_dup 1)))])
3124 ;; When source and destination does not overlap, clear destination
3125 ;; first and then do the movb
3127 [(set (match_operand:SI 0 "register_operand" "")
3128 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3129 (clobber (reg:CC FLAGS_REG))]
3131 && ANY_QI_REG_P (operands[0])
3132 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3133 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3134 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3135 [(set (match_dup 0) (const_int 0))
3136 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3137 "operands[2] = gen_lowpart (QImode, operands[0]);")
3139 ;; Rest is handled by single and.
3141 [(set (match_operand:SI 0 "register_operand" "")
3142 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3143 (clobber (reg:CC FLAGS_REG))]
3145 && true_regnum (operands[0]) == true_regnum (operands[1])"
3146 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3147 (clobber (reg:CC FLAGS_REG))])]
3150 ;; %%% Kill me once multi-word ops are sane.
3151 (define_expand "zero_extendsidi2"
3152 [(set (match_operand:DI 0 "register_operand" "=r")
3153 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3157 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3162 (define_insn "zero_extendsidi2_32"
3163 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3164 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3165 (clobber (reg:CC FLAGS_REG))]
3171 movd\t{%1, %0|%0, %1}
3172 movd\t{%1, %0|%0, %1}"
3173 [(set_attr "mode" "SI,SI,SI,DI,TI")
3174 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3176 (define_insn "zero_extendsidi2_rex64"
3177 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3178 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3181 mov\t{%k1, %k0|%k0, %k1}
3183 movd\t{%1, %0|%0, %1}
3184 movd\t{%1, %0|%0, %1}"
3185 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3186 (set_attr "mode" "SI,DI,SI,SI")])
3189 [(set (match_operand:DI 0 "memory_operand" "")
3190 (zero_extend:DI (match_dup 0)))]
3192 [(set (match_dup 4) (const_int 0))]
3193 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3196 [(set (match_operand:DI 0 "register_operand" "")
3197 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3198 (clobber (reg:CC FLAGS_REG))]
3199 "!TARGET_64BIT && reload_completed
3200 && true_regnum (operands[0]) == true_regnum (operands[1])"
3201 [(set (match_dup 4) (const_int 0))]
3202 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3206 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3207 (clobber (reg:CC FLAGS_REG))]
3208 "!TARGET_64BIT && reload_completed
3209 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3210 [(set (match_dup 3) (match_dup 1))
3211 (set (match_dup 4) (const_int 0))]
3212 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3214 (define_insn "zero_extendhidi2"
3215 [(set (match_operand:DI 0 "register_operand" "=r")
3216 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3218 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3219 [(set_attr "type" "imovx")
3220 (set_attr "mode" "DI")])
3222 (define_insn "zero_extendqidi2"
3223 [(set (match_operand:DI 0 "register_operand" "=r")
3224 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3226 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3227 [(set_attr "type" "imovx")
3228 (set_attr "mode" "DI")])
3230 ;; Sign extension instructions
3232 (define_expand "extendsidi2"
3233 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3234 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3235 (clobber (reg:CC FLAGS_REG))
3236 (clobber (match_scratch:SI 2 ""))])]
3241 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3246 (define_insn "*extendsidi2_1"
3247 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3248 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3249 (clobber (reg:CC FLAGS_REG))
3250 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3254 (define_insn "extendsidi2_rex64"
3255 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3256 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3260 movs{lq|x}\t{%1,%0|%0, %1}"
3261 [(set_attr "type" "imovx")
3262 (set_attr "mode" "DI")
3263 (set_attr "prefix_0f" "0")
3264 (set_attr "modrm" "0,1")])
3266 (define_insn "extendhidi2"
3267 [(set (match_operand:DI 0 "register_operand" "=r")
3268 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3270 "movs{wq|x}\t{%1,%0|%0, %1}"
3271 [(set_attr "type" "imovx")
3272 (set_attr "mode" "DI")])
3274 (define_insn "extendqidi2"
3275 [(set (match_operand:DI 0 "register_operand" "=r")
3276 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278 "movs{bq|x}\t{%1,%0|%0, %1}"
3279 [(set_attr "type" "imovx")
3280 (set_attr "mode" "DI")])
3282 ;; Extend to memory case when source register does die.
3284 [(set (match_operand:DI 0 "memory_operand" "")
3285 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3286 (clobber (reg:CC FLAGS_REG))
3287 (clobber (match_operand:SI 2 "register_operand" ""))]
3289 && dead_or_set_p (insn, operands[1])
3290 && !reg_mentioned_p (operands[1], operands[0]))"
3291 [(set (match_dup 3) (match_dup 1))
3292 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3293 (clobber (reg:CC FLAGS_REG))])
3294 (set (match_dup 4) (match_dup 1))]
3295 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3297 ;; Extend to memory case when source register does not die.
3299 [(set (match_operand:DI 0 "memory_operand" "")
3300 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3301 (clobber (reg:CC FLAGS_REG))
3302 (clobber (match_operand:SI 2 "register_operand" ""))]
3306 split_di (&operands[0], 1, &operands[3], &operands[4]);
3308 emit_move_insn (operands[3], operands[1]);
3310 /* Generate a cltd if possible and doing so it profitable. */
3311 if (true_regnum (operands[1]) == 0
3312 && true_regnum (operands[2]) == 1
3313 && (optimize_size || TARGET_USE_CLTD))
3315 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3319 emit_move_insn (operands[2], operands[1]);
3320 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3322 emit_move_insn (operands[4], operands[2]);
3326 ;; Extend to register case. Optimize case where source and destination
3327 ;; registers match and cases where we can use cltd.
3329 [(set (match_operand:DI 0 "register_operand" "")
3330 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3331 (clobber (reg:CC FLAGS_REG))
3332 (clobber (match_scratch:SI 2 ""))]
3336 split_di (&operands[0], 1, &operands[3], &operands[4]);
3338 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3339 emit_move_insn (operands[3], operands[1]);
3341 /* Generate a cltd if possible and doing so it profitable. */
3342 if (true_regnum (operands[3]) == 0
3343 && (optimize_size || TARGET_USE_CLTD))
3345 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3349 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3350 emit_move_insn (operands[4], operands[1]);
3352 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3356 (define_insn "extendhisi2"
3357 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3358 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3361 switch (get_attr_prefix_0f (insn))
3364 return "{cwtl|cwde}";
3366 return "movs{wl|x}\t{%1,%0|%0, %1}";
3369 [(set_attr "type" "imovx")
3370 (set_attr "mode" "SI")
3371 (set (attr "prefix_0f")
3372 ;; movsx is short decodable while cwtl is vector decoded.
3373 (if_then_else (and (eq_attr "cpu" "!k6")
3374 (eq_attr "alternative" "0"))
3376 (const_string "1")))
3378 (if_then_else (eq_attr "prefix_0f" "0")
3380 (const_string "1")))])
3382 (define_insn "*extendhisi2_zext"
3383 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3385 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3388 switch (get_attr_prefix_0f (insn))
3391 return "{cwtl|cwde}";
3393 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3396 [(set_attr "type" "imovx")
3397 (set_attr "mode" "SI")
3398 (set (attr "prefix_0f")
3399 ;; movsx is short decodable while cwtl is vector decoded.
3400 (if_then_else (and (eq_attr "cpu" "!k6")
3401 (eq_attr "alternative" "0"))
3403 (const_string "1")))
3405 (if_then_else (eq_attr "prefix_0f" "0")
3407 (const_string "1")))])
3409 (define_insn "extendqihi2"
3410 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3411 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3414 switch (get_attr_prefix_0f (insn))
3417 return "{cbtw|cbw}";
3419 return "movs{bw|x}\t{%1,%0|%0, %1}";
3422 [(set_attr "type" "imovx")
3423 (set_attr "mode" "HI")
3424 (set (attr "prefix_0f")
3425 ;; movsx is short decodable while cwtl is vector decoded.
3426 (if_then_else (and (eq_attr "cpu" "!k6")
3427 (eq_attr "alternative" "0"))
3429 (const_string "1")))
3431 (if_then_else (eq_attr "prefix_0f" "0")
3433 (const_string "1")))])
3435 (define_insn "extendqisi2"
3436 [(set (match_operand:SI 0 "register_operand" "=r")
3437 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3439 "movs{bl|x}\t{%1,%0|%0, %1}"
3440 [(set_attr "type" "imovx")
3441 (set_attr "mode" "SI")])
3443 (define_insn "*extendqisi2_zext"
3444 [(set (match_operand:DI 0 "register_operand" "=r")
3446 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3448 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3449 [(set_attr "type" "imovx")
3450 (set_attr "mode" "SI")])
3452 ;; Conversions between float and double.
3454 ;; These are all no-ops in the model used for the 80387. So just
3457 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3458 (define_insn "*dummy_extendsfdf2"
3459 [(set (match_operand:DF 0 "push_operand" "=<")
3460 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3465 [(set (match_operand:DF 0 "push_operand" "")
3466 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3468 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3469 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3472 [(set (match_operand:DF 0 "push_operand" "")
3473 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3475 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3476 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3478 (define_insn "*dummy_extendsfxf2"
3479 [(set (match_operand:XF 0 "push_operand" "=<")
3480 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3485 [(set (match_operand:XF 0 "push_operand" "")
3486 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3488 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3489 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3490 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3493 [(set (match_operand:XF 0 "push_operand" "")
3494 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3496 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3497 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3498 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3501 [(set (match_operand:XF 0 "push_operand" "")
3502 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3504 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3505 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3506 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3509 [(set (match_operand:XF 0 "push_operand" "")
3510 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3512 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3513 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3514 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3516 (define_expand "extendsfdf2"
3517 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3518 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3519 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3521 /* ??? Needed for compress_float_constant since all fp constants
3522 are LEGITIMATE_CONSTANT_P. */
3523 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3524 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3525 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3526 operands[1] = force_reg (SFmode, operands[1]);
3529 (define_insn "*extendsfdf2_mixed"
3530 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3531 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3532 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3533 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3535 switch (which_alternative)
3538 return output_387_reg_move (insn, operands);
3541 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3542 return "fstp%z0\t%y0";
3544 return "fst%z0\t%y0";
3547 return "cvtss2sd\t{%1, %0|%0, %1}";
3553 [(set_attr "type" "fmov,fmov,ssecvt")
3554 (set_attr "mode" "SF,XF,DF")])
3556 (define_insn "*extendsfdf2_sse"
3557 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3558 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3559 "TARGET_SSE2 && TARGET_SSE_MATH
3560 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3561 "cvtss2sd\t{%1, %0|%0, %1}"
3562 [(set_attr "type" "ssecvt")
3563 (set_attr "mode" "DF")])
3565 (define_insn "*extendsfdf2_i387"
3566 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3567 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3569 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3571 switch (which_alternative)
3574 return output_387_reg_move (insn, operands);
3577 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3578 return "fstp%z0\t%y0";
3580 return "fst%z0\t%y0";
3586 [(set_attr "type" "fmov")
3587 (set_attr "mode" "SF,XF")])
3589 (define_expand "extendsfxf2"
3590 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3591 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3594 /* ??? Needed for compress_float_constant since all fp constants
3595 are LEGITIMATE_CONSTANT_P. */
3596 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3597 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3598 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3599 operands[1] = force_reg (SFmode, operands[1]);
3602 (define_insn "*extendsfxf2_i387"
3603 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3604 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3606 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3608 switch (which_alternative)
3611 return output_387_reg_move (insn, operands);
3614 /* There is no non-popping store to memory for XFmode. So if
3615 we need one, follow the store with a load. */
3616 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3617 return "fstp%z0\t%y0";
3619 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3625 [(set_attr "type" "fmov")
3626 (set_attr "mode" "SF,XF")])
3628 (define_expand "extenddfxf2"
3629 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3630 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3633 /* ??? Needed for compress_float_constant since all fp constants
3634 are LEGITIMATE_CONSTANT_P. */
3635 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3636 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3637 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3638 operands[1] = force_reg (DFmode, operands[1]);
3641 (define_insn "*extenddfxf2_i387"
3642 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3643 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3645 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3647 switch (which_alternative)
3650 return output_387_reg_move (insn, operands);
3653 /* There is no non-popping store to memory for XFmode. So if
3654 we need one, follow the store with a load. */
3655 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3656 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3658 return "fstp%z0\t%y0";
3664 [(set_attr "type" "fmov")
3665 (set_attr "mode" "DF,XF")])
3667 ;; %%% This seems bad bad news.
3668 ;; This cannot output into an f-reg because there is no way to be sure
3669 ;; of truncating in that case. Otherwise this is just like a simple move
3670 ;; insn. So we pretend we can output to a reg in order to get better
3671 ;; register preferencing, but we really use a stack slot.
3673 ;; Conversion from DFmode to SFmode.
3675 (define_expand "truncdfsf2"
3676 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3678 (match_operand:DF 1 "nonimmediate_operand" "")))]
3679 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3681 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3682 operands[1] = force_reg (DFmode, operands[1]);
3684 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3686 else if (flag_unsafe_math_optimizations)
3690 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3691 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3696 (define_expand "truncdfsf2_with_temp"
3697 [(parallel [(set (match_operand:SF 0 "" "")
3698 (float_truncate:SF (match_operand:DF 1 "" "")))
3699 (clobber (match_operand:SF 2 "" ""))])]
3702 (define_insn "*truncdfsf_fast_mixed"
3703 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3705 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3706 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3708 switch (which_alternative)
3711 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3712 return "fstp%z0\t%y0";
3714 return "fst%z0\t%y0";
3716 return output_387_reg_move (insn, operands);
3718 return "cvtsd2ss\t{%1, %0|%0, %1}";
3723 [(set_attr "type" "fmov,fmov,ssecvt")
3724 (set_attr "mode" "SF")])
3726 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3727 ;; because nothing we do here is unsafe.
3728 (define_insn "*truncdfsf_fast_sse"
3729 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3731 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3732 "TARGET_SSE2 && TARGET_SSE_MATH"
3733 "cvtsd2ss\t{%1, %0|%0, %1}"
3734 [(set_attr "type" "ssecvt")
3735 (set_attr "mode" "SF")])
3737 (define_insn "*truncdfsf_fast_i387"
3738 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3740 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3741 "TARGET_80387 && flag_unsafe_math_optimizations"
3742 "* return output_387_reg_move (insn, operands);"
3743 [(set_attr "type" "fmov")
3744 (set_attr "mode" "SF")])
3746 (define_insn "*truncdfsf_mixed"
3747 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3749 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3750 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3751 "TARGET_MIX_SSE_I387"
3753 switch (which_alternative)
3756 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3757 return "fstp%z0\t%y0";
3759 return "fst%z0\t%y0";
3763 return "cvtsd2ss\t{%1, %0|%0, %1}";
3768 [(set_attr "type" "fmov,multi,ssecvt")
3769 (set_attr "unit" "*,i387,*")
3770 (set_attr "mode" "SF")])
3772 (define_insn "*truncdfsf_i387"
3773 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3775 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3776 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3779 switch (which_alternative)
3782 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3783 return "fstp%z0\t%y0";
3785 return "fst%z0\t%y0";
3792 [(set_attr "type" "fmov,multi")
3793 (set_attr "unit" "*,i387")
3794 (set_attr "mode" "SF")])
3796 (define_insn "*truncdfsf2_i387_1"
3797 [(set (match_operand:SF 0 "memory_operand" "=m")
3799 (match_operand:DF 1 "register_operand" "f")))]
3801 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3802 && !TARGET_MIX_SSE_I387"
3804 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3805 return "fstp%z0\t%y0";
3807 return "fst%z0\t%y0";
3809 [(set_attr "type" "fmov")
3810 (set_attr "mode" "SF")])
3813 [(set (match_operand:SF 0 "register_operand" "")
3815 (match_operand:DF 1 "fp_register_operand" "")))
3816 (clobber (match_operand 2 "" ""))]
3818 [(set (match_dup 2) (match_dup 1))
3819 (set (match_dup 0) (match_dup 2))]
3821 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3824 ;; Conversion from XFmode to SFmode.
3826 (define_expand "truncxfsf2"
3827 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3829 (match_operand:XF 1 "register_operand" "")))
3830 (clobber (match_dup 2))])]
3833 if (flag_unsafe_math_optimizations)
3835 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3836 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3837 if (reg != operands[0])
3838 emit_move_insn (operands[0], reg);
3842 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3845 (define_insn "*truncxfsf2_mixed"
3846 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3848 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3849 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3850 "TARGET_MIX_SSE_I387"
3852 gcc_assert (!which_alternative);
3853 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3854 return "fstp%z0\t%y0";
3856 return "fst%z0\t%y0";
3858 [(set_attr "type" "fmov,multi,multi,multi")
3859 (set_attr "unit" "*,i387,i387,i387")
3860 (set_attr "mode" "SF")])
3862 (define_insn "truncxfsf2_i387_noop"
3863 [(set (match_operand:SF 0 "register_operand" "=f")
3864 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3865 "TARGET_80387 && flag_unsafe_math_optimizations"
3867 return output_387_reg_move (insn, operands);
3869 [(set_attr "type" "fmov")
3870 (set_attr "mode" "SF")])
3872 (define_insn "*truncxfsf2_i387"
3873 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3875 (match_operand:XF 1 "register_operand" "f,f,f")))
3876 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3879 gcc_assert (!which_alternative);
3880 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3881 return "fstp%z0\t%y0";
3883 return "fst%z0\t%y0";
3885 [(set_attr "type" "fmov,multi,multi")
3886 (set_attr "unit" "*,i387,i387")
3887 (set_attr "mode" "SF")])
3889 (define_insn "*truncxfsf2_i387_1"
3890 [(set (match_operand:SF 0 "memory_operand" "=m")
3892 (match_operand:XF 1 "register_operand" "f")))]
3895 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3896 return "fstp%z0\t%y0";
3898 return "fst%z0\t%y0";
3900 [(set_attr "type" "fmov")
3901 (set_attr "mode" "SF")])
3904 [(set (match_operand:SF 0 "register_operand" "")
3906 (match_operand:XF 1 "register_operand" "")))
3907 (clobber (match_operand:SF 2 "memory_operand" ""))]
3908 "TARGET_80387 && reload_completed"
3909 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3910 (set (match_dup 0) (match_dup 2))]
3914 [(set (match_operand:SF 0 "memory_operand" "")
3916 (match_operand:XF 1 "register_operand" "")))
3917 (clobber (match_operand:SF 2 "memory_operand" ""))]
3919 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3922 ;; Conversion from XFmode to DFmode.
3924 (define_expand "truncxfdf2"
3925 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3927 (match_operand:XF 1 "register_operand" "")))
3928 (clobber (match_dup 2))])]
3931 if (flag_unsafe_math_optimizations)
3933 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3934 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3935 if (reg != operands[0])
3936 emit_move_insn (operands[0], reg);
3940 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3943 (define_insn "*truncxfdf2_mixed"
3944 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3946 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3947 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3948 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3950 gcc_assert (!which_alternative);
3951 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3952 return "fstp%z0\t%y0";
3954 return "fst%z0\t%y0";
3956 [(set_attr "type" "fmov,multi,multi,multi")
3957 (set_attr "unit" "*,i387,i387,i387")
3958 (set_attr "mode" "DF")])
3960 (define_insn "truncxfdf2_i387_noop"
3961 [(set (match_operand:DF 0 "register_operand" "=f")
3962 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3963 "TARGET_80387 && flag_unsafe_math_optimizations"
3965 return output_387_reg_move (insn, operands);
3967 [(set_attr "type" "fmov")
3968 (set_attr "mode" "DF")])
3970 (define_insn "*truncxfdf2_i387"
3971 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3973 (match_operand:XF 1 "register_operand" "f,f,f")))
3974 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3977 gcc_assert (!which_alternative);
3978 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3979 return "fstp%z0\t%y0";
3981 return "fst%z0\t%y0";
3983 [(set_attr "type" "fmov,multi,multi")
3984 (set_attr "unit" "*,i387,i387")
3985 (set_attr "mode" "DF")])
3987 (define_insn "*truncxfdf2_i387_1"
3988 [(set (match_operand:DF 0 "memory_operand" "=m")
3990 (match_operand:XF 1 "register_operand" "f")))]
3993 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3994 return "fstp%z0\t%y0";
3996 return "fst%z0\t%y0";
3998 [(set_attr "type" "fmov")
3999 (set_attr "mode" "DF")])
4002 [(set (match_operand:DF 0 "register_operand" "")
4004 (match_operand:XF 1 "register_operand" "")))
4005 (clobber (match_operand:DF 2 "memory_operand" ""))]
4006 "TARGET_80387 && reload_completed"
4007 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4008 (set (match_dup 0) (match_dup 2))]
4012 [(set (match_operand:DF 0 "memory_operand" "")
4014 (match_operand:XF 1 "register_operand" "")))
4015 (clobber (match_operand:DF 2 "memory_operand" ""))]
4017 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4020 ;; Signed conversion to DImode.
4022 (define_expand "fix_truncxfdi2"
4023 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4024 (fix:DI (match_operand:XF 1 "register_operand" "")))
4025 (clobber (reg:CC FLAGS_REG))])]
4030 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4035 (define_expand "fix_trunc<mode>di2"
4036 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4037 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4038 (clobber (reg:CC FLAGS_REG))])]
4039 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4042 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4044 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4047 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4049 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4050 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4051 if (out != operands[0])
4052 emit_move_insn (operands[0], out);
4057 ;; Signed conversion to SImode.
4059 (define_expand "fix_truncxfsi2"
4060 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4061 (fix:SI (match_operand:XF 1 "register_operand" "")))
4062 (clobber (reg:CC FLAGS_REG))])]
4067 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4072 (define_expand "fix_trunc<mode>si2"
4073 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4074 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4075 (clobber (reg:CC FLAGS_REG))])]
4076 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4079 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4081 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4084 if (SSE_FLOAT_MODE_P (<MODE>mode))
4086 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4087 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4088 if (out != operands[0])
4089 emit_move_insn (operands[0], out);
4094 ;; Signed conversion to HImode.
4096 (define_expand "fix_trunc<mode>hi2"
4097 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4098 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4099 (clobber (reg:CC FLAGS_REG))])]
4101 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4105 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4110 ;; When SSE is available, it is always faster to use it!
4111 (define_insn "fix_truncsfdi_sse"
4112 [(set (match_operand:DI 0 "register_operand" "=r,r")
4113 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4114 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4115 "cvttss2si{q}\t{%1, %0|%0, %1}"
4116 [(set_attr "type" "sseicvt")
4117 (set_attr "mode" "SF")
4118 (set_attr "athlon_decode" "double,vector")])
4120 (define_insn "fix_truncdfdi_sse"
4121 [(set (match_operand:DI 0 "register_operand" "=r,r")
4122 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4123 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4124 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4125 [(set_attr "type" "sseicvt")
4126 (set_attr "mode" "DF")
4127 (set_attr "athlon_decode" "double,vector")])
4129 (define_insn "fix_truncsfsi_sse"
4130 [(set (match_operand:SI 0 "register_operand" "=r,r")
4131 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4132 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4133 "cvttss2si\t{%1, %0|%0, %1}"
4134 [(set_attr "type" "sseicvt")
4135 (set_attr "mode" "DF")
4136 (set_attr "athlon_decode" "double,vector")])
4138 (define_insn "fix_truncdfsi_sse"
4139 [(set (match_operand:SI 0 "register_operand" "=r,r")
4140 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4141 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4142 "cvttsd2si\t{%1, %0|%0, %1}"
4143 [(set_attr "type" "sseicvt")
4144 (set_attr "mode" "DF")
4145 (set_attr "athlon_decode" "double,vector")])
4147 ;; Avoid vector decoded forms of the instruction.
4149 [(match_scratch:DF 2 "Y")
4150 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4151 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4152 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4153 [(set (match_dup 2) (match_dup 1))
4154 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4158 [(match_scratch:SF 2 "x")
4159 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4160 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4161 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4162 [(set (match_dup 2) (match_dup 1))
4163 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4166 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4167 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4168 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4170 && FLOAT_MODE_P (GET_MODE (operands[1]))
4171 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4172 && (TARGET_64BIT || <MODE>mode != DImode))
4174 && !(reload_completed || reload_in_progress)"
4179 if (memory_operand (operands[0], VOIDmode))
4180 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4183 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4184 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4190 [(set_attr "type" "fisttp")
4191 (set_attr "mode" "<MODE>")])
4193 (define_insn "fix_trunc<mode>_i387_fisttp"
4194 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4195 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4196 (clobber (match_scratch:XF 2 "=&1f"))]
4198 && FLOAT_MODE_P (GET_MODE (operands[1]))
4199 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4200 && (TARGET_64BIT || <MODE>mode != DImode))
4201 && TARGET_SSE_MATH)"
4202 "* return output_fix_trunc (insn, operands, 1);"
4203 [(set_attr "type" "fisttp")
4204 (set_attr "mode" "<MODE>")])
4206 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4207 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4208 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4209 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4210 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4212 && FLOAT_MODE_P (GET_MODE (operands[1]))
4213 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4214 && (TARGET_64BIT || <MODE>mode != DImode))
4215 && TARGET_SSE_MATH)"
4217 [(set_attr "type" "fisttp")
4218 (set_attr "mode" "<MODE>")])
4221 [(set (match_operand:X87MODEI 0 "register_operand" "")
4222 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4223 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4224 (clobber (match_scratch 3 ""))]
4226 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4227 (clobber (match_dup 3))])
4228 (set (match_dup 0) (match_dup 2))]
4232 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4233 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4234 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4235 (clobber (match_scratch 3 ""))]
4237 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4238 (clobber (match_dup 3))])]
4241 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4242 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4243 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4244 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4245 ;; function in i386.c.
4246 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4247 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4248 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4249 (clobber (reg:CC FLAGS_REG))]
4250 "TARGET_80387 && !TARGET_FISTTP
4251 && FLOAT_MODE_P (GET_MODE (operands[1]))
4252 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4253 && (TARGET_64BIT || <MODE>mode != DImode))
4254 && !(reload_completed || reload_in_progress)"
4259 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4261 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4262 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4263 if (memory_operand (operands[0], VOIDmode))
4264 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4265 operands[2], operands[3]));
4268 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4269 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4270 operands[2], operands[3],
4275 [(set_attr "type" "fistp")
4276 (set_attr "i387_cw" "trunc")
4277 (set_attr "mode" "<MODE>")])
4279 (define_insn "fix_truncdi_i387"
4280 [(set (match_operand:DI 0 "memory_operand" "=m")
4281 (fix:DI (match_operand 1 "register_operand" "f")))
4282 (use (match_operand:HI 2 "memory_operand" "m"))
4283 (use (match_operand:HI 3 "memory_operand" "m"))
4284 (clobber (match_scratch:XF 4 "=&1f"))]
4285 "TARGET_80387 && !TARGET_FISTTP
4286 && FLOAT_MODE_P (GET_MODE (operands[1]))
4287 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4288 "* return output_fix_trunc (insn, operands, 0);"
4289 [(set_attr "type" "fistp")
4290 (set_attr "i387_cw" "trunc")
4291 (set_attr "mode" "DI")])
4293 (define_insn "fix_truncdi_i387_with_temp"
4294 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4295 (fix:DI (match_operand 1 "register_operand" "f,f")))
4296 (use (match_operand:HI 2 "memory_operand" "m,m"))
4297 (use (match_operand:HI 3 "memory_operand" "m,m"))
4298 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4299 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4300 "TARGET_80387 && !TARGET_FISTTP
4301 && FLOAT_MODE_P (GET_MODE (operands[1]))
4302 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4304 [(set_attr "type" "fistp")
4305 (set_attr "i387_cw" "trunc")
4306 (set_attr "mode" "DI")])
4309 [(set (match_operand:DI 0 "register_operand" "")
4310 (fix:DI (match_operand 1 "register_operand" "")))
4311 (use (match_operand:HI 2 "memory_operand" ""))
4312 (use (match_operand:HI 3 "memory_operand" ""))
4313 (clobber (match_operand:DI 4 "memory_operand" ""))
4314 (clobber (match_scratch 5 ""))]
4316 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4319 (clobber (match_dup 5))])
4320 (set (match_dup 0) (match_dup 4))]
4324 [(set (match_operand:DI 0 "memory_operand" "")
4325 (fix:DI (match_operand 1 "register_operand" "")))
4326 (use (match_operand:HI 2 "memory_operand" ""))
4327 (use (match_operand:HI 3 "memory_operand" ""))
4328 (clobber (match_operand:DI 4 "memory_operand" ""))
4329 (clobber (match_scratch 5 ""))]
4331 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4334 (clobber (match_dup 5))])]
4337 (define_insn "fix_trunc<mode>_i387"
4338 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4339 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4340 (use (match_operand:HI 2 "memory_operand" "m"))
4341 (use (match_operand:HI 3 "memory_operand" "m"))]
4342 "TARGET_80387 && !TARGET_FISTTP
4343 && FLOAT_MODE_P (GET_MODE (operands[1]))
4344 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4345 "* return output_fix_trunc (insn, operands, 0);"
4346 [(set_attr "type" "fistp")
4347 (set_attr "i387_cw" "trunc")
4348 (set_attr "mode" "<MODE>")])
4350 (define_insn "fix_trunc<mode>_i387_with_temp"
4351 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4352 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4353 (use (match_operand:HI 2 "memory_operand" "m,m"))
4354 (use (match_operand:HI 3 "memory_operand" "m,m"))
4355 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4356 "TARGET_80387 && !TARGET_FISTTP
4357 && FLOAT_MODE_P (GET_MODE (operands[1]))
4358 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4360 [(set_attr "type" "fistp")
4361 (set_attr "i387_cw" "trunc")
4362 (set_attr "mode" "<MODE>")])
4365 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4366 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4367 (use (match_operand:HI 2 "memory_operand" ""))
4368 (use (match_operand:HI 3 "memory_operand" ""))
4369 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4371 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4373 (use (match_dup 3))])
4374 (set (match_dup 0) (match_dup 4))]
4378 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4379 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4380 (use (match_operand:HI 2 "memory_operand" ""))
4381 (use (match_operand:HI 3 "memory_operand" ""))
4382 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4384 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4386 (use (match_dup 3))])]
4389 (define_insn "x86_fnstcw_1"
4390 [(set (match_operand:HI 0 "memory_operand" "=m")
4391 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4394 [(set_attr "length" "2")
4395 (set_attr "mode" "HI")
4396 (set_attr "unit" "i387")])
4398 (define_insn "x86_fldcw_1"
4399 [(set (reg:HI FPSR_REG)
4400 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4403 [(set_attr "length" "2")
4404 (set_attr "mode" "HI")
4405 (set_attr "unit" "i387")
4406 (set_attr "athlon_decode" "vector")])
4408 ;; Conversion between fixed point and floating point.
4410 ;; Even though we only accept memory inputs, the backend _really_
4411 ;; wants to be able to do this between registers.
4413 (define_expand "floathisf2"
4414 [(set (match_operand:SF 0 "register_operand" "")
4415 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4416 "TARGET_80387 || TARGET_SSE_MATH"
4418 if (TARGET_SSE_MATH)
4420 emit_insn (gen_floatsisf2 (operands[0],
4421 convert_to_mode (SImode, operands[1], 0)));
4426 (define_insn "*floathisf2_i387"
4427 [(set (match_operand:SF 0 "register_operand" "=f,f")
4428 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4429 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4433 [(set_attr "type" "fmov,multi")
4434 (set_attr "mode" "SF")
4435 (set_attr "unit" "*,i387")
4436 (set_attr "fp_int_src" "true")])
4438 (define_expand "floatsisf2"
4439 [(set (match_operand:SF 0 "register_operand" "")
4440 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4441 "TARGET_80387 || TARGET_SSE_MATH"
4444 (define_insn "*floatsisf2_mixed"
4445 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4446 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4447 "TARGET_MIX_SSE_I387"
4451 cvtsi2ss\t{%1, %0|%0, %1}
4452 cvtsi2ss\t{%1, %0|%0, %1}"
4453 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4454 (set_attr "mode" "SF")
4455 (set_attr "unit" "*,i387,*,*")
4456 (set_attr "athlon_decode" "*,*,vector,double")
4457 (set_attr "fp_int_src" "true")])
4459 (define_insn "*floatsisf2_sse"
4460 [(set (match_operand:SF 0 "register_operand" "=x,x")
4461 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4463 "cvtsi2ss\t{%1, %0|%0, %1}"
4464 [(set_attr "type" "sseicvt")
4465 (set_attr "mode" "SF")
4466 (set_attr "athlon_decode" "vector,double")
4467 (set_attr "fp_int_src" "true")])
4469 (define_insn "*floatsisf2_i387"
4470 [(set (match_operand:SF 0 "register_operand" "=f,f")
4471 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4476 [(set_attr "type" "fmov,multi")
4477 (set_attr "mode" "SF")
4478 (set_attr "unit" "*,i387")
4479 (set_attr "fp_int_src" "true")])
4481 (define_expand "floatdisf2"
4482 [(set (match_operand:SF 0 "register_operand" "")
4483 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4484 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4487 (define_insn "*floatdisf2_mixed"
4488 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4489 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4490 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4494 cvtsi2ss{q}\t{%1, %0|%0, %1}
4495 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4496 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4497 (set_attr "mode" "SF")
4498 (set_attr "unit" "*,i387,*,*")
4499 (set_attr "athlon_decode" "*,*,vector,double")
4500 (set_attr "fp_int_src" "true")])
4502 (define_insn "*floatdisf2_sse"
4503 [(set (match_operand:SF 0 "register_operand" "=x,x")
4504 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4505 "TARGET_64BIT && TARGET_SSE_MATH"
4506 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4507 [(set_attr "type" "sseicvt")
4508 (set_attr "mode" "SF")
4509 (set_attr "athlon_decode" "vector,double")
4510 (set_attr "fp_int_src" "true")])
4512 (define_insn "*floatdisf2_i387"
4513 [(set (match_operand:SF 0 "register_operand" "=f,f")
4514 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4519 [(set_attr "type" "fmov,multi")
4520 (set_attr "mode" "SF")
4521 (set_attr "unit" "*,i387")
4522 (set_attr "fp_int_src" "true")])
4524 (define_expand "floathidf2"
4525 [(set (match_operand:DF 0 "register_operand" "")
4526 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4527 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4529 if (TARGET_SSE2 && TARGET_SSE_MATH)
4531 emit_insn (gen_floatsidf2 (operands[0],
4532 convert_to_mode (SImode, operands[1], 0)));
4537 (define_insn "*floathidf2_i387"
4538 [(set (match_operand:DF 0 "register_operand" "=f,f")
4539 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4540 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4544 [(set_attr "type" "fmov,multi")
4545 (set_attr "mode" "DF")
4546 (set_attr "unit" "*,i387")
4547 (set_attr "fp_int_src" "true")])
4549 (define_expand "floatsidf2"
4550 [(set (match_operand:DF 0 "register_operand" "")
4551 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4552 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4555 (define_insn "*floatsidf2_mixed"
4556 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4557 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4558 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4562 cvtsi2sd\t{%1, %0|%0, %1}
4563 cvtsi2sd\t{%1, %0|%0, %1}"
4564 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4565 (set_attr "mode" "DF")
4566 (set_attr "unit" "*,i387,*,*")
4567 (set_attr "athlon_decode" "*,*,double,direct")
4568 (set_attr "fp_int_src" "true")])
4570 (define_insn "*floatsidf2_sse"
4571 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4572 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4573 "TARGET_SSE2 && TARGET_SSE_MATH"
4574 "cvtsi2sd\t{%1, %0|%0, %1}"
4575 [(set_attr "type" "sseicvt")
4576 (set_attr "mode" "DF")
4577 (set_attr "athlon_decode" "double,direct")
4578 (set_attr "fp_int_src" "true")])
4580 (define_insn "*floatsidf2_i387"
4581 [(set (match_operand:DF 0 "register_operand" "=f,f")
4582 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4587 [(set_attr "type" "fmov,multi")
4588 (set_attr "mode" "DF")
4589 (set_attr "unit" "*,i387")
4590 (set_attr "fp_int_src" "true")])
4592 (define_expand "floatdidf2"
4593 [(set (match_operand:DF 0 "register_operand" "")
4594 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4595 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4598 (define_insn "*floatdidf2_mixed"
4599 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4600 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4601 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4605 cvtsi2sd{q}\t{%1, %0|%0, %1}
4606 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4607 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4608 (set_attr "mode" "DF")
4609 (set_attr "unit" "*,i387,*,*")
4610 (set_attr "athlon_decode" "*,*,double,direct")
4611 (set_attr "fp_int_src" "true")])
4613 (define_insn "*floatdidf2_sse"
4614 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4615 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4616 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4617 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4618 [(set_attr "type" "sseicvt")
4619 (set_attr "mode" "DF")
4620 (set_attr "athlon_decode" "double,direct")
4621 (set_attr "fp_int_src" "true")])
4623 (define_insn "*floatdidf2_i387"
4624 [(set (match_operand:DF 0 "register_operand" "=f,f")
4625 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4630 [(set_attr "type" "fmov,multi")
4631 (set_attr "mode" "DF")
4632 (set_attr "unit" "*,i387")
4633 (set_attr "fp_int_src" "true")])
4635 (define_insn "floathixf2"
4636 [(set (match_operand:XF 0 "register_operand" "=f,f")
4637 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4642 [(set_attr "type" "fmov,multi")
4643 (set_attr "mode" "XF")
4644 (set_attr "unit" "*,i387")
4645 (set_attr "fp_int_src" "true")])
4647 (define_insn "floatsixf2"
4648 [(set (match_operand:XF 0 "register_operand" "=f,f")
4649 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4654 [(set_attr "type" "fmov,multi")
4655 (set_attr "mode" "XF")
4656 (set_attr "unit" "*,i387")
4657 (set_attr "fp_int_src" "true")])
4659 (define_insn "floatdixf2"
4660 [(set (match_operand:XF 0 "register_operand" "=f,f")
4661 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4666 [(set_attr "type" "fmov,multi")
4667 (set_attr "mode" "XF")
4668 (set_attr "unit" "*,i387")
4669 (set_attr "fp_int_src" "true")])
4671 ;; %%% Kill these when reload knows how to do it.
4673 [(set (match_operand 0 "fp_register_operand" "")
4674 (float (match_operand 1 "register_operand" "")))]
4677 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4680 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4681 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4682 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4683 ix86_free_from_memory (GET_MODE (operands[1]));
4687 (define_expand "floatunssisf2"
4688 [(use (match_operand:SF 0 "register_operand" ""))
4689 (use (match_operand:SI 1 "register_operand" ""))]
4690 "!TARGET_64BIT && TARGET_SSE_MATH"
4691 "x86_emit_floatuns (operands); DONE;")
4693 (define_expand "floatunsdisf2"
4694 [(use (match_operand:SF 0 "register_operand" ""))
4695 (use (match_operand:DI 1 "register_operand" ""))]
4696 "TARGET_64BIT && TARGET_SSE_MATH"
4697 "x86_emit_floatuns (operands); DONE;")
4699 (define_expand "floatunsdidf2"
4700 [(use (match_operand:DF 0 "register_operand" ""))
4701 (use (match_operand:DI 1 "register_operand" ""))]
4702 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4703 "x86_emit_floatuns (operands); DONE;")
4705 ;; SSE extract/set expanders
4710 ;; %%% splits for addditi3
4712 (define_expand "addti3"
4713 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4714 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4715 (match_operand:TI 2 "x86_64_general_operand" "")))
4716 (clobber (reg:CC FLAGS_REG))]
4718 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4720 (define_insn "*addti3_1"
4721 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4722 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4723 (match_operand:TI 2 "general_operand" "roiF,riF")))
4724 (clobber (reg:CC FLAGS_REG))]
4725 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4729 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4730 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4731 (match_operand:TI 2 "general_operand" "")))
4732 (clobber (reg:CC FLAGS_REG))]
4733 "TARGET_64BIT && reload_completed"
4734 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4736 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4737 (parallel [(set (match_dup 3)
4738 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4741 (clobber (reg:CC FLAGS_REG))])]
4742 "split_ti (operands+0, 1, operands+0, operands+3);
4743 split_ti (operands+1, 1, operands+1, operands+4);
4744 split_ti (operands+2, 1, operands+2, operands+5);")
4746 ;; %%% splits for addsidi3
4747 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4748 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4749 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4751 (define_expand "adddi3"
4752 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4753 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4754 (match_operand:DI 2 "x86_64_general_operand" "")))
4755 (clobber (reg:CC FLAGS_REG))]
4757 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4759 (define_insn "*adddi3_1"
4760 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4761 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4762 (match_operand:DI 2 "general_operand" "roiF,riF")))
4763 (clobber (reg:CC FLAGS_REG))]
4764 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4768 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4769 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4770 (match_operand:DI 2 "general_operand" "")))
4771 (clobber (reg:CC FLAGS_REG))]
4772 "!TARGET_64BIT && reload_completed"
4773 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4775 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4776 (parallel [(set (match_dup 3)
4777 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4780 (clobber (reg:CC FLAGS_REG))])]
4781 "split_di (operands+0, 1, operands+0, operands+3);
4782 split_di (operands+1, 1, operands+1, operands+4);
4783 split_di (operands+2, 1, operands+2, operands+5);")
4785 (define_insn "adddi3_carry_rex64"
4786 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4787 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4788 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4789 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4790 (clobber (reg:CC FLAGS_REG))]
4791 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4792 "adc{q}\t{%2, %0|%0, %2}"
4793 [(set_attr "type" "alu")
4794 (set_attr "pent_pair" "pu")
4795 (set_attr "mode" "DI")])
4797 (define_insn "*adddi3_cc_rex64"
4798 [(set (reg:CC FLAGS_REG)
4799 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4800 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4802 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4803 (plus:DI (match_dup 1) (match_dup 2)))]
4804 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4805 "add{q}\t{%2, %0|%0, %2}"
4806 [(set_attr "type" "alu")
4807 (set_attr "mode" "DI")])
4809 (define_insn "addqi3_carry"
4810 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4811 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4812 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4813 (match_operand:QI 2 "general_operand" "qi,qm")))
4814 (clobber (reg:CC FLAGS_REG))]
4815 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4816 "adc{b}\t{%2, %0|%0, %2}"
4817 [(set_attr "type" "alu")
4818 (set_attr "pent_pair" "pu")
4819 (set_attr "mode" "QI")])
4821 (define_insn "addhi3_carry"
4822 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4823 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4824 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4825 (match_operand:HI 2 "general_operand" "ri,rm")))
4826 (clobber (reg:CC FLAGS_REG))]
4827 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4828 "adc{w}\t{%2, %0|%0, %2}"
4829 [(set_attr "type" "alu")
4830 (set_attr "pent_pair" "pu")
4831 (set_attr "mode" "HI")])
4833 (define_insn "addsi3_carry"
4834 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4835 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4836 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4837 (match_operand:SI 2 "general_operand" "ri,rm")))
4838 (clobber (reg:CC FLAGS_REG))]
4839 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4840 "adc{l}\t{%2, %0|%0, %2}"
4841 [(set_attr "type" "alu")
4842 (set_attr "pent_pair" "pu")
4843 (set_attr "mode" "SI")])
4845 (define_insn "*addsi3_carry_zext"
4846 [(set (match_operand:DI 0 "register_operand" "=r")
4848 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4849 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4850 (match_operand:SI 2 "general_operand" "rim"))))
4851 (clobber (reg:CC FLAGS_REG))]
4852 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4853 "adc{l}\t{%2, %k0|%k0, %2}"
4854 [(set_attr "type" "alu")
4855 (set_attr "pent_pair" "pu")
4856 (set_attr "mode" "SI")])
4858 (define_insn "*addsi3_cc"
4859 [(set (reg:CC FLAGS_REG)
4860 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4861 (match_operand:SI 2 "general_operand" "ri,rm")]
4863 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4864 (plus:SI (match_dup 1) (match_dup 2)))]
4865 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4866 "add{l}\t{%2, %0|%0, %2}"
4867 [(set_attr "type" "alu")
4868 (set_attr "mode" "SI")])
4870 (define_insn "addqi3_cc"
4871 [(set (reg:CC FLAGS_REG)
4872 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4873 (match_operand:QI 2 "general_operand" "qi,qm")]
4875 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4876 (plus:QI (match_dup 1) (match_dup 2)))]
4877 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4878 "add{b}\t{%2, %0|%0, %2}"
4879 [(set_attr "type" "alu")
4880 (set_attr "mode" "QI")])
4882 (define_expand "addsi3"
4883 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4884 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4885 (match_operand:SI 2 "general_operand" "")))
4886 (clobber (reg:CC FLAGS_REG))])]
4888 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4890 (define_insn "*lea_1"
4891 [(set (match_operand:SI 0 "register_operand" "=r")
4892 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4894 "lea{l}\t{%a1, %0|%0, %a1}"
4895 [(set_attr "type" "lea")
4896 (set_attr "mode" "SI")])
4898 (define_insn "*lea_1_rex64"
4899 [(set (match_operand:SI 0 "register_operand" "=r")
4900 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4902 "lea{l}\t{%a1, %0|%0, %a1}"
4903 [(set_attr "type" "lea")
4904 (set_attr "mode" "SI")])
4906 (define_insn "*lea_1_zext"
4907 [(set (match_operand:DI 0 "register_operand" "=r")
4909 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4911 "lea{l}\t{%a1, %k0|%k0, %a1}"
4912 [(set_attr "type" "lea")
4913 (set_attr "mode" "SI")])
4915 (define_insn "*lea_2_rex64"
4916 [(set (match_operand:DI 0 "register_operand" "=r")
4917 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4919 "lea{q}\t{%a1, %0|%0, %a1}"
4920 [(set_attr "type" "lea")
4921 (set_attr "mode" "DI")])
4923 ;; The lea patterns for non-Pmodes needs to be matched by several
4924 ;; insns converted to real lea by splitters.
4926 (define_insn_and_split "*lea_general_1"
4927 [(set (match_operand 0 "register_operand" "=r")
4928 (plus (plus (match_operand 1 "index_register_operand" "l")
4929 (match_operand 2 "register_operand" "r"))
4930 (match_operand 3 "immediate_operand" "i")))]
4931 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4932 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4933 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4934 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4935 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4936 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4937 || GET_MODE (operands[3]) == VOIDmode)"
4939 "&& reload_completed"
4943 operands[0] = gen_lowpart (SImode, operands[0]);
4944 operands[1] = gen_lowpart (Pmode, operands[1]);
4945 operands[2] = gen_lowpart (Pmode, operands[2]);
4946 operands[3] = gen_lowpart (Pmode, operands[3]);
4947 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4949 if (Pmode != SImode)
4950 pat = gen_rtx_SUBREG (SImode, pat, 0);
4951 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4954 [(set_attr "type" "lea")
4955 (set_attr "mode" "SI")])
4957 (define_insn_and_split "*lea_general_1_zext"
4958 [(set (match_operand:DI 0 "register_operand" "=r")
4960 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4961 (match_operand:SI 2 "register_operand" "r"))
4962 (match_operand:SI 3 "immediate_operand" "i"))))]
4965 "&& reload_completed"
4967 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4969 (match_dup 3)) 0)))]
4971 operands[1] = gen_lowpart (Pmode, operands[1]);
4972 operands[2] = gen_lowpart (Pmode, operands[2]);
4973 operands[3] = gen_lowpart (Pmode, operands[3]);
4975 [(set_attr "type" "lea")
4976 (set_attr "mode" "SI")])
4978 (define_insn_and_split "*lea_general_2"
4979 [(set (match_operand 0 "register_operand" "=r")
4980 (plus (mult (match_operand 1 "index_register_operand" "l")
4981 (match_operand 2 "const248_operand" "i"))
4982 (match_operand 3 "nonmemory_operand" "ri")))]
4983 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4984 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4985 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4986 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4987 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4988 || GET_MODE (operands[3]) == VOIDmode)"
4990 "&& reload_completed"
4994 operands[0] = gen_lowpart (SImode, operands[0]);
4995 operands[1] = gen_lowpart (Pmode, operands[1]);
4996 operands[3] = gen_lowpart (Pmode, operands[3]);
4997 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4999 if (Pmode != SImode)
5000 pat = gen_rtx_SUBREG (SImode, pat, 0);
5001 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5004 [(set_attr "type" "lea")
5005 (set_attr "mode" "SI")])
5007 (define_insn_and_split "*lea_general_2_zext"
5008 [(set (match_operand:DI 0 "register_operand" "=r")
5010 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5011 (match_operand:SI 2 "const248_operand" "n"))
5012 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5015 "&& reload_completed"
5017 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5019 (match_dup 3)) 0)))]
5021 operands[1] = gen_lowpart (Pmode, operands[1]);
5022 operands[3] = gen_lowpart (Pmode, operands[3]);
5024 [(set_attr "type" "lea")
5025 (set_attr "mode" "SI")])
5027 (define_insn_and_split "*lea_general_3"
5028 [(set (match_operand 0 "register_operand" "=r")
5029 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5030 (match_operand 2 "const248_operand" "i"))
5031 (match_operand 3 "register_operand" "r"))
5032 (match_operand 4 "immediate_operand" "i")))]
5033 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5034 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5035 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5036 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5037 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5039 "&& reload_completed"
5043 operands[0] = gen_lowpart (SImode, operands[0]);
5044 operands[1] = gen_lowpart (Pmode, operands[1]);
5045 operands[3] = gen_lowpart (Pmode, operands[3]);
5046 operands[4] = gen_lowpart (Pmode, operands[4]);
5047 pat = gen_rtx_PLUS (Pmode,
5048 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5052 if (Pmode != SImode)
5053 pat = gen_rtx_SUBREG (SImode, pat, 0);
5054 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5057 [(set_attr "type" "lea")
5058 (set_attr "mode" "SI")])
5060 (define_insn_and_split "*lea_general_3_zext"
5061 [(set (match_operand:DI 0 "register_operand" "=r")
5063 (plus:SI (plus:SI (mult:SI
5064 (match_operand:SI 1 "index_register_operand" "l")
5065 (match_operand:SI 2 "const248_operand" "n"))
5066 (match_operand:SI 3 "register_operand" "r"))
5067 (match_operand:SI 4 "immediate_operand" "i"))))]
5070 "&& reload_completed"
5072 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5075 (match_dup 4)) 0)))]
5077 operands[1] = gen_lowpart (Pmode, operands[1]);
5078 operands[3] = gen_lowpart (Pmode, operands[3]);
5079 operands[4] = gen_lowpart (Pmode, operands[4]);
5081 [(set_attr "type" "lea")
5082 (set_attr "mode" "SI")])
5084 (define_insn "*adddi_1_rex64"
5085 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5086 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5087 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5088 (clobber (reg:CC FLAGS_REG))]
5089 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5091 switch (get_attr_type (insn))
5094 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5095 return "lea{q}\t{%a2, %0|%0, %a2}";
5098 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5099 if (operands[2] == const1_rtx)
5100 return "inc{q}\t%0";
5103 gcc_assert (operands[2] == constm1_rtx);
5104 return "dec{q}\t%0";
5108 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5110 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5111 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5112 if (GET_CODE (operands[2]) == CONST_INT
5113 /* Avoid overflows. */
5114 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5115 && (INTVAL (operands[2]) == 128
5116 || (INTVAL (operands[2]) < 0
5117 && INTVAL (operands[2]) != -128)))
5119 operands[2] = GEN_INT (-INTVAL (operands[2]));
5120 return "sub{q}\t{%2, %0|%0, %2}";
5122 return "add{q}\t{%2, %0|%0, %2}";
5126 (cond [(eq_attr "alternative" "2")
5127 (const_string "lea")
5128 ; Current assemblers are broken and do not allow @GOTOFF in
5129 ; ought but a memory context.
5130 (match_operand:DI 2 "pic_symbolic_operand" "")
5131 (const_string "lea")
5132 (match_operand:DI 2 "incdec_operand" "")
5133 (const_string "incdec")
5135 (const_string "alu")))
5136 (set_attr "mode" "DI")])
5138 ;; Convert lea to the lea pattern to avoid flags dependency.
5140 [(set (match_operand:DI 0 "register_operand" "")
5141 (plus:DI (match_operand:DI 1 "register_operand" "")
5142 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5143 (clobber (reg:CC FLAGS_REG))]
5144 "TARGET_64BIT && reload_completed
5145 && true_regnum (operands[0]) != true_regnum (operands[1])"
5147 (plus:DI (match_dup 1)
5151 (define_insn "*adddi_2_rex64"
5152 [(set (reg FLAGS_REG)
5154 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5155 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5157 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5158 (plus:DI (match_dup 1) (match_dup 2)))]
5159 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5160 && ix86_binary_operator_ok (PLUS, DImode, operands)
5161 /* Current assemblers are broken and do not allow @GOTOFF in
5162 ought but a memory context. */
5163 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5165 switch (get_attr_type (insn))
5168 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5169 if (operands[2] == const1_rtx)
5170 return "inc{q}\t%0";
5173 gcc_assert (operands[2] == constm1_rtx);
5174 return "dec{q}\t%0";
5178 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5179 /* ???? We ought to handle there the 32bit case too
5180 - do we need new constraint? */
5181 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5182 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5183 if (GET_CODE (operands[2]) == CONST_INT
5184 /* Avoid overflows. */
5185 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5186 && (INTVAL (operands[2]) == 128
5187 || (INTVAL (operands[2]) < 0
5188 && INTVAL (operands[2]) != -128)))
5190 operands[2] = GEN_INT (-INTVAL (operands[2]));
5191 return "sub{q}\t{%2, %0|%0, %2}";
5193 return "add{q}\t{%2, %0|%0, %2}";
5197 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5198 (const_string "incdec")
5199 (const_string "alu")))
5200 (set_attr "mode" "DI")])
5202 (define_insn "*adddi_3_rex64"
5203 [(set (reg FLAGS_REG)
5204 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5205 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5206 (clobber (match_scratch:DI 0 "=r"))]
5208 && ix86_match_ccmode (insn, CCZmode)
5209 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5210 /* Current assemblers are broken and do not allow @GOTOFF in
5211 ought but a memory context. */
5212 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5214 switch (get_attr_type (insn))
5217 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5218 if (operands[2] == const1_rtx)
5219 return "inc{q}\t%0";
5222 gcc_assert (operands[2] == constm1_rtx);
5223 return "dec{q}\t%0";
5227 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5228 /* ???? We ought to handle there the 32bit case too
5229 - do we need new constraint? */
5230 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5231 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5232 if (GET_CODE (operands[2]) == CONST_INT
5233 /* Avoid overflows. */
5234 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5235 && (INTVAL (operands[2]) == 128
5236 || (INTVAL (operands[2]) < 0
5237 && INTVAL (operands[2]) != -128)))
5239 operands[2] = GEN_INT (-INTVAL (operands[2]));
5240 return "sub{q}\t{%2, %0|%0, %2}";
5242 return "add{q}\t{%2, %0|%0, %2}";
5246 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5247 (const_string "incdec")
5248 (const_string "alu")))
5249 (set_attr "mode" "DI")])
5251 ; For comparisons against 1, -1 and 128, we may generate better code
5252 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5253 ; is matched then. We can't accept general immediate, because for
5254 ; case of overflows, the result is messed up.
5255 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5257 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5258 ; only for comparisons not depending on it.
5259 (define_insn "*adddi_4_rex64"
5260 [(set (reg FLAGS_REG)
5261 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5262 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5263 (clobber (match_scratch:DI 0 "=rm"))]
5265 && ix86_match_ccmode (insn, CCGCmode)"
5267 switch (get_attr_type (insn))
5270 if (operands[2] == constm1_rtx)
5271 return "inc{q}\t%0";
5274 gcc_assert (operands[2] == const1_rtx);
5275 return "dec{q}\t%0";
5279 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5280 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5281 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5282 if ((INTVAL (operands[2]) == -128
5283 || (INTVAL (operands[2]) > 0
5284 && INTVAL (operands[2]) != 128))
5285 /* Avoid overflows. */
5286 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5287 return "sub{q}\t{%2, %0|%0, %2}";
5288 operands[2] = GEN_INT (-INTVAL (operands[2]));
5289 return "add{q}\t{%2, %0|%0, %2}";
5293 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5294 (const_string "incdec")
5295 (const_string "alu")))
5296 (set_attr "mode" "DI")])
5298 (define_insn "*adddi_5_rex64"
5299 [(set (reg FLAGS_REG)
5301 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5302 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5304 (clobber (match_scratch:DI 0 "=r"))]
5306 && ix86_match_ccmode (insn, CCGOCmode)
5307 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5308 /* Current assemblers are broken and do not allow @GOTOFF in
5309 ought but a memory context. */
5310 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5312 switch (get_attr_type (insn))
5315 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5316 if (operands[2] == const1_rtx)
5317 return "inc{q}\t%0";
5320 gcc_assert (operands[2] == constm1_rtx);
5321 return "dec{q}\t%0";
5325 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5326 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5327 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5328 if (GET_CODE (operands[2]) == CONST_INT
5329 /* Avoid overflows. */
5330 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5331 && (INTVAL (operands[2]) == 128
5332 || (INTVAL (operands[2]) < 0
5333 && INTVAL (operands[2]) != -128)))
5335 operands[2] = GEN_INT (-INTVAL (operands[2]));
5336 return "sub{q}\t{%2, %0|%0, %2}";
5338 return "add{q}\t{%2, %0|%0, %2}";
5342 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5343 (const_string "incdec")
5344 (const_string "alu")))
5345 (set_attr "mode" "DI")])
5348 (define_insn "*addsi_1"
5349 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5350 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5351 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5352 (clobber (reg:CC FLAGS_REG))]
5353 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5355 switch (get_attr_type (insn))
5358 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5359 return "lea{l}\t{%a2, %0|%0, %a2}";
5362 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5363 if (operands[2] == const1_rtx)
5364 return "inc{l}\t%0";
5367 gcc_assert (operands[2] == constm1_rtx);
5368 return "dec{l}\t%0";
5372 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5374 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5375 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5376 if (GET_CODE (operands[2]) == CONST_INT
5377 && (INTVAL (operands[2]) == 128
5378 || (INTVAL (operands[2]) < 0
5379 && INTVAL (operands[2]) != -128)))
5381 operands[2] = GEN_INT (-INTVAL (operands[2]));
5382 return "sub{l}\t{%2, %0|%0, %2}";
5384 return "add{l}\t{%2, %0|%0, %2}";
5388 (cond [(eq_attr "alternative" "2")
5389 (const_string "lea")
5390 ; Current assemblers are broken and do not allow @GOTOFF in
5391 ; ought but a memory context.
5392 (match_operand:SI 2 "pic_symbolic_operand" "")
5393 (const_string "lea")
5394 (match_operand:SI 2 "incdec_operand" "")
5395 (const_string "incdec")
5397 (const_string "alu")))
5398 (set_attr "mode" "SI")])
5400 ;; Convert lea to the lea pattern to avoid flags dependency.
5402 [(set (match_operand 0 "register_operand" "")
5403 (plus (match_operand 1 "register_operand" "")
5404 (match_operand 2 "nonmemory_operand" "")))
5405 (clobber (reg:CC FLAGS_REG))]
5407 && true_regnum (operands[0]) != true_regnum (operands[1])"
5411 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5412 may confuse gen_lowpart. */
5413 if (GET_MODE (operands[0]) != Pmode)
5415 operands[1] = gen_lowpart (Pmode, operands[1]);
5416 operands[2] = gen_lowpart (Pmode, operands[2]);
5418 operands[0] = gen_lowpart (SImode, operands[0]);
5419 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5420 if (Pmode != SImode)
5421 pat = gen_rtx_SUBREG (SImode, pat, 0);
5422 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5426 ;; It may seem that nonimmediate operand is proper one for operand 1.
5427 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5428 ;; we take care in ix86_binary_operator_ok to not allow two memory
5429 ;; operands so proper swapping will be done in reload. This allow
5430 ;; patterns constructed from addsi_1 to match.
5431 (define_insn "addsi_1_zext"
5432 [(set (match_operand:DI 0 "register_operand" "=r,r")
5434 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5435 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5436 (clobber (reg:CC FLAGS_REG))]
5437 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5439 switch (get_attr_type (insn))
5442 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5443 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5446 if (operands[2] == const1_rtx)
5447 return "inc{l}\t%k0";
5450 gcc_assert (operands[2] == constm1_rtx);
5451 return "dec{l}\t%k0";
5455 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5456 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5457 if (GET_CODE (operands[2]) == CONST_INT
5458 && (INTVAL (operands[2]) == 128
5459 || (INTVAL (operands[2]) < 0
5460 && INTVAL (operands[2]) != -128)))
5462 operands[2] = GEN_INT (-INTVAL (operands[2]));
5463 return "sub{l}\t{%2, %k0|%k0, %2}";
5465 return "add{l}\t{%2, %k0|%k0, %2}";
5469 (cond [(eq_attr "alternative" "1")
5470 (const_string "lea")
5471 ; Current assemblers are broken and do not allow @GOTOFF in
5472 ; ought but a memory context.
5473 (match_operand:SI 2 "pic_symbolic_operand" "")
5474 (const_string "lea")
5475 (match_operand:SI 2 "incdec_operand" "")
5476 (const_string "incdec")
5478 (const_string "alu")))
5479 (set_attr "mode" "SI")])
5481 ;; Convert lea to the lea pattern to avoid flags dependency.
5483 [(set (match_operand:DI 0 "register_operand" "")
5485 (plus:SI (match_operand:SI 1 "register_operand" "")
5486 (match_operand:SI 2 "nonmemory_operand" ""))))
5487 (clobber (reg:CC FLAGS_REG))]
5488 "TARGET_64BIT && reload_completed
5489 && true_regnum (operands[0]) != true_regnum (operands[1])"
5491 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5493 operands[1] = gen_lowpart (Pmode, operands[1]);
5494 operands[2] = gen_lowpart (Pmode, operands[2]);
5497 (define_insn "*addsi_2"
5498 [(set (reg FLAGS_REG)
5500 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5501 (match_operand:SI 2 "general_operand" "rmni,rni"))
5503 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5504 (plus:SI (match_dup 1) (match_dup 2)))]
5505 "ix86_match_ccmode (insn, CCGOCmode)
5506 && ix86_binary_operator_ok (PLUS, SImode, operands)
5507 /* Current assemblers are broken and do not allow @GOTOFF in
5508 ought but a memory context. */
5509 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5511 switch (get_attr_type (insn))
5514 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515 if (operands[2] == const1_rtx)
5516 return "inc{l}\t%0";
5519 gcc_assert (operands[2] == constm1_rtx);
5520 return "dec{l}\t%0";
5524 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5525 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5526 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5527 if (GET_CODE (operands[2]) == CONST_INT
5528 && (INTVAL (operands[2]) == 128
5529 || (INTVAL (operands[2]) < 0
5530 && INTVAL (operands[2]) != -128)))
5532 operands[2] = GEN_INT (-INTVAL (operands[2]));
5533 return "sub{l}\t{%2, %0|%0, %2}";
5535 return "add{l}\t{%2, %0|%0, %2}";
5539 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5540 (const_string "incdec")
5541 (const_string "alu")))
5542 (set_attr "mode" "SI")])
5544 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5545 (define_insn "*addsi_2_zext"
5546 [(set (reg FLAGS_REG)
5548 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5549 (match_operand:SI 2 "general_operand" "rmni"))
5551 (set (match_operand:DI 0 "register_operand" "=r")
5552 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5553 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5554 && ix86_binary_operator_ok (PLUS, SImode, operands)
5555 /* Current assemblers are broken and do not allow @GOTOFF in
5556 ought but a memory context. */
5557 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5559 switch (get_attr_type (insn))
5562 if (operands[2] == const1_rtx)
5563 return "inc{l}\t%k0";
5566 gcc_assert (operands[2] == constm1_rtx);
5567 return "dec{l}\t%k0";
5571 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5572 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5573 if (GET_CODE (operands[2]) == CONST_INT
5574 && (INTVAL (operands[2]) == 128
5575 || (INTVAL (operands[2]) < 0
5576 && INTVAL (operands[2]) != -128)))
5578 operands[2] = GEN_INT (-INTVAL (operands[2]));
5579 return "sub{l}\t{%2, %k0|%k0, %2}";
5581 return "add{l}\t{%2, %k0|%k0, %2}";
5585 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5586 (const_string "incdec")
5587 (const_string "alu")))
5588 (set_attr "mode" "SI")])
5590 (define_insn "*addsi_3"
5591 [(set (reg FLAGS_REG)
5592 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5593 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5594 (clobber (match_scratch:SI 0 "=r"))]
5595 "ix86_match_ccmode (insn, CCZmode)
5596 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5597 /* Current assemblers are broken and do not allow @GOTOFF in
5598 ought but a memory context. */
5599 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5601 switch (get_attr_type (insn))
5604 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5605 if (operands[2] == const1_rtx)
5606 return "inc{l}\t%0";
5609 gcc_assert (operands[2] == constm1_rtx);
5610 return "dec{l}\t%0";
5614 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5615 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5616 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5617 if (GET_CODE (operands[2]) == CONST_INT
5618 && (INTVAL (operands[2]) == 128
5619 || (INTVAL (operands[2]) < 0
5620 && INTVAL (operands[2]) != -128)))
5622 operands[2] = GEN_INT (-INTVAL (operands[2]));
5623 return "sub{l}\t{%2, %0|%0, %2}";
5625 return "add{l}\t{%2, %0|%0, %2}";
5629 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5630 (const_string "incdec")
5631 (const_string "alu")))
5632 (set_attr "mode" "SI")])
5634 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5635 (define_insn "*addsi_3_zext"
5636 [(set (reg FLAGS_REG)
5637 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5638 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5639 (set (match_operand:DI 0 "register_operand" "=r")
5640 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5641 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5642 && ix86_binary_operator_ok (PLUS, SImode, operands)
5643 /* Current assemblers are broken and do not allow @GOTOFF in
5644 ought but a memory context. */
5645 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5647 switch (get_attr_type (insn))
5650 if (operands[2] == const1_rtx)
5651 return "inc{l}\t%k0";
5654 gcc_assert (operands[2] == constm1_rtx);
5655 return "dec{l}\t%k0";
5659 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5660 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5661 if (GET_CODE (operands[2]) == CONST_INT
5662 && (INTVAL (operands[2]) == 128
5663 || (INTVAL (operands[2]) < 0
5664 && INTVAL (operands[2]) != -128)))
5666 operands[2] = GEN_INT (-INTVAL (operands[2]));
5667 return "sub{l}\t{%2, %k0|%k0, %2}";
5669 return "add{l}\t{%2, %k0|%k0, %2}";
5673 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5674 (const_string "incdec")
5675 (const_string "alu")))
5676 (set_attr "mode" "SI")])
5678 ; For comparisons against 1, -1 and 128, we may generate better code
5679 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5680 ; is matched then. We can't accept general immediate, because for
5681 ; case of overflows, the result is messed up.
5682 ; This pattern also don't hold of 0x80000000, since the value overflows
5684 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5685 ; only for comparisons not depending on it.
5686 (define_insn "*addsi_4"
5687 [(set (reg FLAGS_REG)
5688 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5689 (match_operand:SI 2 "const_int_operand" "n")))
5690 (clobber (match_scratch:SI 0 "=rm"))]
5691 "ix86_match_ccmode (insn, CCGCmode)
5692 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5694 switch (get_attr_type (insn))
5697 if (operands[2] == constm1_rtx)
5698 return "inc{l}\t%0";
5701 gcc_assert (operands[2] == const1_rtx);
5702 return "dec{l}\t%0";
5706 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5707 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5708 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5709 if ((INTVAL (operands[2]) == -128
5710 || (INTVAL (operands[2]) > 0
5711 && INTVAL (operands[2]) != 128)))
5712 return "sub{l}\t{%2, %0|%0, %2}";
5713 operands[2] = GEN_INT (-INTVAL (operands[2]));
5714 return "add{l}\t{%2, %0|%0, %2}";
5718 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5719 (const_string "incdec")
5720 (const_string "alu")))
5721 (set_attr "mode" "SI")])
5723 (define_insn "*addsi_5"
5724 [(set (reg FLAGS_REG)
5726 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5727 (match_operand:SI 2 "general_operand" "rmni"))
5729 (clobber (match_scratch:SI 0 "=r"))]
5730 "ix86_match_ccmode (insn, CCGOCmode)
5731 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5732 /* Current assemblers are broken and do not allow @GOTOFF in
5733 ought but a memory context. */
5734 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5736 switch (get_attr_type (insn))
5739 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5740 if (operands[2] == const1_rtx)
5741 return "inc{l}\t%0";
5744 gcc_assert (operands[2] == constm1_rtx);
5745 return "dec{l}\t%0";
5749 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5750 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5751 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5752 if (GET_CODE (operands[2]) == CONST_INT
5753 && (INTVAL (operands[2]) == 128
5754 || (INTVAL (operands[2]) < 0
5755 && INTVAL (operands[2]) != -128)))
5757 operands[2] = GEN_INT (-INTVAL (operands[2]));
5758 return "sub{l}\t{%2, %0|%0, %2}";
5760 return "add{l}\t{%2, %0|%0, %2}";
5764 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5765 (const_string "incdec")
5766 (const_string "alu")))
5767 (set_attr "mode" "SI")])
5769 (define_expand "addhi3"
5770 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5771 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5772 (match_operand:HI 2 "general_operand" "")))
5773 (clobber (reg:CC FLAGS_REG))])]
5774 "TARGET_HIMODE_MATH"
5775 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5777 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5778 ;; type optimizations enabled by define-splits. This is not important
5779 ;; for PII, and in fact harmful because of partial register stalls.
5781 (define_insn "*addhi_1_lea"
5782 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5783 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5784 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5785 (clobber (reg:CC FLAGS_REG))]
5786 "!TARGET_PARTIAL_REG_STALL
5787 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5789 switch (get_attr_type (insn))
5794 if (operands[2] == const1_rtx)
5795 return "inc{w}\t%0";
5798 gcc_assert (operands[2] == constm1_rtx);
5799 return "dec{w}\t%0";
5803 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5804 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5805 if (GET_CODE (operands[2]) == CONST_INT
5806 && (INTVAL (operands[2]) == 128
5807 || (INTVAL (operands[2]) < 0
5808 && INTVAL (operands[2]) != -128)))
5810 operands[2] = GEN_INT (-INTVAL (operands[2]));
5811 return "sub{w}\t{%2, %0|%0, %2}";
5813 return "add{w}\t{%2, %0|%0, %2}";
5817 (if_then_else (eq_attr "alternative" "2")
5818 (const_string "lea")
5819 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5820 (const_string "incdec")
5821 (const_string "alu"))))
5822 (set_attr "mode" "HI,HI,SI")])
5824 (define_insn "*addhi_1"
5825 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5826 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5827 (match_operand:HI 2 "general_operand" "ri,rm")))
5828 (clobber (reg:CC FLAGS_REG))]
5829 "TARGET_PARTIAL_REG_STALL
5830 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5832 switch (get_attr_type (insn))
5835 if (operands[2] == const1_rtx)
5836 return "inc{w}\t%0";
5839 gcc_assert (operands[2] == constm1_rtx);
5840 return "dec{w}\t%0";
5844 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5845 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5846 if (GET_CODE (operands[2]) == CONST_INT
5847 && (INTVAL (operands[2]) == 128
5848 || (INTVAL (operands[2]) < 0
5849 && INTVAL (operands[2]) != -128)))
5851 operands[2] = GEN_INT (-INTVAL (operands[2]));
5852 return "sub{w}\t{%2, %0|%0, %2}";
5854 return "add{w}\t{%2, %0|%0, %2}";
5858 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5859 (const_string "incdec")
5860 (const_string "alu")))
5861 (set_attr "mode" "HI")])
5863 (define_insn "*addhi_2"
5864 [(set (reg FLAGS_REG)
5866 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5867 (match_operand:HI 2 "general_operand" "rmni,rni"))
5869 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5870 (plus:HI (match_dup 1) (match_dup 2)))]
5871 "ix86_match_ccmode (insn, CCGOCmode)
5872 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5874 switch (get_attr_type (insn))
5877 if (operands[2] == const1_rtx)
5878 return "inc{w}\t%0";
5881 gcc_assert (operands[2] == constm1_rtx);
5882 return "dec{w}\t%0";
5886 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5887 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5888 if (GET_CODE (operands[2]) == CONST_INT
5889 && (INTVAL (operands[2]) == 128
5890 || (INTVAL (operands[2]) < 0
5891 && INTVAL (operands[2]) != -128)))
5893 operands[2] = GEN_INT (-INTVAL (operands[2]));
5894 return "sub{w}\t{%2, %0|%0, %2}";
5896 return "add{w}\t{%2, %0|%0, %2}";
5900 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set_attr "mode" "HI")])
5905 (define_insn "*addhi_3"
5906 [(set (reg FLAGS_REG)
5907 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5908 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5909 (clobber (match_scratch:HI 0 "=r"))]
5910 "ix86_match_ccmode (insn, CCZmode)
5911 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5913 switch (get_attr_type (insn))
5916 if (operands[2] == const1_rtx)
5917 return "inc{w}\t%0";
5920 gcc_assert (operands[2] == constm1_rtx);
5921 return "dec{w}\t%0";
5925 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5926 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5927 if (GET_CODE (operands[2]) == CONST_INT
5928 && (INTVAL (operands[2]) == 128
5929 || (INTVAL (operands[2]) < 0
5930 && INTVAL (operands[2]) != -128)))
5932 operands[2] = GEN_INT (-INTVAL (operands[2]));
5933 return "sub{w}\t{%2, %0|%0, %2}";
5935 return "add{w}\t{%2, %0|%0, %2}";
5939 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5940 (const_string "incdec")
5941 (const_string "alu")))
5942 (set_attr "mode" "HI")])
5944 ; See comments above addsi_4 for details.
5945 (define_insn "*addhi_4"
5946 [(set (reg FLAGS_REG)
5947 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5948 (match_operand:HI 2 "const_int_operand" "n")))
5949 (clobber (match_scratch:HI 0 "=rm"))]
5950 "ix86_match_ccmode (insn, CCGCmode)
5951 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5953 switch (get_attr_type (insn))
5956 if (operands[2] == constm1_rtx)
5957 return "inc{w}\t%0";
5960 gcc_assert (operands[2] == const1_rtx);
5961 return "dec{w}\t%0";
5965 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5966 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5967 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5968 if ((INTVAL (operands[2]) == -128
5969 || (INTVAL (operands[2]) > 0
5970 && INTVAL (operands[2]) != 128)))
5971 return "sub{w}\t{%2, %0|%0, %2}";
5972 operands[2] = GEN_INT (-INTVAL (operands[2]));
5973 return "add{w}\t{%2, %0|%0, %2}";
5977 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5978 (const_string "incdec")
5979 (const_string "alu")))
5980 (set_attr "mode" "SI")])
5983 (define_insn "*addhi_5"
5984 [(set (reg FLAGS_REG)
5986 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5987 (match_operand:HI 2 "general_operand" "rmni"))
5989 (clobber (match_scratch:HI 0 "=r"))]
5990 "ix86_match_ccmode (insn, CCGOCmode)
5991 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5993 switch (get_attr_type (insn))
5996 if (operands[2] == const1_rtx)
5997 return "inc{w}\t%0";
6000 gcc_assert (operands[2] == constm1_rtx);
6001 return "dec{w}\t%0";
6005 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6006 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6007 if (GET_CODE (operands[2]) == CONST_INT
6008 && (INTVAL (operands[2]) == 128
6009 || (INTVAL (operands[2]) < 0
6010 && INTVAL (operands[2]) != -128)))
6012 operands[2] = GEN_INT (-INTVAL (operands[2]));
6013 return "sub{w}\t{%2, %0|%0, %2}";
6015 return "add{w}\t{%2, %0|%0, %2}";
6019 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6020 (const_string "incdec")
6021 (const_string "alu")))
6022 (set_attr "mode" "HI")])
6024 (define_expand "addqi3"
6025 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6026 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6027 (match_operand:QI 2 "general_operand" "")))
6028 (clobber (reg:CC FLAGS_REG))])]
6029 "TARGET_QIMODE_MATH"
6030 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6032 ;; %%% Potential partial reg stall on alternative 2. What to do?
6033 (define_insn "*addqi_1_lea"
6034 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6035 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6036 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6037 (clobber (reg:CC FLAGS_REG))]
6038 "!TARGET_PARTIAL_REG_STALL
6039 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6041 int widen = (which_alternative == 2);
6042 switch (get_attr_type (insn))
6047 if (operands[2] == const1_rtx)
6048 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6051 gcc_assert (operands[2] == constm1_rtx);
6052 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6056 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6057 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6058 if (GET_CODE (operands[2]) == CONST_INT
6059 && (INTVAL (operands[2]) == 128
6060 || (INTVAL (operands[2]) < 0
6061 && INTVAL (operands[2]) != -128)))
6063 operands[2] = GEN_INT (-INTVAL (operands[2]));
6065 return "sub{l}\t{%2, %k0|%k0, %2}";
6067 return "sub{b}\t{%2, %0|%0, %2}";
6070 return "add{l}\t{%k2, %k0|%k0, %k2}";
6072 return "add{b}\t{%2, %0|%0, %2}";
6076 (if_then_else (eq_attr "alternative" "3")
6077 (const_string "lea")
6078 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6079 (const_string "incdec")
6080 (const_string "alu"))))
6081 (set_attr "mode" "QI,QI,SI,SI")])
6083 (define_insn "*addqi_1"
6084 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6085 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6086 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6087 (clobber (reg:CC FLAGS_REG))]
6088 "TARGET_PARTIAL_REG_STALL
6089 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6091 int widen = (which_alternative == 2);
6092 switch (get_attr_type (insn))
6095 if (operands[2] == const1_rtx)
6096 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6099 gcc_assert (operands[2] == constm1_rtx);
6100 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6104 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6105 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6106 if (GET_CODE (operands[2]) == CONST_INT
6107 && (INTVAL (operands[2]) == 128
6108 || (INTVAL (operands[2]) < 0
6109 && INTVAL (operands[2]) != -128)))
6111 operands[2] = GEN_INT (-INTVAL (operands[2]));
6113 return "sub{l}\t{%2, %k0|%k0, %2}";
6115 return "sub{b}\t{%2, %0|%0, %2}";
6118 return "add{l}\t{%k2, %k0|%k0, %k2}";
6120 return "add{b}\t{%2, %0|%0, %2}";
6124 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6125 (const_string "incdec")
6126 (const_string "alu")))
6127 (set_attr "mode" "QI,QI,SI")])
6129 (define_insn "*addqi_1_slp"
6130 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6131 (plus:QI (match_dup 0)
6132 (match_operand:QI 1 "general_operand" "qn,qnm")))
6133 (clobber (reg:CC FLAGS_REG))]
6134 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6135 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6137 switch (get_attr_type (insn))
6140 if (operands[1] == const1_rtx)
6141 return "inc{b}\t%0";
6144 gcc_assert (operands[1] == constm1_rtx);
6145 return "dec{b}\t%0";
6149 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6150 if (GET_CODE (operands[1]) == CONST_INT
6151 && INTVAL (operands[1]) < 0)
6153 operands[1] = GEN_INT (-INTVAL (operands[1]));
6154 return "sub{b}\t{%1, %0|%0, %1}";
6156 return "add{b}\t{%1, %0|%0, %1}";
6160 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6161 (const_string "incdec")
6162 (const_string "alu1")))
6163 (set (attr "memory")
6164 (if_then_else (match_operand 1 "memory_operand" "")
6165 (const_string "load")
6166 (const_string "none")))
6167 (set_attr "mode" "QI")])
6169 (define_insn "*addqi_2"
6170 [(set (reg FLAGS_REG)
6172 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6173 (match_operand:QI 2 "general_operand" "qmni,qni"))
6175 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6176 (plus:QI (match_dup 1) (match_dup 2)))]
6177 "ix86_match_ccmode (insn, CCGOCmode)
6178 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6180 switch (get_attr_type (insn))
6183 if (operands[2] == const1_rtx)
6184 return "inc{b}\t%0";
6187 gcc_assert (operands[2] == constm1_rtx
6188 || (GET_CODE (operands[2]) == CONST_INT
6189 && INTVAL (operands[2]) == 255));
6190 return "dec{b}\t%0";
6194 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6195 if (GET_CODE (operands[2]) == CONST_INT
6196 && INTVAL (operands[2]) < 0)
6198 operands[2] = GEN_INT (-INTVAL (operands[2]));
6199 return "sub{b}\t{%2, %0|%0, %2}";
6201 return "add{b}\t{%2, %0|%0, %2}";
6205 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6206 (const_string "incdec")
6207 (const_string "alu")))
6208 (set_attr "mode" "QI")])
6210 (define_insn "*addqi_3"
6211 [(set (reg FLAGS_REG)
6212 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6213 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6214 (clobber (match_scratch:QI 0 "=q"))]
6215 "ix86_match_ccmode (insn, CCZmode)
6216 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6218 switch (get_attr_type (insn))
6221 if (operands[2] == const1_rtx)
6222 return "inc{b}\t%0";
6225 gcc_assert (operands[2] == constm1_rtx
6226 || (GET_CODE (operands[2]) == CONST_INT
6227 && INTVAL (operands[2]) == 255));
6228 return "dec{b}\t%0";
6232 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6233 if (GET_CODE (operands[2]) == CONST_INT
6234 && INTVAL (operands[2]) < 0)
6236 operands[2] = GEN_INT (-INTVAL (operands[2]));
6237 return "sub{b}\t{%2, %0|%0, %2}";
6239 return "add{b}\t{%2, %0|%0, %2}";
6243 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6244 (const_string "incdec")
6245 (const_string "alu")))
6246 (set_attr "mode" "QI")])
6248 ; See comments above addsi_4 for details.
6249 (define_insn "*addqi_4"
6250 [(set (reg FLAGS_REG)
6251 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6252 (match_operand:QI 2 "const_int_operand" "n")))
6253 (clobber (match_scratch:QI 0 "=qm"))]
6254 "ix86_match_ccmode (insn, CCGCmode)
6255 && (INTVAL (operands[2]) & 0xff) != 0x80"
6257 switch (get_attr_type (insn))
6260 if (operands[2] == constm1_rtx
6261 || (GET_CODE (operands[2]) == CONST_INT
6262 && INTVAL (operands[2]) == 255))
6263 return "inc{b}\t%0";
6266 gcc_assert (operands[2] == const1_rtx);
6267 return "dec{b}\t%0";
6271 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6272 if (INTVAL (operands[2]) < 0)
6274 operands[2] = GEN_INT (-INTVAL (operands[2]));
6275 return "add{b}\t{%2, %0|%0, %2}";
6277 return "sub{b}\t{%2, %0|%0, %2}";
6281 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6282 (const_string "incdec")
6283 (const_string "alu")))
6284 (set_attr "mode" "QI")])
6287 (define_insn "*addqi_5"
6288 [(set (reg FLAGS_REG)
6290 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6291 (match_operand:QI 2 "general_operand" "qmni"))
6293 (clobber (match_scratch:QI 0 "=q"))]
6294 "ix86_match_ccmode (insn, CCGOCmode)
6295 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6297 switch (get_attr_type (insn))
6300 if (operands[2] == const1_rtx)
6301 return "inc{b}\t%0";
6304 gcc_assert (operands[2] == constm1_rtx
6305 || (GET_CODE (operands[2]) == CONST_INT
6306 && INTVAL (operands[2]) == 255));
6307 return "dec{b}\t%0";
6311 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6312 if (GET_CODE (operands[2]) == CONST_INT
6313 && INTVAL (operands[2]) < 0)
6315 operands[2] = GEN_INT (-INTVAL (operands[2]));
6316 return "sub{b}\t{%2, %0|%0, %2}";
6318 return "add{b}\t{%2, %0|%0, %2}";
6322 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6323 (const_string "incdec")
6324 (const_string "alu")))
6325 (set_attr "mode" "QI")])
6328 (define_insn "addqi_ext_1"
6329 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6334 (match_operand 1 "ext_register_operand" "0")
6337 (match_operand:QI 2 "general_operand" "Qmn")))
6338 (clobber (reg:CC FLAGS_REG))]
6341 switch (get_attr_type (insn))
6344 if (operands[2] == const1_rtx)
6345 return "inc{b}\t%h0";
6348 gcc_assert (operands[2] == constm1_rtx
6349 || (GET_CODE (operands[2]) == CONST_INT
6350 && INTVAL (operands[2]) == 255));
6351 return "dec{b}\t%h0";
6355 return "add{b}\t{%2, %h0|%h0, %2}";
6359 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6360 (const_string "incdec")
6361 (const_string "alu")))
6362 (set_attr "mode" "QI")])
6364 (define_insn "*addqi_ext_1_rex64"
6365 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6370 (match_operand 1 "ext_register_operand" "0")
6373 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6374 (clobber (reg:CC FLAGS_REG))]
6377 switch (get_attr_type (insn))
6380 if (operands[2] == const1_rtx)
6381 return "inc{b}\t%h0";
6384 gcc_assert (operands[2] == constm1_rtx
6385 || (GET_CODE (operands[2]) == CONST_INT
6386 && INTVAL (operands[2]) == 255));
6387 return "dec{b}\t%h0";
6391 return "add{b}\t{%2, %h0|%h0, %2}";
6395 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6396 (const_string "incdec")
6397 (const_string "alu")))
6398 (set_attr "mode" "QI")])
6400 (define_insn "*addqi_ext_2"
6401 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6406 (match_operand 1 "ext_register_operand" "%0")
6410 (match_operand 2 "ext_register_operand" "Q")
6413 (clobber (reg:CC FLAGS_REG))]
6415 "add{b}\t{%h2, %h0|%h0, %h2}"
6416 [(set_attr "type" "alu")
6417 (set_attr "mode" "QI")])
6419 ;; The patterns that match these are at the end of this file.
6421 (define_expand "addxf3"
6422 [(set (match_operand:XF 0 "register_operand" "")
6423 (plus:XF (match_operand:XF 1 "register_operand" "")
6424 (match_operand:XF 2 "register_operand" "")))]
6428 (define_expand "adddf3"
6429 [(set (match_operand:DF 0 "register_operand" "")
6430 (plus:DF (match_operand:DF 1 "register_operand" "")
6431 (match_operand:DF 2 "nonimmediate_operand" "")))]
6432 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6435 (define_expand "addsf3"
6436 [(set (match_operand:SF 0 "register_operand" "")
6437 (plus:SF (match_operand:SF 1 "register_operand" "")
6438 (match_operand:SF 2 "nonimmediate_operand" "")))]
6439 "TARGET_80387 || TARGET_SSE_MATH"
6442 ;; Subtract instructions
6444 ;; %%% splits for subditi3
6446 (define_expand "subti3"
6447 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6448 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6449 (match_operand:TI 2 "x86_64_general_operand" "")))
6450 (clobber (reg:CC FLAGS_REG))])]
6452 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6454 (define_insn "*subti3_1"
6455 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6456 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6457 (match_operand:TI 2 "general_operand" "roiF,riF")))
6458 (clobber (reg:CC FLAGS_REG))]
6459 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6463 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6464 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6465 (match_operand:TI 2 "general_operand" "")))
6466 (clobber (reg:CC FLAGS_REG))]
6467 "TARGET_64BIT && reload_completed"
6468 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6469 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6470 (parallel [(set (match_dup 3)
6471 (minus:DI (match_dup 4)
6472 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6474 (clobber (reg:CC FLAGS_REG))])]
6475 "split_ti (operands+0, 1, operands+0, operands+3);
6476 split_ti (operands+1, 1, operands+1, operands+4);
6477 split_ti (operands+2, 1, operands+2, operands+5);")
6479 ;; %%% splits for subsidi3
6481 (define_expand "subdi3"
6482 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6483 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6484 (match_operand:DI 2 "x86_64_general_operand" "")))
6485 (clobber (reg:CC FLAGS_REG))])]
6487 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6489 (define_insn "*subdi3_1"
6490 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6491 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6492 (match_operand:DI 2 "general_operand" "roiF,riF")))
6493 (clobber (reg:CC FLAGS_REG))]
6494 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6498 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6499 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6500 (match_operand:DI 2 "general_operand" "")))
6501 (clobber (reg:CC FLAGS_REG))]
6502 "!TARGET_64BIT && reload_completed"
6503 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6504 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6505 (parallel [(set (match_dup 3)
6506 (minus:SI (match_dup 4)
6507 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6509 (clobber (reg:CC FLAGS_REG))])]
6510 "split_di (operands+0, 1, operands+0, operands+3);
6511 split_di (operands+1, 1, operands+1, operands+4);
6512 split_di (operands+2, 1, operands+2, operands+5);")
6514 (define_insn "subdi3_carry_rex64"
6515 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6516 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6517 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6518 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6519 (clobber (reg:CC FLAGS_REG))]
6520 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6521 "sbb{q}\t{%2, %0|%0, %2}"
6522 [(set_attr "type" "alu")
6523 (set_attr "pent_pair" "pu")
6524 (set_attr "mode" "DI")])
6526 (define_insn "*subdi_1_rex64"
6527 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6528 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6529 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6530 (clobber (reg:CC FLAGS_REG))]
6531 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6532 "sub{q}\t{%2, %0|%0, %2}"
6533 [(set_attr "type" "alu")
6534 (set_attr "mode" "DI")])
6536 (define_insn "*subdi_2_rex64"
6537 [(set (reg FLAGS_REG)
6539 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6540 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6542 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6543 (minus:DI (match_dup 1) (match_dup 2)))]
6544 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6545 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6546 "sub{q}\t{%2, %0|%0, %2}"
6547 [(set_attr "type" "alu")
6548 (set_attr "mode" "DI")])
6550 (define_insn "*subdi_3_rex63"
6551 [(set (reg FLAGS_REG)
6552 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6553 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6554 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6555 (minus:DI (match_dup 1) (match_dup 2)))]
6556 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6557 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6558 "sub{q}\t{%2, %0|%0, %2}"
6559 [(set_attr "type" "alu")
6560 (set_attr "mode" "DI")])
6562 (define_insn "subqi3_carry"
6563 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6564 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6565 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6566 (match_operand:QI 2 "general_operand" "qi,qm"))))
6567 (clobber (reg:CC FLAGS_REG))]
6568 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6569 "sbb{b}\t{%2, %0|%0, %2}"
6570 [(set_attr "type" "alu")
6571 (set_attr "pent_pair" "pu")
6572 (set_attr "mode" "QI")])
6574 (define_insn "subhi3_carry"
6575 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6576 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6577 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6578 (match_operand:HI 2 "general_operand" "ri,rm"))))
6579 (clobber (reg:CC FLAGS_REG))]
6580 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6581 "sbb{w}\t{%2, %0|%0, %2}"
6582 [(set_attr "type" "alu")
6583 (set_attr "pent_pair" "pu")
6584 (set_attr "mode" "HI")])
6586 (define_insn "subsi3_carry"
6587 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6588 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6589 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6590 (match_operand:SI 2 "general_operand" "ri,rm"))))
6591 (clobber (reg:CC FLAGS_REG))]
6592 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6593 "sbb{l}\t{%2, %0|%0, %2}"
6594 [(set_attr "type" "alu")
6595 (set_attr "pent_pair" "pu")
6596 (set_attr "mode" "SI")])
6598 (define_insn "subsi3_carry_zext"
6599 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6601 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6602 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6603 (match_operand:SI 2 "general_operand" "ri,rm")))))
6604 (clobber (reg:CC FLAGS_REG))]
6605 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6606 "sbb{l}\t{%2, %k0|%k0, %2}"
6607 [(set_attr "type" "alu")
6608 (set_attr "pent_pair" "pu")
6609 (set_attr "mode" "SI")])
6611 (define_expand "subsi3"
6612 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6613 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6614 (match_operand:SI 2 "general_operand" "")))
6615 (clobber (reg:CC FLAGS_REG))])]
6617 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6619 (define_insn "*subsi_1"
6620 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6621 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6622 (match_operand:SI 2 "general_operand" "ri,rm")))
6623 (clobber (reg:CC FLAGS_REG))]
6624 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6625 "sub{l}\t{%2, %0|%0, %2}"
6626 [(set_attr "type" "alu")
6627 (set_attr "mode" "SI")])
6629 (define_insn "*subsi_1_zext"
6630 [(set (match_operand:DI 0 "register_operand" "=r")
6632 (minus:SI (match_operand:SI 1 "register_operand" "0")
6633 (match_operand:SI 2 "general_operand" "rim"))))
6634 (clobber (reg:CC FLAGS_REG))]
6635 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6636 "sub{l}\t{%2, %k0|%k0, %2}"
6637 [(set_attr "type" "alu")
6638 (set_attr "mode" "SI")])
6640 (define_insn "*subsi_2"
6641 [(set (reg FLAGS_REG)
6643 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6644 (match_operand:SI 2 "general_operand" "ri,rm"))
6646 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6647 (minus:SI (match_dup 1) (match_dup 2)))]
6648 "ix86_match_ccmode (insn, CCGOCmode)
6649 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650 "sub{l}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "mode" "SI")])
6654 (define_insn "*subsi_2_zext"
6655 [(set (reg FLAGS_REG)
6657 (minus:SI (match_operand:SI 1 "register_operand" "0")
6658 (match_operand:SI 2 "general_operand" "rim"))
6660 (set (match_operand:DI 0 "register_operand" "=r")
6662 (minus:SI (match_dup 1)
6664 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6665 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6666 "sub{l}\t{%2, %k0|%k0, %2}"
6667 [(set_attr "type" "alu")
6668 (set_attr "mode" "SI")])
6670 (define_insn "*subsi_3"
6671 [(set (reg FLAGS_REG)
6672 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673 (match_operand:SI 2 "general_operand" "ri,rm")))
6674 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6675 (minus:SI (match_dup 1) (match_dup 2)))]
6676 "ix86_match_ccmode (insn, CCmode)
6677 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6678 "sub{l}\t{%2, %0|%0, %2}"
6679 [(set_attr "type" "alu")
6680 (set_attr "mode" "SI")])
6682 (define_insn "*subsi_3_zext"
6683 [(set (reg FLAGS_REG)
6684 (compare (match_operand:SI 1 "register_operand" "0")
6685 (match_operand:SI 2 "general_operand" "rim")))
6686 (set (match_operand:DI 0 "register_operand" "=r")
6688 (minus:SI (match_dup 1)
6690 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6691 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6692 "sub{q}\t{%2, %0|%0, %2}"
6693 [(set_attr "type" "alu")
6694 (set_attr "mode" "DI")])
6696 (define_expand "subhi3"
6697 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6698 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6699 (match_operand:HI 2 "general_operand" "")))
6700 (clobber (reg:CC FLAGS_REG))])]
6701 "TARGET_HIMODE_MATH"
6702 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6704 (define_insn "*subhi_1"
6705 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6706 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6707 (match_operand:HI 2 "general_operand" "ri,rm")))
6708 (clobber (reg:CC FLAGS_REG))]
6709 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6710 "sub{w}\t{%2, %0|%0, %2}"
6711 [(set_attr "type" "alu")
6712 (set_attr "mode" "HI")])
6714 (define_insn "*subhi_2"
6715 [(set (reg FLAGS_REG)
6717 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6718 (match_operand:HI 2 "general_operand" "ri,rm"))
6720 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6721 (minus:HI (match_dup 1) (match_dup 2)))]
6722 "ix86_match_ccmode (insn, CCGOCmode)
6723 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6724 "sub{w}\t{%2, %0|%0, %2}"
6725 [(set_attr "type" "alu")
6726 (set_attr "mode" "HI")])
6728 (define_insn "*subhi_3"
6729 [(set (reg FLAGS_REG)
6730 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6731 (match_operand:HI 2 "general_operand" "ri,rm")))
6732 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6733 (minus:HI (match_dup 1) (match_dup 2)))]
6734 "ix86_match_ccmode (insn, CCmode)
6735 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6736 "sub{w}\t{%2, %0|%0, %2}"
6737 [(set_attr "type" "alu")
6738 (set_attr "mode" "HI")])
6740 (define_expand "subqi3"
6741 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6742 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6743 (match_operand:QI 2 "general_operand" "")))
6744 (clobber (reg:CC FLAGS_REG))])]
6745 "TARGET_QIMODE_MATH"
6746 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6748 (define_insn "*subqi_1"
6749 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6750 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6751 (match_operand:QI 2 "general_operand" "qn,qmn")))
6752 (clobber (reg:CC FLAGS_REG))]
6753 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6754 "sub{b}\t{%2, %0|%0, %2}"
6755 [(set_attr "type" "alu")
6756 (set_attr "mode" "QI")])
6758 (define_insn "*subqi_1_slp"
6759 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6760 (minus:QI (match_dup 0)
6761 (match_operand:QI 1 "general_operand" "qn,qmn")))
6762 (clobber (reg:CC FLAGS_REG))]
6763 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6764 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6765 "sub{b}\t{%1, %0|%0, %1}"
6766 [(set_attr "type" "alu1")
6767 (set_attr "mode" "QI")])
6769 (define_insn "*subqi_2"
6770 [(set (reg FLAGS_REG)
6772 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6773 (match_operand:QI 2 "general_operand" "qi,qm"))
6775 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6776 (minus:HI (match_dup 1) (match_dup 2)))]
6777 "ix86_match_ccmode (insn, CCGOCmode)
6778 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6779 "sub{b}\t{%2, %0|%0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "mode" "QI")])
6783 (define_insn "*subqi_3"
6784 [(set (reg FLAGS_REG)
6785 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6786 (match_operand:QI 2 "general_operand" "qi,qm")))
6787 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6788 (minus:HI (match_dup 1) (match_dup 2)))]
6789 "ix86_match_ccmode (insn, CCmode)
6790 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6791 "sub{b}\t{%2, %0|%0, %2}"
6792 [(set_attr "type" "alu")
6793 (set_attr "mode" "QI")])
6795 ;; The patterns that match these are at the end of this file.
6797 (define_expand "subxf3"
6798 [(set (match_operand:XF 0 "register_operand" "")
6799 (minus:XF (match_operand:XF 1 "register_operand" "")
6800 (match_operand:XF 2 "register_operand" "")))]
6804 (define_expand "subdf3"
6805 [(set (match_operand:DF 0 "register_operand" "")
6806 (minus:DF (match_operand:DF 1 "register_operand" "")
6807 (match_operand:DF 2 "nonimmediate_operand" "")))]
6808 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6811 (define_expand "subsf3"
6812 [(set (match_operand:SF 0 "register_operand" "")
6813 (minus:SF (match_operand:SF 1 "register_operand" "")
6814 (match_operand:SF 2 "nonimmediate_operand" "")))]
6815 "TARGET_80387 || TARGET_SSE_MATH"
6818 ;; Multiply instructions
6820 (define_expand "muldi3"
6821 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6822 (mult:DI (match_operand:DI 1 "register_operand" "")
6823 (match_operand:DI 2 "x86_64_general_operand" "")))
6824 (clobber (reg:CC FLAGS_REG))])]
6828 (define_insn "*muldi3_1_rex64"
6829 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6830 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6831 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6832 (clobber (reg:CC FLAGS_REG))]
6834 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6836 imul{q}\t{%2, %1, %0|%0, %1, %2}
6837 imul{q}\t{%2, %1, %0|%0, %1, %2}
6838 imul{q}\t{%2, %0|%0, %2}"
6839 [(set_attr "type" "imul")
6840 (set_attr "prefix_0f" "0,0,1")
6841 (set (attr "athlon_decode")
6842 (cond [(eq_attr "cpu" "athlon")
6843 (const_string "vector")
6844 (eq_attr "alternative" "1")
6845 (const_string "vector")
6846 (and (eq_attr "alternative" "2")
6847 (match_operand 1 "memory_operand" ""))
6848 (const_string "vector")]
6849 (const_string "direct")))
6850 (set_attr "mode" "DI")])
6852 (define_expand "mulsi3"
6853 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6854 (mult:SI (match_operand:SI 1 "register_operand" "")
6855 (match_operand:SI 2 "general_operand" "")))
6856 (clobber (reg:CC FLAGS_REG))])]
6860 (define_insn "*mulsi3_1"
6861 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6862 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6863 (match_operand:SI 2 "general_operand" "K,i,mr")))
6864 (clobber (reg:CC FLAGS_REG))]
6865 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6867 imul{l}\t{%2, %1, %0|%0, %1, %2}
6868 imul{l}\t{%2, %1, %0|%0, %1, %2}
6869 imul{l}\t{%2, %0|%0, %2}"
6870 [(set_attr "type" "imul")
6871 (set_attr "prefix_0f" "0,0,1")
6872 (set (attr "athlon_decode")
6873 (cond [(eq_attr "cpu" "athlon")
6874 (const_string "vector")
6875 (eq_attr "alternative" "1")
6876 (const_string "vector")
6877 (and (eq_attr "alternative" "2")
6878 (match_operand 1 "memory_operand" ""))
6879 (const_string "vector")]
6880 (const_string "direct")))
6881 (set_attr "mode" "SI")])
6883 (define_insn "*mulsi3_1_zext"
6884 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6886 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6887 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6888 (clobber (reg:CC FLAGS_REG))]
6890 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6892 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6893 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6894 imul{l}\t{%2, %k0|%k0, %2}"
6895 [(set_attr "type" "imul")
6896 (set_attr "prefix_0f" "0,0,1")
6897 (set (attr "athlon_decode")
6898 (cond [(eq_attr "cpu" "athlon")
6899 (const_string "vector")
6900 (eq_attr "alternative" "1")
6901 (const_string "vector")
6902 (and (eq_attr "alternative" "2")
6903 (match_operand 1 "memory_operand" ""))
6904 (const_string "vector")]
6905 (const_string "direct")))
6906 (set_attr "mode" "SI")])
6908 (define_expand "mulhi3"
6909 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6910 (mult:HI (match_operand:HI 1 "register_operand" "")
6911 (match_operand:HI 2 "general_operand" "")))
6912 (clobber (reg:CC FLAGS_REG))])]
6913 "TARGET_HIMODE_MATH"
6916 (define_insn "*mulhi3_1"
6917 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6918 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6919 (match_operand:HI 2 "general_operand" "K,i,mr")))
6920 (clobber (reg:CC FLAGS_REG))]
6921 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6923 imul{w}\t{%2, %1, %0|%0, %1, %2}
6924 imul{w}\t{%2, %1, %0|%0, %1, %2}
6925 imul{w}\t{%2, %0|%0, %2}"
6926 [(set_attr "type" "imul")
6927 (set_attr "prefix_0f" "0,0,1")
6928 (set (attr "athlon_decode")
6929 (cond [(eq_attr "cpu" "athlon")
6930 (const_string "vector")
6931 (eq_attr "alternative" "1,2")
6932 (const_string "vector")]
6933 (const_string "direct")))
6934 (set_attr "mode" "HI")])
6936 (define_expand "mulqi3"
6937 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6938 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6939 (match_operand:QI 2 "register_operand" "")))
6940 (clobber (reg:CC FLAGS_REG))])]
6941 "TARGET_QIMODE_MATH"
6944 (define_insn "*mulqi3_1"
6945 [(set (match_operand:QI 0 "register_operand" "=a")
6946 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6947 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6948 (clobber (reg:CC FLAGS_REG))]
6950 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6952 [(set_attr "type" "imul")
6953 (set_attr "length_immediate" "0")
6954 (set (attr "athlon_decode")
6955 (if_then_else (eq_attr "cpu" "athlon")
6956 (const_string "vector")
6957 (const_string "direct")))
6958 (set_attr "mode" "QI")])
6960 (define_expand "umulqihi3"
6961 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6962 (mult:HI (zero_extend:HI
6963 (match_operand:QI 1 "nonimmediate_operand" ""))
6965 (match_operand:QI 2 "register_operand" ""))))
6966 (clobber (reg:CC FLAGS_REG))])]
6967 "TARGET_QIMODE_MATH"
6970 (define_insn "*umulqihi3_1"
6971 [(set (match_operand:HI 0 "register_operand" "=a")
6972 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6973 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6974 (clobber (reg:CC FLAGS_REG))]
6976 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6978 [(set_attr "type" "imul")
6979 (set_attr "length_immediate" "0")
6980 (set (attr "athlon_decode")
6981 (if_then_else (eq_attr "cpu" "athlon")
6982 (const_string "vector")
6983 (const_string "direct")))
6984 (set_attr "mode" "QI")])
6986 (define_expand "mulqihi3"
6987 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6988 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6989 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6990 (clobber (reg:CC FLAGS_REG))])]
6991 "TARGET_QIMODE_MATH"
6994 (define_insn "*mulqihi3_insn"
6995 [(set (match_operand:HI 0 "register_operand" "=a")
6996 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6997 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6998 (clobber (reg:CC FLAGS_REG))]
7000 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7002 [(set_attr "type" "imul")
7003 (set_attr "length_immediate" "0")
7004 (set (attr "athlon_decode")
7005 (if_then_else (eq_attr "cpu" "athlon")
7006 (const_string "vector")
7007 (const_string "direct")))
7008 (set_attr "mode" "QI")])
7010 (define_expand "umulditi3"
7011 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7012 (mult:TI (zero_extend:TI
7013 (match_operand:DI 1 "nonimmediate_operand" ""))
7015 (match_operand:DI 2 "register_operand" ""))))
7016 (clobber (reg:CC FLAGS_REG))])]
7020 (define_insn "*umulditi3_insn"
7021 [(set (match_operand:TI 0 "register_operand" "=A")
7022 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7023 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7024 (clobber (reg:CC FLAGS_REG))]
7026 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7028 [(set_attr "type" "imul")
7029 (set_attr "length_immediate" "0")
7030 (set (attr "athlon_decode")
7031 (if_then_else (eq_attr "cpu" "athlon")
7032 (const_string "vector")
7033 (const_string "double")))
7034 (set_attr "mode" "DI")])
7036 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7037 (define_expand "umulsidi3"
7038 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7039 (mult:DI (zero_extend:DI
7040 (match_operand:SI 1 "nonimmediate_operand" ""))
7042 (match_operand:SI 2 "register_operand" ""))))
7043 (clobber (reg:CC FLAGS_REG))])]
7047 (define_insn "*umulsidi3_insn"
7048 [(set (match_operand:DI 0 "register_operand" "=A")
7049 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7050 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7051 (clobber (reg:CC FLAGS_REG))]
7053 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7055 [(set_attr "type" "imul")
7056 (set_attr "length_immediate" "0")
7057 (set (attr "athlon_decode")
7058 (if_then_else (eq_attr "cpu" "athlon")
7059 (const_string "vector")
7060 (const_string "double")))
7061 (set_attr "mode" "SI")])
7063 (define_expand "mulditi3"
7064 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7065 (mult:TI (sign_extend:TI
7066 (match_operand:DI 1 "nonimmediate_operand" ""))
7068 (match_operand:DI 2 "register_operand" ""))))
7069 (clobber (reg:CC FLAGS_REG))])]
7073 (define_insn "*mulditi3_insn"
7074 [(set (match_operand:TI 0 "register_operand" "=A")
7075 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7076 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7077 (clobber (reg:CC FLAGS_REG))]
7079 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7081 [(set_attr "type" "imul")
7082 (set_attr "length_immediate" "0")
7083 (set (attr "athlon_decode")
7084 (if_then_else (eq_attr "cpu" "athlon")
7085 (const_string "vector")
7086 (const_string "double")))
7087 (set_attr "mode" "DI")])
7089 (define_expand "mulsidi3"
7090 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7091 (mult:DI (sign_extend:DI
7092 (match_operand:SI 1 "nonimmediate_operand" ""))
7094 (match_operand:SI 2 "register_operand" ""))))
7095 (clobber (reg:CC FLAGS_REG))])]
7099 (define_insn "*mulsidi3_insn"
7100 [(set (match_operand:DI 0 "register_operand" "=A")
7101 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7102 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7103 (clobber (reg:CC FLAGS_REG))]
7105 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7107 [(set_attr "type" "imul")
7108 (set_attr "length_immediate" "0")
7109 (set (attr "athlon_decode")
7110 (if_then_else (eq_attr "cpu" "athlon")
7111 (const_string "vector")
7112 (const_string "double")))
7113 (set_attr "mode" "SI")])
7115 (define_expand "umuldi3_highpart"
7116 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7119 (mult:TI (zero_extend:TI
7120 (match_operand:DI 1 "nonimmediate_operand" ""))
7122 (match_operand:DI 2 "register_operand" "")))
7124 (clobber (match_scratch:DI 3 ""))
7125 (clobber (reg:CC FLAGS_REG))])]
7129 (define_insn "*umuldi3_highpart_rex64"
7130 [(set (match_operand:DI 0 "register_operand" "=d")
7133 (mult:TI (zero_extend:TI
7134 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7136 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7138 (clobber (match_scratch:DI 3 "=1"))
7139 (clobber (reg:CC FLAGS_REG))]
7141 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7143 [(set_attr "type" "imul")
7144 (set_attr "length_immediate" "0")
7145 (set (attr "athlon_decode")
7146 (if_then_else (eq_attr "cpu" "athlon")
7147 (const_string "vector")
7148 (const_string "double")))
7149 (set_attr "mode" "DI")])
7151 (define_expand "umulsi3_highpart"
7152 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7155 (mult:DI (zero_extend:DI
7156 (match_operand:SI 1 "nonimmediate_operand" ""))
7158 (match_operand:SI 2 "register_operand" "")))
7160 (clobber (match_scratch:SI 3 ""))
7161 (clobber (reg:CC FLAGS_REG))])]
7165 (define_insn "*umulsi3_highpart_insn"
7166 [(set (match_operand:SI 0 "register_operand" "=d")
7169 (mult:DI (zero_extend:DI
7170 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7172 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7174 (clobber (match_scratch:SI 3 "=1"))
7175 (clobber (reg:CC FLAGS_REG))]
7176 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7178 [(set_attr "type" "imul")
7179 (set_attr "length_immediate" "0")
7180 (set (attr "athlon_decode")
7181 (if_then_else (eq_attr "cpu" "athlon")
7182 (const_string "vector")
7183 (const_string "double")))
7184 (set_attr "mode" "SI")])
7186 (define_insn "*umulsi3_highpart_zext"
7187 [(set (match_operand:DI 0 "register_operand" "=d")
7188 (zero_extend:DI (truncate:SI
7190 (mult:DI (zero_extend:DI
7191 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7193 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7195 (clobber (match_scratch:SI 3 "=1"))
7196 (clobber (reg:CC FLAGS_REG))]
7198 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7200 [(set_attr "type" "imul")
7201 (set_attr "length_immediate" "0")
7202 (set (attr "athlon_decode")
7203 (if_then_else (eq_attr "cpu" "athlon")
7204 (const_string "vector")
7205 (const_string "double")))
7206 (set_attr "mode" "SI")])
7208 (define_expand "smuldi3_highpart"
7209 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7212 (mult:TI (sign_extend:TI
7213 (match_operand:DI 1 "nonimmediate_operand" ""))
7215 (match_operand:DI 2 "register_operand" "")))
7217 (clobber (match_scratch:DI 3 ""))
7218 (clobber (reg:CC FLAGS_REG))])]
7222 (define_insn "*smuldi3_highpart_rex64"
7223 [(set (match_operand:DI 0 "register_operand" "=d")
7226 (mult:TI (sign_extend:TI
7227 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7229 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7231 (clobber (match_scratch:DI 3 "=1"))
7232 (clobber (reg:CC FLAGS_REG))]
7234 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7236 [(set_attr "type" "imul")
7237 (set (attr "athlon_decode")
7238 (if_then_else (eq_attr "cpu" "athlon")
7239 (const_string "vector")
7240 (const_string "double")))
7241 (set_attr "mode" "DI")])
7243 (define_expand "smulsi3_highpart"
7244 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7247 (mult:DI (sign_extend:DI
7248 (match_operand:SI 1 "nonimmediate_operand" ""))
7250 (match_operand:SI 2 "register_operand" "")))
7252 (clobber (match_scratch:SI 3 ""))
7253 (clobber (reg:CC FLAGS_REG))])]
7257 (define_insn "*smulsi3_highpart_insn"
7258 [(set (match_operand:SI 0 "register_operand" "=d")
7261 (mult:DI (sign_extend:DI
7262 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7264 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7266 (clobber (match_scratch:SI 3 "=1"))
7267 (clobber (reg:CC FLAGS_REG))]
7268 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7270 [(set_attr "type" "imul")
7271 (set (attr "athlon_decode")
7272 (if_then_else (eq_attr "cpu" "athlon")
7273 (const_string "vector")
7274 (const_string "double")))
7275 (set_attr "mode" "SI")])
7277 (define_insn "*smulsi3_highpart_zext"
7278 [(set (match_operand:DI 0 "register_operand" "=d")
7279 (zero_extend:DI (truncate:SI
7281 (mult:DI (sign_extend:DI
7282 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7284 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7286 (clobber (match_scratch:SI 3 "=1"))
7287 (clobber (reg:CC FLAGS_REG))]
7289 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7291 [(set_attr "type" "imul")
7292 (set (attr "athlon_decode")
7293 (if_then_else (eq_attr "cpu" "athlon")
7294 (const_string "vector")
7295 (const_string "double")))
7296 (set_attr "mode" "SI")])
7298 ;; The patterns that match these are at the end of this file.
7300 (define_expand "mulxf3"
7301 [(set (match_operand:XF 0 "register_operand" "")
7302 (mult:XF (match_operand:XF 1 "register_operand" "")
7303 (match_operand:XF 2 "register_operand" "")))]
7307 (define_expand "muldf3"
7308 [(set (match_operand:DF 0 "register_operand" "")
7309 (mult:DF (match_operand:DF 1 "register_operand" "")
7310 (match_operand:DF 2 "nonimmediate_operand" "")))]
7311 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7314 (define_expand "mulsf3"
7315 [(set (match_operand:SF 0 "register_operand" "")
7316 (mult:SF (match_operand:SF 1 "register_operand" "")
7317 (match_operand:SF 2 "nonimmediate_operand" "")))]
7318 "TARGET_80387 || TARGET_SSE_MATH"
7321 ;; Divide instructions
7323 (define_insn "divqi3"
7324 [(set (match_operand:QI 0 "register_operand" "=a")
7325 (div:QI (match_operand:HI 1 "register_operand" "0")
7326 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7327 (clobber (reg:CC FLAGS_REG))]
7328 "TARGET_QIMODE_MATH"
7330 [(set_attr "type" "idiv")
7331 (set_attr "mode" "QI")])
7333 (define_insn "udivqi3"
7334 [(set (match_operand:QI 0 "register_operand" "=a")
7335 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7336 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7337 (clobber (reg:CC FLAGS_REG))]
7338 "TARGET_QIMODE_MATH"
7340 [(set_attr "type" "idiv")
7341 (set_attr "mode" "QI")])
7343 ;; The patterns that match these are at the end of this file.
7345 (define_expand "divxf3"
7346 [(set (match_operand:XF 0 "register_operand" "")
7347 (div:XF (match_operand:XF 1 "register_operand" "")
7348 (match_operand:XF 2 "register_operand" "")))]
7352 (define_expand "divdf3"
7353 [(set (match_operand:DF 0 "register_operand" "")
7354 (div:DF (match_operand:DF 1 "register_operand" "")
7355 (match_operand:DF 2 "nonimmediate_operand" "")))]
7356 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7359 (define_expand "divsf3"
7360 [(set (match_operand:SF 0 "register_operand" "")
7361 (div:SF (match_operand:SF 1 "register_operand" "")
7362 (match_operand:SF 2 "nonimmediate_operand" "")))]
7363 "TARGET_80387 || TARGET_SSE_MATH"
7366 ;; Remainder instructions.
7368 (define_expand "divmoddi4"
7369 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7370 (div:DI (match_operand:DI 1 "register_operand" "")
7371 (match_operand:DI 2 "nonimmediate_operand" "")))
7372 (set (match_operand:DI 3 "register_operand" "")
7373 (mod:DI (match_dup 1) (match_dup 2)))
7374 (clobber (reg:CC FLAGS_REG))])]
7378 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7379 ;; Penalize eax case slightly because it results in worse scheduling
7381 (define_insn "*divmoddi4_nocltd_rex64"
7382 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7383 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7384 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7385 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7386 (mod:DI (match_dup 2) (match_dup 3)))
7387 (clobber (reg:CC FLAGS_REG))]
7388 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7390 [(set_attr "type" "multi")])
7392 (define_insn "*divmoddi4_cltd_rex64"
7393 [(set (match_operand:DI 0 "register_operand" "=a")
7394 (div:DI (match_operand:DI 2 "register_operand" "a")
7395 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7396 (set (match_operand:DI 1 "register_operand" "=&d")
7397 (mod:DI (match_dup 2) (match_dup 3)))
7398 (clobber (reg:CC FLAGS_REG))]
7399 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7401 [(set_attr "type" "multi")])
7403 (define_insn "*divmoddi_noext_rex64"
7404 [(set (match_operand:DI 0 "register_operand" "=a")
7405 (div:DI (match_operand:DI 1 "register_operand" "0")
7406 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7407 (set (match_operand:DI 3 "register_operand" "=d")
7408 (mod:DI (match_dup 1) (match_dup 2)))
7409 (use (match_operand:DI 4 "register_operand" "3"))
7410 (clobber (reg:CC FLAGS_REG))]
7413 [(set_attr "type" "idiv")
7414 (set_attr "mode" "DI")])
7417 [(set (match_operand:DI 0 "register_operand" "")
7418 (div:DI (match_operand:DI 1 "register_operand" "")
7419 (match_operand:DI 2 "nonimmediate_operand" "")))
7420 (set (match_operand:DI 3 "register_operand" "")
7421 (mod:DI (match_dup 1) (match_dup 2)))
7422 (clobber (reg:CC FLAGS_REG))]
7423 "TARGET_64BIT && reload_completed"
7424 [(parallel [(set (match_dup 3)
7425 (ashiftrt:DI (match_dup 4) (const_int 63)))
7426 (clobber (reg:CC FLAGS_REG))])
7427 (parallel [(set (match_dup 0)
7428 (div:DI (reg:DI 0) (match_dup 2)))
7430 (mod:DI (reg:DI 0) (match_dup 2)))
7432 (clobber (reg:CC FLAGS_REG))])]
7434 /* Avoid use of cltd in favor of a mov+shift. */
7435 if (!TARGET_USE_CLTD && !optimize_size)
7437 if (true_regnum (operands[1]))
7438 emit_move_insn (operands[0], operands[1]);
7440 emit_move_insn (operands[3], operands[1]);
7441 operands[4] = operands[3];
7445 gcc_assert (!true_regnum (operands[1]));
7446 operands[4] = operands[1];
7451 (define_expand "divmodsi4"
7452 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7453 (div:SI (match_operand:SI 1 "register_operand" "")
7454 (match_operand:SI 2 "nonimmediate_operand" "")))
7455 (set (match_operand:SI 3 "register_operand" "")
7456 (mod:SI (match_dup 1) (match_dup 2)))
7457 (clobber (reg:CC FLAGS_REG))])]
7461 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7462 ;; Penalize eax case slightly because it results in worse scheduling
7464 (define_insn "*divmodsi4_nocltd"
7465 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7466 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7467 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7468 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7469 (mod:SI (match_dup 2) (match_dup 3)))
7470 (clobber (reg:CC FLAGS_REG))]
7471 "!optimize_size && !TARGET_USE_CLTD"
7473 [(set_attr "type" "multi")])
7475 (define_insn "*divmodsi4_cltd"
7476 [(set (match_operand:SI 0 "register_operand" "=a")
7477 (div:SI (match_operand:SI 2 "register_operand" "a")
7478 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7479 (set (match_operand:SI 1 "register_operand" "=&d")
7480 (mod:SI (match_dup 2) (match_dup 3)))
7481 (clobber (reg:CC FLAGS_REG))]
7482 "optimize_size || TARGET_USE_CLTD"
7484 [(set_attr "type" "multi")])
7486 (define_insn "*divmodsi_noext"
7487 [(set (match_operand:SI 0 "register_operand" "=a")
7488 (div:SI (match_operand:SI 1 "register_operand" "0")
7489 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7490 (set (match_operand:SI 3 "register_operand" "=d")
7491 (mod:SI (match_dup 1) (match_dup 2)))
7492 (use (match_operand:SI 4 "register_operand" "3"))
7493 (clobber (reg:CC FLAGS_REG))]
7496 [(set_attr "type" "idiv")
7497 (set_attr "mode" "SI")])
7500 [(set (match_operand:SI 0 "register_operand" "")
7501 (div:SI (match_operand:SI 1 "register_operand" "")
7502 (match_operand:SI 2 "nonimmediate_operand" "")))
7503 (set (match_operand:SI 3 "register_operand" "")
7504 (mod:SI (match_dup 1) (match_dup 2)))
7505 (clobber (reg:CC FLAGS_REG))]
7507 [(parallel [(set (match_dup 3)
7508 (ashiftrt:SI (match_dup 4) (const_int 31)))
7509 (clobber (reg:CC FLAGS_REG))])
7510 (parallel [(set (match_dup 0)
7511 (div:SI (reg:SI 0) (match_dup 2)))
7513 (mod:SI (reg:SI 0) (match_dup 2)))
7515 (clobber (reg:CC FLAGS_REG))])]
7517 /* Avoid use of cltd in favor of a mov+shift. */
7518 if (!TARGET_USE_CLTD && !optimize_size)
7520 if (true_regnum (operands[1]))
7521 emit_move_insn (operands[0], operands[1]);
7523 emit_move_insn (operands[3], operands[1]);
7524 operands[4] = operands[3];
7528 gcc_assert (!true_regnum (operands[1]));
7529 operands[4] = operands[1];
7533 (define_insn "divmodhi4"
7534 [(set (match_operand:HI 0 "register_operand" "=a")
7535 (div:HI (match_operand:HI 1 "register_operand" "0")
7536 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7537 (set (match_operand:HI 3 "register_operand" "=&d")
7538 (mod:HI (match_dup 1) (match_dup 2)))
7539 (clobber (reg:CC FLAGS_REG))]
7540 "TARGET_HIMODE_MATH"
7542 [(set_attr "type" "multi")
7543 (set_attr "length_immediate" "0")
7544 (set_attr "mode" "SI")])
7546 (define_insn "udivmoddi4"
7547 [(set (match_operand:DI 0 "register_operand" "=a")
7548 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7549 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7550 (set (match_operand:DI 3 "register_operand" "=&d")
7551 (umod:DI (match_dup 1) (match_dup 2)))
7552 (clobber (reg:CC FLAGS_REG))]
7554 "xor{q}\t%3, %3\;div{q}\t%2"
7555 [(set_attr "type" "multi")
7556 (set_attr "length_immediate" "0")
7557 (set_attr "mode" "DI")])
7559 (define_insn "*udivmoddi4_noext"
7560 [(set (match_operand:DI 0 "register_operand" "=a")
7561 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7562 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7563 (set (match_operand:DI 3 "register_operand" "=d")
7564 (umod:DI (match_dup 1) (match_dup 2)))
7566 (clobber (reg:CC FLAGS_REG))]
7569 [(set_attr "type" "idiv")
7570 (set_attr "mode" "DI")])
7573 [(set (match_operand:DI 0 "register_operand" "")
7574 (udiv:DI (match_operand:DI 1 "register_operand" "")
7575 (match_operand:DI 2 "nonimmediate_operand" "")))
7576 (set (match_operand:DI 3 "register_operand" "")
7577 (umod:DI (match_dup 1) (match_dup 2)))
7578 (clobber (reg:CC FLAGS_REG))]
7579 "TARGET_64BIT && reload_completed"
7580 [(set (match_dup 3) (const_int 0))
7581 (parallel [(set (match_dup 0)
7582 (udiv:DI (match_dup 1) (match_dup 2)))
7584 (umod:DI (match_dup 1) (match_dup 2)))
7586 (clobber (reg:CC FLAGS_REG))])]
7589 (define_insn "udivmodsi4"
7590 [(set (match_operand:SI 0 "register_operand" "=a")
7591 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7592 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7593 (set (match_operand:SI 3 "register_operand" "=&d")
7594 (umod:SI (match_dup 1) (match_dup 2)))
7595 (clobber (reg:CC FLAGS_REG))]
7597 "xor{l}\t%3, %3\;div{l}\t%2"
7598 [(set_attr "type" "multi")
7599 (set_attr "length_immediate" "0")
7600 (set_attr "mode" "SI")])
7602 (define_insn "*udivmodsi4_noext"
7603 [(set (match_operand:SI 0 "register_operand" "=a")
7604 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7605 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7606 (set (match_operand:SI 3 "register_operand" "=d")
7607 (umod:SI (match_dup 1) (match_dup 2)))
7609 (clobber (reg:CC FLAGS_REG))]
7612 [(set_attr "type" "idiv")
7613 (set_attr "mode" "SI")])
7616 [(set (match_operand:SI 0 "register_operand" "")
7617 (udiv:SI (match_operand:SI 1 "register_operand" "")
7618 (match_operand:SI 2 "nonimmediate_operand" "")))
7619 (set (match_operand:SI 3 "register_operand" "")
7620 (umod:SI (match_dup 1) (match_dup 2)))
7621 (clobber (reg:CC FLAGS_REG))]
7623 [(set (match_dup 3) (const_int 0))
7624 (parallel [(set (match_dup 0)
7625 (udiv:SI (match_dup 1) (match_dup 2)))
7627 (umod:SI (match_dup 1) (match_dup 2)))
7629 (clobber (reg:CC FLAGS_REG))])]
7632 (define_expand "udivmodhi4"
7633 [(set (match_dup 4) (const_int 0))
7634 (parallel [(set (match_operand:HI 0 "register_operand" "")
7635 (udiv:HI (match_operand:HI 1 "register_operand" "")
7636 (match_operand:HI 2 "nonimmediate_operand" "")))
7637 (set (match_operand:HI 3 "register_operand" "")
7638 (umod:HI (match_dup 1) (match_dup 2)))
7640 (clobber (reg:CC FLAGS_REG))])]
7641 "TARGET_HIMODE_MATH"
7642 "operands[4] = gen_reg_rtx (HImode);")
7644 (define_insn "*udivmodhi_noext"
7645 [(set (match_operand:HI 0 "register_operand" "=a")
7646 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7647 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7648 (set (match_operand:HI 3 "register_operand" "=d")
7649 (umod:HI (match_dup 1) (match_dup 2)))
7650 (use (match_operand:HI 4 "register_operand" "3"))
7651 (clobber (reg:CC FLAGS_REG))]
7654 [(set_attr "type" "idiv")
7655 (set_attr "mode" "HI")])
7657 ;; We cannot use div/idiv for double division, because it causes
7658 ;; "division by zero" on the overflow and that's not what we expect
7659 ;; from truncate. Because true (non truncating) double division is
7660 ;; never generated, we can't create this insn anyway.
7663 ; [(set (match_operand:SI 0 "register_operand" "=a")
7665 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7667 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7668 ; (set (match_operand:SI 3 "register_operand" "=d")
7670 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7671 ; (clobber (reg:CC FLAGS_REG))]
7673 ; "div{l}\t{%2, %0|%0, %2}"
7674 ; [(set_attr "type" "idiv")])
7676 ;;- Logical AND instructions
7678 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7679 ;; Note that this excludes ah.
7681 (define_insn "*testdi_1_rex64"
7682 [(set (reg FLAGS_REG)
7684 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7685 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7687 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7688 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7690 test{l}\t{%k1, %k0|%k0, %k1}
7691 test{l}\t{%k1, %k0|%k0, %k1}
7692 test{q}\t{%1, %0|%0, %1}
7693 test{q}\t{%1, %0|%0, %1}
7694 test{q}\t{%1, %0|%0, %1}"
7695 [(set_attr "type" "test")
7696 (set_attr "modrm" "0,1,0,1,1")
7697 (set_attr "mode" "SI,SI,DI,DI,DI")
7698 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7700 (define_insn "testsi_1"
7701 [(set (reg FLAGS_REG)
7703 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7704 (match_operand:SI 1 "general_operand" "in,in,rin"))
7706 "ix86_match_ccmode (insn, CCNOmode)
7707 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7708 "test{l}\t{%1, %0|%0, %1}"
7709 [(set_attr "type" "test")
7710 (set_attr "modrm" "0,1,1")
7711 (set_attr "mode" "SI")
7712 (set_attr "pent_pair" "uv,np,uv")])
7714 (define_expand "testsi_ccno_1"
7715 [(set (reg:CCNO FLAGS_REG)
7717 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7718 (match_operand:SI 1 "nonmemory_operand" ""))
7723 (define_insn "*testhi_1"
7724 [(set (reg FLAGS_REG)
7725 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7726 (match_operand:HI 1 "general_operand" "n,n,rn"))
7728 "ix86_match_ccmode (insn, CCNOmode)
7729 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7730 "test{w}\t{%1, %0|%0, %1}"
7731 [(set_attr "type" "test")
7732 (set_attr "modrm" "0,1,1")
7733 (set_attr "mode" "HI")
7734 (set_attr "pent_pair" "uv,np,uv")])
7736 (define_expand "testqi_ccz_1"
7737 [(set (reg:CCZ FLAGS_REG)
7738 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7739 (match_operand:QI 1 "nonmemory_operand" ""))
7744 (define_insn "*testqi_1_maybe_si"
7745 [(set (reg FLAGS_REG)
7748 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7749 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7751 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7752 && ix86_match_ccmode (insn,
7753 GET_CODE (operands[1]) == CONST_INT
7754 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7756 if (which_alternative == 3)
7758 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7759 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7760 return "test{l}\t{%1, %k0|%k0, %1}";
7762 return "test{b}\t{%1, %0|%0, %1}";
7764 [(set_attr "type" "test")
7765 (set_attr "modrm" "0,1,1,1")
7766 (set_attr "mode" "QI,QI,QI,SI")
7767 (set_attr "pent_pair" "uv,np,uv,np")])
7769 (define_insn "*testqi_1"
7770 [(set (reg FLAGS_REG)
7773 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7774 (match_operand:QI 1 "general_operand" "n,n,qn"))
7776 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7777 && ix86_match_ccmode (insn, CCNOmode)"
7778 "test{b}\t{%1, %0|%0, %1}"
7779 [(set_attr "type" "test")
7780 (set_attr "modrm" "0,1,1")
7781 (set_attr "mode" "QI")
7782 (set_attr "pent_pair" "uv,np,uv")])
7784 (define_expand "testqi_ext_ccno_0"
7785 [(set (reg:CCNO FLAGS_REG)
7789 (match_operand 0 "ext_register_operand" "")
7792 (match_operand 1 "const_int_operand" ""))
7797 (define_insn "*testqi_ext_0"
7798 [(set (reg FLAGS_REG)
7802 (match_operand 0 "ext_register_operand" "Q")
7805 (match_operand 1 "const_int_operand" "n"))
7807 "ix86_match_ccmode (insn, CCNOmode)"
7808 "test{b}\t{%1, %h0|%h0, %1}"
7809 [(set_attr "type" "test")
7810 (set_attr "mode" "QI")
7811 (set_attr "length_immediate" "1")
7812 (set_attr "pent_pair" "np")])
7814 (define_insn "*testqi_ext_1"
7815 [(set (reg FLAGS_REG)
7819 (match_operand 0 "ext_register_operand" "Q")
7823 (match_operand:QI 1 "general_operand" "Qm")))
7825 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7826 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7827 "test{b}\t{%1, %h0|%h0, %1}"
7828 [(set_attr "type" "test")
7829 (set_attr "mode" "QI")])
7831 (define_insn "*testqi_ext_1_rex64"
7832 [(set (reg FLAGS_REG)
7836 (match_operand 0 "ext_register_operand" "Q")
7840 (match_operand:QI 1 "register_operand" "Q")))
7842 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7843 "test{b}\t{%1, %h0|%h0, %1}"
7844 [(set_attr "type" "test")
7845 (set_attr "mode" "QI")])
7847 (define_insn "*testqi_ext_2"
7848 [(set (reg FLAGS_REG)
7852 (match_operand 0 "ext_register_operand" "Q")
7856 (match_operand 1 "ext_register_operand" "Q")
7860 "ix86_match_ccmode (insn, CCNOmode)"
7861 "test{b}\t{%h1, %h0|%h0, %h1}"
7862 [(set_attr "type" "test")
7863 (set_attr "mode" "QI")])
7865 ;; Combine likes to form bit extractions for some tests. Humor it.
7866 (define_insn "*testqi_ext_3"
7867 [(set (reg FLAGS_REG)
7868 (compare (zero_extract:SI
7869 (match_operand 0 "nonimmediate_operand" "rm")
7870 (match_operand:SI 1 "const_int_operand" "")
7871 (match_operand:SI 2 "const_int_operand" ""))
7873 "ix86_match_ccmode (insn, CCNOmode)
7874 && INTVAL (operands[1]) > 0
7875 && INTVAL (operands[2]) >= 0
7876 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7877 && (GET_MODE (operands[0]) == SImode
7878 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7879 || GET_MODE (operands[0]) == HImode
7880 || GET_MODE (operands[0]) == QImode)"
7883 (define_insn "*testqi_ext_3_rex64"
7884 [(set (reg FLAGS_REG)
7885 (compare (zero_extract:DI
7886 (match_operand 0 "nonimmediate_operand" "rm")
7887 (match_operand:DI 1 "const_int_operand" "")
7888 (match_operand:DI 2 "const_int_operand" ""))
7891 && ix86_match_ccmode (insn, CCNOmode)
7892 && INTVAL (operands[1]) > 0
7893 && INTVAL (operands[2]) >= 0
7894 /* Ensure that resulting mask is zero or sign extended operand. */
7895 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7896 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7897 && INTVAL (operands[1]) > 32))
7898 && (GET_MODE (operands[0]) == SImode
7899 || GET_MODE (operands[0]) == DImode
7900 || GET_MODE (operands[0]) == HImode
7901 || GET_MODE (operands[0]) == QImode)"
7905 [(set (match_operand 0 "flags_reg_operand" "")
7906 (match_operator 1 "compare_operator"
7908 (match_operand 2 "nonimmediate_operand" "")
7909 (match_operand 3 "const_int_operand" "")
7910 (match_operand 4 "const_int_operand" ""))
7912 "ix86_match_ccmode (insn, CCNOmode)"
7913 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7915 rtx val = operands[2];
7916 HOST_WIDE_INT len = INTVAL (operands[3]);
7917 HOST_WIDE_INT pos = INTVAL (operands[4]);
7919 enum machine_mode mode, submode;
7921 mode = GET_MODE (val);
7922 if (GET_CODE (val) == MEM)
7924 /* ??? Combine likes to put non-volatile mem extractions in QImode
7925 no matter the size of the test. So find a mode that works. */
7926 if (! MEM_VOLATILE_P (val))
7928 mode = smallest_mode_for_size (pos + len, MODE_INT);
7929 val = adjust_address (val, mode, 0);
7932 else if (GET_CODE (val) == SUBREG
7933 && (submode = GET_MODE (SUBREG_REG (val)),
7934 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7935 && pos + len <= GET_MODE_BITSIZE (submode))
7937 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7939 val = SUBREG_REG (val);
7941 else if (mode == HImode && pos + len <= 8)
7943 /* Small HImode tests can be converted to QImode. */
7945 val = gen_lowpart (QImode, val);
7948 if (len == HOST_BITS_PER_WIDE_INT)
7951 mask = ((HOST_WIDE_INT)1 << len) - 1;
7954 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7957 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7958 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7959 ;; this is relatively important trick.
7960 ;; Do the conversion only post-reload to avoid limiting of the register class
7963 [(set (match_operand 0 "flags_reg_operand" "")
7964 (match_operator 1 "compare_operator"
7965 [(and (match_operand 2 "register_operand" "")
7966 (match_operand 3 "const_int_operand" ""))
7969 && QI_REG_P (operands[2])
7970 && GET_MODE (operands[2]) != QImode
7971 && ((ix86_match_ccmode (insn, CCZmode)
7972 && !(INTVAL (operands[3]) & ~(255 << 8)))
7973 || (ix86_match_ccmode (insn, CCNOmode)
7974 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7977 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7980 "operands[2] = gen_lowpart (SImode, operands[2]);
7981 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7984 [(set (match_operand 0 "flags_reg_operand" "")
7985 (match_operator 1 "compare_operator"
7986 [(and (match_operand 2 "nonimmediate_operand" "")
7987 (match_operand 3 "const_int_operand" ""))
7990 && GET_MODE (operands[2]) != QImode
7991 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7992 && ((ix86_match_ccmode (insn, CCZmode)
7993 && !(INTVAL (operands[3]) & ~255))
7994 || (ix86_match_ccmode (insn, CCNOmode)
7995 && !(INTVAL (operands[3]) & ~127)))"
7997 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7999 "operands[2] = gen_lowpart (QImode, operands[2]);
8000 operands[3] = gen_lowpart (QImode, operands[3]);")
8003 ;; %%% This used to optimize known byte-wide and operations to memory,
8004 ;; and sometimes to QImode registers. If this is considered useful,
8005 ;; it should be done with splitters.
8007 (define_expand "anddi3"
8008 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8009 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8010 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8011 (clobber (reg:CC FLAGS_REG))]
8013 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8015 (define_insn "*anddi_1_rex64"
8016 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8017 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8018 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8019 (clobber (reg:CC FLAGS_REG))]
8020 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8022 switch (get_attr_type (insn))
8026 enum machine_mode mode;
8028 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8029 if (INTVAL (operands[2]) == 0xff)
8033 gcc_assert (INTVAL (operands[2]) == 0xffff);
8037 operands[1] = gen_lowpart (mode, operands[1]);
8039 return "movz{bq|x}\t{%1,%0|%0, %1}";
8041 return "movz{wq|x}\t{%1,%0|%0, %1}";
8045 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8046 if (get_attr_mode (insn) == MODE_SI)
8047 return "and{l}\t{%k2, %k0|%k0, %k2}";
8049 return "and{q}\t{%2, %0|%0, %2}";
8052 [(set_attr "type" "alu,alu,alu,imovx")
8053 (set_attr "length_immediate" "*,*,*,0")
8054 (set_attr "mode" "SI,DI,DI,DI")])
8056 (define_insn "*anddi_2"
8057 [(set (reg FLAGS_REG)
8058 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8059 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8061 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8062 (and:DI (match_dup 1) (match_dup 2)))]
8063 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8064 && ix86_binary_operator_ok (AND, DImode, operands)"
8066 and{l}\t{%k2, %k0|%k0, %k2}
8067 and{q}\t{%2, %0|%0, %2}
8068 and{q}\t{%2, %0|%0, %2}"
8069 [(set_attr "type" "alu")
8070 (set_attr "mode" "SI,DI,DI")])
8072 (define_expand "andsi3"
8073 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8074 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8075 (match_operand:SI 2 "general_operand" "")))
8076 (clobber (reg:CC FLAGS_REG))]
8078 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8080 (define_insn "*andsi_1"
8081 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8082 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8083 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8084 (clobber (reg:CC FLAGS_REG))]
8085 "ix86_binary_operator_ok (AND, SImode, operands)"
8087 switch (get_attr_type (insn))
8091 enum machine_mode mode;
8093 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8094 if (INTVAL (operands[2]) == 0xff)
8098 gcc_assert (INTVAL (operands[2]) == 0xffff);
8102 operands[1] = gen_lowpart (mode, operands[1]);
8104 return "movz{bl|x}\t{%1,%0|%0, %1}";
8106 return "movz{wl|x}\t{%1,%0|%0, %1}";
8110 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8111 return "and{l}\t{%2, %0|%0, %2}";
8114 [(set_attr "type" "alu,alu,imovx")
8115 (set_attr "length_immediate" "*,*,0")
8116 (set_attr "mode" "SI")])
8119 [(set (match_operand 0 "register_operand" "")
8121 (const_int -65536)))
8122 (clobber (reg:CC FLAGS_REG))]
8123 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8124 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8125 "operands[1] = gen_lowpart (HImode, operands[0]);")
8128 [(set (match_operand 0 "ext_register_operand" "")
8131 (clobber (reg:CC FLAGS_REG))]
8132 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8133 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8134 "operands[1] = gen_lowpart (QImode, operands[0]);")
8137 [(set (match_operand 0 "ext_register_operand" "")
8139 (const_int -65281)))
8140 (clobber (reg:CC FLAGS_REG))]
8141 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8142 [(parallel [(set (zero_extract:SI (match_dup 0)
8146 (zero_extract:SI (match_dup 0)
8149 (zero_extract:SI (match_dup 0)
8152 (clobber (reg:CC FLAGS_REG))])]
8153 "operands[0] = gen_lowpart (SImode, operands[0]);")
8155 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8156 (define_insn "*andsi_1_zext"
8157 [(set (match_operand:DI 0 "register_operand" "=r")
8159 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8160 (match_operand:SI 2 "general_operand" "rim"))))
8161 (clobber (reg:CC FLAGS_REG))]
8162 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8163 "and{l}\t{%2, %k0|%k0, %2}"
8164 [(set_attr "type" "alu")
8165 (set_attr "mode" "SI")])
8167 (define_insn "*andsi_2"
8168 [(set (reg FLAGS_REG)
8169 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8170 (match_operand:SI 2 "general_operand" "rim,ri"))
8172 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8173 (and:SI (match_dup 1) (match_dup 2)))]
8174 "ix86_match_ccmode (insn, CCNOmode)
8175 && ix86_binary_operator_ok (AND, SImode, operands)"
8176 "and{l}\t{%2, %0|%0, %2}"
8177 [(set_attr "type" "alu")
8178 (set_attr "mode" "SI")])
8180 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8181 (define_insn "*andsi_2_zext"
8182 [(set (reg FLAGS_REG)
8183 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8184 (match_operand:SI 2 "general_operand" "rim"))
8186 (set (match_operand:DI 0 "register_operand" "=r")
8187 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8188 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8189 && ix86_binary_operator_ok (AND, SImode, operands)"
8190 "and{l}\t{%2, %k0|%k0, %2}"
8191 [(set_attr "type" "alu")
8192 (set_attr "mode" "SI")])
8194 (define_expand "andhi3"
8195 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8196 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8197 (match_operand:HI 2 "general_operand" "")))
8198 (clobber (reg:CC FLAGS_REG))]
8199 "TARGET_HIMODE_MATH"
8200 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8202 (define_insn "*andhi_1"
8203 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8204 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8205 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8206 (clobber (reg:CC FLAGS_REG))]
8207 "ix86_binary_operator_ok (AND, HImode, operands)"
8209 switch (get_attr_type (insn))
8212 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8213 gcc_assert (INTVAL (operands[2]) == 0xff);
8214 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8217 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8219 return "and{w}\t{%2, %0|%0, %2}";
8222 [(set_attr "type" "alu,alu,imovx")
8223 (set_attr "length_immediate" "*,*,0")
8224 (set_attr "mode" "HI,HI,SI")])
8226 (define_insn "*andhi_2"
8227 [(set (reg FLAGS_REG)
8228 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8229 (match_operand:HI 2 "general_operand" "rim,ri"))
8231 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8232 (and:HI (match_dup 1) (match_dup 2)))]
8233 "ix86_match_ccmode (insn, CCNOmode)
8234 && ix86_binary_operator_ok (AND, HImode, operands)"
8235 "and{w}\t{%2, %0|%0, %2}"
8236 [(set_attr "type" "alu")
8237 (set_attr "mode" "HI")])
8239 (define_expand "andqi3"
8240 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8241 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8242 (match_operand:QI 2 "general_operand" "")))
8243 (clobber (reg:CC FLAGS_REG))]
8244 "TARGET_QIMODE_MATH"
8245 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8247 ;; %%% Potential partial reg stall on alternative 2. What to do?
8248 (define_insn "*andqi_1"
8249 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8250 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8251 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8252 (clobber (reg:CC FLAGS_REG))]
8253 "ix86_binary_operator_ok (AND, QImode, operands)"
8255 and{b}\t{%2, %0|%0, %2}
8256 and{b}\t{%2, %0|%0, %2}
8257 and{l}\t{%k2, %k0|%k0, %k2}"
8258 [(set_attr "type" "alu")
8259 (set_attr "mode" "QI,QI,SI")])
8261 (define_insn "*andqi_1_slp"
8262 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8263 (and:QI (match_dup 0)
8264 (match_operand:QI 1 "general_operand" "qi,qmi")))
8265 (clobber (reg:CC FLAGS_REG))]
8266 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8267 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8268 "and{b}\t{%1, %0|%0, %1}"
8269 [(set_attr "type" "alu1")
8270 (set_attr "mode" "QI")])
8272 (define_insn "*andqi_2_maybe_si"
8273 [(set (reg FLAGS_REG)
8275 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8276 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8278 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8279 (and:QI (match_dup 1) (match_dup 2)))]
8280 "ix86_binary_operator_ok (AND, QImode, operands)
8281 && ix86_match_ccmode (insn,
8282 GET_CODE (operands[2]) == CONST_INT
8283 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8285 if (which_alternative == 2)
8287 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8288 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8289 return "and{l}\t{%2, %k0|%k0, %2}";
8291 return "and{b}\t{%2, %0|%0, %2}";
8293 [(set_attr "type" "alu")
8294 (set_attr "mode" "QI,QI,SI")])
8296 (define_insn "*andqi_2"
8297 [(set (reg FLAGS_REG)
8299 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8300 (match_operand:QI 2 "general_operand" "qim,qi"))
8302 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8303 (and:QI (match_dup 1) (match_dup 2)))]
8304 "ix86_match_ccmode (insn, CCNOmode)
8305 && ix86_binary_operator_ok (AND, QImode, operands)"
8306 "and{b}\t{%2, %0|%0, %2}"
8307 [(set_attr "type" "alu")
8308 (set_attr "mode" "QI")])
8310 (define_insn "*andqi_2_slp"
8311 [(set (reg FLAGS_REG)
8313 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8314 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8316 (set (strict_low_part (match_dup 0))
8317 (and:QI (match_dup 0) (match_dup 1)))]
8318 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8319 && ix86_match_ccmode (insn, CCNOmode)
8320 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8321 "and{b}\t{%1, %0|%0, %1}"
8322 [(set_attr "type" "alu1")
8323 (set_attr "mode" "QI")])
8325 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8326 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8327 ;; for a QImode operand, which of course failed.
8329 (define_insn "andqi_ext_0"
8330 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8335 (match_operand 1 "ext_register_operand" "0")
8338 (match_operand 2 "const_int_operand" "n")))
8339 (clobber (reg:CC FLAGS_REG))]
8341 "and{b}\t{%2, %h0|%h0, %2}"
8342 [(set_attr "type" "alu")
8343 (set_attr "length_immediate" "1")
8344 (set_attr "mode" "QI")])
8346 ;; Generated by peephole translating test to and. This shows up
8347 ;; often in fp comparisons.
8349 (define_insn "*andqi_ext_0_cc"
8350 [(set (reg FLAGS_REG)
8354 (match_operand 1 "ext_register_operand" "0")
8357 (match_operand 2 "const_int_operand" "n"))
8359 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8368 "ix86_match_ccmode (insn, CCNOmode)"
8369 "and{b}\t{%2, %h0|%h0, %2}"
8370 [(set_attr "type" "alu")
8371 (set_attr "length_immediate" "1")
8372 (set_attr "mode" "QI")])
8374 (define_insn "*andqi_ext_1"
8375 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8380 (match_operand 1 "ext_register_operand" "0")
8384 (match_operand:QI 2 "general_operand" "Qm"))))
8385 (clobber (reg:CC FLAGS_REG))]
8387 "and{b}\t{%2, %h0|%h0, %2}"
8388 [(set_attr "type" "alu")
8389 (set_attr "length_immediate" "0")
8390 (set_attr "mode" "QI")])
8392 (define_insn "*andqi_ext_1_rex64"
8393 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8398 (match_operand 1 "ext_register_operand" "0")
8402 (match_operand 2 "ext_register_operand" "Q"))))
8403 (clobber (reg:CC FLAGS_REG))]
8405 "and{b}\t{%2, %h0|%h0, %2}"
8406 [(set_attr "type" "alu")
8407 (set_attr "length_immediate" "0")
8408 (set_attr "mode" "QI")])
8410 (define_insn "*andqi_ext_2"
8411 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8416 (match_operand 1 "ext_register_operand" "%0")
8420 (match_operand 2 "ext_register_operand" "Q")
8423 (clobber (reg:CC FLAGS_REG))]
8425 "and{b}\t{%h2, %h0|%h0, %h2}"
8426 [(set_attr "type" "alu")
8427 (set_attr "length_immediate" "0")
8428 (set_attr "mode" "QI")])
8430 ;; Convert wide AND instructions with immediate operand to shorter QImode
8431 ;; equivalents when possible.
8432 ;; Don't do the splitting with memory operands, since it introduces risk
8433 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8434 ;; for size, but that can (should?) be handled by generic code instead.
8436 [(set (match_operand 0 "register_operand" "")
8437 (and (match_operand 1 "register_operand" "")
8438 (match_operand 2 "const_int_operand" "")))
8439 (clobber (reg:CC FLAGS_REG))]
8441 && QI_REG_P (operands[0])
8442 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8443 && !(~INTVAL (operands[2]) & ~(255 << 8))
8444 && GET_MODE (operands[0]) != QImode"
8445 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8446 (and:SI (zero_extract:SI (match_dup 1)
8447 (const_int 8) (const_int 8))
8449 (clobber (reg:CC FLAGS_REG))])]
8450 "operands[0] = gen_lowpart (SImode, operands[0]);
8451 operands[1] = gen_lowpart (SImode, operands[1]);
8452 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8454 ;; Since AND can be encoded with sign extended immediate, this is only
8455 ;; profitable when 7th bit is not set.
8457 [(set (match_operand 0 "register_operand" "")
8458 (and (match_operand 1 "general_operand" "")
8459 (match_operand 2 "const_int_operand" "")))
8460 (clobber (reg:CC FLAGS_REG))]
8462 && ANY_QI_REG_P (operands[0])
8463 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8464 && !(~INTVAL (operands[2]) & ~255)
8465 && !(INTVAL (operands[2]) & 128)
8466 && GET_MODE (operands[0]) != QImode"
8467 [(parallel [(set (strict_low_part (match_dup 0))
8468 (and:QI (match_dup 1)
8470 (clobber (reg:CC FLAGS_REG))])]
8471 "operands[0] = gen_lowpart (QImode, operands[0]);
8472 operands[1] = gen_lowpart (QImode, operands[1]);
8473 operands[2] = gen_lowpart (QImode, operands[2]);")
8475 ;; Logical inclusive OR instructions
8477 ;; %%% This used to optimize known byte-wide and operations to memory.
8478 ;; If this is considered useful, it should be done with splitters.
8480 (define_expand "iordi3"
8481 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8482 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8483 (match_operand:DI 2 "x86_64_general_operand" "")))
8484 (clobber (reg:CC FLAGS_REG))]
8486 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8488 (define_insn "*iordi_1_rex64"
8489 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8490 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8491 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8492 (clobber (reg:CC FLAGS_REG))]
8494 && ix86_binary_operator_ok (IOR, DImode, operands)"
8495 "or{q}\t{%2, %0|%0, %2}"
8496 [(set_attr "type" "alu")
8497 (set_attr "mode" "DI")])
8499 (define_insn "*iordi_2_rex64"
8500 [(set (reg FLAGS_REG)
8501 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8502 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8504 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8505 (ior:DI (match_dup 1) (match_dup 2)))]
8507 && ix86_match_ccmode (insn, CCNOmode)
8508 && ix86_binary_operator_ok (IOR, DImode, operands)"
8509 "or{q}\t{%2, %0|%0, %2}"
8510 [(set_attr "type" "alu")
8511 (set_attr "mode" "DI")])
8513 (define_insn "*iordi_3_rex64"
8514 [(set (reg FLAGS_REG)
8515 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8516 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8518 (clobber (match_scratch:DI 0 "=r"))]
8520 && ix86_match_ccmode (insn, CCNOmode)
8521 && ix86_binary_operator_ok (IOR, DImode, operands)"
8522 "or{q}\t{%2, %0|%0, %2}"
8523 [(set_attr "type" "alu")
8524 (set_attr "mode" "DI")])
8527 (define_expand "iorsi3"
8528 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8529 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8530 (match_operand:SI 2 "general_operand" "")))
8531 (clobber (reg:CC FLAGS_REG))]
8533 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8535 (define_insn "*iorsi_1"
8536 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8537 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8538 (match_operand:SI 2 "general_operand" "ri,rmi")))
8539 (clobber (reg:CC FLAGS_REG))]
8540 "ix86_binary_operator_ok (IOR, SImode, operands)"
8541 "or{l}\t{%2, %0|%0, %2}"
8542 [(set_attr "type" "alu")
8543 (set_attr "mode" "SI")])
8545 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8546 (define_insn "*iorsi_1_zext"
8547 [(set (match_operand:DI 0 "register_operand" "=rm")
8549 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8550 (match_operand:SI 2 "general_operand" "rim"))))
8551 (clobber (reg:CC FLAGS_REG))]
8552 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8553 "or{l}\t{%2, %k0|%k0, %2}"
8554 [(set_attr "type" "alu")
8555 (set_attr "mode" "SI")])
8557 (define_insn "*iorsi_1_zext_imm"
8558 [(set (match_operand:DI 0 "register_operand" "=rm")
8559 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8560 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8561 (clobber (reg:CC FLAGS_REG))]
8563 "or{l}\t{%2, %k0|%k0, %2}"
8564 [(set_attr "type" "alu")
8565 (set_attr "mode" "SI")])
8567 (define_insn "*iorsi_2"
8568 [(set (reg FLAGS_REG)
8569 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8570 (match_operand:SI 2 "general_operand" "rim,ri"))
8572 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8573 (ior:SI (match_dup 1) (match_dup 2)))]
8574 "ix86_match_ccmode (insn, CCNOmode)
8575 && ix86_binary_operator_ok (IOR, SImode, operands)"
8576 "or{l}\t{%2, %0|%0, %2}"
8577 [(set_attr "type" "alu")
8578 (set_attr "mode" "SI")])
8580 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8581 ;; ??? Special case for immediate operand is missing - it is tricky.
8582 (define_insn "*iorsi_2_zext"
8583 [(set (reg FLAGS_REG)
8584 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8585 (match_operand:SI 2 "general_operand" "rim"))
8587 (set (match_operand:DI 0 "register_operand" "=r")
8588 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8589 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8590 && ix86_binary_operator_ok (IOR, SImode, operands)"
8591 "or{l}\t{%2, %k0|%k0, %2}"
8592 [(set_attr "type" "alu")
8593 (set_attr "mode" "SI")])
8595 (define_insn "*iorsi_2_zext_imm"
8596 [(set (reg FLAGS_REG)
8597 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8598 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8600 (set (match_operand:DI 0 "register_operand" "=r")
8601 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8602 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8603 && ix86_binary_operator_ok (IOR, SImode, operands)"
8604 "or{l}\t{%2, %k0|%k0, %2}"
8605 [(set_attr "type" "alu")
8606 (set_attr "mode" "SI")])
8608 (define_insn "*iorsi_3"
8609 [(set (reg FLAGS_REG)
8610 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8611 (match_operand:SI 2 "general_operand" "rim"))
8613 (clobber (match_scratch:SI 0 "=r"))]
8614 "ix86_match_ccmode (insn, CCNOmode)
8615 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8616 "or{l}\t{%2, %0|%0, %2}"
8617 [(set_attr "type" "alu")
8618 (set_attr "mode" "SI")])
8620 (define_expand "iorhi3"
8621 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8622 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8623 (match_operand:HI 2 "general_operand" "")))
8624 (clobber (reg:CC FLAGS_REG))]
8625 "TARGET_HIMODE_MATH"
8626 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8628 (define_insn "*iorhi_1"
8629 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8630 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8631 (match_operand:HI 2 "general_operand" "rmi,ri")))
8632 (clobber (reg:CC FLAGS_REG))]
8633 "ix86_binary_operator_ok (IOR, HImode, operands)"
8634 "or{w}\t{%2, %0|%0, %2}"
8635 [(set_attr "type" "alu")
8636 (set_attr "mode" "HI")])
8638 (define_insn "*iorhi_2"
8639 [(set (reg FLAGS_REG)
8640 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8641 (match_operand:HI 2 "general_operand" "rim,ri"))
8643 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8644 (ior:HI (match_dup 1) (match_dup 2)))]
8645 "ix86_match_ccmode (insn, CCNOmode)
8646 && ix86_binary_operator_ok (IOR, HImode, operands)"
8647 "or{w}\t{%2, %0|%0, %2}"
8648 [(set_attr "type" "alu")
8649 (set_attr "mode" "HI")])
8651 (define_insn "*iorhi_3"
8652 [(set (reg FLAGS_REG)
8653 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8654 (match_operand:HI 2 "general_operand" "rim"))
8656 (clobber (match_scratch:HI 0 "=r"))]
8657 "ix86_match_ccmode (insn, CCNOmode)
8658 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8659 "or{w}\t{%2, %0|%0, %2}"
8660 [(set_attr "type" "alu")
8661 (set_attr "mode" "HI")])
8663 (define_expand "iorqi3"
8664 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8665 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8666 (match_operand:QI 2 "general_operand" "")))
8667 (clobber (reg:CC FLAGS_REG))]
8668 "TARGET_QIMODE_MATH"
8669 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8671 ;; %%% Potential partial reg stall on alternative 2. What to do?
8672 (define_insn "*iorqi_1"
8673 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8674 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8675 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8676 (clobber (reg:CC FLAGS_REG))]
8677 "ix86_binary_operator_ok (IOR, QImode, operands)"
8679 or{b}\t{%2, %0|%0, %2}
8680 or{b}\t{%2, %0|%0, %2}
8681 or{l}\t{%k2, %k0|%k0, %k2}"
8682 [(set_attr "type" "alu")
8683 (set_attr "mode" "QI,QI,SI")])
8685 (define_insn "*iorqi_1_slp"
8686 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8687 (ior:QI (match_dup 0)
8688 (match_operand:QI 1 "general_operand" "qmi,qi")))
8689 (clobber (reg:CC FLAGS_REG))]
8690 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8691 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8692 "or{b}\t{%1, %0|%0, %1}"
8693 [(set_attr "type" "alu1")
8694 (set_attr "mode" "QI")])
8696 (define_insn "*iorqi_2"
8697 [(set (reg FLAGS_REG)
8698 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8699 (match_operand:QI 2 "general_operand" "qim,qi"))
8701 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8702 (ior:QI (match_dup 1) (match_dup 2)))]
8703 "ix86_match_ccmode (insn, CCNOmode)
8704 && ix86_binary_operator_ok (IOR, QImode, operands)"
8705 "or{b}\t{%2, %0|%0, %2}"
8706 [(set_attr "type" "alu")
8707 (set_attr "mode" "QI")])
8709 (define_insn "*iorqi_2_slp"
8710 [(set (reg FLAGS_REG)
8711 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8712 (match_operand:QI 1 "general_operand" "qim,qi"))
8714 (set (strict_low_part (match_dup 0))
8715 (ior:QI (match_dup 0) (match_dup 1)))]
8716 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8717 && ix86_match_ccmode (insn, CCNOmode)
8718 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8719 "or{b}\t{%1, %0|%0, %1}"
8720 [(set_attr "type" "alu1")
8721 (set_attr "mode" "QI")])
8723 (define_insn "*iorqi_3"
8724 [(set (reg FLAGS_REG)
8725 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8726 (match_operand:QI 2 "general_operand" "qim"))
8728 (clobber (match_scratch:QI 0 "=q"))]
8729 "ix86_match_ccmode (insn, CCNOmode)
8730 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8731 "or{b}\t{%2, %0|%0, %2}"
8732 [(set_attr "type" "alu")
8733 (set_attr "mode" "QI")])
8735 (define_insn "iorqi_ext_0"
8736 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8741 (match_operand 1 "ext_register_operand" "0")
8744 (match_operand 2 "const_int_operand" "n")))
8745 (clobber (reg:CC FLAGS_REG))]
8746 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8747 "or{b}\t{%2, %h0|%h0, %2}"
8748 [(set_attr "type" "alu")
8749 (set_attr "length_immediate" "1")
8750 (set_attr "mode" "QI")])
8752 (define_insn "*iorqi_ext_1"
8753 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8758 (match_operand 1 "ext_register_operand" "0")
8762 (match_operand:QI 2 "general_operand" "Qm"))))
8763 (clobber (reg:CC FLAGS_REG))]
8765 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8766 "or{b}\t{%2, %h0|%h0, %2}"
8767 [(set_attr "type" "alu")
8768 (set_attr "length_immediate" "0")
8769 (set_attr "mode" "QI")])
8771 (define_insn "*iorqi_ext_1_rex64"
8772 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8777 (match_operand 1 "ext_register_operand" "0")
8781 (match_operand 2 "ext_register_operand" "Q"))))
8782 (clobber (reg:CC FLAGS_REG))]
8784 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8785 "or{b}\t{%2, %h0|%h0, %2}"
8786 [(set_attr "type" "alu")
8787 (set_attr "length_immediate" "0")
8788 (set_attr "mode" "QI")])
8790 (define_insn "*iorqi_ext_2"
8791 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8795 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8798 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8801 (clobber (reg:CC FLAGS_REG))]
8802 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8803 "ior{b}\t{%h2, %h0|%h0, %h2}"
8804 [(set_attr "type" "alu")
8805 (set_attr "length_immediate" "0")
8806 (set_attr "mode" "QI")])
8809 [(set (match_operand 0 "register_operand" "")
8810 (ior (match_operand 1 "register_operand" "")
8811 (match_operand 2 "const_int_operand" "")))
8812 (clobber (reg:CC FLAGS_REG))]
8814 && QI_REG_P (operands[0])
8815 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8816 && !(INTVAL (operands[2]) & ~(255 << 8))
8817 && GET_MODE (operands[0]) != QImode"
8818 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8819 (ior:SI (zero_extract:SI (match_dup 1)
8820 (const_int 8) (const_int 8))
8822 (clobber (reg:CC FLAGS_REG))])]
8823 "operands[0] = gen_lowpart (SImode, operands[0]);
8824 operands[1] = gen_lowpart (SImode, operands[1]);
8825 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8827 ;; Since OR can be encoded with sign extended immediate, this is only
8828 ;; profitable when 7th bit is set.
8830 [(set (match_operand 0 "register_operand" "")
8831 (ior (match_operand 1 "general_operand" "")
8832 (match_operand 2 "const_int_operand" "")))
8833 (clobber (reg:CC FLAGS_REG))]
8835 && ANY_QI_REG_P (operands[0])
8836 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8837 && !(INTVAL (operands[2]) & ~255)
8838 && (INTVAL (operands[2]) & 128)
8839 && GET_MODE (operands[0]) != QImode"
8840 [(parallel [(set (strict_low_part (match_dup 0))
8841 (ior:QI (match_dup 1)
8843 (clobber (reg:CC FLAGS_REG))])]
8844 "operands[0] = gen_lowpart (QImode, operands[0]);
8845 operands[1] = gen_lowpart (QImode, operands[1]);
8846 operands[2] = gen_lowpart (QImode, operands[2]);")
8848 ;; Logical XOR instructions
8850 ;; %%% This used to optimize known byte-wide and operations to memory.
8851 ;; If this is considered useful, it should be done with splitters.
8853 (define_expand "xordi3"
8854 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8855 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8856 (match_operand:DI 2 "x86_64_general_operand" "")))
8857 (clobber (reg:CC FLAGS_REG))]
8859 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8861 (define_insn "*xordi_1_rex64"
8862 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8863 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8864 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8865 (clobber (reg:CC FLAGS_REG))]
8867 && ix86_binary_operator_ok (XOR, DImode, operands)"
8869 xor{q}\t{%2, %0|%0, %2}
8870 xor{q}\t{%2, %0|%0, %2}"
8871 [(set_attr "type" "alu")
8872 (set_attr "mode" "DI,DI")])
8874 (define_insn "*xordi_2_rex64"
8875 [(set (reg FLAGS_REG)
8876 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8877 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8879 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8880 (xor:DI (match_dup 1) (match_dup 2)))]
8882 && ix86_match_ccmode (insn, CCNOmode)
8883 && ix86_binary_operator_ok (XOR, DImode, operands)"
8885 xor{q}\t{%2, %0|%0, %2}
8886 xor{q}\t{%2, %0|%0, %2}"
8887 [(set_attr "type" "alu")
8888 (set_attr "mode" "DI,DI")])
8890 (define_insn "*xordi_3_rex64"
8891 [(set (reg FLAGS_REG)
8892 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8893 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8895 (clobber (match_scratch:DI 0 "=r"))]
8897 && ix86_match_ccmode (insn, CCNOmode)
8898 && ix86_binary_operator_ok (XOR, DImode, operands)"
8899 "xor{q}\t{%2, %0|%0, %2}"
8900 [(set_attr "type" "alu")
8901 (set_attr "mode" "DI")])
8903 (define_expand "xorsi3"
8904 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8905 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8906 (match_operand:SI 2 "general_operand" "")))
8907 (clobber (reg:CC FLAGS_REG))]
8909 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8911 (define_insn "*xorsi_1"
8912 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8913 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8914 (match_operand:SI 2 "general_operand" "ri,rm")))
8915 (clobber (reg:CC FLAGS_REG))]
8916 "ix86_binary_operator_ok (XOR, SImode, operands)"
8917 "xor{l}\t{%2, %0|%0, %2}"
8918 [(set_attr "type" "alu")
8919 (set_attr "mode" "SI")])
8921 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8922 ;; Add speccase for immediates
8923 (define_insn "*xorsi_1_zext"
8924 [(set (match_operand:DI 0 "register_operand" "=r")
8926 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8927 (match_operand:SI 2 "general_operand" "rim"))))
8928 (clobber (reg:CC FLAGS_REG))]
8929 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8930 "xor{l}\t{%2, %k0|%k0, %2}"
8931 [(set_attr "type" "alu")
8932 (set_attr "mode" "SI")])
8934 (define_insn "*xorsi_1_zext_imm"
8935 [(set (match_operand:DI 0 "register_operand" "=r")
8936 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8937 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8938 (clobber (reg:CC FLAGS_REG))]
8939 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8940 "xor{l}\t{%2, %k0|%k0, %2}"
8941 [(set_attr "type" "alu")
8942 (set_attr "mode" "SI")])
8944 (define_insn "*xorsi_2"
8945 [(set (reg FLAGS_REG)
8946 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8947 (match_operand:SI 2 "general_operand" "rim,ri"))
8949 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8950 (xor:SI (match_dup 1) (match_dup 2)))]
8951 "ix86_match_ccmode (insn, CCNOmode)
8952 && ix86_binary_operator_ok (XOR, SImode, operands)"
8953 "xor{l}\t{%2, %0|%0, %2}"
8954 [(set_attr "type" "alu")
8955 (set_attr "mode" "SI")])
8957 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8958 ;; ??? Special case for immediate operand is missing - it is tricky.
8959 (define_insn "*xorsi_2_zext"
8960 [(set (reg FLAGS_REG)
8961 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8962 (match_operand:SI 2 "general_operand" "rim"))
8964 (set (match_operand:DI 0 "register_operand" "=r")
8965 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8966 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8967 && ix86_binary_operator_ok (XOR, SImode, operands)"
8968 "xor{l}\t{%2, %k0|%k0, %2}"
8969 [(set_attr "type" "alu")
8970 (set_attr "mode" "SI")])
8972 (define_insn "*xorsi_2_zext_imm"
8973 [(set (reg FLAGS_REG)
8974 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8975 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8977 (set (match_operand:DI 0 "register_operand" "=r")
8978 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8979 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8980 && ix86_binary_operator_ok (XOR, SImode, operands)"
8981 "xor{l}\t{%2, %k0|%k0, %2}"
8982 [(set_attr "type" "alu")
8983 (set_attr "mode" "SI")])
8985 (define_insn "*xorsi_3"
8986 [(set (reg FLAGS_REG)
8987 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8988 (match_operand:SI 2 "general_operand" "rim"))
8990 (clobber (match_scratch:SI 0 "=r"))]
8991 "ix86_match_ccmode (insn, CCNOmode)
8992 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8993 "xor{l}\t{%2, %0|%0, %2}"
8994 [(set_attr "type" "alu")
8995 (set_attr "mode" "SI")])
8997 (define_expand "xorhi3"
8998 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8999 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9000 (match_operand:HI 2 "general_operand" "")))
9001 (clobber (reg:CC FLAGS_REG))]
9002 "TARGET_HIMODE_MATH"
9003 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9005 (define_insn "*xorhi_1"
9006 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9007 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9008 (match_operand:HI 2 "general_operand" "rmi,ri")))
9009 (clobber (reg:CC FLAGS_REG))]
9010 "ix86_binary_operator_ok (XOR, HImode, operands)"
9011 "xor{w}\t{%2, %0|%0, %2}"
9012 [(set_attr "type" "alu")
9013 (set_attr "mode" "HI")])
9015 (define_insn "*xorhi_2"
9016 [(set (reg FLAGS_REG)
9017 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9018 (match_operand:HI 2 "general_operand" "rim,ri"))
9020 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9021 (xor:HI (match_dup 1) (match_dup 2)))]
9022 "ix86_match_ccmode (insn, CCNOmode)
9023 && ix86_binary_operator_ok (XOR, HImode, operands)"
9024 "xor{w}\t{%2, %0|%0, %2}"
9025 [(set_attr "type" "alu")
9026 (set_attr "mode" "HI")])
9028 (define_insn "*xorhi_3"
9029 [(set (reg FLAGS_REG)
9030 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9031 (match_operand:HI 2 "general_operand" "rim"))
9033 (clobber (match_scratch:HI 0 "=r"))]
9034 "ix86_match_ccmode (insn, CCNOmode)
9035 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9036 "xor{w}\t{%2, %0|%0, %2}"
9037 [(set_attr "type" "alu")
9038 (set_attr "mode" "HI")])
9040 (define_expand "xorqi3"
9041 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9042 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9043 (match_operand:QI 2 "general_operand" "")))
9044 (clobber (reg:CC FLAGS_REG))]
9045 "TARGET_QIMODE_MATH"
9046 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9048 ;; %%% Potential partial reg stall on alternative 2. What to do?
9049 (define_insn "*xorqi_1"
9050 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9051 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9052 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9053 (clobber (reg:CC FLAGS_REG))]
9054 "ix86_binary_operator_ok (XOR, QImode, operands)"
9056 xor{b}\t{%2, %0|%0, %2}
9057 xor{b}\t{%2, %0|%0, %2}
9058 xor{l}\t{%k2, %k0|%k0, %k2}"
9059 [(set_attr "type" "alu")
9060 (set_attr "mode" "QI,QI,SI")])
9062 (define_insn "*xorqi_1_slp"
9063 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9064 (xor:QI (match_dup 0)
9065 (match_operand:QI 1 "general_operand" "qi,qmi")))
9066 (clobber (reg:CC FLAGS_REG))]
9067 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9068 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9069 "xor{b}\t{%1, %0|%0, %1}"
9070 [(set_attr "type" "alu1")
9071 (set_attr "mode" "QI")])
9073 (define_insn "xorqi_ext_0"
9074 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9079 (match_operand 1 "ext_register_operand" "0")
9082 (match_operand 2 "const_int_operand" "n")))
9083 (clobber (reg:CC FLAGS_REG))]
9084 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9085 "xor{b}\t{%2, %h0|%h0, %2}"
9086 [(set_attr "type" "alu")
9087 (set_attr "length_immediate" "1")
9088 (set_attr "mode" "QI")])
9090 (define_insn "*xorqi_ext_1"
9091 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9096 (match_operand 1 "ext_register_operand" "0")
9100 (match_operand:QI 2 "general_operand" "Qm"))))
9101 (clobber (reg:CC FLAGS_REG))]
9103 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9104 "xor{b}\t{%2, %h0|%h0, %2}"
9105 [(set_attr "type" "alu")
9106 (set_attr "length_immediate" "0")
9107 (set_attr "mode" "QI")])
9109 (define_insn "*xorqi_ext_1_rex64"
9110 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9115 (match_operand 1 "ext_register_operand" "0")
9119 (match_operand 2 "ext_register_operand" "Q"))))
9120 (clobber (reg:CC FLAGS_REG))]
9122 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9123 "xor{b}\t{%2, %h0|%h0, %2}"
9124 [(set_attr "type" "alu")
9125 (set_attr "length_immediate" "0")
9126 (set_attr "mode" "QI")])
9128 (define_insn "*xorqi_ext_2"
9129 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9133 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9136 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9139 (clobber (reg:CC FLAGS_REG))]
9140 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9141 "xor{b}\t{%h2, %h0|%h0, %h2}"
9142 [(set_attr "type" "alu")
9143 (set_attr "length_immediate" "0")
9144 (set_attr "mode" "QI")])
9146 (define_insn "*xorqi_cc_1"
9147 [(set (reg FLAGS_REG)
9149 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9150 (match_operand:QI 2 "general_operand" "qim,qi"))
9152 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9153 (xor:QI (match_dup 1) (match_dup 2)))]
9154 "ix86_match_ccmode (insn, CCNOmode)
9155 && ix86_binary_operator_ok (XOR, QImode, operands)"
9156 "xor{b}\t{%2, %0|%0, %2}"
9157 [(set_attr "type" "alu")
9158 (set_attr "mode" "QI")])
9160 (define_insn "*xorqi_2_slp"
9161 [(set (reg FLAGS_REG)
9162 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9163 (match_operand:QI 1 "general_operand" "qim,qi"))
9165 (set (strict_low_part (match_dup 0))
9166 (xor:QI (match_dup 0) (match_dup 1)))]
9167 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9168 && ix86_match_ccmode (insn, CCNOmode)
9169 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9170 "xor{b}\t{%1, %0|%0, %1}"
9171 [(set_attr "type" "alu1")
9172 (set_attr "mode" "QI")])
9174 (define_insn "*xorqi_cc_2"
9175 [(set (reg FLAGS_REG)
9177 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9178 (match_operand:QI 2 "general_operand" "qim"))
9180 (clobber (match_scratch:QI 0 "=q"))]
9181 "ix86_match_ccmode (insn, CCNOmode)
9182 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9183 "xor{b}\t{%2, %0|%0, %2}"
9184 [(set_attr "type" "alu")
9185 (set_attr "mode" "QI")])
9187 (define_insn "*xorqi_cc_ext_1"
9188 [(set (reg FLAGS_REG)
9192 (match_operand 1 "ext_register_operand" "0")
9195 (match_operand:QI 2 "general_operand" "qmn"))
9197 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9201 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9203 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9204 "xor{b}\t{%2, %h0|%h0, %2}"
9205 [(set_attr "type" "alu")
9206 (set_attr "mode" "QI")])
9208 (define_insn "*xorqi_cc_ext_1_rex64"
9209 [(set (reg FLAGS_REG)
9213 (match_operand 1 "ext_register_operand" "0")
9216 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9218 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9222 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9224 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9225 "xor{b}\t{%2, %h0|%h0, %2}"
9226 [(set_attr "type" "alu")
9227 (set_attr "mode" "QI")])
9229 (define_expand "xorqi_cc_ext_1"
9231 (set (reg:CCNO FLAGS_REG)
9235 (match_operand 1 "ext_register_operand" "")
9238 (match_operand:QI 2 "general_operand" ""))
9240 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9244 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9250 [(set (match_operand 0 "register_operand" "")
9251 (xor (match_operand 1 "register_operand" "")
9252 (match_operand 2 "const_int_operand" "")))
9253 (clobber (reg:CC FLAGS_REG))]
9255 && QI_REG_P (operands[0])
9256 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9257 && !(INTVAL (operands[2]) & ~(255 << 8))
9258 && GET_MODE (operands[0]) != QImode"
9259 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9260 (xor:SI (zero_extract:SI (match_dup 1)
9261 (const_int 8) (const_int 8))
9263 (clobber (reg:CC FLAGS_REG))])]
9264 "operands[0] = gen_lowpart (SImode, operands[0]);
9265 operands[1] = gen_lowpart (SImode, operands[1]);
9266 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9268 ;; Since XOR can be encoded with sign extended immediate, this is only
9269 ;; profitable when 7th bit is set.
9271 [(set (match_operand 0 "register_operand" "")
9272 (xor (match_operand 1 "general_operand" "")
9273 (match_operand 2 "const_int_operand" "")))
9274 (clobber (reg:CC FLAGS_REG))]
9276 && ANY_QI_REG_P (operands[0])
9277 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9278 && !(INTVAL (operands[2]) & ~255)
9279 && (INTVAL (operands[2]) & 128)
9280 && GET_MODE (operands[0]) != QImode"
9281 [(parallel [(set (strict_low_part (match_dup 0))
9282 (xor:QI (match_dup 1)
9284 (clobber (reg:CC FLAGS_REG))])]
9285 "operands[0] = gen_lowpart (QImode, operands[0]);
9286 operands[1] = gen_lowpart (QImode, operands[1]);
9287 operands[2] = gen_lowpart (QImode, operands[2]);")
9289 ;; Negation instructions
9291 (define_expand "negti2"
9292 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9293 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9294 (clobber (reg:CC FLAGS_REG))])]
9296 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9298 (define_insn "*negti2_1"
9299 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9300 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9301 (clobber (reg:CC FLAGS_REG))]
9303 && ix86_unary_operator_ok (NEG, TImode, operands)"
9307 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9308 (neg:TI (match_operand:TI 1 "general_operand" "")))
9309 (clobber (reg:CC FLAGS_REG))]
9310 "TARGET_64BIT && reload_completed"
9312 [(set (reg:CCZ FLAGS_REG)
9313 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9314 (set (match_dup 0) (neg:DI (match_dup 2)))])
9317 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9320 (clobber (reg:CC FLAGS_REG))])
9323 (neg:DI (match_dup 1)))
9324 (clobber (reg:CC FLAGS_REG))])]
9325 "split_ti (operands+1, 1, operands+2, operands+3);
9326 split_ti (operands+0, 1, operands+0, operands+1);")
9328 (define_expand "negdi2"
9329 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9330 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9331 (clobber (reg:CC FLAGS_REG))])]
9333 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9335 (define_insn "*negdi2_1"
9336 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9337 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9338 (clobber (reg:CC FLAGS_REG))]
9340 && ix86_unary_operator_ok (NEG, DImode, operands)"
9344 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9345 (neg:DI (match_operand:DI 1 "general_operand" "")))
9346 (clobber (reg:CC FLAGS_REG))]
9347 "!TARGET_64BIT && reload_completed"
9349 [(set (reg:CCZ FLAGS_REG)
9350 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9351 (set (match_dup 0) (neg:SI (match_dup 2)))])
9354 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9357 (clobber (reg:CC FLAGS_REG))])
9360 (neg:SI (match_dup 1)))
9361 (clobber (reg:CC FLAGS_REG))])]
9362 "split_di (operands+1, 1, operands+2, operands+3);
9363 split_di (operands+0, 1, operands+0, operands+1);")
9365 (define_insn "*negdi2_1_rex64"
9366 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9367 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9368 (clobber (reg:CC FLAGS_REG))]
9369 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9371 [(set_attr "type" "negnot")
9372 (set_attr "mode" "DI")])
9374 ;; The problem with neg is that it does not perform (compare x 0),
9375 ;; it really performs (compare 0 x), which leaves us with the zero
9376 ;; flag being the only useful item.
9378 (define_insn "*negdi2_cmpz_rex64"
9379 [(set (reg:CCZ FLAGS_REG)
9380 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9382 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9383 (neg:DI (match_dup 1)))]
9384 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9386 [(set_attr "type" "negnot")
9387 (set_attr "mode" "DI")])
9390 (define_expand "negsi2"
9391 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9392 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9393 (clobber (reg:CC FLAGS_REG))])]
9395 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9397 (define_insn "*negsi2_1"
9398 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9399 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9400 (clobber (reg:CC FLAGS_REG))]
9401 "ix86_unary_operator_ok (NEG, SImode, operands)"
9403 [(set_attr "type" "negnot")
9404 (set_attr "mode" "SI")])
9406 ;; Combine is quite creative about this pattern.
9407 (define_insn "*negsi2_1_zext"
9408 [(set (match_operand:DI 0 "register_operand" "=r")
9409 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9412 (clobber (reg:CC FLAGS_REG))]
9413 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9415 [(set_attr "type" "negnot")
9416 (set_attr "mode" "SI")])
9418 ;; The problem with neg is that it does not perform (compare x 0),
9419 ;; it really performs (compare 0 x), which leaves us with the zero
9420 ;; flag being the only useful item.
9422 (define_insn "*negsi2_cmpz"
9423 [(set (reg:CCZ FLAGS_REG)
9424 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9426 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9427 (neg:SI (match_dup 1)))]
9428 "ix86_unary_operator_ok (NEG, SImode, operands)"
9430 [(set_attr "type" "negnot")
9431 (set_attr "mode" "SI")])
9433 (define_insn "*negsi2_cmpz_zext"
9434 [(set (reg:CCZ FLAGS_REG)
9435 (compare:CCZ (lshiftrt:DI
9437 (match_operand:DI 1 "register_operand" "0")
9441 (set (match_operand:DI 0 "register_operand" "=r")
9442 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9445 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9447 [(set_attr "type" "negnot")
9448 (set_attr "mode" "SI")])
9450 (define_expand "neghi2"
9451 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9452 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9453 (clobber (reg:CC FLAGS_REG))])]
9454 "TARGET_HIMODE_MATH"
9455 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9457 (define_insn "*neghi2_1"
9458 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9459 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9460 (clobber (reg:CC FLAGS_REG))]
9461 "ix86_unary_operator_ok (NEG, HImode, operands)"
9463 [(set_attr "type" "negnot")
9464 (set_attr "mode" "HI")])
9466 (define_insn "*neghi2_cmpz"
9467 [(set (reg:CCZ FLAGS_REG)
9468 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9470 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9471 (neg:HI (match_dup 1)))]
9472 "ix86_unary_operator_ok (NEG, HImode, operands)"
9474 [(set_attr "type" "negnot")
9475 (set_attr "mode" "HI")])
9477 (define_expand "negqi2"
9478 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9479 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9480 (clobber (reg:CC FLAGS_REG))])]
9481 "TARGET_QIMODE_MATH"
9482 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9484 (define_insn "*negqi2_1"
9485 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9486 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9487 (clobber (reg:CC FLAGS_REG))]
9488 "ix86_unary_operator_ok (NEG, QImode, operands)"
9490 [(set_attr "type" "negnot")
9491 (set_attr "mode" "QI")])
9493 (define_insn "*negqi2_cmpz"
9494 [(set (reg:CCZ FLAGS_REG)
9495 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9497 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9498 (neg:QI (match_dup 1)))]
9499 "ix86_unary_operator_ok (NEG, QImode, operands)"
9501 [(set_attr "type" "negnot")
9502 (set_attr "mode" "QI")])
9504 ;; Changing of sign for FP values is doable using integer unit too.
9506 (define_expand "negsf2"
9507 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9508 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9509 "TARGET_80387 || TARGET_SSE_MATH"
9510 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9512 (define_expand "abssf2"
9513 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9514 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9515 "TARGET_80387 || TARGET_SSE_MATH"
9516 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9518 (define_insn "*absnegsf2_mixed"
9519 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#f,x#f,f#x,rm")
9520 (match_operator:SF 3 "absneg_operator"
9521 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#f,0 ,0")]))
9522 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9523 (clobber (reg:CC FLAGS_REG))]
9524 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9525 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9528 (define_insn "*absnegsf2_sse"
9529 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9530 (match_operator:SF 3 "absneg_operator"
9531 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9532 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9533 (clobber (reg:CC FLAGS_REG))]
9535 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9538 (define_insn "*absnegsf2_i387"
9539 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9540 (match_operator:SF 3 "absneg_operator"
9541 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9542 (use (match_operand 2 "" ""))
9543 (clobber (reg:CC FLAGS_REG))]
9544 "TARGET_80387 && !TARGET_SSE_MATH
9545 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9548 (define_expand "copysignsf3"
9549 [(match_operand:SF 0 "register_operand" "")
9550 (match_operand:SF 1 "nonmemory_operand" "")
9551 (match_operand:SF 2 "register_operand" "")]
9554 ix86_expand_copysign (operands);
9558 (define_insn_and_split "copysignsf3_const"
9559 [(set (match_operand:SF 0 "register_operand" "=x")
9561 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9562 (match_operand:SF 2 "register_operand" "0")
9563 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9567 "&& reload_completed"
9570 ix86_split_copysign_const (operands);
9574 (define_insn "copysignsf3_var"
9575 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9577 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9578 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9579 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9580 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9582 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9587 [(set (match_operand:SF 0 "register_operand" "")
9589 [(match_operand:SF 2 "register_operand" "")
9590 (match_operand:SF 3 "register_operand" "")
9591 (match_operand:V4SF 4 "" "")
9592 (match_operand:V4SF 5 "" "")]
9594 (clobber (match_scratch:V4SF 1 ""))]
9595 "TARGET_SSE_MATH && reload_completed"
9598 ix86_split_copysign_var (operands);
9602 (define_expand "negdf2"
9603 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9604 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9605 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9606 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9608 (define_expand "absdf2"
9609 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9610 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9611 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9612 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9614 (define_insn "*absnegdf2_mixed"
9615 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,f#Y,rm")
9616 (match_operator:DF 3 "absneg_operator"
9617 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#f,0 ,0")]))
9618 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9619 (clobber (reg:CC FLAGS_REG))]
9620 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9621 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9624 (define_insn "*absnegdf2_sse"
9625 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9626 (match_operator:DF 3 "absneg_operator"
9627 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9628 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X"))
9629 (clobber (reg:CC FLAGS_REG))]
9630 "TARGET_SSE2 && TARGET_SSE_MATH
9631 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9634 (define_insn "*absnegdf2_i387"
9635 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9636 (match_operator:DF 3 "absneg_operator"
9637 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9638 (use (match_operand 2 "" ""))
9639 (clobber (reg:CC FLAGS_REG))]
9640 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9641 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9644 (define_expand "copysigndf3"
9645 [(match_operand:DF 0 "register_operand" "")
9646 (match_operand:DF 1 "nonmemory_operand" "")
9647 (match_operand:DF 2 "register_operand" "")]
9648 "TARGET_SSE2 && TARGET_SSE_MATH"
9650 ix86_expand_copysign (operands);
9654 (define_insn_and_split "copysigndf3_const"
9655 [(set (match_operand:DF 0 "register_operand" "=x")
9657 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9658 (match_operand:DF 2 "register_operand" "0")
9659 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9661 "TARGET_SSE2 && TARGET_SSE_MATH"
9663 "&& reload_completed"
9666 ix86_split_copysign_const (operands);
9670 (define_insn "copysigndf3_var"
9671 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9673 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9674 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9675 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9676 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9678 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9679 "TARGET_SSE2 && TARGET_SSE_MATH"
9683 [(set (match_operand:DF 0 "register_operand" "")
9685 [(match_operand:DF 2 "register_operand" "")
9686 (match_operand:DF 3 "register_operand" "")
9687 (match_operand:V2DF 4 "" "")
9688 (match_operand:V2DF 5 "" "")]
9690 (clobber (match_scratch:V2DF 1 ""))]
9691 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9694 ix86_split_copysign_var (operands);
9698 (define_expand "negxf2"
9699 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9700 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9702 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9704 (define_expand "absxf2"
9705 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9706 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9708 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9710 (define_insn "*absnegxf2_i387"
9711 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9712 (match_operator:XF 3 "absneg_operator"
9713 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9714 (use (match_operand 2 "" ""))
9715 (clobber (reg:CC FLAGS_REG))]
9717 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9720 ;; Splitters for fp abs and neg.
9723 [(set (match_operand 0 "fp_register_operand" "")
9724 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9725 (use (match_operand 2 "" ""))
9726 (clobber (reg:CC FLAGS_REG))]
9728 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9731 [(set (match_operand 0 "register_operand" "")
9732 (match_operator 3 "absneg_operator"
9733 [(match_operand 1 "register_operand" "")]))
9734 (use (match_operand 2 "nonimmediate_operand" ""))
9735 (clobber (reg:CC FLAGS_REG))]
9736 "reload_completed && SSE_REG_P (operands[0])"
9737 [(set (match_dup 0) (match_dup 3))]
9739 enum machine_mode mode = GET_MODE (operands[0]);
9740 enum machine_mode vmode = GET_MODE (operands[2]);
9743 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9744 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9745 if (operands_match_p (operands[0], operands[2]))
9748 operands[1] = operands[2];
9751 if (GET_CODE (operands[3]) == ABS)
9752 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9754 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9759 [(set (match_operand:SF 0 "register_operand" "")
9760 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9761 (use (match_operand:V4SF 2 "" ""))
9762 (clobber (reg:CC FLAGS_REG))]
9764 [(parallel [(set (match_dup 0) (match_dup 1))
9765 (clobber (reg:CC FLAGS_REG))])]
9768 operands[0] = gen_lowpart (SImode, operands[0]);
9769 if (GET_CODE (operands[1]) == ABS)
9771 tmp = gen_int_mode (0x7fffffff, SImode);
9772 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9776 tmp = gen_int_mode (0x80000000, SImode);
9777 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9783 [(set (match_operand:DF 0 "register_operand" "")
9784 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9785 (use (match_operand 2 "" ""))
9786 (clobber (reg:CC FLAGS_REG))]
9788 [(parallel [(set (match_dup 0) (match_dup 1))
9789 (clobber (reg:CC FLAGS_REG))])]
9794 tmp = gen_lowpart (DImode, operands[0]);
9795 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9798 if (GET_CODE (operands[1]) == ABS)
9801 tmp = gen_rtx_NOT (DImode, tmp);
9805 operands[0] = gen_highpart (SImode, operands[0]);
9806 if (GET_CODE (operands[1]) == ABS)
9808 tmp = gen_int_mode (0x7fffffff, SImode);
9809 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9813 tmp = gen_int_mode (0x80000000, SImode);
9814 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9821 [(set (match_operand:XF 0 "register_operand" "")
9822 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9823 (use (match_operand 2 "" ""))
9824 (clobber (reg:CC FLAGS_REG))]
9826 [(parallel [(set (match_dup 0) (match_dup 1))
9827 (clobber (reg:CC FLAGS_REG))])]
9830 operands[0] = gen_rtx_REG (SImode,
9831 true_regnum (operands[0])
9832 + (TARGET_64BIT ? 1 : 2));
9833 if (GET_CODE (operands[1]) == ABS)
9835 tmp = GEN_INT (0x7fff);
9836 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9840 tmp = GEN_INT (0x8000);
9841 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9847 [(set (match_operand 0 "memory_operand" "")
9848 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9849 (use (match_operand 2 "" ""))
9850 (clobber (reg:CC FLAGS_REG))]
9852 [(parallel [(set (match_dup 0) (match_dup 1))
9853 (clobber (reg:CC FLAGS_REG))])]
9855 enum machine_mode mode = GET_MODE (operands[0]);
9856 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9859 operands[0] = adjust_address (operands[0], QImode, size - 1);
9860 if (GET_CODE (operands[1]) == ABS)
9862 tmp = gen_int_mode (0x7f, QImode);
9863 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9867 tmp = gen_int_mode (0x80, QImode);
9868 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9873 ;; Conditionalize these after reload. If they match before reload, we
9874 ;; lose the clobber and ability to use integer instructions.
9876 (define_insn "*negsf2_1"
9877 [(set (match_operand:SF 0 "register_operand" "=f")
9878 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9879 "TARGET_80387 && reload_completed"
9881 [(set_attr "type" "fsgn")
9882 (set_attr "mode" "SF")])
9884 (define_insn "*negdf2_1"
9885 [(set (match_operand:DF 0 "register_operand" "=f")
9886 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9887 "TARGET_80387 && reload_completed"
9889 [(set_attr "type" "fsgn")
9890 (set_attr "mode" "DF")])
9892 (define_insn "*negxf2_1"
9893 [(set (match_operand:XF 0 "register_operand" "=f")
9894 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9895 "TARGET_80387 && reload_completed"
9897 [(set_attr "type" "fsgn")
9898 (set_attr "mode" "XF")])
9900 (define_insn "*abssf2_1"
9901 [(set (match_operand:SF 0 "register_operand" "=f")
9902 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9903 "TARGET_80387 && reload_completed"
9905 [(set_attr "type" "fsgn")
9906 (set_attr "mode" "SF")])
9908 (define_insn "*absdf2_1"
9909 [(set (match_operand:DF 0 "register_operand" "=f")
9910 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9911 "TARGET_80387 && reload_completed"
9913 [(set_attr "type" "fsgn")
9914 (set_attr "mode" "DF")])
9916 (define_insn "*absxf2_1"
9917 [(set (match_operand:XF 0 "register_operand" "=f")
9918 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9919 "TARGET_80387 && reload_completed"
9921 [(set_attr "type" "fsgn")
9922 (set_attr "mode" "DF")])
9924 (define_insn "*negextendsfdf2"
9925 [(set (match_operand:DF 0 "register_operand" "=f")
9926 (neg:DF (float_extend:DF
9927 (match_operand:SF 1 "register_operand" "0"))))]
9928 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9930 [(set_attr "type" "fsgn")
9931 (set_attr "mode" "DF")])
9933 (define_insn "*negextenddfxf2"
9934 [(set (match_operand:XF 0 "register_operand" "=f")
9935 (neg:XF (float_extend:XF
9936 (match_operand:DF 1 "register_operand" "0"))))]
9939 [(set_attr "type" "fsgn")
9940 (set_attr "mode" "XF")])
9942 (define_insn "*negextendsfxf2"
9943 [(set (match_operand:XF 0 "register_operand" "=f")
9944 (neg:XF (float_extend:XF
9945 (match_operand:SF 1 "register_operand" "0"))))]
9948 [(set_attr "type" "fsgn")
9949 (set_attr "mode" "XF")])
9951 (define_insn "*absextendsfdf2"
9952 [(set (match_operand:DF 0 "register_operand" "=f")
9953 (abs:DF (float_extend:DF
9954 (match_operand:SF 1 "register_operand" "0"))))]
9955 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9957 [(set_attr "type" "fsgn")
9958 (set_attr "mode" "DF")])
9960 (define_insn "*absextenddfxf2"
9961 [(set (match_operand:XF 0 "register_operand" "=f")
9962 (abs:XF (float_extend:XF
9963 (match_operand:DF 1 "register_operand" "0"))))]
9966 [(set_attr "type" "fsgn")
9967 (set_attr "mode" "XF")])
9969 (define_insn "*absextendsfxf2"
9970 [(set (match_operand:XF 0 "register_operand" "=f")
9971 (abs:XF (float_extend:XF
9972 (match_operand:SF 1 "register_operand" "0"))))]
9975 [(set_attr "type" "fsgn")
9976 (set_attr "mode" "XF")])
9978 ;; One complement instructions
9980 (define_expand "one_cmpldi2"
9981 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9982 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9984 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9986 (define_insn "*one_cmpldi2_1_rex64"
9987 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9988 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9989 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9991 [(set_attr "type" "negnot")
9992 (set_attr "mode" "DI")])
9994 (define_insn "*one_cmpldi2_2_rex64"
9995 [(set (reg FLAGS_REG)
9996 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9998 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9999 (not:DI (match_dup 1)))]
10000 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10001 && ix86_unary_operator_ok (NOT, DImode, operands)"
10003 [(set_attr "type" "alu1")
10004 (set_attr "mode" "DI")])
10007 [(set (match_operand 0 "flags_reg_operand" "")
10008 (match_operator 2 "compare_operator"
10009 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10011 (set (match_operand:DI 1 "nonimmediate_operand" "")
10012 (not:DI (match_dup 3)))]
10013 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10014 [(parallel [(set (match_dup 0)
10016 [(xor:DI (match_dup 3) (const_int -1))
10019 (xor:DI (match_dup 3) (const_int -1)))])]
10022 (define_expand "one_cmplsi2"
10023 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10024 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10026 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10028 (define_insn "*one_cmplsi2_1"
10029 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10030 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10031 "ix86_unary_operator_ok (NOT, SImode, operands)"
10033 [(set_attr "type" "negnot")
10034 (set_attr "mode" "SI")])
10036 ;; ??? Currently never generated - xor is used instead.
10037 (define_insn "*one_cmplsi2_1_zext"
10038 [(set (match_operand:DI 0 "register_operand" "=r")
10039 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10040 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10042 [(set_attr "type" "negnot")
10043 (set_attr "mode" "SI")])
10045 (define_insn "*one_cmplsi2_2"
10046 [(set (reg FLAGS_REG)
10047 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10049 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10050 (not:SI (match_dup 1)))]
10051 "ix86_match_ccmode (insn, CCNOmode)
10052 && ix86_unary_operator_ok (NOT, SImode, operands)"
10054 [(set_attr "type" "alu1")
10055 (set_attr "mode" "SI")])
10058 [(set (match_operand 0 "flags_reg_operand" "")
10059 (match_operator 2 "compare_operator"
10060 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10062 (set (match_operand:SI 1 "nonimmediate_operand" "")
10063 (not:SI (match_dup 3)))]
10064 "ix86_match_ccmode (insn, CCNOmode)"
10065 [(parallel [(set (match_dup 0)
10066 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10069 (xor:SI (match_dup 3) (const_int -1)))])]
10072 ;; ??? Currently never generated - xor is used instead.
10073 (define_insn "*one_cmplsi2_2_zext"
10074 [(set (reg FLAGS_REG)
10075 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10077 (set (match_operand:DI 0 "register_operand" "=r")
10078 (zero_extend:DI (not:SI (match_dup 1))))]
10079 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10080 && ix86_unary_operator_ok (NOT, SImode, operands)"
10082 [(set_attr "type" "alu1")
10083 (set_attr "mode" "SI")])
10086 [(set (match_operand 0 "flags_reg_operand" "")
10087 (match_operator 2 "compare_operator"
10088 [(not:SI (match_operand:SI 3 "register_operand" ""))
10090 (set (match_operand:DI 1 "register_operand" "")
10091 (zero_extend:DI (not:SI (match_dup 3))))]
10092 "ix86_match_ccmode (insn, CCNOmode)"
10093 [(parallel [(set (match_dup 0)
10094 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10097 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10100 (define_expand "one_cmplhi2"
10101 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10102 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10103 "TARGET_HIMODE_MATH"
10104 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10106 (define_insn "*one_cmplhi2_1"
10107 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10108 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10109 "ix86_unary_operator_ok (NOT, HImode, operands)"
10111 [(set_attr "type" "negnot")
10112 (set_attr "mode" "HI")])
10114 (define_insn "*one_cmplhi2_2"
10115 [(set (reg FLAGS_REG)
10116 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10118 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10119 (not:HI (match_dup 1)))]
10120 "ix86_match_ccmode (insn, CCNOmode)
10121 && ix86_unary_operator_ok (NEG, HImode, operands)"
10123 [(set_attr "type" "alu1")
10124 (set_attr "mode" "HI")])
10127 [(set (match_operand 0 "flags_reg_operand" "")
10128 (match_operator 2 "compare_operator"
10129 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10131 (set (match_operand:HI 1 "nonimmediate_operand" "")
10132 (not:HI (match_dup 3)))]
10133 "ix86_match_ccmode (insn, CCNOmode)"
10134 [(parallel [(set (match_dup 0)
10135 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10138 (xor:HI (match_dup 3) (const_int -1)))])]
10141 ;; %%% Potential partial reg stall on alternative 1. What to do?
10142 (define_expand "one_cmplqi2"
10143 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10144 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10145 "TARGET_QIMODE_MATH"
10146 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10148 (define_insn "*one_cmplqi2_1"
10149 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10150 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10151 "ix86_unary_operator_ok (NOT, QImode, operands)"
10155 [(set_attr "type" "negnot")
10156 (set_attr "mode" "QI,SI")])
10158 (define_insn "*one_cmplqi2_2"
10159 [(set (reg FLAGS_REG)
10160 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10162 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10163 (not:QI (match_dup 1)))]
10164 "ix86_match_ccmode (insn, CCNOmode)
10165 && ix86_unary_operator_ok (NOT, QImode, operands)"
10167 [(set_attr "type" "alu1")
10168 (set_attr "mode" "QI")])
10171 [(set (match_operand 0 "flags_reg_operand" "")
10172 (match_operator 2 "compare_operator"
10173 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10175 (set (match_operand:QI 1 "nonimmediate_operand" "")
10176 (not:QI (match_dup 3)))]
10177 "ix86_match_ccmode (insn, CCNOmode)"
10178 [(parallel [(set (match_dup 0)
10179 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10182 (xor:QI (match_dup 3) (const_int -1)))])]
10185 ;; Arithmetic shift instructions
10187 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10188 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10189 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10190 ;; from the assembler input.
10192 ;; This instruction shifts the target reg/mem as usual, but instead of
10193 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10194 ;; is a left shift double, bits are taken from the high order bits of
10195 ;; reg, else if the insn is a shift right double, bits are taken from the
10196 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10197 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10199 ;; Since sh[lr]d does not change the `reg' operand, that is done
10200 ;; separately, making all shifts emit pairs of shift double and normal
10201 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10202 ;; support a 63 bit shift, each shift where the count is in a reg expands
10203 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10205 ;; If the shift count is a constant, we need never emit more than one
10206 ;; shift pair, instead using moves and sign extension for counts greater
10209 (define_expand "ashlti3"
10210 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10211 (ashift:TI (match_operand:TI 1 "register_operand" "")
10212 (match_operand:QI 2 "nonmemory_operand" "")))
10213 (clobber (reg:CC FLAGS_REG))])]
10216 if (! immediate_operand (operands[2], QImode))
10218 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10221 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10225 (define_insn "ashlti3_1"
10226 [(set (match_operand:TI 0 "register_operand" "=r")
10227 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10228 (match_operand:QI 2 "register_operand" "c")))
10229 (clobber (match_scratch:DI 3 "=&r"))
10230 (clobber (reg:CC FLAGS_REG))]
10233 [(set_attr "type" "multi")])
10235 (define_insn "*ashlti3_2"
10236 [(set (match_operand:TI 0 "register_operand" "=r")
10237 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10238 (match_operand:QI 2 "immediate_operand" "O")))
10239 (clobber (reg:CC FLAGS_REG))]
10242 [(set_attr "type" "multi")])
10245 [(set (match_operand:TI 0 "register_operand" "")
10246 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10247 (match_operand:QI 2 "register_operand" "")))
10248 (clobber (match_scratch:DI 3 ""))
10249 (clobber (reg:CC FLAGS_REG))]
10250 "TARGET_64BIT && reload_completed"
10252 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10255 [(set (match_operand:TI 0 "register_operand" "")
10256 (ashift:TI (match_operand:TI 1 "register_operand" "")
10257 (match_operand:QI 2 "immediate_operand" "")))
10258 (clobber (reg:CC FLAGS_REG))]
10259 "TARGET_64BIT && reload_completed"
10261 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10263 (define_insn "x86_64_shld"
10264 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10265 (ior:DI (ashift:DI (match_dup 0)
10266 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10267 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10268 (minus:QI (const_int 64) (match_dup 2)))))
10269 (clobber (reg:CC FLAGS_REG))]
10272 shld{q}\t{%2, %1, %0|%0, %1, %2}
10273 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10274 [(set_attr "type" "ishift")
10275 (set_attr "prefix_0f" "1")
10276 (set_attr "mode" "DI")
10277 (set_attr "athlon_decode" "vector")])
10279 (define_expand "x86_64_shift_adj"
10280 [(set (reg:CCZ FLAGS_REG)
10281 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10284 (set (match_operand:DI 0 "register_operand" "")
10285 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10286 (match_operand:DI 1 "register_operand" "")
10289 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10290 (match_operand:DI 3 "register_operand" "r")
10295 (define_expand "ashldi3"
10296 [(set (match_operand:DI 0 "shiftdi_operand" "")
10297 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10298 (match_operand:QI 2 "nonmemory_operand" "")))]
10300 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10302 (define_insn "*ashldi3_1_rex64"
10303 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10304 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10305 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10306 (clobber (reg:CC FLAGS_REG))]
10307 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10309 switch (get_attr_type (insn))
10312 gcc_assert (operands[2] == const1_rtx);
10313 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10314 return "add{q}\t{%0, %0|%0, %0}";
10317 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10318 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10319 operands[1] = gen_rtx_MULT (DImode, operands[1],
10320 GEN_INT (1 << INTVAL (operands[2])));
10321 return "lea{q}\t{%a1, %0|%0, %a1}";
10324 if (REG_P (operands[2]))
10325 return "sal{q}\t{%b2, %0|%0, %b2}";
10326 else if (operands[2] == const1_rtx
10327 && (TARGET_SHIFT1 || optimize_size))
10328 return "sal{q}\t%0";
10330 return "sal{q}\t{%2, %0|%0, %2}";
10333 [(set (attr "type")
10334 (cond [(eq_attr "alternative" "1")
10335 (const_string "lea")
10336 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10338 (match_operand 0 "register_operand" ""))
10339 (match_operand 2 "const1_operand" ""))
10340 (const_string "alu")
10342 (const_string "ishift")))
10343 (set_attr "mode" "DI")])
10345 ;; Convert lea to the lea pattern to avoid flags dependency.
10347 [(set (match_operand:DI 0 "register_operand" "")
10348 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10349 (match_operand:QI 2 "immediate_operand" "")))
10350 (clobber (reg:CC FLAGS_REG))]
10351 "TARGET_64BIT && reload_completed
10352 && true_regnum (operands[0]) != true_regnum (operands[1])"
10353 [(set (match_dup 0)
10354 (mult:DI (match_dup 1)
10356 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10358 ;; This pattern can't accept a variable shift count, since shifts by
10359 ;; zero don't affect the flags. We assume that shifts by constant
10360 ;; zero are optimized away.
10361 (define_insn "*ashldi3_cmp_rex64"
10362 [(set (reg FLAGS_REG)
10364 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10365 (match_operand:QI 2 "immediate_operand" "e"))
10367 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10368 (ashift:DI (match_dup 1) (match_dup 2)))]
10369 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10370 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10372 switch (get_attr_type (insn))
10375 gcc_assert (operands[2] == const1_rtx);
10376 return "add{q}\t{%0, %0|%0, %0}";
10379 if (REG_P (operands[2]))
10380 return "sal{q}\t{%b2, %0|%0, %b2}";
10381 else if (operands[2] == const1_rtx
10382 && (TARGET_SHIFT1 || optimize_size))
10383 return "sal{q}\t%0";
10385 return "sal{q}\t{%2, %0|%0, %2}";
10388 [(set (attr "type")
10389 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10391 (match_operand 0 "register_operand" ""))
10392 (match_operand 2 "const1_operand" ""))
10393 (const_string "alu")
10395 (const_string "ishift")))
10396 (set_attr "mode" "DI")])
10398 (define_insn "*ashldi3_1"
10399 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10400 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10401 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10402 (clobber (reg:CC FLAGS_REG))]
10405 [(set_attr "type" "multi")])
10407 ;; By default we don't ask for a scratch register, because when DImode
10408 ;; values are manipulated, registers are already at a premium. But if
10409 ;; we have one handy, we won't turn it away.
10411 [(match_scratch:SI 3 "r")
10412 (parallel [(set (match_operand:DI 0 "register_operand" "")
10413 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10414 (match_operand:QI 2 "nonmemory_operand" "")))
10415 (clobber (reg:CC FLAGS_REG))])
10417 "!TARGET_64BIT && TARGET_CMOVE"
10419 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10422 [(set (match_operand:DI 0 "register_operand" "")
10423 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10424 (match_operand:QI 2 "nonmemory_operand" "")))
10425 (clobber (reg:CC FLAGS_REG))]
10426 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10427 ? flow2_completed : reload_completed)"
10429 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10431 (define_insn "x86_shld_1"
10432 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10433 (ior:SI (ashift:SI (match_dup 0)
10434 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10435 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10436 (minus:QI (const_int 32) (match_dup 2)))))
10437 (clobber (reg:CC FLAGS_REG))]
10440 shld{l}\t{%2, %1, %0|%0, %1, %2}
10441 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10442 [(set_attr "type" "ishift")
10443 (set_attr "prefix_0f" "1")
10444 (set_attr "mode" "SI")
10445 (set_attr "pent_pair" "np")
10446 (set_attr "athlon_decode" "vector")])
10448 (define_expand "x86_shift_adj_1"
10449 [(set (reg:CCZ FLAGS_REG)
10450 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10453 (set (match_operand:SI 0 "register_operand" "")
10454 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10455 (match_operand:SI 1 "register_operand" "")
10458 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10459 (match_operand:SI 3 "register_operand" "r")
10464 (define_expand "x86_shift_adj_2"
10465 [(use (match_operand:SI 0 "register_operand" ""))
10466 (use (match_operand:SI 1 "register_operand" ""))
10467 (use (match_operand:QI 2 "register_operand" ""))]
10470 rtx label = gen_label_rtx ();
10473 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10475 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10476 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10477 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10478 gen_rtx_LABEL_REF (VOIDmode, label),
10480 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10481 JUMP_LABEL (tmp) = label;
10483 emit_move_insn (operands[0], operands[1]);
10484 ix86_expand_clear (operands[1]);
10486 emit_label (label);
10487 LABEL_NUSES (label) = 1;
10492 (define_expand "ashlsi3"
10493 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10494 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10495 (match_operand:QI 2 "nonmemory_operand" "")))
10496 (clobber (reg:CC FLAGS_REG))]
10498 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10500 (define_insn "*ashlsi3_1"
10501 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10502 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10503 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10504 (clobber (reg:CC FLAGS_REG))]
10505 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10507 switch (get_attr_type (insn))
10510 gcc_assert (operands[2] == const1_rtx);
10511 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10512 return "add{l}\t{%0, %0|%0, %0}";
10518 if (REG_P (operands[2]))
10519 return "sal{l}\t{%b2, %0|%0, %b2}";
10520 else if (operands[2] == const1_rtx
10521 && (TARGET_SHIFT1 || optimize_size))
10522 return "sal{l}\t%0";
10524 return "sal{l}\t{%2, %0|%0, %2}";
10527 [(set (attr "type")
10528 (cond [(eq_attr "alternative" "1")
10529 (const_string "lea")
10530 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10532 (match_operand 0 "register_operand" ""))
10533 (match_operand 2 "const1_operand" ""))
10534 (const_string "alu")
10536 (const_string "ishift")))
10537 (set_attr "mode" "SI")])
10539 ;; Convert lea to the lea pattern to avoid flags dependency.
10541 [(set (match_operand 0 "register_operand" "")
10542 (ashift (match_operand 1 "index_register_operand" "")
10543 (match_operand:QI 2 "const_int_operand" "")))
10544 (clobber (reg:CC FLAGS_REG))]
10546 && true_regnum (operands[0]) != true_regnum (operands[1])
10547 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10551 enum machine_mode mode = GET_MODE (operands[0]);
10553 if (GET_MODE_SIZE (mode) < 4)
10554 operands[0] = gen_lowpart (SImode, operands[0]);
10556 operands[1] = gen_lowpart (Pmode, operands[1]);
10557 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10559 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10560 if (Pmode != SImode)
10561 pat = gen_rtx_SUBREG (SImode, pat, 0);
10562 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10566 ;; Rare case of shifting RSP is handled by generating move and shift
10568 [(set (match_operand 0 "register_operand" "")
10569 (ashift (match_operand 1 "register_operand" "")
10570 (match_operand:QI 2 "const_int_operand" "")))
10571 (clobber (reg:CC FLAGS_REG))]
10573 && true_regnum (operands[0]) != true_regnum (operands[1])"
10577 emit_move_insn (operands[0], operands[1]);
10578 pat = gen_rtx_SET (VOIDmode, operands[0],
10579 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10580 operands[0], operands[2]));
10581 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10582 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10586 (define_insn "*ashlsi3_1_zext"
10587 [(set (match_operand:DI 0 "register_operand" "=r,r")
10588 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10589 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10590 (clobber (reg:CC FLAGS_REG))]
10591 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10593 switch (get_attr_type (insn))
10596 gcc_assert (operands[2] == const1_rtx);
10597 return "add{l}\t{%k0, %k0|%k0, %k0}";
10603 if (REG_P (operands[2]))
10604 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10605 else if (operands[2] == const1_rtx
10606 && (TARGET_SHIFT1 || optimize_size))
10607 return "sal{l}\t%k0";
10609 return "sal{l}\t{%2, %k0|%k0, %2}";
10612 [(set (attr "type")
10613 (cond [(eq_attr "alternative" "1")
10614 (const_string "lea")
10615 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10617 (match_operand 2 "const1_operand" ""))
10618 (const_string "alu")
10620 (const_string "ishift")))
10621 (set_attr "mode" "SI")])
10623 ;; Convert lea to the lea pattern to avoid flags dependency.
10625 [(set (match_operand:DI 0 "register_operand" "")
10626 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10627 (match_operand:QI 2 "const_int_operand" ""))))
10628 (clobber (reg:CC FLAGS_REG))]
10629 "TARGET_64BIT && reload_completed
10630 && true_regnum (operands[0]) != true_regnum (operands[1])"
10631 [(set (match_dup 0) (zero_extend:DI
10632 (subreg:SI (mult:SI (match_dup 1)
10633 (match_dup 2)) 0)))]
10635 operands[1] = gen_lowpart (Pmode, operands[1]);
10636 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10639 ;; This pattern can't accept a variable shift count, since shifts by
10640 ;; zero don't affect the flags. We assume that shifts by constant
10641 ;; zero are optimized away.
10642 (define_insn "*ashlsi3_cmp"
10643 [(set (reg FLAGS_REG)
10645 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10646 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10648 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10649 (ashift:SI (match_dup 1) (match_dup 2)))]
10650 "ix86_match_ccmode (insn, CCGOCmode)
10651 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10653 switch (get_attr_type (insn))
10656 gcc_assert (operands[2] == const1_rtx);
10657 return "add{l}\t{%0, %0|%0, %0}";
10660 if (REG_P (operands[2]))
10661 return "sal{l}\t{%b2, %0|%0, %b2}";
10662 else if (operands[2] == const1_rtx
10663 && (TARGET_SHIFT1 || optimize_size))
10664 return "sal{l}\t%0";
10666 return "sal{l}\t{%2, %0|%0, %2}";
10669 [(set (attr "type")
10670 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10672 (match_operand 0 "register_operand" ""))
10673 (match_operand 2 "const1_operand" ""))
10674 (const_string "alu")
10676 (const_string "ishift")))
10677 (set_attr "mode" "SI")])
10679 (define_insn "*ashlsi3_cmp_zext"
10680 [(set (reg FLAGS_REG)
10682 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10683 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10685 (set (match_operand:DI 0 "register_operand" "=r")
10686 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10687 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10688 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10690 switch (get_attr_type (insn))
10693 gcc_assert (operands[2] == const1_rtx);
10694 return "add{l}\t{%k0, %k0|%k0, %k0}";
10697 if (REG_P (operands[2]))
10698 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10699 else if (operands[2] == const1_rtx
10700 && (TARGET_SHIFT1 || optimize_size))
10701 return "sal{l}\t%k0";
10703 return "sal{l}\t{%2, %k0|%k0, %2}";
10706 [(set (attr "type")
10707 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10709 (match_operand 2 "const1_operand" ""))
10710 (const_string "alu")
10712 (const_string "ishift")))
10713 (set_attr "mode" "SI")])
10715 (define_expand "ashlhi3"
10716 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10717 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10718 (match_operand:QI 2 "nonmemory_operand" "")))
10719 (clobber (reg:CC FLAGS_REG))]
10720 "TARGET_HIMODE_MATH"
10721 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10723 (define_insn "*ashlhi3_1_lea"
10724 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10725 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10726 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10727 (clobber (reg:CC FLAGS_REG))]
10728 "!TARGET_PARTIAL_REG_STALL
10729 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10731 switch (get_attr_type (insn))
10736 gcc_assert (operands[2] == const1_rtx);
10737 return "add{w}\t{%0, %0|%0, %0}";
10740 if (REG_P (operands[2]))
10741 return "sal{w}\t{%b2, %0|%0, %b2}";
10742 else if (operands[2] == const1_rtx
10743 && (TARGET_SHIFT1 || optimize_size))
10744 return "sal{w}\t%0";
10746 return "sal{w}\t{%2, %0|%0, %2}";
10749 [(set (attr "type")
10750 (cond [(eq_attr "alternative" "1")
10751 (const_string "lea")
10752 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10754 (match_operand 0 "register_operand" ""))
10755 (match_operand 2 "const1_operand" ""))
10756 (const_string "alu")
10758 (const_string "ishift")))
10759 (set_attr "mode" "HI,SI")])
10761 (define_insn "*ashlhi3_1"
10762 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10763 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10764 (match_operand:QI 2 "nonmemory_operand" "cI")))
10765 (clobber (reg:CC FLAGS_REG))]
10766 "TARGET_PARTIAL_REG_STALL
10767 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10769 switch (get_attr_type (insn))
10772 gcc_assert (operands[2] == const1_rtx);
10773 return "add{w}\t{%0, %0|%0, %0}";
10776 if (REG_P (operands[2]))
10777 return "sal{w}\t{%b2, %0|%0, %b2}";
10778 else if (operands[2] == const1_rtx
10779 && (TARGET_SHIFT1 || optimize_size))
10780 return "sal{w}\t%0";
10782 return "sal{w}\t{%2, %0|%0, %2}";
10785 [(set (attr "type")
10786 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10788 (match_operand 0 "register_operand" ""))
10789 (match_operand 2 "const1_operand" ""))
10790 (const_string "alu")
10792 (const_string "ishift")))
10793 (set_attr "mode" "HI")])
10795 ;; This pattern can't accept a variable shift count, since shifts by
10796 ;; zero don't affect the flags. We assume that shifts by constant
10797 ;; zero are optimized away.
10798 (define_insn "*ashlhi3_cmp"
10799 [(set (reg FLAGS_REG)
10801 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10802 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10804 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10805 (ashift:HI (match_dup 1) (match_dup 2)))]
10806 "ix86_match_ccmode (insn, CCGOCmode)
10807 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10809 switch (get_attr_type (insn))
10812 gcc_assert (operands[2] == const1_rtx);
10813 return "add{w}\t{%0, %0|%0, %0}";
10816 if (REG_P (operands[2]))
10817 return "sal{w}\t{%b2, %0|%0, %b2}";
10818 else if (operands[2] == const1_rtx
10819 && (TARGET_SHIFT1 || optimize_size))
10820 return "sal{w}\t%0";
10822 return "sal{w}\t{%2, %0|%0, %2}";
10825 [(set (attr "type")
10826 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10828 (match_operand 0 "register_operand" ""))
10829 (match_operand 2 "const1_operand" ""))
10830 (const_string "alu")
10832 (const_string "ishift")))
10833 (set_attr "mode" "HI")])
10835 (define_expand "ashlqi3"
10836 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10837 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10838 (match_operand:QI 2 "nonmemory_operand" "")))
10839 (clobber (reg:CC FLAGS_REG))]
10840 "TARGET_QIMODE_MATH"
10841 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10843 ;; %%% Potential partial reg stall on alternative 2. What to do?
10845 (define_insn "*ashlqi3_1_lea"
10846 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10847 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10848 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10849 (clobber (reg:CC FLAGS_REG))]
10850 "!TARGET_PARTIAL_REG_STALL
10851 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10853 switch (get_attr_type (insn))
10858 gcc_assert (operands[2] == const1_rtx);
10859 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10860 return "add{l}\t{%k0, %k0|%k0, %k0}";
10862 return "add{b}\t{%0, %0|%0, %0}";
10865 if (REG_P (operands[2]))
10867 if (get_attr_mode (insn) == MODE_SI)
10868 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10870 return "sal{b}\t{%b2, %0|%0, %b2}";
10872 else if (operands[2] == const1_rtx
10873 && (TARGET_SHIFT1 || optimize_size))
10875 if (get_attr_mode (insn) == MODE_SI)
10876 return "sal{l}\t%0";
10878 return "sal{b}\t%0";
10882 if (get_attr_mode (insn) == MODE_SI)
10883 return "sal{l}\t{%2, %k0|%k0, %2}";
10885 return "sal{b}\t{%2, %0|%0, %2}";
10889 [(set (attr "type")
10890 (cond [(eq_attr "alternative" "2")
10891 (const_string "lea")
10892 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10894 (match_operand 0 "register_operand" ""))
10895 (match_operand 2 "const1_operand" ""))
10896 (const_string "alu")
10898 (const_string "ishift")))
10899 (set_attr "mode" "QI,SI,SI")])
10901 (define_insn "*ashlqi3_1"
10902 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10903 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10904 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10905 (clobber (reg:CC FLAGS_REG))]
10906 "TARGET_PARTIAL_REG_STALL
10907 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10909 switch (get_attr_type (insn))
10912 gcc_assert (operands[2] == const1_rtx);
10913 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10914 return "add{l}\t{%k0, %k0|%k0, %k0}";
10916 return "add{b}\t{%0, %0|%0, %0}";
10919 if (REG_P (operands[2]))
10921 if (get_attr_mode (insn) == MODE_SI)
10922 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10924 return "sal{b}\t{%b2, %0|%0, %b2}";
10926 else if (operands[2] == const1_rtx
10927 && (TARGET_SHIFT1 || optimize_size))
10929 if (get_attr_mode (insn) == MODE_SI)
10930 return "sal{l}\t%0";
10932 return "sal{b}\t%0";
10936 if (get_attr_mode (insn) == MODE_SI)
10937 return "sal{l}\t{%2, %k0|%k0, %2}";
10939 return "sal{b}\t{%2, %0|%0, %2}";
10943 [(set (attr "type")
10944 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10946 (match_operand 0 "register_operand" ""))
10947 (match_operand 2 "const1_operand" ""))
10948 (const_string "alu")
10950 (const_string "ishift")))
10951 (set_attr "mode" "QI,SI")])
10953 ;; This pattern can't accept a variable shift count, since shifts by
10954 ;; zero don't affect the flags. We assume that shifts by constant
10955 ;; zero are optimized away.
10956 (define_insn "*ashlqi3_cmp"
10957 [(set (reg FLAGS_REG)
10959 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10960 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10962 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10963 (ashift:QI (match_dup 1) (match_dup 2)))]
10964 "ix86_match_ccmode (insn, CCGOCmode)
10965 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10967 switch (get_attr_type (insn))
10970 gcc_assert (operands[2] == const1_rtx);
10971 return "add{b}\t{%0, %0|%0, %0}";
10974 if (REG_P (operands[2]))
10975 return "sal{b}\t{%b2, %0|%0, %b2}";
10976 else if (operands[2] == const1_rtx
10977 && (TARGET_SHIFT1 || optimize_size))
10978 return "sal{b}\t%0";
10980 return "sal{b}\t{%2, %0|%0, %2}";
10983 [(set (attr "type")
10984 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10986 (match_operand 0 "register_operand" ""))
10987 (match_operand 2 "const1_operand" ""))
10988 (const_string "alu")
10990 (const_string "ishift")))
10991 (set_attr "mode" "QI")])
10993 ;; See comment above `ashldi3' about how this works.
10995 (define_expand "ashrti3"
10996 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10997 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10998 (match_operand:QI 2 "nonmemory_operand" "")))
10999 (clobber (reg:CC FLAGS_REG))])]
11002 if (! immediate_operand (operands[2], QImode))
11004 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11007 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11011 (define_insn "ashrti3_1"
11012 [(set (match_operand:TI 0 "register_operand" "=r")
11013 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11014 (match_operand:QI 2 "register_operand" "c")))
11015 (clobber (match_scratch:DI 3 "=&r"))
11016 (clobber (reg:CC FLAGS_REG))]
11019 [(set_attr "type" "multi")])
11021 (define_insn "*ashrti3_2"
11022 [(set (match_operand:TI 0 "register_operand" "=r")
11023 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11024 (match_operand:QI 2 "immediate_operand" "O")))
11025 (clobber (reg:CC FLAGS_REG))]
11028 [(set_attr "type" "multi")])
11031 [(set (match_operand:TI 0 "register_operand" "")
11032 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11033 (match_operand:QI 2 "register_operand" "")))
11034 (clobber (match_scratch:DI 3 ""))
11035 (clobber (reg:CC FLAGS_REG))]
11036 "TARGET_64BIT && reload_completed"
11038 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11041 [(set (match_operand:TI 0 "register_operand" "")
11042 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11043 (match_operand:QI 2 "immediate_operand" "")))
11044 (clobber (reg:CC FLAGS_REG))]
11045 "TARGET_64BIT && reload_completed"
11047 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11049 (define_insn "x86_64_shrd"
11050 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11051 (ior:DI (ashiftrt:DI (match_dup 0)
11052 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11053 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11054 (minus:QI (const_int 64) (match_dup 2)))))
11055 (clobber (reg:CC FLAGS_REG))]
11058 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11059 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11060 [(set_attr "type" "ishift")
11061 (set_attr "prefix_0f" "1")
11062 (set_attr "mode" "DI")
11063 (set_attr "athlon_decode" "vector")])
11065 (define_expand "ashrdi3"
11066 [(set (match_operand:DI 0 "shiftdi_operand" "")
11067 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11068 (match_operand:QI 2 "nonmemory_operand" "")))]
11070 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11072 (define_insn "*ashrdi3_63_rex64"
11073 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11074 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11075 (match_operand:DI 2 "const_int_operand" "i,i")))
11076 (clobber (reg:CC FLAGS_REG))]
11077 "TARGET_64BIT && INTVAL (operands[2]) == 63
11078 && (TARGET_USE_CLTD || optimize_size)
11079 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11082 sar{q}\t{%2, %0|%0, %2}"
11083 [(set_attr "type" "imovx,ishift")
11084 (set_attr "prefix_0f" "0,*")
11085 (set_attr "length_immediate" "0,*")
11086 (set_attr "modrm" "0,1")
11087 (set_attr "mode" "DI")])
11089 (define_insn "*ashrdi3_1_one_bit_rex64"
11090 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11091 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11092 (match_operand:QI 2 "const1_operand" "")))
11093 (clobber (reg:CC FLAGS_REG))]
11094 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11095 && (TARGET_SHIFT1 || optimize_size)"
11097 [(set_attr "type" "ishift")
11098 (set (attr "length")
11099 (if_then_else (match_operand:DI 0 "register_operand" "")
11101 (const_string "*")))])
11103 (define_insn "*ashrdi3_1_rex64"
11104 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11105 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11106 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11107 (clobber (reg:CC FLAGS_REG))]
11108 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11110 sar{q}\t{%2, %0|%0, %2}
11111 sar{q}\t{%b2, %0|%0, %b2}"
11112 [(set_attr "type" "ishift")
11113 (set_attr "mode" "DI")])
11115 ;; This pattern can't accept a variable shift count, since shifts by
11116 ;; zero don't affect the flags. We assume that shifts by constant
11117 ;; zero are optimized away.
11118 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11119 [(set (reg FLAGS_REG)
11121 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11122 (match_operand:QI 2 "const1_operand" ""))
11124 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11125 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11126 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11127 && (TARGET_SHIFT1 || optimize_size)
11128 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11130 [(set_attr "type" "ishift")
11131 (set (attr "length")
11132 (if_then_else (match_operand:DI 0 "register_operand" "")
11134 (const_string "*")))])
11136 ;; This pattern can't accept a variable shift count, since shifts by
11137 ;; zero don't affect the flags. We assume that shifts by constant
11138 ;; zero are optimized away.
11139 (define_insn "*ashrdi3_cmp_rex64"
11140 [(set (reg FLAGS_REG)
11142 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11143 (match_operand:QI 2 "const_int_operand" "n"))
11145 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11146 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11147 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11148 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11149 "sar{q}\t{%2, %0|%0, %2}"
11150 [(set_attr "type" "ishift")
11151 (set_attr "mode" "DI")])
11153 (define_insn "*ashrdi3_1"
11154 [(set (match_operand:DI 0 "register_operand" "=r")
11155 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11156 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11157 (clobber (reg:CC FLAGS_REG))]
11160 [(set_attr "type" "multi")])
11162 ;; By default we don't ask for a scratch register, because when DImode
11163 ;; values are manipulated, registers are already at a premium. But if
11164 ;; we have one handy, we won't turn it away.
11166 [(match_scratch:SI 3 "r")
11167 (parallel [(set (match_operand:DI 0 "register_operand" "")
11168 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11169 (match_operand:QI 2 "nonmemory_operand" "")))
11170 (clobber (reg:CC FLAGS_REG))])
11172 "!TARGET_64BIT && TARGET_CMOVE"
11174 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11177 [(set (match_operand:DI 0 "register_operand" "")
11178 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11179 (match_operand:QI 2 "nonmemory_operand" "")))
11180 (clobber (reg:CC FLAGS_REG))]
11181 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11182 ? flow2_completed : reload_completed)"
11184 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11186 (define_insn "x86_shrd_1"
11187 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11188 (ior:SI (ashiftrt:SI (match_dup 0)
11189 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11190 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11191 (minus:QI (const_int 32) (match_dup 2)))))
11192 (clobber (reg:CC FLAGS_REG))]
11195 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11196 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11197 [(set_attr "type" "ishift")
11198 (set_attr "prefix_0f" "1")
11199 (set_attr "pent_pair" "np")
11200 (set_attr "mode" "SI")])
11202 (define_expand "x86_shift_adj_3"
11203 [(use (match_operand:SI 0 "register_operand" ""))
11204 (use (match_operand:SI 1 "register_operand" ""))
11205 (use (match_operand:QI 2 "register_operand" ""))]
11208 rtx label = gen_label_rtx ();
11211 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11213 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11214 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11215 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11216 gen_rtx_LABEL_REF (VOIDmode, label),
11218 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11219 JUMP_LABEL (tmp) = label;
11221 emit_move_insn (operands[0], operands[1]);
11222 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11224 emit_label (label);
11225 LABEL_NUSES (label) = 1;
11230 (define_insn "ashrsi3_31"
11231 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11232 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11233 (match_operand:SI 2 "const_int_operand" "i,i")))
11234 (clobber (reg:CC FLAGS_REG))]
11235 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11236 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11239 sar{l}\t{%2, %0|%0, %2}"
11240 [(set_attr "type" "imovx,ishift")
11241 (set_attr "prefix_0f" "0,*")
11242 (set_attr "length_immediate" "0,*")
11243 (set_attr "modrm" "0,1")
11244 (set_attr "mode" "SI")])
11246 (define_insn "*ashrsi3_31_zext"
11247 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11248 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11249 (match_operand:SI 2 "const_int_operand" "i,i"))))
11250 (clobber (reg:CC FLAGS_REG))]
11251 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11252 && INTVAL (operands[2]) == 31
11253 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11256 sar{l}\t{%2, %k0|%k0, %2}"
11257 [(set_attr "type" "imovx,ishift")
11258 (set_attr "prefix_0f" "0,*")
11259 (set_attr "length_immediate" "0,*")
11260 (set_attr "modrm" "0,1")
11261 (set_attr "mode" "SI")])
11263 (define_expand "ashrsi3"
11264 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11265 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11266 (match_operand:QI 2 "nonmemory_operand" "")))
11267 (clobber (reg:CC FLAGS_REG))]
11269 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11271 (define_insn "*ashrsi3_1_one_bit"
11272 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11273 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11274 (match_operand:QI 2 "const1_operand" "")))
11275 (clobber (reg:CC FLAGS_REG))]
11276 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11277 && (TARGET_SHIFT1 || optimize_size)"
11279 [(set_attr "type" "ishift")
11280 (set (attr "length")
11281 (if_then_else (match_operand:SI 0 "register_operand" "")
11283 (const_string "*")))])
11285 (define_insn "*ashrsi3_1_one_bit_zext"
11286 [(set (match_operand:DI 0 "register_operand" "=r")
11287 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11288 (match_operand:QI 2 "const1_operand" ""))))
11289 (clobber (reg:CC FLAGS_REG))]
11290 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11291 && (TARGET_SHIFT1 || optimize_size)"
11293 [(set_attr "type" "ishift")
11294 (set_attr "length" "2")])
11296 (define_insn "*ashrsi3_1"
11297 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11298 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11299 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11300 (clobber (reg:CC FLAGS_REG))]
11301 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11303 sar{l}\t{%2, %0|%0, %2}
11304 sar{l}\t{%b2, %0|%0, %b2}"
11305 [(set_attr "type" "ishift")
11306 (set_attr "mode" "SI")])
11308 (define_insn "*ashrsi3_1_zext"
11309 [(set (match_operand:DI 0 "register_operand" "=r,r")
11310 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11311 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11312 (clobber (reg:CC FLAGS_REG))]
11313 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11315 sar{l}\t{%2, %k0|%k0, %2}
11316 sar{l}\t{%b2, %k0|%k0, %b2}"
11317 [(set_attr "type" "ishift")
11318 (set_attr "mode" "SI")])
11320 ;; This pattern can't accept a variable shift count, since shifts by
11321 ;; zero don't affect the flags. We assume that shifts by constant
11322 ;; zero are optimized away.
11323 (define_insn "*ashrsi3_one_bit_cmp"
11324 [(set (reg FLAGS_REG)
11326 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11327 (match_operand:QI 2 "const1_operand" ""))
11329 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11330 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11331 "ix86_match_ccmode (insn, CCGOCmode)
11332 && (TARGET_SHIFT1 || optimize_size)
11333 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11335 [(set_attr "type" "ishift")
11336 (set (attr "length")
11337 (if_then_else (match_operand:SI 0 "register_operand" "")
11339 (const_string "*")))])
11341 (define_insn "*ashrsi3_one_bit_cmp_zext"
11342 [(set (reg FLAGS_REG)
11344 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11345 (match_operand:QI 2 "const1_operand" ""))
11347 (set (match_operand:DI 0 "register_operand" "=r")
11348 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11349 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11350 && (TARGET_SHIFT1 || optimize_size)
11351 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11353 [(set_attr "type" "ishift")
11354 (set_attr "length" "2")])
11356 ;; This pattern can't accept a variable shift count, since shifts by
11357 ;; zero don't affect the flags. We assume that shifts by constant
11358 ;; zero are optimized away.
11359 (define_insn "*ashrsi3_cmp"
11360 [(set (reg FLAGS_REG)
11362 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11363 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11365 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11366 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11367 "ix86_match_ccmode (insn, CCGOCmode)
11368 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11369 "sar{l}\t{%2, %0|%0, %2}"
11370 [(set_attr "type" "ishift")
11371 (set_attr "mode" "SI")])
11373 (define_insn "*ashrsi3_cmp_zext"
11374 [(set (reg FLAGS_REG)
11376 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11377 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11379 (set (match_operand:DI 0 "register_operand" "=r")
11380 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11381 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11382 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11383 "sar{l}\t{%2, %k0|%k0, %2}"
11384 [(set_attr "type" "ishift")
11385 (set_attr "mode" "SI")])
11387 (define_expand "ashrhi3"
11388 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11389 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11390 (match_operand:QI 2 "nonmemory_operand" "")))
11391 (clobber (reg:CC FLAGS_REG))]
11392 "TARGET_HIMODE_MATH"
11393 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11395 (define_insn "*ashrhi3_1_one_bit"
11396 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11397 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11398 (match_operand:QI 2 "const1_operand" "")))
11399 (clobber (reg:CC FLAGS_REG))]
11400 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11401 && (TARGET_SHIFT1 || optimize_size)"
11403 [(set_attr "type" "ishift")
11404 (set (attr "length")
11405 (if_then_else (match_operand 0 "register_operand" "")
11407 (const_string "*")))])
11409 (define_insn "*ashrhi3_1"
11410 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11411 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11412 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11413 (clobber (reg:CC FLAGS_REG))]
11414 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11416 sar{w}\t{%2, %0|%0, %2}
11417 sar{w}\t{%b2, %0|%0, %b2}"
11418 [(set_attr "type" "ishift")
11419 (set_attr "mode" "HI")])
11421 ;; This pattern can't accept a variable shift count, since shifts by
11422 ;; zero don't affect the flags. We assume that shifts by constant
11423 ;; zero are optimized away.
11424 (define_insn "*ashrhi3_one_bit_cmp"
11425 [(set (reg FLAGS_REG)
11427 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11428 (match_operand:QI 2 "const1_operand" ""))
11430 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11431 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11432 "ix86_match_ccmode (insn, CCGOCmode)
11433 && (TARGET_SHIFT1 || optimize_size)
11434 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11436 [(set_attr "type" "ishift")
11437 (set (attr "length")
11438 (if_then_else (match_operand 0 "register_operand" "")
11440 (const_string "*")))])
11442 ;; This pattern can't accept a variable shift count, since shifts by
11443 ;; zero don't affect the flags. We assume that shifts by constant
11444 ;; zero are optimized away.
11445 (define_insn "*ashrhi3_cmp"
11446 [(set (reg FLAGS_REG)
11448 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11449 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11451 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11452 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11453 "ix86_match_ccmode (insn, CCGOCmode)
11454 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11455 "sar{w}\t{%2, %0|%0, %2}"
11456 [(set_attr "type" "ishift")
11457 (set_attr "mode" "HI")])
11459 (define_expand "ashrqi3"
11460 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11461 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11462 (match_operand:QI 2 "nonmemory_operand" "")))
11463 (clobber (reg:CC FLAGS_REG))]
11464 "TARGET_QIMODE_MATH"
11465 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11467 (define_insn "*ashrqi3_1_one_bit"
11468 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11469 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11470 (match_operand:QI 2 "const1_operand" "")))
11471 (clobber (reg:CC FLAGS_REG))]
11472 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11473 && (TARGET_SHIFT1 || optimize_size)"
11475 [(set_attr "type" "ishift")
11476 (set (attr "length")
11477 (if_then_else (match_operand 0 "register_operand" "")
11479 (const_string "*")))])
11481 (define_insn "*ashrqi3_1_one_bit_slp"
11482 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11483 (ashiftrt:QI (match_dup 0)
11484 (match_operand:QI 1 "const1_operand" "")))
11485 (clobber (reg:CC FLAGS_REG))]
11486 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11487 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11488 && (TARGET_SHIFT1 || optimize_size)"
11490 [(set_attr "type" "ishift1")
11491 (set (attr "length")
11492 (if_then_else (match_operand 0 "register_operand" "")
11494 (const_string "*")))])
11496 (define_insn "*ashrqi3_1"
11497 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11498 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11499 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11500 (clobber (reg:CC FLAGS_REG))]
11501 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11503 sar{b}\t{%2, %0|%0, %2}
11504 sar{b}\t{%b2, %0|%0, %b2}"
11505 [(set_attr "type" "ishift")
11506 (set_attr "mode" "QI")])
11508 (define_insn "*ashrqi3_1_slp"
11509 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11510 (ashiftrt:QI (match_dup 0)
11511 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11512 (clobber (reg:CC FLAGS_REG))]
11513 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11514 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11516 sar{b}\t{%1, %0|%0, %1}
11517 sar{b}\t{%b1, %0|%0, %b1}"
11518 [(set_attr "type" "ishift1")
11519 (set_attr "mode" "QI")])
11521 ;; This pattern can't accept a variable shift count, since shifts by
11522 ;; zero don't affect the flags. We assume that shifts by constant
11523 ;; zero are optimized away.
11524 (define_insn "*ashrqi3_one_bit_cmp"
11525 [(set (reg FLAGS_REG)
11527 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11528 (match_operand:QI 2 "const1_operand" "I"))
11530 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11531 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11532 "ix86_match_ccmode (insn, CCGOCmode)
11533 && (TARGET_SHIFT1 || optimize_size)
11534 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11536 [(set_attr "type" "ishift")
11537 (set (attr "length")
11538 (if_then_else (match_operand 0 "register_operand" "")
11540 (const_string "*")))])
11542 ;; This pattern can't accept a variable shift count, since shifts by
11543 ;; zero don't affect the flags. We assume that shifts by constant
11544 ;; zero are optimized away.
11545 (define_insn "*ashrqi3_cmp"
11546 [(set (reg FLAGS_REG)
11548 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11549 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11551 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11552 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11553 "ix86_match_ccmode (insn, CCGOCmode)
11554 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11555 "sar{b}\t{%2, %0|%0, %2}"
11556 [(set_attr "type" "ishift")
11557 (set_attr "mode" "QI")])
11559 ;; Logical shift instructions
11561 ;; See comment above `ashldi3' about how this works.
11563 (define_expand "lshrti3"
11564 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11565 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11566 (match_operand:QI 2 "nonmemory_operand" "")))
11567 (clobber (reg:CC FLAGS_REG))])]
11570 if (! immediate_operand (operands[2], QImode))
11572 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11575 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11579 (define_insn "lshrti3_1"
11580 [(set (match_operand:TI 0 "register_operand" "=r")
11581 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11582 (match_operand:QI 2 "register_operand" "c")))
11583 (clobber (match_scratch:DI 3 "=&r"))
11584 (clobber (reg:CC FLAGS_REG))]
11587 [(set_attr "type" "multi")])
11589 (define_insn "*lshrti3_2"
11590 [(set (match_operand:TI 0 "register_operand" "=r")
11591 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11592 (match_operand:QI 2 "immediate_operand" "O")))
11593 (clobber (reg:CC FLAGS_REG))]
11596 [(set_attr "type" "multi")])
11599 [(set (match_operand:TI 0 "register_operand" "")
11600 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11601 (match_operand:QI 2 "register_operand" "")))
11602 (clobber (match_scratch:DI 3 ""))
11603 (clobber (reg:CC FLAGS_REG))]
11604 "TARGET_64BIT && reload_completed"
11606 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11609 [(set (match_operand:TI 0 "register_operand" "")
11610 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11611 (match_operand:QI 2 "immediate_operand" "")))
11612 (clobber (reg:CC FLAGS_REG))]
11613 "TARGET_64BIT && reload_completed"
11615 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11617 (define_expand "lshrdi3"
11618 [(set (match_operand:DI 0 "shiftdi_operand" "")
11619 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11620 (match_operand:QI 2 "nonmemory_operand" "")))]
11622 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11624 (define_insn "*lshrdi3_1_one_bit_rex64"
11625 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11626 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11627 (match_operand:QI 2 "const1_operand" "")))
11628 (clobber (reg:CC FLAGS_REG))]
11629 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11630 && (TARGET_SHIFT1 || optimize_size)"
11632 [(set_attr "type" "ishift")
11633 (set (attr "length")
11634 (if_then_else (match_operand:DI 0 "register_operand" "")
11636 (const_string "*")))])
11638 (define_insn "*lshrdi3_1_rex64"
11639 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11640 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11641 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11642 (clobber (reg:CC FLAGS_REG))]
11643 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11645 shr{q}\t{%2, %0|%0, %2}
11646 shr{q}\t{%b2, %0|%0, %b2}"
11647 [(set_attr "type" "ishift")
11648 (set_attr "mode" "DI")])
11650 ;; This pattern can't accept a variable shift count, since shifts by
11651 ;; zero don't affect the flags. We assume that shifts by constant
11652 ;; zero are optimized away.
11653 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11654 [(set (reg FLAGS_REG)
11656 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11657 (match_operand:QI 2 "const1_operand" ""))
11659 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11660 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11661 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11662 && (TARGET_SHIFT1 || optimize_size)
11663 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11665 [(set_attr "type" "ishift")
11666 (set (attr "length")
11667 (if_then_else (match_operand:DI 0 "register_operand" "")
11669 (const_string "*")))])
11671 ;; This pattern can't accept a variable shift count, since shifts by
11672 ;; zero don't affect the flags. We assume that shifts by constant
11673 ;; zero are optimized away.
11674 (define_insn "*lshrdi3_cmp_rex64"
11675 [(set (reg FLAGS_REG)
11677 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11678 (match_operand:QI 2 "const_int_operand" "e"))
11680 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11681 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11682 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11683 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11684 "shr{q}\t{%2, %0|%0, %2}"
11685 [(set_attr "type" "ishift")
11686 (set_attr "mode" "DI")])
11688 (define_insn "*lshrdi3_1"
11689 [(set (match_operand:DI 0 "register_operand" "=r")
11690 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11691 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11692 (clobber (reg:CC FLAGS_REG))]
11695 [(set_attr "type" "multi")])
11697 ;; By default we don't ask for a scratch register, because when DImode
11698 ;; values are manipulated, registers are already at a premium. But if
11699 ;; we have one handy, we won't turn it away.
11701 [(match_scratch:SI 3 "r")
11702 (parallel [(set (match_operand:DI 0 "register_operand" "")
11703 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11704 (match_operand:QI 2 "nonmemory_operand" "")))
11705 (clobber (reg:CC FLAGS_REG))])
11707 "!TARGET_64BIT && TARGET_CMOVE"
11709 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11712 [(set (match_operand:DI 0 "register_operand" "")
11713 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11714 (match_operand:QI 2 "nonmemory_operand" "")))
11715 (clobber (reg:CC FLAGS_REG))]
11716 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11717 ? flow2_completed : reload_completed)"
11719 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11721 (define_expand "lshrsi3"
11722 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11723 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11724 (match_operand:QI 2 "nonmemory_operand" "")))
11725 (clobber (reg:CC FLAGS_REG))]
11727 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11729 (define_insn "*lshrsi3_1_one_bit"
11730 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11731 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11732 (match_operand:QI 2 "const1_operand" "")))
11733 (clobber (reg:CC FLAGS_REG))]
11734 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11735 && (TARGET_SHIFT1 || optimize_size)"
11737 [(set_attr "type" "ishift")
11738 (set (attr "length")
11739 (if_then_else (match_operand:SI 0 "register_operand" "")
11741 (const_string "*")))])
11743 (define_insn "*lshrsi3_1_one_bit_zext"
11744 [(set (match_operand:DI 0 "register_operand" "=r")
11745 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11746 (match_operand:QI 2 "const1_operand" "")))
11747 (clobber (reg:CC FLAGS_REG))]
11748 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11749 && (TARGET_SHIFT1 || optimize_size)"
11751 [(set_attr "type" "ishift")
11752 (set_attr "length" "2")])
11754 (define_insn "*lshrsi3_1"
11755 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11756 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11757 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11758 (clobber (reg:CC FLAGS_REG))]
11759 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11761 shr{l}\t{%2, %0|%0, %2}
11762 shr{l}\t{%b2, %0|%0, %b2}"
11763 [(set_attr "type" "ishift")
11764 (set_attr "mode" "SI")])
11766 (define_insn "*lshrsi3_1_zext"
11767 [(set (match_operand:DI 0 "register_operand" "=r,r")
11769 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11770 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11771 (clobber (reg:CC FLAGS_REG))]
11772 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11774 shr{l}\t{%2, %k0|%k0, %2}
11775 shr{l}\t{%b2, %k0|%k0, %b2}"
11776 [(set_attr "type" "ishift")
11777 (set_attr "mode" "SI")])
11779 ;; This pattern can't accept a variable shift count, since shifts by
11780 ;; zero don't affect the flags. We assume that shifts by constant
11781 ;; zero are optimized away.
11782 (define_insn "*lshrsi3_one_bit_cmp"
11783 [(set (reg FLAGS_REG)
11785 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11786 (match_operand:QI 2 "const1_operand" ""))
11788 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11789 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11790 "ix86_match_ccmode (insn, CCGOCmode)
11791 && (TARGET_SHIFT1 || optimize_size)
11792 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11794 [(set_attr "type" "ishift")
11795 (set (attr "length")
11796 (if_then_else (match_operand:SI 0 "register_operand" "")
11798 (const_string "*")))])
11800 (define_insn "*lshrsi3_cmp_one_bit_zext"
11801 [(set (reg FLAGS_REG)
11803 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11804 (match_operand:QI 2 "const1_operand" ""))
11806 (set (match_operand:DI 0 "register_operand" "=r")
11807 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11808 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11809 && (TARGET_SHIFT1 || optimize_size)
11810 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11812 [(set_attr "type" "ishift")
11813 (set_attr "length" "2")])
11815 ;; This pattern can't accept a variable shift count, since shifts by
11816 ;; zero don't affect the flags. We assume that shifts by constant
11817 ;; zero are optimized away.
11818 (define_insn "*lshrsi3_cmp"
11819 [(set (reg FLAGS_REG)
11821 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11822 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11824 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11825 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11826 "ix86_match_ccmode (insn, CCGOCmode)
11827 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11828 "shr{l}\t{%2, %0|%0, %2}"
11829 [(set_attr "type" "ishift")
11830 (set_attr "mode" "SI")])
11832 (define_insn "*lshrsi3_cmp_zext"
11833 [(set (reg FLAGS_REG)
11835 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11836 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11838 (set (match_operand:DI 0 "register_operand" "=r")
11839 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11840 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11841 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11842 "shr{l}\t{%2, %k0|%k0, %2}"
11843 [(set_attr "type" "ishift")
11844 (set_attr "mode" "SI")])
11846 (define_expand "lshrhi3"
11847 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11848 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11849 (match_operand:QI 2 "nonmemory_operand" "")))
11850 (clobber (reg:CC FLAGS_REG))]
11851 "TARGET_HIMODE_MATH"
11852 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11854 (define_insn "*lshrhi3_1_one_bit"
11855 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11856 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11857 (match_operand:QI 2 "const1_operand" "")))
11858 (clobber (reg:CC FLAGS_REG))]
11859 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11860 && (TARGET_SHIFT1 || optimize_size)"
11862 [(set_attr "type" "ishift")
11863 (set (attr "length")
11864 (if_then_else (match_operand 0 "register_operand" "")
11866 (const_string "*")))])
11868 (define_insn "*lshrhi3_1"
11869 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11870 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11871 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11872 (clobber (reg:CC FLAGS_REG))]
11873 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11875 shr{w}\t{%2, %0|%0, %2}
11876 shr{w}\t{%b2, %0|%0, %b2}"
11877 [(set_attr "type" "ishift")
11878 (set_attr "mode" "HI")])
11880 ;; This pattern can't accept a variable shift count, since shifts by
11881 ;; zero don't affect the flags. We assume that shifts by constant
11882 ;; zero are optimized away.
11883 (define_insn "*lshrhi3_one_bit_cmp"
11884 [(set (reg FLAGS_REG)
11886 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11887 (match_operand:QI 2 "const1_operand" ""))
11889 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11890 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11891 "ix86_match_ccmode (insn, CCGOCmode)
11892 && (TARGET_SHIFT1 || optimize_size)
11893 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11895 [(set_attr "type" "ishift")
11896 (set (attr "length")
11897 (if_then_else (match_operand:SI 0 "register_operand" "")
11899 (const_string "*")))])
11901 ;; This pattern can't accept a variable shift count, since shifts by
11902 ;; zero don't affect the flags. We assume that shifts by constant
11903 ;; zero are optimized away.
11904 (define_insn "*lshrhi3_cmp"
11905 [(set (reg FLAGS_REG)
11907 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11908 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11910 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11911 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11912 "ix86_match_ccmode (insn, CCGOCmode)
11913 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11914 "shr{w}\t{%2, %0|%0, %2}"
11915 [(set_attr "type" "ishift")
11916 (set_attr "mode" "HI")])
11918 (define_expand "lshrqi3"
11919 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11920 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11921 (match_operand:QI 2 "nonmemory_operand" "")))
11922 (clobber (reg:CC FLAGS_REG))]
11923 "TARGET_QIMODE_MATH"
11924 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11926 (define_insn "*lshrqi3_1_one_bit"
11927 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11928 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11929 (match_operand:QI 2 "const1_operand" "")))
11930 (clobber (reg:CC FLAGS_REG))]
11931 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11932 && (TARGET_SHIFT1 || optimize_size)"
11934 [(set_attr "type" "ishift")
11935 (set (attr "length")
11936 (if_then_else (match_operand 0 "register_operand" "")
11938 (const_string "*")))])
11940 (define_insn "*lshrqi3_1_one_bit_slp"
11941 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11942 (lshiftrt:QI (match_dup 0)
11943 (match_operand:QI 1 "const1_operand" "")))
11944 (clobber (reg:CC FLAGS_REG))]
11945 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11946 && (TARGET_SHIFT1 || optimize_size)"
11948 [(set_attr "type" "ishift1")
11949 (set (attr "length")
11950 (if_then_else (match_operand 0 "register_operand" "")
11952 (const_string "*")))])
11954 (define_insn "*lshrqi3_1"
11955 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11956 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11957 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11958 (clobber (reg:CC FLAGS_REG))]
11959 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11961 shr{b}\t{%2, %0|%0, %2}
11962 shr{b}\t{%b2, %0|%0, %b2}"
11963 [(set_attr "type" "ishift")
11964 (set_attr "mode" "QI")])
11966 (define_insn "*lshrqi3_1_slp"
11967 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11968 (lshiftrt:QI (match_dup 0)
11969 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11970 (clobber (reg:CC FLAGS_REG))]
11971 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11972 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11974 shr{b}\t{%1, %0|%0, %1}
11975 shr{b}\t{%b1, %0|%0, %b1}"
11976 [(set_attr "type" "ishift1")
11977 (set_attr "mode" "QI")])
11979 ;; This pattern can't accept a variable shift count, since shifts by
11980 ;; zero don't affect the flags. We assume that shifts by constant
11981 ;; zero are optimized away.
11982 (define_insn "*lshrqi2_one_bit_cmp"
11983 [(set (reg FLAGS_REG)
11985 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11986 (match_operand:QI 2 "const1_operand" ""))
11988 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11989 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11990 "ix86_match_ccmode (insn, CCGOCmode)
11991 && (TARGET_SHIFT1 || optimize_size)
11992 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11994 [(set_attr "type" "ishift")
11995 (set (attr "length")
11996 (if_then_else (match_operand:SI 0 "register_operand" "")
11998 (const_string "*")))])
12000 ;; This pattern can't accept a variable shift count, since shifts by
12001 ;; zero don't affect the flags. We assume that shifts by constant
12002 ;; zero are optimized away.
12003 (define_insn "*lshrqi2_cmp"
12004 [(set (reg FLAGS_REG)
12006 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12007 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12009 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12010 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12011 "ix86_match_ccmode (insn, CCGOCmode)
12012 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12013 "shr{b}\t{%2, %0|%0, %2}"
12014 [(set_attr "type" "ishift")
12015 (set_attr "mode" "QI")])
12017 ;; Rotate instructions
12019 (define_expand "rotldi3"
12020 [(set (match_operand:DI 0 "shiftdi_operand" "")
12021 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12022 (match_operand:QI 2 "nonmemory_operand" "")))
12023 (clobber (reg:CC FLAGS_REG))]
12028 ix86_expand_binary_operator (ROTATE, DImode, operands);
12031 if (!const_1_to_31_operand (operands[2], VOIDmode))
12033 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12037 ;; Implement rotation using two double-precision shift instructions
12038 ;; and a scratch register.
12039 (define_insn_and_split "ix86_rotldi3"
12040 [(set (match_operand:DI 0 "register_operand" "=r")
12041 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12042 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12043 (clobber (reg:CC FLAGS_REG))
12044 (clobber (match_scratch:SI 3 "=&r"))]
12047 "&& reload_completed"
12048 [(set (match_dup 3) (match_dup 4))
12050 [(set (match_dup 4)
12051 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12052 (lshiftrt:SI (match_dup 5)
12053 (minus:QI (const_int 32) (match_dup 2)))))
12054 (clobber (reg:CC FLAGS_REG))])
12056 [(set (match_dup 5)
12057 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12058 (lshiftrt:SI (match_dup 3)
12059 (minus:QI (const_int 32) (match_dup 2)))))
12060 (clobber (reg:CC FLAGS_REG))])]
12061 "split_di (operands, 1, operands + 4, operands + 5);")
12063 (define_insn "*rotlsi3_1_one_bit_rex64"
12064 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12065 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12066 (match_operand:QI 2 "const1_operand" "")))
12067 (clobber (reg:CC FLAGS_REG))]
12068 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12069 && (TARGET_SHIFT1 || optimize_size)"
12071 [(set_attr "type" "rotate")
12072 (set (attr "length")
12073 (if_then_else (match_operand:DI 0 "register_operand" "")
12075 (const_string "*")))])
12077 (define_insn "*rotldi3_1_rex64"
12078 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12079 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12080 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12081 (clobber (reg:CC FLAGS_REG))]
12082 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12084 rol{q}\t{%2, %0|%0, %2}
12085 rol{q}\t{%b2, %0|%0, %b2}"
12086 [(set_attr "type" "rotate")
12087 (set_attr "mode" "DI")])
12089 (define_expand "rotlsi3"
12090 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12091 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12092 (match_operand:QI 2 "nonmemory_operand" "")))
12093 (clobber (reg:CC FLAGS_REG))]
12095 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12097 (define_insn "*rotlsi3_1_one_bit"
12098 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12099 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12100 (match_operand:QI 2 "const1_operand" "")))
12101 (clobber (reg:CC FLAGS_REG))]
12102 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12103 && (TARGET_SHIFT1 || optimize_size)"
12105 [(set_attr "type" "rotate")
12106 (set (attr "length")
12107 (if_then_else (match_operand:SI 0 "register_operand" "")
12109 (const_string "*")))])
12111 (define_insn "*rotlsi3_1_one_bit_zext"
12112 [(set (match_operand:DI 0 "register_operand" "=r")
12114 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12115 (match_operand:QI 2 "const1_operand" ""))))
12116 (clobber (reg:CC FLAGS_REG))]
12117 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12118 && (TARGET_SHIFT1 || optimize_size)"
12120 [(set_attr "type" "rotate")
12121 (set_attr "length" "2")])
12123 (define_insn "*rotlsi3_1"
12124 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12125 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12126 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12127 (clobber (reg:CC FLAGS_REG))]
12128 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12130 rol{l}\t{%2, %0|%0, %2}
12131 rol{l}\t{%b2, %0|%0, %b2}"
12132 [(set_attr "type" "rotate")
12133 (set_attr "mode" "SI")])
12135 (define_insn "*rotlsi3_1_zext"
12136 [(set (match_operand:DI 0 "register_operand" "=r,r")
12138 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12139 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12140 (clobber (reg:CC FLAGS_REG))]
12141 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12143 rol{l}\t{%2, %k0|%k0, %2}
12144 rol{l}\t{%b2, %k0|%k0, %b2}"
12145 [(set_attr "type" "rotate")
12146 (set_attr "mode" "SI")])
12148 (define_expand "rotlhi3"
12149 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12150 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12151 (match_operand:QI 2 "nonmemory_operand" "")))
12152 (clobber (reg:CC FLAGS_REG))]
12153 "TARGET_HIMODE_MATH"
12154 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12156 (define_insn "*rotlhi3_1_one_bit"
12157 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12158 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12159 (match_operand:QI 2 "const1_operand" "")))
12160 (clobber (reg:CC FLAGS_REG))]
12161 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12162 && (TARGET_SHIFT1 || optimize_size)"
12164 [(set_attr "type" "rotate")
12165 (set (attr "length")
12166 (if_then_else (match_operand 0 "register_operand" "")
12168 (const_string "*")))])
12170 (define_insn "*rotlhi3_1"
12171 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12172 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12173 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12174 (clobber (reg:CC FLAGS_REG))]
12175 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12177 rol{w}\t{%2, %0|%0, %2}
12178 rol{w}\t{%b2, %0|%0, %b2}"
12179 [(set_attr "type" "rotate")
12180 (set_attr "mode" "HI")])
12182 (define_expand "rotlqi3"
12183 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12184 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12185 (match_operand:QI 2 "nonmemory_operand" "")))
12186 (clobber (reg:CC FLAGS_REG))]
12187 "TARGET_QIMODE_MATH"
12188 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12190 (define_insn "*rotlqi3_1_one_bit_slp"
12191 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12192 (rotate:QI (match_dup 0)
12193 (match_operand:QI 1 "const1_operand" "")))
12194 (clobber (reg:CC FLAGS_REG))]
12195 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12196 && (TARGET_SHIFT1 || optimize_size)"
12198 [(set_attr "type" "rotate1")
12199 (set (attr "length")
12200 (if_then_else (match_operand 0 "register_operand" "")
12202 (const_string "*")))])
12204 (define_insn "*rotlqi3_1_one_bit"
12205 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12206 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12207 (match_operand:QI 2 "const1_operand" "")))
12208 (clobber (reg:CC FLAGS_REG))]
12209 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12210 && (TARGET_SHIFT1 || optimize_size)"
12212 [(set_attr "type" "rotate")
12213 (set (attr "length")
12214 (if_then_else (match_operand 0 "register_operand" "")
12216 (const_string "*")))])
12218 (define_insn "*rotlqi3_1_slp"
12219 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12220 (rotate:QI (match_dup 0)
12221 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12222 (clobber (reg:CC FLAGS_REG))]
12223 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12224 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12226 rol{b}\t{%1, %0|%0, %1}
12227 rol{b}\t{%b1, %0|%0, %b1}"
12228 [(set_attr "type" "rotate1")
12229 (set_attr "mode" "QI")])
12231 (define_insn "*rotlqi3_1"
12232 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12233 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12234 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12235 (clobber (reg:CC FLAGS_REG))]
12236 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12238 rol{b}\t{%2, %0|%0, %2}
12239 rol{b}\t{%b2, %0|%0, %b2}"
12240 [(set_attr "type" "rotate")
12241 (set_attr "mode" "QI")])
12243 (define_expand "rotrdi3"
12244 [(set (match_operand:DI 0 "shiftdi_operand" "")
12245 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12246 (match_operand:QI 2 "nonmemory_operand" "")))
12247 (clobber (reg:CC FLAGS_REG))]
12252 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12255 if (!const_1_to_31_operand (operands[2], VOIDmode))
12257 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12261 ;; Implement rotation using two double-precision shift instructions
12262 ;; and a scratch register.
12263 (define_insn_and_split "ix86_rotrdi3"
12264 [(set (match_operand:DI 0 "register_operand" "=r")
12265 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12266 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12267 (clobber (reg:CC FLAGS_REG))
12268 (clobber (match_scratch:SI 3 "=&r"))]
12271 "&& reload_completed"
12272 [(set (match_dup 3) (match_dup 4))
12274 [(set (match_dup 4)
12275 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12276 (ashift:SI (match_dup 5)
12277 (minus:QI (const_int 32) (match_dup 2)))))
12278 (clobber (reg:CC FLAGS_REG))])
12280 [(set (match_dup 5)
12281 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12282 (ashift:SI (match_dup 3)
12283 (minus:QI (const_int 32) (match_dup 2)))))
12284 (clobber (reg:CC FLAGS_REG))])]
12285 "split_di (operands, 1, operands + 4, operands + 5);")
12287 (define_insn "*rotrdi3_1_one_bit_rex64"
12288 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12289 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12290 (match_operand:QI 2 "const1_operand" "")))
12291 (clobber (reg:CC FLAGS_REG))]
12292 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12293 && (TARGET_SHIFT1 || optimize_size)"
12295 [(set_attr "type" "rotate")
12296 (set (attr "length")
12297 (if_then_else (match_operand:DI 0 "register_operand" "")
12299 (const_string "*")))])
12301 (define_insn "*rotrdi3_1_rex64"
12302 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12303 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12304 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12305 (clobber (reg:CC FLAGS_REG))]
12306 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12308 ror{q}\t{%2, %0|%0, %2}
12309 ror{q}\t{%b2, %0|%0, %b2}"
12310 [(set_attr "type" "rotate")
12311 (set_attr "mode" "DI")])
12313 (define_expand "rotrsi3"
12314 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12315 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12316 (match_operand:QI 2 "nonmemory_operand" "")))
12317 (clobber (reg:CC FLAGS_REG))]
12319 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12321 (define_insn "*rotrsi3_1_one_bit"
12322 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12323 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12324 (match_operand:QI 2 "const1_operand" "")))
12325 (clobber (reg:CC FLAGS_REG))]
12326 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12327 && (TARGET_SHIFT1 || optimize_size)"
12329 [(set_attr "type" "rotate")
12330 (set (attr "length")
12331 (if_then_else (match_operand:SI 0 "register_operand" "")
12333 (const_string "*")))])
12335 (define_insn "*rotrsi3_1_one_bit_zext"
12336 [(set (match_operand:DI 0 "register_operand" "=r")
12338 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12339 (match_operand:QI 2 "const1_operand" ""))))
12340 (clobber (reg:CC FLAGS_REG))]
12341 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12342 && (TARGET_SHIFT1 || optimize_size)"
12344 [(set_attr "type" "rotate")
12345 (set (attr "length")
12346 (if_then_else (match_operand:SI 0 "register_operand" "")
12348 (const_string "*")))])
12350 (define_insn "*rotrsi3_1"
12351 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12352 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12353 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12354 (clobber (reg:CC FLAGS_REG))]
12355 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12357 ror{l}\t{%2, %0|%0, %2}
12358 ror{l}\t{%b2, %0|%0, %b2}"
12359 [(set_attr "type" "rotate")
12360 (set_attr "mode" "SI")])
12362 (define_insn "*rotrsi3_1_zext"
12363 [(set (match_operand:DI 0 "register_operand" "=r,r")
12365 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12366 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12367 (clobber (reg:CC FLAGS_REG))]
12368 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12370 ror{l}\t{%2, %k0|%k0, %2}
12371 ror{l}\t{%b2, %k0|%k0, %b2}"
12372 [(set_attr "type" "rotate")
12373 (set_attr "mode" "SI")])
12375 (define_expand "rotrhi3"
12376 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12377 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12378 (match_operand:QI 2 "nonmemory_operand" "")))
12379 (clobber (reg:CC FLAGS_REG))]
12380 "TARGET_HIMODE_MATH"
12381 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12383 (define_insn "*rotrhi3_one_bit"
12384 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12385 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12386 (match_operand:QI 2 "const1_operand" "")))
12387 (clobber (reg:CC FLAGS_REG))]
12388 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12389 && (TARGET_SHIFT1 || optimize_size)"
12391 [(set_attr "type" "rotate")
12392 (set (attr "length")
12393 (if_then_else (match_operand 0 "register_operand" "")
12395 (const_string "*")))])
12397 (define_insn "*rotrhi3"
12398 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12399 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12400 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12401 (clobber (reg:CC FLAGS_REG))]
12402 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12404 ror{w}\t{%2, %0|%0, %2}
12405 ror{w}\t{%b2, %0|%0, %b2}"
12406 [(set_attr "type" "rotate")
12407 (set_attr "mode" "HI")])
12409 (define_expand "rotrqi3"
12410 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12411 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12412 (match_operand:QI 2 "nonmemory_operand" "")))
12413 (clobber (reg:CC FLAGS_REG))]
12414 "TARGET_QIMODE_MATH"
12415 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12417 (define_insn "*rotrqi3_1_one_bit"
12418 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12419 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12420 (match_operand:QI 2 "const1_operand" "")))
12421 (clobber (reg:CC FLAGS_REG))]
12422 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12423 && (TARGET_SHIFT1 || optimize_size)"
12425 [(set_attr "type" "rotate")
12426 (set (attr "length")
12427 (if_then_else (match_operand 0 "register_operand" "")
12429 (const_string "*")))])
12431 (define_insn "*rotrqi3_1_one_bit_slp"
12432 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12433 (rotatert:QI (match_dup 0)
12434 (match_operand:QI 1 "const1_operand" "")))
12435 (clobber (reg:CC FLAGS_REG))]
12436 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12437 && (TARGET_SHIFT1 || optimize_size)"
12439 [(set_attr "type" "rotate1")
12440 (set (attr "length")
12441 (if_then_else (match_operand 0 "register_operand" "")
12443 (const_string "*")))])
12445 (define_insn "*rotrqi3_1"
12446 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12447 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12448 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12449 (clobber (reg:CC FLAGS_REG))]
12450 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12452 ror{b}\t{%2, %0|%0, %2}
12453 ror{b}\t{%b2, %0|%0, %b2}"
12454 [(set_attr "type" "rotate")
12455 (set_attr "mode" "QI")])
12457 (define_insn "*rotrqi3_1_slp"
12458 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12459 (rotatert:QI (match_dup 0)
12460 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12461 (clobber (reg:CC FLAGS_REG))]
12462 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12463 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12465 ror{b}\t{%1, %0|%0, %1}
12466 ror{b}\t{%b1, %0|%0, %b1}"
12467 [(set_attr "type" "rotate1")
12468 (set_attr "mode" "QI")])
12470 ;; Bit set / bit test instructions
12472 (define_expand "extv"
12473 [(set (match_operand:SI 0 "register_operand" "")
12474 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12475 (match_operand:SI 2 "immediate_operand" "")
12476 (match_operand:SI 3 "immediate_operand" "")))]
12479 /* Handle extractions from %ah et al. */
12480 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12483 /* From mips.md: extract_bit_field doesn't verify that our source
12484 matches the predicate, so check it again here. */
12485 if (! ext_register_operand (operands[1], VOIDmode))
12489 (define_expand "extzv"
12490 [(set (match_operand:SI 0 "register_operand" "")
12491 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12492 (match_operand:SI 2 "immediate_operand" "")
12493 (match_operand:SI 3 "immediate_operand" "")))]
12496 /* Handle extractions from %ah et al. */
12497 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12500 /* From mips.md: extract_bit_field doesn't verify that our source
12501 matches the predicate, so check it again here. */
12502 if (! ext_register_operand (operands[1], VOIDmode))
12506 (define_expand "insv"
12507 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12508 (match_operand 1 "immediate_operand" "")
12509 (match_operand 2 "immediate_operand" ""))
12510 (match_operand 3 "register_operand" ""))]
12513 /* Handle extractions from %ah et al. */
12514 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12517 /* From mips.md: insert_bit_field doesn't verify that our source
12518 matches the predicate, so check it again here. */
12519 if (! ext_register_operand (operands[0], VOIDmode))
12523 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12525 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12530 ;; %%% bts, btr, btc, bt.
12531 ;; In general these instructions are *slow* when applied to memory,
12532 ;; since they enforce atomic operation. When applied to registers,
12533 ;; it depends on the cpu implementation. They're never faster than
12534 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12535 ;; no point. But in 64-bit, we can't hold the relevant immediates
12536 ;; within the instruction itself, so operating on bits in the high
12537 ;; 32-bits of a register becomes easier.
12539 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12540 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12541 ;; negdf respectively, so they can never be disabled entirely.
12543 (define_insn "*btsq"
12544 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12546 (match_operand:DI 1 "const_0_to_63_operand" ""))
12548 (clobber (reg:CC FLAGS_REG))]
12549 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12551 [(set_attr "type" "alu1")])
12553 (define_insn "*btrq"
12554 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12556 (match_operand:DI 1 "const_0_to_63_operand" ""))
12558 (clobber (reg:CC FLAGS_REG))]
12559 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12561 [(set_attr "type" "alu1")])
12563 (define_insn "*btcq"
12564 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12566 (match_operand:DI 1 "const_0_to_63_operand" ""))
12567 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12568 (clobber (reg:CC FLAGS_REG))]
12569 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12571 [(set_attr "type" "alu1")])
12573 ;; Allow Nocona to avoid these instructions if a register is available.
12576 [(match_scratch:DI 2 "r")
12577 (parallel [(set (zero_extract:DI
12578 (match_operand:DI 0 "register_operand" "")
12580 (match_operand:DI 1 "const_0_to_63_operand" ""))
12582 (clobber (reg:CC FLAGS_REG))])]
12583 "TARGET_64BIT && !TARGET_USE_BT"
12586 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12589 if (HOST_BITS_PER_WIDE_INT >= 64)
12590 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12591 else if (i < HOST_BITS_PER_WIDE_INT)
12592 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12594 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12596 op1 = immed_double_const (lo, hi, DImode);
12599 emit_move_insn (operands[2], op1);
12603 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12608 [(match_scratch:DI 2 "r")
12609 (parallel [(set (zero_extract:DI
12610 (match_operand:DI 0 "register_operand" "")
12612 (match_operand:DI 1 "const_0_to_63_operand" ""))
12614 (clobber (reg:CC FLAGS_REG))])]
12615 "TARGET_64BIT && !TARGET_USE_BT"
12618 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12621 if (HOST_BITS_PER_WIDE_INT >= 64)
12622 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12623 else if (i < HOST_BITS_PER_WIDE_INT)
12624 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12626 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12628 op1 = immed_double_const (~lo, ~hi, DImode);
12631 emit_move_insn (operands[2], op1);
12635 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12640 [(match_scratch:DI 2 "r")
12641 (parallel [(set (zero_extract:DI
12642 (match_operand:DI 0 "register_operand" "")
12644 (match_operand:DI 1 "const_0_to_63_operand" ""))
12645 (not:DI (zero_extract:DI
12646 (match_dup 0) (const_int 1) (match_dup 1))))
12647 (clobber (reg:CC FLAGS_REG))])]
12648 "TARGET_64BIT && !TARGET_USE_BT"
12651 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12654 if (HOST_BITS_PER_WIDE_INT >= 64)
12655 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12656 else if (i < HOST_BITS_PER_WIDE_INT)
12657 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12659 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12661 op1 = immed_double_const (lo, hi, DImode);
12664 emit_move_insn (operands[2], op1);
12668 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12672 ;; Store-flag instructions.
12674 ;; For all sCOND expanders, also expand the compare or test insn that
12675 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12677 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12678 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12679 ;; way, which can later delete the movzx if only QImode is needed.
12681 (define_expand "seq"
12682 [(set (match_operand:QI 0 "register_operand" "")
12683 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12685 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12687 (define_expand "sne"
12688 [(set (match_operand:QI 0 "register_operand" "")
12689 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12691 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12693 (define_expand "sgt"
12694 [(set (match_operand:QI 0 "register_operand" "")
12695 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12697 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12699 (define_expand "sgtu"
12700 [(set (match_operand:QI 0 "register_operand" "")
12701 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12703 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12705 (define_expand "slt"
12706 [(set (match_operand:QI 0 "register_operand" "")
12707 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12709 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12711 (define_expand "sltu"
12712 [(set (match_operand:QI 0 "register_operand" "")
12713 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12715 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12717 (define_expand "sge"
12718 [(set (match_operand:QI 0 "register_operand" "")
12719 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12721 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12723 (define_expand "sgeu"
12724 [(set (match_operand:QI 0 "register_operand" "")
12725 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12727 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12729 (define_expand "sle"
12730 [(set (match_operand:QI 0 "register_operand" "")
12731 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12733 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12735 (define_expand "sleu"
12736 [(set (match_operand:QI 0 "register_operand" "")
12737 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12739 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12741 (define_expand "sunordered"
12742 [(set (match_operand:QI 0 "register_operand" "")
12743 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12744 "TARGET_80387 || TARGET_SSE"
12745 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12747 (define_expand "sordered"
12748 [(set (match_operand:QI 0 "register_operand" "")
12749 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12751 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12753 (define_expand "suneq"
12754 [(set (match_operand:QI 0 "register_operand" "")
12755 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12756 "TARGET_80387 || TARGET_SSE"
12757 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12759 (define_expand "sunge"
12760 [(set (match_operand:QI 0 "register_operand" "")
12761 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12762 "TARGET_80387 || TARGET_SSE"
12763 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12765 (define_expand "sungt"
12766 [(set (match_operand:QI 0 "register_operand" "")
12767 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12768 "TARGET_80387 || TARGET_SSE"
12769 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12771 (define_expand "sunle"
12772 [(set (match_operand:QI 0 "register_operand" "")
12773 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12774 "TARGET_80387 || TARGET_SSE"
12775 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12777 (define_expand "sunlt"
12778 [(set (match_operand:QI 0 "register_operand" "")
12779 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12780 "TARGET_80387 || TARGET_SSE"
12781 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12783 (define_expand "sltgt"
12784 [(set (match_operand:QI 0 "register_operand" "")
12785 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12786 "TARGET_80387 || TARGET_SSE"
12787 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12789 (define_insn "*setcc_1"
12790 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12791 (match_operator:QI 1 "ix86_comparison_operator"
12792 [(reg FLAGS_REG) (const_int 0)]))]
12795 [(set_attr "type" "setcc")
12796 (set_attr "mode" "QI")])
12798 (define_insn "*setcc_2"
12799 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12800 (match_operator:QI 1 "ix86_comparison_operator"
12801 [(reg FLAGS_REG) (const_int 0)]))]
12804 [(set_attr "type" "setcc")
12805 (set_attr "mode" "QI")])
12807 ;; In general it is not safe to assume too much about CCmode registers,
12808 ;; so simplify-rtx stops when it sees a second one. Under certain
12809 ;; conditions this is safe on x86, so help combine not create
12816 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12817 (ne:QI (match_operator 1 "ix86_comparison_operator"
12818 [(reg FLAGS_REG) (const_int 0)])
12821 [(set (match_dup 0) (match_dup 1))]
12823 PUT_MODE (operands[1], QImode);
12827 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12828 (ne:QI (match_operator 1 "ix86_comparison_operator"
12829 [(reg FLAGS_REG) (const_int 0)])
12832 [(set (match_dup 0) (match_dup 1))]
12834 PUT_MODE (operands[1], QImode);
12838 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12839 (eq:QI (match_operator 1 "ix86_comparison_operator"
12840 [(reg FLAGS_REG) (const_int 0)])
12843 [(set (match_dup 0) (match_dup 1))]
12845 rtx new_op1 = copy_rtx (operands[1]);
12846 operands[1] = new_op1;
12847 PUT_MODE (new_op1, QImode);
12848 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12849 GET_MODE (XEXP (new_op1, 0))));
12851 /* Make sure that (a) the CCmode we have for the flags is strong
12852 enough for the reversed compare or (b) we have a valid FP compare. */
12853 if (! ix86_comparison_operator (new_op1, VOIDmode))
12858 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12859 (eq:QI (match_operator 1 "ix86_comparison_operator"
12860 [(reg FLAGS_REG) (const_int 0)])
12863 [(set (match_dup 0) (match_dup 1))]
12865 rtx new_op1 = copy_rtx (operands[1]);
12866 operands[1] = new_op1;
12867 PUT_MODE (new_op1, QImode);
12868 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12869 GET_MODE (XEXP (new_op1, 0))));
12871 /* Make sure that (a) the CCmode we have for the flags is strong
12872 enough for the reversed compare or (b) we have a valid FP compare. */
12873 if (! ix86_comparison_operator (new_op1, VOIDmode))
12877 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12878 ;; subsequent logical operations are used to imitate conditional moves.
12879 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12882 (define_insn "*sse_setccsf"
12883 [(set (match_operand:SF 0 "register_operand" "=x")
12884 (match_operator:SF 1 "sse_comparison_operator"
12885 [(match_operand:SF 2 "register_operand" "0")
12886 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12888 "cmp%D1ss\t{%3, %0|%0, %3}"
12889 [(set_attr "type" "ssecmp")
12890 (set_attr "mode" "SF")])
12892 (define_insn "*sse_setccdf"
12893 [(set (match_operand:DF 0 "register_operand" "=Y")
12894 (match_operator:DF 1 "sse_comparison_operator"
12895 [(match_operand:DF 2 "register_operand" "0")
12896 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12898 "cmp%D1sd\t{%3, %0|%0, %3}"
12899 [(set_attr "type" "ssecmp")
12900 (set_attr "mode" "DF")])
12902 ;; Basic conditional jump instructions.
12903 ;; We ignore the overflow flag for signed branch instructions.
12905 ;; For all bCOND expanders, also expand the compare or test insn that
12906 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12908 (define_expand "beq"
12910 (if_then_else (match_dup 1)
12911 (label_ref (match_operand 0 "" ""))
12914 "ix86_expand_branch (EQ, operands[0]); DONE;")
12916 (define_expand "bne"
12918 (if_then_else (match_dup 1)
12919 (label_ref (match_operand 0 "" ""))
12922 "ix86_expand_branch (NE, operands[0]); DONE;")
12924 (define_expand "bgt"
12926 (if_then_else (match_dup 1)
12927 (label_ref (match_operand 0 "" ""))
12930 "ix86_expand_branch (GT, operands[0]); DONE;")
12932 (define_expand "bgtu"
12934 (if_then_else (match_dup 1)
12935 (label_ref (match_operand 0 "" ""))
12938 "ix86_expand_branch (GTU, operands[0]); DONE;")
12940 (define_expand "blt"
12942 (if_then_else (match_dup 1)
12943 (label_ref (match_operand 0 "" ""))
12946 "ix86_expand_branch (LT, operands[0]); DONE;")
12948 (define_expand "bltu"
12950 (if_then_else (match_dup 1)
12951 (label_ref (match_operand 0 "" ""))
12954 "ix86_expand_branch (LTU, operands[0]); DONE;")
12956 (define_expand "bge"
12958 (if_then_else (match_dup 1)
12959 (label_ref (match_operand 0 "" ""))
12962 "ix86_expand_branch (GE, operands[0]); DONE;")
12964 (define_expand "bgeu"
12966 (if_then_else (match_dup 1)
12967 (label_ref (match_operand 0 "" ""))
12970 "ix86_expand_branch (GEU, operands[0]); DONE;")
12972 (define_expand "ble"
12974 (if_then_else (match_dup 1)
12975 (label_ref (match_operand 0 "" ""))
12978 "ix86_expand_branch (LE, operands[0]); DONE;")
12980 (define_expand "bleu"
12982 (if_then_else (match_dup 1)
12983 (label_ref (match_operand 0 "" ""))
12986 "ix86_expand_branch (LEU, operands[0]); DONE;")
12988 (define_expand "bunordered"
12990 (if_then_else (match_dup 1)
12991 (label_ref (match_operand 0 "" ""))
12993 "TARGET_80387 || TARGET_SSE_MATH"
12994 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12996 (define_expand "bordered"
12998 (if_then_else (match_dup 1)
12999 (label_ref (match_operand 0 "" ""))
13001 "TARGET_80387 || TARGET_SSE_MATH"
13002 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13004 (define_expand "buneq"
13006 (if_then_else (match_dup 1)
13007 (label_ref (match_operand 0 "" ""))
13009 "TARGET_80387 || TARGET_SSE_MATH"
13010 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13012 (define_expand "bunge"
13014 (if_then_else (match_dup 1)
13015 (label_ref (match_operand 0 "" ""))
13017 "TARGET_80387 || TARGET_SSE_MATH"
13018 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13020 (define_expand "bungt"
13022 (if_then_else (match_dup 1)
13023 (label_ref (match_operand 0 "" ""))
13025 "TARGET_80387 || TARGET_SSE_MATH"
13026 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13028 (define_expand "bunle"
13030 (if_then_else (match_dup 1)
13031 (label_ref (match_operand 0 "" ""))
13033 "TARGET_80387 || TARGET_SSE_MATH"
13034 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13036 (define_expand "bunlt"
13038 (if_then_else (match_dup 1)
13039 (label_ref (match_operand 0 "" ""))
13041 "TARGET_80387 || TARGET_SSE_MATH"
13042 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13044 (define_expand "bltgt"
13046 (if_then_else (match_dup 1)
13047 (label_ref (match_operand 0 "" ""))
13049 "TARGET_80387 || TARGET_SSE_MATH"
13050 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13052 (define_insn "*jcc_1"
13054 (if_then_else (match_operator 1 "ix86_comparison_operator"
13055 [(reg FLAGS_REG) (const_int 0)])
13056 (label_ref (match_operand 0 "" ""))
13060 [(set_attr "type" "ibr")
13061 (set_attr "modrm" "0")
13062 (set (attr "length")
13063 (if_then_else (and (ge (minus (match_dup 0) (pc))
13065 (lt (minus (match_dup 0) (pc))
13070 (define_insn "*jcc_2"
13072 (if_then_else (match_operator 1 "ix86_comparison_operator"
13073 [(reg FLAGS_REG) (const_int 0)])
13075 (label_ref (match_operand 0 "" ""))))]
13078 [(set_attr "type" "ibr")
13079 (set_attr "modrm" "0")
13080 (set (attr "length")
13081 (if_then_else (and (ge (minus (match_dup 0) (pc))
13083 (lt (minus (match_dup 0) (pc))
13088 ;; In general it is not safe to assume too much about CCmode registers,
13089 ;; so simplify-rtx stops when it sees a second one. Under certain
13090 ;; conditions this is safe on x86, so help combine not create
13098 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13099 [(reg FLAGS_REG) (const_int 0)])
13101 (label_ref (match_operand 1 "" ""))
13105 (if_then_else (match_dup 0)
13106 (label_ref (match_dup 1))
13109 PUT_MODE (operands[0], VOIDmode);
13114 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13115 [(reg FLAGS_REG) (const_int 0)])
13117 (label_ref (match_operand 1 "" ""))
13121 (if_then_else (match_dup 0)
13122 (label_ref (match_dup 1))
13125 rtx new_op0 = copy_rtx (operands[0]);
13126 operands[0] = new_op0;
13127 PUT_MODE (new_op0, VOIDmode);
13128 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13129 GET_MODE (XEXP (new_op0, 0))));
13131 /* Make sure that (a) the CCmode we have for the flags is strong
13132 enough for the reversed compare or (b) we have a valid FP compare. */
13133 if (! ix86_comparison_operator (new_op0, VOIDmode))
13137 ;; Define combination compare-and-branch fp compare instructions to use
13138 ;; during early optimization. Splitting the operation apart early makes
13139 ;; for bad code when we want to reverse the operation.
13141 (define_insn "*fp_jcc_1_mixed"
13143 (if_then_else (match_operator 0 "comparison_operator"
13144 [(match_operand 1 "register_operand" "f#x,x#f")
13145 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13146 (label_ref (match_operand 3 "" ""))
13148 (clobber (reg:CCFP FPSR_REG))
13149 (clobber (reg:CCFP FLAGS_REG))]
13150 "TARGET_MIX_SSE_I387
13151 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13152 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13153 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13156 (define_insn "*fp_jcc_1_sse"
13158 (if_then_else (match_operator 0 "comparison_operator"
13159 [(match_operand 1 "register_operand" "x")
13160 (match_operand 2 "nonimmediate_operand" "xm")])
13161 (label_ref (match_operand 3 "" ""))
13163 (clobber (reg:CCFP FPSR_REG))
13164 (clobber (reg:CCFP FLAGS_REG))]
13166 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13167 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13168 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13171 (define_insn "*fp_jcc_1_387"
13173 (if_then_else (match_operator 0 "comparison_operator"
13174 [(match_operand 1 "register_operand" "f")
13175 (match_operand 2 "register_operand" "f")])
13176 (label_ref (match_operand 3 "" ""))
13178 (clobber (reg:CCFP FPSR_REG))
13179 (clobber (reg:CCFP FLAGS_REG))]
13180 "TARGET_CMOVE && TARGET_80387
13181 && FLOAT_MODE_P (GET_MODE (operands[1]))
13182 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13183 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13186 (define_insn "*fp_jcc_2_mixed"
13188 (if_then_else (match_operator 0 "comparison_operator"
13189 [(match_operand 1 "register_operand" "f#x,x#f")
13190 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13192 (label_ref (match_operand 3 "" ""))))
13193 (clobber (reg:CCFP FPSR_REG))
13194 (clobber (reg:CCFP FLAGS_REG))]
13195 "TARGET_MIX_SSE_I387
13196 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13197 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13198 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13201 (define_insn "*fp_jcc_2_sse"
13203 (if_then_else (match_operator 0 "comparison_operator"
13204 [(match_operand 1 "register_operand" "x")
13205 (match_operand 2 "nonimmediate_operand" "xm")])
13207 (label_ref (match_operand 3 "" ""))))
13208 (clobber (reg:CCFP FPSR_REG))
13209 (clobber (reg:CCFP FLAGS_REG))]
13211 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13212 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13213 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13216 (define_insn "*fp_jcc_2_387"
13218 (if_then_else (match_operator 0 "comparison_operator"
13219 [(match_operand 1 "register_operand" "f")
13220 (match_operand 2 "register_operand" "f")])
13222 (label_ref (match_operand 3 "" ""))))
13223 (clobber (reg:CCFP FPSR_REG))
13224 (clobber (reg:CCFP FLAGS_REG))]
13225 "TARGET_CMOVE && TARGET_80387
13226 && FLOAT_MODE_P (GET_MODE (operands[1]))
13227 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13228 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13231 (define_insn "*fp_jcc_3_387"
13233 (if_then_else (match_operator 0 "comparison_operator"
13234 [(match_operand 1 "register_operand" "f")
13235 (match_operand 2 "nonimmediate_operand" "fm")])
13236 (label_ref (match_operand 3 "" ""))
13238 (clobber (reg:CCFP FPSR_REG))
13239 (clobber (reg:CCFP FLAGS_REG))
13240 (clobber (match_scratch:HI 4 "=a"))]
13242 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13243 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13244 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13245 && SELECT_CC_MODE (GET_CODE (operands[0]),
13246 operands[1], operands[2]) == CCFPmode
13247 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13250 (define_insn "*fp_jcc_4_387"
13252 (if_then_else (match_operator 0 "comparison_operator"
13253 [(match_operand 1 "register_operand" "f")
13254 (match_operand 2 "nonimmediate_operand" "fm")])
13256 (label_ref (match_operand 3 "" ""))))
13257 (clobber (reg:CCFP FPSR_REG))
13258 (clobber (reg:CCFP FLAGS_REG))
13259 (clobber (match_scratch:HI 4 "=a"))]
13261 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13262 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13263 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13264 && SELECT_CC_MODE (GET_CODE (operands[0]),
13265 operands[1], operands[2]) == CCFPmode
13266 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13269 (define_insn "*fp_jcc_5_387"
13271 (if_then_else (match_operator 0 "comparison_operator"
13272 [(match_operand 1 "register_operand" "f")
13273 (match_operand 2 "register_operand" "f")])
13274 (label_ref (match_operand 3 "" ""))
13276 (clobber (reg:CCFP FPSR_REG))
13277 (clobber (reg:CCFP FLAGS_REG))
13278 (clobber (match_scratch:HI 4 "=a"))]
13280 && FLOAT_MODE_P (GET_MODE (operands[1]))
13281 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13282 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13285 (define_insn "*fp_jcc_6_387"
13287 (if_then_else (match_operator 0 "comparison_operator"
13288 [(match_operand 1 "register_operand" "f")
13289 (match_operand 2 "register_operand" "f")])
13291 (label_ref (match_operand 3 "" ""))))
13292 (clobber (reg:CCFP FPSR_REG))
13293 (clobber (reg:CCFP FLAGS_REG))
13294 (clobber (match_scratch:HI 4 "=a"))]
13296 && FLOAT_MODE_P (GET_MODE (operands[1]))
13297 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13298 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13301 (define_insn "*fp_jcc_7_387"
13303 (if_then_else (match_operator 0 "comparison_operator"
13304 [(match_operand 1 "register_operand" "f")
13305 (match_operand 2 "const0_operand" "X")])
13306 (label_ref (match_operand 3 "" ""))
13308 (clobber (reg:CCFP FPSR_REG))
13309 (clobber (reg:CCFP FLAGS_REG))
13310 (clobber (match_scratch:HI 4 "=a"))]
13312 && FLOAT_MODE_P (GET_MODE (operands[1]))
13313 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13314 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13315 && SELECT_CC_MODE (GET_CODE (operands[0]),
13316 operands[1], operands[2]) == CCFPmode
13317 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13320 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13321 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13322 ;; with a precedence over other operators and is always put in the first
13323 ;; place. Swap condition and operands to match ficom instruction.
13325 (define_insn "*fp_jcc_8<mode>_387"
13327 (if_then_else (match_operator 0 "comparison_operator"
13328 [(match_operator 1 "float_operator"
13329 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13330 (match_operand 3 "register_operand" "f,f")])
13331 (label_ref (match_operand 4 "" ""))
13333 (clobber (reg:CCFP FPSR_REG))
13334 (clobber (reg:CCFP FLAGS_REG))
13335 (clobber (match_scratch:HI 5 "=a,a"))]
13336 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13337 && FLOAT_MODE_P (GET_MODE (operands[3]))
13338 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13339 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13340 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13341 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13346 (if_then_else (match_operator 0 "comparison_operator"
13347 [(match_operand 1 "register_operand" "")
13348 (match_operand 2 "nonimmediate_operand" "")])
13349 (match_operand 3 "" "")
13350 (match_operand 4 "" "")))
13351 (clobber (reg:CCFP FPSR_REG))
13352 (clobber (reg:CCFP FLAGS_REG))]
13356 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13357 operands[3], operands[4], NULL_RTX, NULL_RTX);
13363 (if_then_else (match_operator 0 "comparison_operator"
13364 [(match_operand 1 "register_operand" "")
13365 (match_operand 2 "general_operand" "")])
13366 (match_operand 3 "" "")
13367 (match_operand 4 "" "")))
13368 (clobber (reg:CCFP FPSR_REG))
13369 (clobber (reg:CCFP FLAGS_REG))
13370 (clobber (match_scratch:HI 5 "=a"))]
13374 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13375 operands[3], operands[4], operands[5], NULL_RTX);
13381 (if_then_else (match_operator 0 "comparison_operator"
13382 [(match_operator 1 "float_operator"
13383 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13384 (match_operand 3 "register_operand" "")])
13385 (match_operand 4 "" "")
13386 (match_operand 5 "" "")))
13387 (clobber (reg:CCFP FPSR_REG))
13388 (clobber (reg:CCFP FLAGS_REG))
13389 (clobber (match_scratch:HI 6 "=a"))]
13393 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13394 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13395 operands[3], operands[7],
13396 operands[4], operands[5], operands[6], NULL_RTX);
13400 ;; %%% Kill this when reload knows how to do it.
13403 (if_then_else (match_operator 0 "comparison_operator"
13404 [(match_operator 1 "float_operator"
13405 [(match_operand:X87MODEI12 2 "register_operand" "")])
13406 (match_operand 3 "register_operand" "")])
13407 (match_operand 4 "" "")
13408 (match_operand 5 "" "")))
13409 (clobber (reg:CCFP FPSR_REG))
13410 (clobber (reg:CCFP FLAGS_REG))
13411 (clobber (match_scratch:HI 6 "=a"))]
13415 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13416 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13417 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13418 operands[3], operands[7],
13419 operands[4], operands[5], operands[6], operands[2]);
13423 ;; Unconditional and other jump instructions
13425 (define_insn "jump"
13427 (label_ref (match_operand 0 "" "")))]
13430 [(set_attr "type" "ibr")
13431 (set (attr "length")
13432 (if_then_else (and (ge (minus (match_dup 0) (pc))
13434 (lt (minus (match_dup 0) (pc))
13438 (set_attr "modrm" "0")])
13440 (define_expand "indirect_jump"
13441 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13445 (define_insn "*indirect_jump"
13446 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13449 [(set_attr "type" "ibr")
13450 (set_attr "length_immediate" "0")])
13452 (define_insn "*indirect_jump_rtx64"
13453 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13456 [(set_attr "type" "ibr")
13457 (set_attr "length_immediate" "0")])
13459 (define_expand "tablejump"
13460 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13461 (use (label_ref (match_operand 1 "" "")))])]
13464 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13465 relative. Convert the relative address to an absolute address. */
13469 enum rtx_code code;
13475 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13477 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13481 op1 = pic_offset_table_rtx;
13486 op0 = pic_offset_table_rtx;
13490 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13495 (define_insn "*tablejump_1"
13496 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13497 (use (label_ref (match_operand 1 "" "")))]
13500 [(set_attr "type" "ibr")
13501 (set_attr "length_immediate" "0")])
13503 (define_insn "*tablejump_1_rtx64"
13504 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13505 (use (label_ref (match_operand 1 "" "")))]
13508 [(set_attr "type" "ibr")
13509 (set_attr "length_immediate" "0")])
13511 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13514 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13515 (set (match_operand:QI 1 "register_operand" "")
13516 (match_operator:QI 2 "ix86_comparison_operator"
13517 [(reg FLAGS_REG) (const_int 0)]))
13518 (set (match_operand 3 "q_regs_operand" "")
13519 (zero_extend (match_dup 1)))]
13520 "(peep2_reg_dead_p (3, operands[1])
13521 || operands_match_p (operands[1], operands[3]))
13522 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13523 [(set (match_dup 4) (match_dup 0))
13524 (set (strict_low_part (match_dup 5))
13527 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13528 operands[5] = gen_lowpart (QImode, operands[3]);
13529 ix86_expand_clear (operands[3]);
13532 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13535 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13536 (set (match_operand:QI 1 "register_operand" "")
13537 (match_operator:QI 2 "ix86_comparison_operator"
13538 [(reg FLAGS_REG) (const_int 0)]))
13539 (parallel [(set (match_operand 3 "q_regs_operand" "")
13540 (zero_extend (match_dup 1)))
13541 (clobber (reg:CC FLAGS_REG))])]
13542 "(peep2_reg_dead_p (3, operands[1])
13543 || operands_match_p (operands[1], operands[3]))
13544 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13545 [(set (match_dup 4) (match_dup 0))
13546 (set (strict_low_part (match_dup 5))
13549 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13550 operands[5] = gen_lowpart (QImode, operands[3]);
13551 ix86_expand_clear (operands[3]);
13554 ;; Call instructions.
13556 ;; The predicates normally associated with named expanders are not properly
13557 ;; checked for calls. This is a bug in the generic code, but it isn't that
13558 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13560 ;; Call subroutine returning no value.
13562 (define_expand "call_pop"
13563 [(parallel [(call (match_operand:QI 0 "" "")
13564 (match_operand:SI 1 "" ""))
13565 (set (reg:SI SP_REG)
13566 (plus:SI (reg:SI SP_REG)
13567 (match_operand:SI 3 "" "")))])]
13570 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13574 (define_insn "*call_pop_0"
13575 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13576 (match_operand:SI 1 "" ""))
13577 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13578 (match_operand:SI 2 "immediate_operand" "")))]
13581 if (SIBLING_CALL_P (insn))
13584 return "call\t%P0";
13586 [(set_attr "type" "call")])
13588 (define_insn "*call_pop_1"
13589 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13590 (match_operand:SI 1 "" ""))
13591 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13592 (match_operand:SI 2 "immediate_operand" "i")))]
13595 if (constant_call_address_operand (operands[0], Pmode))
13597 if (SIBLING_CALL_P (insn))
13600 return "call\t%P0";
13602 if (SIBLING_CALL_P (insn))
13605 return "call\t%A0";
13607 [(set_attr "type" "call")])
13609 (define_expand "call"
13610 [(call (match_operand:QI 0 "" "")
13611 (match_operand 1 "" ""))
13612 (use (match_operand 2 "" ""))]
13615 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13619 (define_expand "sibcall"
13620 [(call (match_operand:QI 0 "" "")
13621 (match_operand 1 "" ""))
13622 (use (match_operand 2 "" ""))]
13625 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13629 (define_insn "*call_0"
13630 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13631 (match_operand 1 "" ""))]
13634 if (SIBLING_CALL_P (insn))
13637 return "call\t%P0";
13639 [(set_attr "type" "call")])
13641 (define_insn "*call_1"
13642 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13643 (match_operand 1 "" ""))]
13644 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13646 if (constant_call_address_operand (operands[0], Pmode))
13647 return "call\t%P0";
13648 return "call\t%A0";
13650 [(set_attr "type" "call")])
13652 (define_insn "*sibcall_1"
13653 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13654 (match_operand 1 "" ""))]
13655 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13657 if (constant_call_address_operand (operands[0], Pmode))
13661 [(set_attr "type" "call")])
13663 (define_insn "*call_1_rex64"
13664 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13665 (match_operand 1 "" ""))]
13666 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13668 if (constant_call_address_operand (operands[0], Pmode))
13669 return "call\t%P0";
13670 return "call\t%A0";
13672 [(set_attr "type" "call")])
13674 (define_insn "*sibcall_1_rex64"
13675 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13676 (match_operand 1 "" ""))]
13677 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13679 [(set_attr "type" "call")])
13681 (define_insn "*sibcall_1_rex64_v"
13682 [(call (mem:QI (reg:DI 40))
13683 (match_operand 0 "" ""))]
13684 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13686 [(set_attr "type" "call")])
13689 ;; Call subroutine, returning value in operand 0
13691 (define_expand "call_value_pop"
13692 [(parallel [(set (match_operand 0 "" "")
13693 (call (match_operand:QI 1 "" "")
13694 (match_operand:SI 2 "" "")))
13695 (set (reg:SI SP_REG)
13696 (plus:SI (reg:SI SP_REG)
13697 (match_operand:SI 4 "" "")))])]
13700 ix86_expand_call (operands[0], operands[1], operands[2],
13701 operands[3], operands[4], 0);
13705 (define_expand "call_value"
13706 [(set (match_operand 0 "" "")
13707 (call (match_operand:QI 1 "" "")
13708 (match_operand:SI 2 "" "")))
13709 (use (match_operand:SI 3 "" ""))]
13710 ;; Operand 2 not used on the i386.
13713 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13717 (define_expand "sibcall_value"
13718 [(set (match_operand 0 "" "")
13719 (call (match_operand:QI 1 "" "")
13720 (match_operand:SI 2 "" "")))
13721 (use (match_operand:SI 3 "" ""))]
13722 ;; Operand 2 not used on the i386.
13725 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13729 ;; Call subroutine returning any type.
13731 (define_expand "untyped_call"
13732 [(parallel [(call (match_operand 0 "" "")
13734 (match_operand 1 "" "")
13735 (match_operand 2 "" "")])]
13740 /* In order to give reg-stack an easier job in validating two
13741 coprocessor registers as containing a possible return value,
13742 simply pretend the untyped call returns a complex long double
13745 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13746 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13747 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13750 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13752 rtx set = XVECEXP (operands[2], 0, i);
13753 emit_move_insn (SET_DEST (set), SET_SRC (set));
13756 /* The optimizer does not know that the call sets the function value
13757 registers we stored in the result block. We avoid problems by
13758 claiming that all hard registers are used and clobbered at this
13760 emit_insn (gen_blockage (const0_rtx));
13765 ;; Prologue and epilogue instructions
13767 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13768 ;; all of memory. This blocks insns from being moved across this point.
13770 (define_insn "blockage"
13771 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13774 [(set_attr "length" "0")])
13776 ;; Insn emitted into the body of a function to return from a function.
13777 ;; This is only done if the function's epilogue is known to be simple.
13778 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13780 (define_expand "return"
13782 "ix86_can_use_return_insn_p ()"
13784 if (current_function_pops_args)
13786 rtx popc = GEN_INT (current_function_pops_args);
13787 emit_jump_insn (gen_return_pop_internal (popc));
13792 (define_insn "return_internal"
13796 [(set_attr "length" "1")
13797 (set_attr "length_immediate" "0")
13798 (set_attr "modrm" "0")])
13800 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13801 ;; instruction Athlon and K8 have.
13803 (define_insn "return_internal_long"
13805 (unspec [(const_int 0)] UNSPEC_REP)]
13808 [(set_attr "length" "1")
13809 (set_attr "length_immediate" "0")
13810 (set_attr "prefix_rep" "1")
13811 (set_attr "modrm" "0")])
13813 (define_insn "return_pop_internal"
13815 (use (match_operand:SI 0 "const_int_operand" ""))]
13818 [(set_attr "length" "3")
13819 (set_attr "length_immediate" "2")
13820 (set_attr "modrm" "0")])
13822 (define_insn "return_indirect_internal"
13824 (use (match_operand:SI 0 "register_operand" "r"))]
13827 [(set_attr "type" "ibr")
13828 (set_attr "length_immediate" "0")])
13834 [(set_attr "length" "1")
13835 (set_attr "length_immediate" "0")
13836 (set_attr "modrm" "0")])
13838 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13839 ;; branch prediction penalty for the third jump in a 16-byte
13842 (define_insn "align"
13843 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13846 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13847 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13849 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13850 The align insn is used to avoid 3 jump instructions in the row to improve
13851 branch prediction and the benefits hardly outweight the cost of extra 8
13852 nops on the average inserted by full alignment pseudo operation. */
13856 [(set_attr "length" "16")])
13858 (define_expand "prologue"
13861 "ix86_expand_prologue (); DONE;")
13863 (define_insn "set_got"
13864 [(set (match_operand:SI 0 "register_operand" "=r")
13865 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13866 (clobber (reg:CC FLAGS_REG))]
13868 { return output_set_got (operands[0], NULL_RTX); }
13869 [(set_attr "type" "multi")
13870 (set_attr "length" "12")])
13872 (define_insn "set_got_labelled"
13873 [(set (match_operand:SI 0 "register_operand" "=r")
13874 (unspec:SI [(label_ref (match_operand 1 "" ""))]
13876 (clobber (reg:CC FLAGS_REG))]
13878 { return output_set_got (operands[0], operands[1]); }
13879 [(set_attr "type" "multi")
13880 (set_attr "length" "12")])
13882 (define_insn "set_got_rex64"
13883 [(set (match_operand:DI 0 "register_operand" "=r")
13884 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13886 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13887 [(set_attr "type" "lea")
13888 (set_attr "length" "6")])
13890 (define_expand "epilogue"
13893 "ix86_expand_epilogue (1); DONE;")
13895 (define_expand "sibcall_epilogue"
13898 "ix86_expand_epilogue (0); DONE;")
13900 (define_expand "eh_return"
13901 [(use (match_operand 0 "register_operand" ""))]
13904 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13906 /* Tricky bit: we write the address of the handler to which we will
13907 be returning into someone else's stack frame, one word below the
13908 stack address we wish to restore. */
13909 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13910 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13911 tmp = gen_rtx_MEM (Pmode, tmp);
13912 emit_move_insn (tmp, ra);
13914 if (Pmode == SImode)
13915 emit_jump_insn (gen_eh_return_si (sa));
13917 emit_jump_insn (gen_eh_return_di (sa));
13922 (define_insn_and_split "eh_return_si"
13924 (unspec [(match_operand:SI 0 "register_operand" "c")]
13925 UNSPEC_EH_RETURN))]
13930 "ix86_expand_epilogue (2); DONE;")
13932 (define_insn_and_split "eh_return_di"
13934 (unspec [(match_operand:DI 0 "register_operand" "c")]
13935 UNSPEC_EH_RETURN))]
13940 "ix86_expand_epilogue (2); DONE;")
13942 (define_insn "leave"
13943 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13944 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13945 (clobber (mem:BLK (scratch)))]
13948 [(set_attr "type" "leave")])
13950 (define_insn "leave_rex64"
13951 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13952 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13953 (clobber (mem:BLK (scratch)))]
13956 [(set_attr "type" "leave")])
13958 (define_expand "ffssi2"
13960 [(set (match_operand:SI 0 "register_operand" "")
13961 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13962 (clobber (match_scratch:SI 2 ""))
13963 (clobber (reg:CC FLAGS_REG))])]
13967 (define_insn_and_split "*ffs_cmove"
13968 [(set (match_operand:SI 0 "register_operand" "=r")
13969 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13970 (clobber (match_scratch:SI 2 "=&r"))
13971 (clobber (reg:CC FLAGS_REG))]
13974 "&& reload_completed"
13975 [(set (match_dup 2) (const_int -1))
13976 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13977 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13978 (set (match_dup 0) (if_then_else:SI
13979 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13982 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13983 (clobber (reg:CC FLAGS_REG))])]
13986 (define_insn_and_split "*ffs_no_cmove"
13987 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13988 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13989 (clobber (match_scratch:SI 2 "=&q"))
13990 (clobber (reg:CC FLAGS_REG))]
13994 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13995 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13996 (set (strict_low_part (match_dup 3))
13997 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13998 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13999 (clobber (reg:CC FLAGS_REG))])
14000 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14001 (clobber (reg:CC FLAGS_REG))])
14002 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14003 (clobber (reg:CC FLAGS_REG))])]
14005 operands[3] = gen_lowpart (QImode, operands[2]);
14006 ix86_expand_clear (operands[2]);
14009 (define_insn "*ffssi_1"
14010 [(set (reg:CCZ FLAGS_REG)
14011 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14013 (set (match_operand:SI 0 "register_operand" "=r")
14014 (ctz:SI (match_dup 1)))]
14016 "bsf{l}\t{%1, %0|%0, %1}"
14017 [(set_attr "prefix_0f" "1")])
14019 (define_expand "ffsdi2"
14021 [(set (match_operand:DI 0 "register_operand" "")
14022 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14023 (clobber (match_scratch:DI 2 ""))
14024 (clobber (reg:CC FLAGS_REG))])]
14025 "TARGET_64BIT && TARGET_CMOVE"
14028 (define_insn_and_split "*ffs_rex64"
14029 [(set (match_operand:DI 0 "register_operand" "=r")
14030 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14031 (clobber (match_scratch:DI 2 "=&r"))
14032 (clobber (reg:CC FLAGS_REG))]
14033 "TARGET_64BIT && TARGET_CMOVE"
14035 "&& reload_completed"
14036 [(set (match_dup 2) (const_int -1))
14037 (parallel [(set (reg:CCZ FLAGS_REG)
14038 (compare:CCZ (match_dup 1) (const_int 0)))
14039 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14040 (set (match_dup 0) (if_then_else:DI
14041 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14044 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14045 (clobber (reg:CC FLAGS_REG))])]
14048 (define_insn "*ffsdi_1"
14049 [(set (reg:CCZ FLAGS_REG)
14050 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14052 (set (match_operand:DI 0 "register_operand" "=r")
14053 (ctz:DI (match_dup 1)))]
14055 "bsf{q}\t{%1, %0|%0, %1}"
14056 [(set_attr "prefix_0f" "1")])
14058 (define_insn "ctzsi2"
14059 [(set (match_operand:SI 0 "register_operand" "=r")
14060 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14061 (clobber (reg:CC FLAGS_REG))]
14063 "bsf{l}\t{%1, %0|%0, %1}"
14064 [(set_attr "prefix_0f" "1")])
14066 (define_insn "ctzdi2"
14067 [(set (match_operand:DI 0 "register_operand" "=r")
14068 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14069 (clobber (reg:CC FLAGS_REG))]
14071 "bsf{q}\t{%1, %0|%0, %1}"
14072 [(set_attr "prefix_0f" "1")])
14074 (define_expand "clzsi2"
14076 [(set (match_operand:SI 0 "register_operand" "")
14077 (minus:SI (const_int 31)
14078 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14079 (clobber (reg:CC FLAGS_REG))])
14081 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14082 (clobber (reg:CC FLAGS_REG))])]
14086 (define_insn "*bsr"
14087 [(set (match_operand:SI 0 "register_operand" "=r")
14088 (minus:SI (const_int 31)
14089 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14090 (clobber (reg:CC FLAGS_REG))]
14092 "bsr{l}\t{%1, %0|%0, %1}"
14093 [(set_attr "prefix_0f" "1")])
14095 (define_expand "clzdi2"
14097 [(set (match_operand:DI 0 "register_operand" "")
14098 (minus:DI (const_int 63)
14099 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14100 (clobber (reg:CC FLAGS_REG))])
14102 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14103 (clobber (reg:CC FLAGS_REG))])]
14107 (define_insn "*bsr_rex64"
14108 [(set (match_operand:DI 0 "register_operand" "=r")
14109 (minus:DI (const_int 63)
14110 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14111 (clobber (reg:CC FLAGS_REG))]
14113 "bsr{q}\t{%1, %0|%0, %1}"
14114 [(set_attr "prefix_0f" "1")])
14116 ;; Thread-local storage patterns for ELF.
14118 ;; Note that these code sequences must appear exactly as shown
14119 ;; in order to allow linker relaxation.
14121 (define_insn "*tls_global_dynamic_32_gnu"
14122 [(set (match_operand:SI 0 "register_operand" "=a")
14123 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14124 (match_operand:SI 2 "tls_symbolic_operand" "")
14125 (match_operand:SI 3 "call_insn_operand" "")]
14127 (clobber (match_scratch:SI 4 "=d"))
14128 (clobber (match_scratch:SI 5 "=c"))
14129 (clobber (reg:CC FLAGS_REG))]
14130 "!TARGET_64BIT && TARGET_GNU_TLS"
14131 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14132 [(set_attr "type" "multi")
14133 (set_attr "length" "12")])
14135 (define_insn "*tls_global_dynamic_32_sun"
14136 [(set (match_operand:SI 0 "register_operand" "=a")
14137 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14138 (match_operand:SI 2 "tls_symbolic_operand" "")
14139 (match_operand:SI 3 "call_insn_operand" "")]
14141 (clobber (match_scratch:SI 4 "=d"))
14142 (clobber (match_scratch:SI 5 "=c"))
14143 (clobber (reg:CC FLAGS_REG))]
14144 "!TARGET_64BIT && TARGET_SUN_TLS"
14145 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14146 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14147 [(set_attr "type" "multi")
14148 (set_attr "length" "14")])
14150 (define_expand "tls_global_dynamic_32"
14151 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14154 (match_operand:SI 1 "tls_symbolic_operand" "")
14157 (clobber (match_scratch:SI 4 ""))
14158 (clobber (match_scratch:SI 5 ""))
14159 (clobber (reg:CC FLAGS_REG))])]
14163 operands[2] = pic_offset_table_rtx;
14166 operands[2] = gen_reg_rtx (Pmode);
14167 emit_insn (gen_set_got (operands[2]));
14169 if (TARGET_GNU2_TLS)
14171 emit_insn (gen_tls_dynamic_gnu2_32
14172 (operands[0], operands[1], operands[2]));
14175 operands[3] = ix86_tls_get_addr ();
14178 (define_insn "*tls_global_dynamic_64"
14179 [(set (match_operand:DI 0 "register_operand" "=a")
14180 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14181 (match_operand:DI 3 "" "")))
14182 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14185 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14186 [(set_attr "type" "multi")
14187 (set_attr "length" "16")])
14189 (define_expand "tls_global_dynamic_64"
14190 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14191 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14192 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14196 if (TARGET_GNU2_TLS)
14198 emit_insn (gen_tls_dynamic_gnu2_64
14199 (operands[0], operands[1]));
14202 operands[2] = ix86_tls_get_addr ();
14205 (define_insn "*tls_local_dynamic_base_32_gnu"
14206 [(set (match_operand:SI 0 "register_operand" "=a")
14207 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14208 (match_operand:SI 2 "call_insn_operand" "")]
14209 UNSPEC_TLS_LD_BASE))
14210 (clobber (match_scratch:SI 3 "=d"))
14211 (clobber (match_scratch:SI 4 "=c"))
14212 (clobber (reg:CC FLAGS_REG))]
14213 "!TARGET_64BIT && TARGET_GNU_TLS"
14214 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14215 [(set_attr "type" "multi")
14216 (set_attr "length" "11")])
14218 (define_insn "*tls_local_dynamic_base_32_sun"
14219 [(set (match_operand:SI 0 "register_operand" "=a")
14220 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14221 (match_operand:SI 2 "call_insn_operand" "")]
14222 UNSPEC_TLS_LD_BASE))
14223 (clobber (match_scratch:SI 3 "=d"))
14224 (clobber (match_scratch:SI 4 "=c"))
14225 (clobber (reg:CC FLAGS_REG))]
14226 "!TARGET_64BIT && TARGET_SUN_TLS"
14227 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14228 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14229 [(set_attr "type" "multi")
14230 (set_attr "length" "13")])
14232 (define_expand "tls_local_dynamic_base_32"
14233 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14234 (unspec:SI [(match_dup 1) (match_dup 2)]
14235 UNSPEC_TLS_LD_BASE))
14236 (clobber (match_scratch:SI 3 ""))
14237 (clobber (match_scratch:SI 4 ""))
14238 (clobber (reg:CC FLAGS_REG))])]
14242 operands[1] = pic_offset_table_rtx;
14245 operands[1] = gen_reg_rtx (Pmode);
14246 emit_insn (gen_set_got (operands[1]));
14248 if (TARGET_GNU2_TLS)
14250 emit_insn (gen_tls_dynamic_gnu2_32
14251 (operands[0], ix86_tls_module_base (), operands[1]));
14254 operands[2] = ix86_tls_get_addr ();
14257 (define_insn "*tls_local_dynamic_base_64"
14258 [(set (match_operand:DI 0 "register_operand" "=a")
14259 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14260 (match_operand:DI 2 "" "")))
14261 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14263 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14264 [(set_attr "type" "multi")
14265 (set_attr "length" "12")])
14267 (define_expand "tls_local_dynamic_base_64"
14268 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14269 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14270 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14273 if (TARGET_GNU2_TLS)
14275 emit_insn (gen_tls_dynamic_gnu2_64
14276 (operands[0], ix86_tls_module_base ()));
14279 operands[1] = ix86_tls_get_addr ();
14282 ;; Local dynamic of a single variable is a lose. Show combine how
14283 ;; to convert that back to global dynamic.
14285 (define_insn_and_split "*tls_local_dynamic_32_once"
14286 [(set (match_operand:SI 0 "register_operand" "=a")
14287 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14288 (match_operand:SI 2 "call_insn_operand" "")]
14289 UNSPEC_TLS_LD_BASE)
14290 (const:SI (unspec:SI
14291 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14293 (clobber (match_scratch:SI 4 "=d"))
14294 (clobber (match_scratch:SI 5 "=c"))
14295 (clobber (reg:CC FLAGS_REG))]
14299 [(parallel [(set (match_dup 0)
14300 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14302 (clobber (match_dup 4))
14303 (clobber (match_dup 5))
14304 (clobber (reg:CC FLAGS_REG))])]
14307 ;; Load and add the thread base pointer from %gs:0.
14309 (define_insn "*load_tp_si"
14310 [(set (match_operand:SI 0 "register_operand" "=r")
14311 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14313 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14314 [(set_attr "type" "imov")
14315 (set_attr "modrm" "0")
14316 (set_attr "length" "7")
14317 (set_attr "memory" "load")
14318 (set_attr "imm_disp" "false")])
14320 (define_insn "*add_tp_si"
14321 [(set (match_operand:SI 0 "register_operand" "=r")
14322 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14323 (match_operand:SI 1 "register_operand" "0")))
14324 (clobber (reg:CC FLAGS_REG))]
14326 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14327 [(set_attr "type" "alu")
14328 (set_attr "modrm" "0")
14329 (set_attr "length" "7")
14330 (set_attr "memory" "load")
14331 (set_attr "imm_disp" "false")])
14333 (define_insn "*load_tp_di"
14334 [(set (match_operand:DI 0 "register_operand" "=r")
14335 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14337 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14338 [(set_attr "type" "imov")
14339 (set_attr "modrm" "0")
14340 (set_attr "length" "7")
14341 (set_attr "memory" "load")
14342 (set_attr "imm_disp" "false")])
14344 (define_insn "*add_tp_di"
14345 [(set (match_operand:DI 0 "register_operand" "=r")
14346 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14347 (match_operand:DI 1 "register_operand" "0")))
14348 (clobber (reg:CC FLAGS_REG))]
14350 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14351 [(set_attr "type" "alu")
14352 (set_attr "modrm" "0")
14353 (set_attr "length" "7")
14354 (set_attr "memory" "load")
14355 (set_attr "imm_disp" "false")])
14357 ;; GNU2 TLS patterns can be split.
14359 (define_expand "tls_dynamic_gnu2_32"
14360 [(set (match_dup 3)
14361 (plus:SI (match_operand:SI 2 "register_operand" "")
14363 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14366 [(set (match_operand:SI 0 "register_operand" "")
14367 (unspec:SI [(match_dup 1) (match_dup 3)
14368 (match_dup 2) (reg:SI SP_REG)]
14370 (clobber (reg:CC FLAGS_REG))])]
14371 "!TARGET_64BIT && TARGET_GNU2_TLS"
14373 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14374 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14377 (define_insn "*tls_dynamic_lea_32"
14378 [(set (match_operand:SI 0 "register_operand" "=r")
14379 (plus:SI (match_operand:SI 1 "register_operand" "b")
14381 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14382 UNSPEC_TLSDESC))))]
14383 "!TARGET_64BIT && TARGET_GNU2_TLS"
14384 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14385 [(set_attr "type" "lea")
14386 (set_attr "mode" "SI")
14387 (set_attr "length" "6")
14388 (set_attr "length_address" "4")])
14390 (define_insn "*tls_dynamic_call_32"
14391 [(set (match_operand:SI 0 "register_operand" "=a")
14392 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14393 (match_operand:SI 2 "register_operand" "0")
14394 ;; we have to make sure %ebx still points to the GOT
14395 (match_operand:SI 3 "register_operand" "b")
14398 (clobber (reg:CC FLAGS_REG))]
14399 "!TARGET_64BIT && TARGET_GNU2_TLS"
14400 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14401 [(set_attr "type" "call")
14402 (set_attr "length" "2")
14403 (set_attr "length_address" "0")])
14405 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14406 [(set (match_operand:SI 0 "register_operand" "=&a")
14408 (plus:SI (match_operand:SI 3 "tp_or_register_operand" "ir")
14409 (unspec:SI [(match_operand:SI 4 "tls_modbase_operand" "")
14410 (match_operand:SI 5 "" "")
14411 (match_operand:SI 2 "register_operand" "b")
14414 (const:SI (unspec:SI
14415 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14417 (clobber (reg:CC FLAGS_REG))]
14418 "!TARGET_64BIT && TARGET_GNU2_TLS"
14422 [(set (match_dup 0)
14423 (plus:SI (match_dup 3)
14425 (clobber (reg:CC FLAGS_REG))])]
14427 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14428 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14431 (define_expand "tls_dynamic_gnu2_64"
14432 [(set (match_dup 2)
14433 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14436 [(set (match_operand:DI 0 "register_operand" "")
14437 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14439 (clobber (reg:CC FLAGS_REG))])]
14440 "TARGET_64BIT && TARGET_GNU2_TLS"
14442 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14443 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14446 (define_insn "*tls_dynamic_lea_64"
14447 [(set (match_operand:DI 0 "register_operand" "=r")
14448 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14450 "TARGET_64BIT && TARGET_GNU2_TLS"
14451 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14452 [(set_attr "type" "lea")
14453 (set_attr "mode" "DI")
14454 (set_attr "length" "7")
14455 (set_attr "length_address" "4")])
14457 (define_insn "*tls_dynamic_call_64"
14458 [(set (match_operand:DI 0 "register_operand" "=a")
14459 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14460 (match_operand:DI 2 "register_operand" "0")
14463 (clobber (reg:CC FLAGS_REG))]
14464 "TARGET_64BIT && TARGET_GNU2_TLS"
14465 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14466 [(set_attr "type" "call")
14467 (set_attr "length" "2")
14468 (set_attr "length_address" "0")])
14470 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14471 [(set (match_operand:DI 0 "register_operand" "=&a")
14473 (plus:DI (match_operand:DI 2 "tp_or_register_operand" "ir")
14474 (unspec:DI [(match_operand:DI 3 "tls_modbase_operand" "")
14475 (match_operand:DI 4 "" "")
14478 (const:DI (unspec:DI
14479 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14481 (clobber (reg:CC FLAGS_REG))]
14482 "TARGET_64BIT && TARGET_GNU2_TLS"
14486 [(set (match_dup 0)
14487 (plus:DI (match_dup 2)
14489 (clobber (reg:CC FLAGS_REG))])]
14491 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14492 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14497 ;; These patterns match the binary 387 instructions for addM3, subM3,
14498 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14499 ;; SFmode. The first is the normal insn, the second the same insn but
14500 ;; with one operand a conversion, and the third the same insn but with
14501 ;; the other operand a conversion. The conversion may be SFmode or
14502 ;; SImode if the target mode DFmode, but only SImode if the target mode
14505 ;; Gcc is slightly more smart about handling normal two address instructions
14506 ;; so use special patterns for add and mull.
14508 (define_insn "*fop_sf_comm_mixed"
14509 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14510 (match_operator:SF 3 "binary_fp_operator"
14511 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14512 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14513 "TARGET_MIX_SSE_I387
14514 && COMMUTATIVE_ARITH_P (operands[3])
14515 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14516 "* return output_387_binary_op (insn, operands);"
14517 [(set (attr "type")
14518 (if_then_else (eq_attr "alternative" "1")
14519 (if_then_else (match_operand:SF 3 "mult_operator" "")
14520 (const_string "ssemul")
14521 (const_string "sseadd"))
14522 (if_then_else (match_operand:SF 3 "mult_operator" "")
14523 (const_string "fmul")
14524 (const_string "fop"))))
14525 (set_attr "mode" "SF")])
14527 (define_insn "*fop_sf_comm_sse"
14528 [(set (match_operand:SF 0 "register_operand" "=x")
14529 (match_operator:SF 3 "binary_fp_operator"
14530 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14531 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14533 && COMMUTATIVE_ARITH_P (operands[3])
14534 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14535 "* return output_387_binary_op (insn, operands);"
14536 [(set (attr "type")
14537 (if_then_else (match_operand:SF 3 "mult_operator" "")
14538 (const_string "ssemul")
14539 (const_string "sseadd")))
14540 (set_attr "mode" "SF")])
14542 (define_insn "*fop_sf_comm_i387"
14543 [(set (match_operand:SF 0 "register_operand" "=f")
14544 (match_operator:SF 3 "binary_fp_operator"
14545 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14546 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14548 && COMMUTATIVE_ARITH_P (operands[3])
14549 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14550 "* return output_387_binary_op (insn, operands);"
14551 [(set (attr "type")
14552 (if_then_else (match_operand:SF 3 "mult_operator" "")
14553 (const_string "fmul")
14554 (const_string "fop")))
14555 (set_attr "mode" "SF")])
14557 (define_insn "*fop_sf_1_mixed"
14558 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14559 (match_operator:SF 3 "binary_fp_operator"
14560 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14561 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14562 "TARGET_MIX_SSE_I387
14563 && !COMMUTATIVE_ARITH_P (operands[3])
14564 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14565 "* return output_387_binary_op (insn, operands);"
14566 [(set (attr "type")
14567 (cond [(and (eq_attr "alternative" "2")
14568 (match_operand:SF 3 "mult_operator" ""))
14569 (const_string "ssemul")
14570 (and (eq_attr "alternative" "2")
14571 (match_operand:SF 3 "div_operator" ""))
14572 (const_string "ssediv")
14573 (eq_attr "alternative" "2")
14574 (const_string "sseadd")
14575 (match_operand:SF 3 "mult_operator" "")
14576 (const_string "fmul")
14577 (match_operand:SF 3 "div_operator" "")
14578 (const_string "fdiv")
14580 (const_string "fop")))
14581 (set_attr "mode" "SF")])
14583 (define_insn "*fop_sf_1_sse"
14584 [(set (match_operand:SF 0 "register_operand" "=x")
14585 (match_operator:SF 3 "binary_fp_operator"
14586 [(match_operand:SF 1 "register_operand" "0")
14587 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14589 && !COMMUTATIVE_ARITH_P (operands[3])"
14590 "* return output_387_binary_op (insn, operands);"
14591 [(set (attr "type")
14592 (cond [(match_operand:SF 3 "mult_operator" "")
14593 (const_string "ssemul")
14594 (match_operand:SF 3 "div_operator" "")
14595 (const_string "ssediv")
14597 (const_string "sseadd")))
14598 (set_attr "mode" "SF")])
14600 ;; This pattern is not fully shadowed by the pattern above.
14601 (define_insn "*fop_sf_1_i387"
14602 [(set (match_operand:SF 0 "register_operand" "=f,f")
14603 (match_operator:SF 3 "binary_fp_operator"
14604 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14605 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14606 "TARGET_80387 && !TARGET_SSE_MATH
14607 && !COMMUTATIVE_ARITH_P (operands[3])
14608 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14609 "* return output_387_binary_op (insn, operands);"
14610 [(set (attr "type")
14611 (cond [(match_operand:SF 3 "mult_operator" "")
14612 (const_string "fmul")
14613 (match_operand:SF 3 "div_operator" "")
14614 (const_string "fdiv")
14616 (const_string "fop")))
14617 (set_attr "mode" "SF")])
14619 ;; ??? Add SSE splitters for these!
14620 (define_insn "*fop_sf_2<mode>_i387"
14621 [(set (match_operand:SF 0 "register_operand" "=f,f")
14622 (match_operator:SF 3 "binary_fp_operator"
14623 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14624 (match_operand:SF 2 "register_operand" "0,0")]))]
14625 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14626 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14627 [(set (attr "type")
14628 (cond [(match_operand:SF 3 "mult_operator" "")
14629 (const_string "fmul")
14630 (match_operand:SF 3 "div_operator" "")
14631 (const_string "fdiv")
14633 (const_string "fop")))
14634 (set_attr "fp_int_src" "true")
14635 (set_attr "mode" "<MODE>")])
14637 (define_insn "*fop_sf_3<mode>_i387"
14638 [(set (match_operand:SF 0 "register_operand" "=f,f")
14639 (match_operator:SF 3 "binary_fp_operator"
14640 [(match_operand:SF 1 "register_operand" "0,0")
14641 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14642 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14643 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14644 [(set (attr "type")
14645 (cond [(match_operand:SF 3 "mult_operator" "")
14646 (const_string "fmul")
14647 (match_operand:SF 3 "div_operator" "")
14648 (const_string "fdiv")
14650 (const_string "fop")))
14651 (set_attr "fp_int_src" "true")
14652 (set_attr "mode" "<MODE>")])
14654 (define_insn "*fop_df_comm_mixed"
14655 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14656 (match_operator:DF 3 "binary_fp_operator"
14657 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14658 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14659 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14660 && COMMUTATIVE_ARITH_P (operands[3])
14661 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14662 "* return output_387_binary_op (insn, operands);"
14663 [(set (attr "type")
14664 (if_then_else (eq_attr "alternative" "1")
14665 (if_then_else (match_operand:SF 3 "mult_operator" "")
14666 (const_string "ssemul")
14667 (const_string "sseadd"))
14668 (if_then_else (match_operand:SF 3 "mult_operator" "")
14669 (const_string "fmul")
14670 (const_string "fop"))))
14671 (set_attr "mode" "DF")])
14673 (define_insn "*fop_df_comm_sse"
14674 [(set (match_operand:DF 0 "register_operand" "=Y")
14675 (match_operator:DF 3 "binary_fp_operator"
14676 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14677 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14678 "TARGET_SSE2 && TARGET_SSE_MATH
14679 && COMMUTATIVE_ARITH_P (operands[3])
14680 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14681 "* return output_387_binary_op (insn, operands);"
14682 [(set (attr "type")
14683 (if_then_else (match_operand:SF 3 "mult_operator" "")
14684 (const_string "ssemul")
14685 (const_string "sseadd")))
14686 (set_attr "mode" "DF")])
14688 (define_insn "*fop_df_comm_i387"
14689 [(set (match_operand:DF 0 "register_operand" "=f")
14690 (match_operator:DF 3 "binary_fp_operator"
14691 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14692 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14694 && COMMUTATIVE_ARITH_P (operands[3])
14695 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14696 "* return output_387_binary_op (insn, operands);"
14697 [(set (attr "type")
14698 (if_then_else (match_operand:SF 3 "mult_operator" "")
14699 (const_string "fmul")
14700 (const_string "fop")))
14701 (set_attr "mode" "DF")])
14703 (define_insn "*fop_df_1_mixed"
14704 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14705 (match_operator:DF 3 "binary_fp_operator"
14706 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14707 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14708 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14709 && !COMMUTATIVE_ARITH_P (operands[3])
14710 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14711 "* return output_387_binary_op (insn, operands);"
14712 [(set (attr "type")
14713 (cond [(and (eq_attr "alternative" "2")
14714 (match_operand:SF 3 "mult_operator" ""))
14715 (const_string "ssemul")
14716 (and (eq_attr "alternative" "2")
14717 (match_operand:SF 3 "div_operator" ""))
14718 (const_string "ssediv")
14719 (eq_attr "alternative" "2")
14720 (const_string "sseadd")
14721 (match_operand:DF 3 "mult_operator" "")
14722 (const_string "fmul")
14723 (match_operand:DF 3 "div_operator" "")
14724 (const_string "fdiv")
14726 (const_string "fop")))
14727 (set_attr "mode" "DF")])
14729 (define_insn "*fop_df_1_sse"
14730 [(set (match_operand:DF 0 "register_operand" "=Y")
14731 (match_operator:DF 3 "binary_fp_operator"
14732 [(match_operand:DF 1 "register_operand" "0")
14733 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14734 "TARGET_SSE2 && TARGET_SSE_MATH
14735 && !COMMUTATIVE_ARITH_P (operands[3])"
14736 "* return output_387_binary_op (insn, operands);"
14737 [(set_attr "mode" "DF")
14739 (cond [(match_operand:SF 3 "mult_operator" "")
14740 (const_string "ssemul")
14741 (match_operand:SF 3 "div_operator" "")
14742 (const_string "ssediv")
14744 (const_string "sseadd")))])
14746 ;; This pattern is not fully shadowed by the pattern above.
14747 (define_insn "*fop_df_1_i387"
14748 [(set (match_operand:DF 0 "register_operand" "=f,f")
14749 (match_operator:DF 3 "binary_fp_operator"
14750 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14751 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14752 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14753 && !COMMUTATIVE_ARITH_P (operands[3])
14754 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14755 "* return output_387_binary_op (insn, operands);"
14756 [(set (attr "type")
14757 (cond [(match_operand:DF 3 "mult_operator" "")
14758 (const_string "fmul")
14759 (match_operand:DF 3 "div_operator" "")
14760 (const_string "fdiv")
14762 (const_string "fop")))
14763 (set_attr "mode" "DF")])
14765 ;; ??? Add SSE splitters for these!
14766 (define_insn "*fop_df_2<mode>_i387"
14767 [(set (match_operand:DF 0 "register_operand" "=f,f")
14768 (match_operator:DF 3 "binary_fp_operator"
14769 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14770 (match_operand:DF 2 "register_operand" "0,0")]))]
14771 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14772 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14773 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14774 [(set (attr "type")
14775 (cond [(match_operand:DF 3 "mult_operator" "")
14776 (const_string "fmul")
14777 (match_operand:DF 3 "div_operator" "")
14778 (const_string "fdiv")
14780 (const_string "fop")))
14781 (set_attr "fp_int_src" "true")
14782 (set_attr "mode" "<MODE>")])
14784 (define_insn "*fop_df_3<mode>_i387"
14785 [(set (match_operand:DF 0 "register_operand" "=f,f")
14786 (match_operator:DF 3 "binary_fp_operator"
14787 [(match_operand:DF 1 "register_operand" "0,0")
14788 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14789 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14790 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14791 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14792 [(set (attr "type")
14793 (cond [(match_operand:DF 3 "mult_operator" "")
14794 (const_string "fmul")
14795 (match_operand:DF 3 "div_operator" "")
14796 (const_string "fdiv")
14798 (const_string "fop")))
14799 (set_attr "fp_int_src" "true")
14800 (set_attr "mode" "<MODE>")])
14802 (define_insn "*fop_df_4_i387"
14803 [(set (match_operand:DF 0 "register_operand" "=f,f")
14804 (match_operator:DF 3 "binary_fp_operator"
14805 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14806 (match_operand:DF 2 "register_operand" "0,f")]))]
14807 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14808 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14809 "* return output_387_binary_op (insn, operands);"
14810 [(set (attr "type")
14811 (cond [(match_operand:DF 3 "mult_operator" "")
14812 (const_string "fmul")
14813 (match_operand:DF 3 "div_operator" "")
14814 (const_string "fdiv")
14816 (const_string "fop")))
14817 (set_attr "mode" "SF")])
14819 (define_insn "*fop_df_5_i387"
14820 [(set (match_operand:DF 0 "register_operand" "=f,f")
14821 (match_operator:DF 3 "binary_fp_operator"
14822 [(match_operand:DF 1 "register_operand" "0,f")
14824 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14825 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14826 "* return output_387_binary_op (insn, operands);"
14827 [(set (attr "type")
14828 (cond [(match_operand:DF 3 "mult_operator" "")
14829 (const_string "fmul")
14830 (match_operand:DF 3 "div_operator" "")
14831 (const_string "fdiv")
14833 (const_string "fop")))
14834 (set_attr "mode" "SF")])
14836 (define_insn "*fop_df_6_i387"
14837 [(set (match_operand:DF 0 "register_operand" "=f,f")
14838 (match_operator:DF 3 "binary_fp_operator"
14840 (match_operand:SF 1 "register_operand" "0,f"))
14842 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14843 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14844 "* return output_387_binary_op (insn, operands);"
14845 [(set (attr "type")
14846 (cond [(match_operand:DF 3 "mult_operator" "")
14847 (const_string "fmul")
14848 (match_operand:DF 3 "div_operator" "")
14849 (const_string "fdiv")
14851 (const_string "fop")))
14852 (set_attr "mode" "SF")])
14854 (define_insn "*fop_xf_comm_i387"
14855 [(set (match_operand:XF 0 "register_operand" "=f")
14856 (match_operator:XF 3 "binary_fp_operator"
14857 [(match_operand:XF 1 "register_operand" "%0")
14858 (match_operand:XF 2 "register_operand" "f")]))]
14860 && COMMUTATIVE_ARITH_P (operands[3])"
14861 "* return output_387_binary_op (insn, operands);"
14862 [(set (attr "type")
14863 (if_then_else (match_operand:XF 3 "mult_operator" "")
14864 (const_string "fmul")
14865 (const_string "fop")))
14866 (set_attr "mode" "XF")])
14868 (define_insn "*fop_xf_1_i387"
14869 [(set (match_operand:XF 0 "register_operand" "=f,f")
14870 (match_operator:XF 3 "binary_fp_operator"
14871 [(match_operand:XF 1 "register_operand" "0,f")
14872 (match_operand:XF 2 "register_operand" "f,0")]))]
14874 && !COMMUTATIVE_ARITH_P (operands[3])"
14875 "* return output_387_binary_op (insn, operands);"
14876 [(set (attr "type")
14877 (cond [(match_operand:XF 3 "mult_operator" "")
14878 (const_string "fmul")
14879 (match_operand:XF 3 "div_operator" "")
14880 (const_string "fdiv")
14882 (const_string "fop")))
14883 (set_attr "mode" "XF")])
14885 (define_insn "*fop_xf_2<mode>_i387"
14886 [(set (match_operand:XF 0 "register_operand" "=f,f")
14887 (match_operator:XF 3 "binary_fp_operator"
14888 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14889 (match_operand:XF 2 "register_operand" "0,0")]))]
14890 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14891 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14892 [(set (attr "type")
14893 (cond [(match_operand:XF 3 "mult_operator" "")
14894 (const_string "fmul")
14895 (match_operand:XF 3 "div_operator" "")
14896 (const_string "fdiv")
14898 (const_string "fop")))
14899 (set_attr "fp_int_src" "true")
14900 (set_attr "mode" "<MODE>")])
14902 (define_insn "*fop_xf_3<mode>_i387"
14903 [(set (match_operand:XF 0 "register_operand" "=f,f")
14904 (match_operator:XF 3 "binary_fp_operator"
14905 [(match_operand:XF 1 "register_operand" "0,0")
14906 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14907 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14908 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14909 [(set (attr "type")
14910 (cond [(match_operand:XF 3 "mult_operator" "")
14911 (const_string "fmul")
14912 (match_operand:XF 3 "div_operator" "")
14913 (const_string "fdiv")
14915 (const_string "fop")))
14916 (set_attr "fp_int_src" "true")
14917 (set_attr "mode" "<MODE>")])
14919 (define_insn "*fop_xf_4_i387"
14920 [(set (match_operand:XF 0 "register_operand" "=f,f")
14921 (match_operator:XF 3 "binary_fp_operator"
14922 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14923 (match_operand:XF 2 "register_operand" "0,f")]))]
14925 "* return output_387_binary_op (insn, operands);"
14926 [(set (attr "type")
14927 (cond [(match_operand:XF 3 "mult_operator" "")
14928 (const_string "fmul")
14929 (match_operand:XF 3 "div_operator" "")
14930 (const_string "fdiv")
14932 (const_string "fop")))
14933 (set_attr "mode" "SF")])
14935 (define_insn "*fop_xf_5_i387"
14936 [(set (match_operand:XF 0 "register_operand" "=f,f")
14937 (match_operator:XF 3 "binary_fp_operator"
14938 [(match_operand:XF 1 "register_operand" "0,f")
14940 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14942 "* return output_387_binary_op (insn, operands);"
14943 [(set (attr "type")
14944 (cond [(match_operand:XF 3 "mult_operator" "")
14945 (const_string "fmul")
14946 (match_operand:XF 3 "div_operator" "")
14947 (const_string "fdiv")
14949 (const_string "fop")))
14950 (set_attr "mode" "SF")])
14952 (define_insn "*fop_xf_6_i387"
14953 [(set (match_operand:XF 0 "register_operand" "=f,f")
14954 (match_operator:XF 3 "binary_fp_operator"
14956 (match_operand 1 "register_operand" "0,f"))
14958 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14960 "* return output_387_binary_op (insn, operands);"
14961 [(set (attr "type")
14962 (cond [(match_operand:XF 3 "mult_operator" "")
14963 (const_string "fmul")
14964 (match_operand:XF 3 "div_operator" "")
14965 (const_string "fdiv")
14967 (const_string "fop")))
14968 (set_attr "mode" "SF")])
14971 [(set (match_operand 0 "register_operand" "")
14972 (match_operator 3 "binary_fp_operator"
14973 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14974 (match_operand 2 "register_operand" "")]))]
14975 "TARGET_80387 && reload_completed
14976 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14979 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14980 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14981 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14982 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14983 GET_MODE (operands[3]),
14986 ix86_free_from_memory (GET_MODE (operands[1]));
14991 [(set (match_operand 0 "register_operand" "")
14992 (match_operator 3 "binary_fp_operator"
14993 [(match_operand 1 "register_operand" "")
14994 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14995 "TARGET_80387 && reload_completed
14996 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14999 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15000 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15001 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15002 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15003 GET_MODE (operands[3]),
15006 ix86_free_from_memory (GET_MODE (operands[2]));
15010 ;; FPU special functions.
15012 (define_expand "sqrtsf2"
15013 [(set (match_operand:SF 0 "register_operand" "")
15014 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15015 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15017 if (!TARGET_SSE_MATH)
15018 operands[1] = force_reg (SFmode, operands[1]);
15021 (define_insn "*sqrtsf2_mixed"
15022 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15023 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15024 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15027 sqrtss\t{%1, %0|%0, %1}"
15028 [(set_attr "type" "fpspc,sse")
15029 (set_attr "mode" "SF,SF")
15030 (set_attr "athlon_decode" "direct,*")])
15032 (define_insn "*sqrtsf2_sse"
15033 [(set (match_operand:SF 0 "register_operand" "=x")
15034 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15036 "sqrtss\t{%1, %0|%0, %1}"
15037 [(set_attr "type" "sse")
15038 (set_attr "mode" "SF")
15039 (set_attr "athlon_decode" "*")])
15041 (define_insn "*sqrtsf2_i387"
15042 [(set (match_operand:SF 0 "register_operand" "=f")
15043 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15044 "TARGET_USE_FANCY_MATH_387"
15046 [(set_attr "type" "fpspc")
15047 (set_attr "mode" "SF")
15048 (set_attr "athlon_decode" "direct")])
15050 (define_expand "sqrtdf2"
15051 [(set (match_operand:DF 0 "register_operand" "")
15052 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15053 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15055 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15056 operands[1] = force_reg (DFmode, operands[1]);
15059 (define_insn "*sqrtdf2_mixed"
15060 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15061 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15062 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15065 sqrtsd\t{%1, %0|%0, %1}"
15066 [(set_attr "type" "fpspc,sse")
15067 (set_attr "mode" "DF,DF")
15068 (set_attr "athlon_decode" "direct,*")])
15070 (define_insn "*sqrtdf2_sse"
15071 [(set (match_operand:DF 0 "register_operand" "=Y")
15072 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15073 "TARGET_SSE2 && TARGET_SSE_MATH"
15074 "sqrtsd\t{%1, %0|%0, %1}"
15075 [(set_attr "type" "sse")
15076 (set_attr "mode" "DF")
15077 (set_attr "athlon_decode" "*")])
15079 (define_insn "*sqrtdf2_i387"
15080 [(set (match_operand:DF 0 "register_operand" "=f")
15081 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15082 "TARGET_USE_FANCY_MATH_387"
15084 [(set_attr "type" "fpspc")
15085 (set_attr "mode" "DF")
15086 (set_attr "athlon_decode" "direct")])
15088 (define_insn "*sqrtextendsfdf2_i387"
15089 [(set (match_operand:DF 0 "register_operand" "=f")
15090 (sqrt:DF (float_extend:DF
15091 (match_operand:SF 1 "register_operand" "0"))))]
15092 "TARGET_USE_FANCY_MATH_387
15093 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15095 [(set_attr "type" "fpspc")
15096 (set_attr "mode" "DF")
15097 (set_attr "athlon_decode" "direct")])
15099 (define_insn "sqrtxf2"
15100 [(set (match_operand:XF 0 "register_operand" "=f")
15101 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15102 "TARGET_USE_FANCY_MATH_387
15103 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15105 [(set_attr "type" "fpspc")
15106 (set_attr "mode" "XF")
15107 (set_attr "athlon_decode" "direct")])
15109 (define_insn "*sqrtextendsfxf2_i387"
15110 [(set (match_operand:XF 0 "register_operand" "=f")
15111 (sqrt:XF (float_extend:XF
15112 (match_operand:SF 1 "register_operand" "0"))))]
15113 "TARGET_USE_FANCY_MATH_387"
15115 [(set_attr "type" "fpspc")
15116 (set_attr "mode" "XF")
15117 (set_attr "athlon_decode" "direct")])
15119 (define_insn "*sqrtextenddfxf2_i387"
15120 [(set (match_operand:XF 0 "register_operand" "=f")
15121 (sqrt:XF (float_extend:XF
15122 (match_operand:DF 1 "register_operand" "0"))))]
15123 "TARGET_USE_FANCY_MATH_387"
15125 [(set_attr "type" "fpspc")
15126 (set_attr "mode" "XF")
15127 (set_attr "athlon_decode" "direct")])
15129 (define_insn "fpremxf4"
15130 [(set (match_operand:XF 0 "register_operand" "=f")
15131 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15132 (match_operand:XF 3 "register_operand" "1")]
15134 (set (match_operand:XF 1 "register_operand" "=u")
15135 (unspec:XF [(match_dup 2) (match_dup 3)]
15137 (set (reg:CCFP FPSR_REG)
15138 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15139 "TARGET_USE_FANCY_MATH_387
15140 && flag_unsafe_math_optimizations"
15142 [(set_attr "type" "fpspc")
15143 (set_attr "mode" "XF")])
15145 (define_expand "fmodsf3"
15146 [(use (match_operand:SF 0 "register_operand" ""))
15147 (use (match_operand:SF 1 "register_operand" ""))
15148 (use (match_operand:SF 2 "register_operand" ""))]
15149 "TARGET_USE_FANCY_MATH_387
15150 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15151 && flag_unsafe_math_optimizations"
15153 rtx label = gen_label_rtx ();
15155 rtx op1 = gen_reg_rtx (XFmode);
15156 rtx op2 = gen_reg_rtx (XFmode);
15158 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15159 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15161 emit_label (label);
15163 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15164 ix86_emit_fp_unordered_jump (label);
15166 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15170 (define_expand "fmoddf3"
15171 [(use (match_operand:DF 0 "register_operand" ""))
15172 (use (match_operand:DF 1 "register_operand" ""))
15173 (use (match_operand:DF 2 "register_operand" ""))]
15174 "TARGET_USE_FANCY_MATH_387
15175 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15176 && flag_unsafe_math_optimizations"
15178 rtx label = gen_label_rtx ();
15180 rtx op1 = gen_reg_rtx (XFmode);
15181 rtx op2 = gen_reg_rtx (XFmode);
15183 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15184 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15186 emit_label (label);
15188 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15189 ix86_emit_fp_unordered_jump (label);
15191 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15195 (define_expand "fmodxf3"
15196 [(use (match_operand:XF 0 "register_operand" ""))
15197 (use (match_operand:XF 1 "register_operand" ""))
15198 (use (match_operand:XF 2 "register_operand" ""))]
15199 "TARGET_USE_FANCY_MATH_387
15200 && flag_unsafe_math_optimizations"
15202 rtx label = gen_label_rtx ();
15204 emit_label (label);
15206 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15207 operands[1], operands[2]));
15208 ix86_emit_fp_unordered_jump (label);
15210 emit_move_insn (operands[0], operands[1]);
15214 (define_insn "fprem1xf4"
15215 [(set (match_operand:XF 0 "register_operand" "=f")
15216 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15217 (match_operand:XF 3 "register_operand" "1")]
15219 (set (match_operand:XF 1 "register_operand" "=u")
15220 (unspec:XF [(match_dup 2) (match_dup 3)]
15222 (set (reg:CCFP FPSR_REG)
15223 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15224 "TARGET_USE_FANCY_MATH_387
15225 && flag_unsafe_math_optimizations"
15227 [(set_attr "type" "fpspc")
15228 (set_attr "mode" "XF")])
15230 (define_expand "dremsf3"
15231 [(use (match_operand:SF 0 "register_operand" ""))
15232 (use (match_operand:SF 1 "register_operand" ""))
15233 (use (match_operand:SF 2 "register_operand" ""))]
15234 "TARGET_USE_FANCY_MATH_387
15235 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15236 && flag_unsafe_math_optimizations"
15238 rtx label = gen_label_rtx ();
15240 rtx op1 = gen_reg_rtx (XFmode);
15241 rtx op2 = gen_reg_rtx (XFmode);
15243 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15244 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15246 emit_label (label);
15248 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15249 ix86_emit_fp_unordered_jump (label);
15251 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15255 (define_expand "dremdf3"
15256 [(use (match_operand:DF 0 "register_operand" ""))
15257 (use (match_operand:DF 1 "register_operand" ""))
15258 (use (match_operand:DF 2 "register_operand" ""))]
15259 "TARGET_USE_FANCY_MATH_387
15260 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15261 && flag_unsafe_math_optimizations"
15263 rtx label = gen_label_rtx ();
15265 rtx op1 = gen_reg_rtx (XFmode);
15266 rtx op2 = gen_reg_rtx (XFmode);
15268 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15269 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15271 emit_label (label);
15273 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15274 ix86_emit_fp_unordered_jump (label);
15276 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15280 (define_expand "dremxf3"
15281 [(use (match_operand:XF 0 "register_operand" ""))
15282 (use (match_operand:XF 1 "register_operand" ""))
15283 (use (match_operand:XF 2 "register_operand" ""))]
15284 "TARGET_USE_FANCY_MATH_387
15285 && flag_unsafe_math_optimizations"
15287 rtx label = gen_label_rtx ();
15289 emit_label (label);
15291 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15292 operands[1], operands[2]));
15293 ix86_emit_fp_unordered_jump (label);
15295 emit_move_insn (operands[0], operands[1]);
15299 (define_insn "*sindf2"
15300 [(set (match_operand:DF 0 "register_operand" "=f")
15301 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15302 "TARGET_USE_FANCY_MATH_387
15303 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15304 && flag_unsafe_math_optimizations"
15306 [(set_attr "type" "fpspc")
15307 (set_attr "mode" "DF")])
15309 (define_insn "*sinsf2"
15310 [(set (match_operand:SF 0 "register_operand" "=f")
15311 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15312 "TARGET_USE_FANCY_MATH_387
15313 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15314 && flag_unsafe_math_optimizations"
15316 [(set_attr "type" "fpspc")
15317 (set_attr "mode" "SF")])
15319 (define_insn "*sinextendsfdf2"
15320 [(set (match_operand:DF 0 "register_operand" "=f")
15321 (unspec:DF [(float_extend:DF
15322 (match_operand:SF 1 "register_operand" "0"))]
15324 "TARGET_USE_FANCY_MATH_387
15325 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15326 && flag_unsafe_math_optimizations"
15328 [(set_attr "type" "fpspc")
15329 (set_attr "mode" "DF")])
15331 (define_insn "*sinxf2"
15332 [(set (match_operand:XF 0 "register_operand" "=f")
15333 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15334 "TARGET_USE_FANCY_MATH_387
15335 && flag_unsafe_math_optimizations"
15337 [(set_attr "type" "fpspc")
15338 (set_attr "mode" "XF")])
15340 (define_insn "*cosdf2"
15341 [(set (match_operand:DF 0 "register_operand" "=f")
15342 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15343 "TARGET_USE_FANCY_MATH_387
15344 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15345 && flag_unsafe_math_optimizations"
15347 [(set_attr "type" "fpspc")
15348 (set_attr "mode" "DF")])
15350 (define_insn "*cossf2"
15351 [(set (match_operand:SF 0 "register_operand" "=f")
15352 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15353 "TARGET_USE_FANCY_MATH_387
15354 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15355 && flag_unsafe_math_optimizations"
15357 [(set_attr "type" "fpspc")
15358 (set_attr "mode" "SF")])
15360 (define_insn "*cosextendsfdf2"
15361 [(set (match_operand:DF 0 "register_operand" "=f")
15362 (unspec:DF [(float_extend:DF
15363 (match_operand:SF 1 "register_operand" "0"))]
15365 "TARGET_USE_FANCY_MATH_387
15366 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15367 && flag_unsafe_math_optimizations"
15369 [(set_attr "type" "fpspc")
15370 (set_attr "mode" "DF")])
15372 (define_insn "*cosxf2"
15373 [(set (match_operand:XF 0 "register_operand" "=f")
15374 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15375 "TARGET_USE_FANCY_MATH_387
15376 && flag_unsafe_math_optimizations"
15378 [(set_attr "type" "fpspc")
15379 (set_attr "mode" "XF")])
15381 ;; With sincos pattern defined, sin and cos builtin function will be
15382 ;; expanded to sincos pattern with one of its outputs left unused.
15383 ;; Cse pass will detected, if two sincos patterns can be combined,
15384 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15385 ;; depending on the unused output.
15387 (define_insn "sincosdf3"
15388 [(set (match_operand:DF 0 "register_operand" "=f")
15389 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15390 UNSPEC_SINCOS_COS))
15391 (set (match_operand:DF 1 "register_operand" "=u")
15392 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15393 "TARGET_USE_FANCY_MATH_387
15394 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15395 && flag_unsafe_math_optimizations"
15397 [(set_attr "type" "fpspc")
15398 (set_attr "mode" "DF")])
15401 [(set (match_operand:DF 0 "register_operand" "")
15402 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15403 UNSPEC_SINCOS_COS))
15404 (set (match_operand:DF 1 "register_operand" "")
15405 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15406 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15407 && !reload_completed && !reload_in_progress"
15408 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15412 [(set (match_operand:DF 0 "register_operand" "")
15413 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15414 UNSPEC_SINCOS_COS))
15415 (set (match_operand:DF 1 "register_operand" "")
15416 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15417 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15418 && !reload_completed && !reload_in_progress"
15419 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15422 (define_insn "sincossf3"
15423 [(set (match_operand:SF 0 "register_operand" "=f")
15424 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15425 UNSPEC_SINCOS_COS))
15426 (set (match_operand:SF 1 "register_operand" "=u")
15427 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15428 "TARGET_USE_FANCY_MATH_387
15429 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15430 && flag_unsafe_math_optimizations"
15432 [(set_attr "type" "fpspc")
15433 (set_attr "mode" "SF")])
15436 [(set (match_operand:SF 0 "register_operand" "")
15437 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15438 UNSPEC_SINCOS_COS))
15439 (set (match_operand:SF 1 "register_operand" "")
15440 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15441 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15442 && !reload_completed && !reload_in_progress"
15443 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15447 [(set (match_operand:SF 0 "register_operand" "")
15448 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15449 UNSPEC_SINCOS_COS))
15450 (set (match_operand:SF 1 "register_operand" "")
15451 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15452 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15453 && !reload_completed && !reload_in_progress"
15454 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15457 (define_insn "*sincosextendsfdf3"
15458 [(set (match_operand:DF 0 "register_operand" "=f")
15459 (unspec:DF [(float_extend:DF
15460 (match_operand:SF 2 "register_operand" "0"))]
15461 UNSPEC_SINCOS_COS))
15462 (set (match_operand:DF 1 "register_operand" "=u")
15463 (unspec:DF [(float_extend:DF
15464 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15465 "TARGET_USE_FANCY_MATH_387
15466 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15467 && flag_unsafe_math_optimizations"
15469 [(set_attr "type" "fpspc")
15470 (set_attr "mode" "DF")])
15473 [(set (match_operand:DF 0 "register_operand" "")
15474 (unspec:DF [(float_extend:DF
15475 (match_operand:SF 2 "register_operand" ""))]
15476 UNSPEC_SINCOS_COS))
15477 (set (match_operand:DF 1 "register_operand" "")
15478 (unspec:DF [(float_extend:DF
15479 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15480 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15481 && !reload_completed && !reload_in_progress"
15482 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15483 (match_dup 2))] UNSPEC_SIN))]
15487 [(set (match_operand:DF 0 "register_operand" "")
15488 (unspec:DF [(float_extend:DF
15489 (match_operand:SF 2 "register_operand" ""))]
15490 UNSPEC_SINCOS_COS))
15491 (set (match_operand:DF 1 "register_operand" "")
15492 (unspec:DF [(float_extend:DF
15493 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15494 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15495 && !reload_completed && !reload_in_progress"
15496 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15497 (match_dup 2))] UNSPEC_COS))]
15500 (define_insn "sincosxf3"
15501 [(set (match_operand:XF 0 "register_operand" "=f")
15502 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15503 UNSPEC_SINCOS_COS))
15504 (set (match_operand:XF 1 "register_operand" "=u")
15505 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15506 "TARGET_USE_FANCY_MATH_387
15507 && flag_unsafe_math_optimizations"
15509 [(set_attr "type" "fpspc")
15510 (set_attr "mode" "XF")])
15513 [(set (match_operand:XF 0 "register_operand" "")
15514 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15515 UNSPEC_SINCOS_COS))
15516 (set (match_operand:XF 1 "register_operand" "")
15517 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15518 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15519 && !reload_completed && !reload_in_progress"
15520 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15524 [(set (match_operand:XF 0 "register_operand" "")
15525 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15526 UNSPEC_SINCOS_COS))
15527 (set (match_operand:XF 1 "register_operand" "")
15528 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15529 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15530 && !reload_completed && !reload_in_progress"
15531 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15534 (define_insn "*tandf3_1"
15535 [(set (match_operand:DF 0 "register_operand" "=f")
15536 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15538 (set (match_operand:DF 1 "register_operand" "=u")
15539 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15540 "TARGET_USE_FANCY_MATH_387
15541 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15542 && flag_unsafe_math_optimizations"
15544 [(set_attr "type" "fpspc")
15545 (set_attr "mode" "DF")])
15547 ;; optimize sequence: fptan
15550 ;; into fptan insn.
15553 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15554 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15556 (set (match_operand:DF 1 "register_operand" "")
15557 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15559 (match_operand:DF 3 "immediate_operand" ""))]
15560 "standard_80387_constant_p (operands[3]) == 2"
15561 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15562 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15565 (define_expand "tandf2"
15566 [(parallel [(set (match_dup 2)
15567 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15569 (set (match_operand:DF 0 "register_operand" "")
15570 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15571 "TARGET_USE_FANCY_MATH_387
15572 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15573 && flag_unsafe_math_optimizations"
15575 operands[2] = gen_reg_rtx (DFmode);
15578 (define_insn "*tansf3_1"
15579 [(set (match_operand:SF 0 "register_operand" "=f")
15580 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15582 (set (match_operand:SF 1 "register_operand" "=u")
15583 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15584 "TARGET_USE_FANCY_MATH_387
15585 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15586 && flag_unsafe_math_optimizations"
15588 [(set_attr "type" "fpspc")
15589 (set_attr "mode" "SF")])
15591 ;; optimize sequence: fptan
15594 ;; into fptan insn.
15597 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15598 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15600 (set (match_operand:SF 1 "register_operand" "")
15601 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15603 (match_operand:SF 3 "immediate_operand" ""))]
15604 "standard_80387_constant_p (operands[3]) == 2"
15605 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15606 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15609 (define_expand "tansf2"
15610 [(parallel [(set (match_dup 2)
15611 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15613 (set (match_operand:SF 0 "register_operand" "")
15614 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15615 "TARGET_USE_FANCY_MATH_387
15616 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15617 && flag_unsafe_math_optimizations"
15619 operands[2] = gen_reg_rtx (SFmode);
15622 (define_insn "*tanxf3_1"
15623 [(set (match_operand:XF 0 "register_operand" "=f")
15624 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15626 (set (match_operand:XF 1 "register_operand" "=u")
15627 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15628 "TARGET_USE_FANCY_MATH_387
15629 && flag_unsafe_math_optimizations"
15631 [(set_attr "type" "fpspc")
15632 (set_attr "mode" "XF")])
15634 ;; optimize sequence: fptan
15637 ;; into fptan insn.
15640 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15641 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15643 (set (match_operand:XF 1 "register_operand" "")
15644 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15646 (match_operand:XF 3 "immediate_operand" ""))]
15647 "standard_80387_constant_p (operands[3]) == 2"
15648 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15649 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15652 (define_expand "tanxf2"
15653 [(parallel [(set (match_dup 2)
15654 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15656 (set (match_operand:XF 0 "register_operand" "")
15657 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15658 "TARGET_USE_FANCY_MATH_387
15659 && flag_unsafe_math_optimizations"
15661 operands[2] = gen_reg_rtx (XFmode);
15664 (define_insn "atan2df3_1"
15665 [(set (match_operand:DF 0 "register_operand" "=f")
15666 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15667 (match_operand:DF 1 "register_operand" "u")]
15669 (clobber (match_scratch:DF 3 "=1"))]
15670 "TARGET_USE_FANCY_MATH_387
15671 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15672 && flag_unsafe_math_optimizations"
15674 [(set_attr "type" "fpspc")
15675 (set_attr "mode" "DF")])
15677 (define_expand "atan2df3"
15678 [(use (match_operand:DF 0 "register_operand" ""))
15679 (use (match_operand:DF 2 "register_operand" ""))
15680 (use (match_operand:DF 1 "register_operand" ""))]
15681 "TARGET_USE_FANCY_MATH_387
15682 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15683 && flag_unsafe_math_optimizations"
15685 rtx copy = gen_reg_rtx (DFmode);
15686 emit_move_insn (copy, operands[1]);
15687 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15691 (define_expand "atandf2"
15692 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15693 (unspec:DF [(match_dup 2)
15694 (match_operand:DF 1 "register_operand" "")]
15696 (clobber (match_scratch:DF 3 ""))])]
15697 "TARGET_USE_FANCY_MATH_387
15698 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15699 && flag_unsafe_math_optimizations"
15701 operands[2] = gen_reg_rtx (DFmode);
15702 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15705 (define_insn "atan2sf3_1"
15706 [(set (match_operand:SF 0 "register_operand" "=f")
15707 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15708 (match_operand:SF 1 "register_operand" "u")]
15710 (clobber (match_scratch:SF 3 "=1"))]
15711 "TARGET_USE_FANCY_MATH_387
15712 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15713 && flag_unsafe_math_optimizations"
15715 [(set_attr "type" "fpspc")
15716 (set_attr "mode" "SF")])
15718 (define_expand "atan2sf3"
15719 [(use (match_operand:SF 0 "register_operand" ""))
15720 (use (match_operand:SF 2 "register_operand" ""))
15721 (use (match_operand:SF 1 "register_operand" ""))]
15722 "TARGET_USE_FANCY_MATH_387
15723 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15724 && flag_unsafe_math_optimizations"
15726 rtx copy = gen_reg_rtx (SFmode);
15727 emit_move_insn (copy, operands[1]);
15728 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15732 (define_expand "atansf2"
15733 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15734 (unspec:SF [(match_dup 2)
15735 (match_operand:SF 1 "register_operand" "")]
15737 (clobber (match_scratch:SF 3 ""))])]
15738 "TARGET_USE_FANCY_MATH_387
15739 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15740 && flag_unsafe_math_optimizations"
15742 operands[2] = gen_reg_rtx (SFmode);
15743 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15746 (define_insn "atan2xf3_1"
15747 [(set (match_operand:XF 0 "register_operand" "=f")
15748 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15749 (match_operand:XF 1 "register_operand" "u")]
15751 (clobber (match_scratch:XF 3 "=1"))]
15752 "TARGET_USE_FANCY_MATH_387
15753 && flag_unsafe_math_optimizations"
15755 [(set_attr "type" "fpspc")
15756 (set_attr "mode" "XF")])
15758 (define_expand "atan2xf3"
15759 [(use (match_operand:XF 0 "register_operand" ""))
15760 (use (match_operand:XF 2 "register_operand" ""))
15761 (use (match_operand:XF 1 "register_operand" ""))]
15762 "TARGET_USE_FANCY_MATH_387
15763 && flag_unsafe_math_optimizations"
15765 rtx copy = gen_reg_rtx (XFmode);
15766 emit_move_insn (copy, operands[1]);
15767 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15771 (define_expand "atanxf2"
15772 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15773 (unspec:XF [(match_dup 2)
15774 (match_operand:XF 1 "register_operand" "")]
15776 (clobber (match_scratch:XF 3 ""))])]
15777 "TARGET_USE_FANCY_MATH_387
15778 && flag_unsafe_math_optimizations"
15780 operands[2] = gen_reg_rtx (XFmode);
15781 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15784 (define_expand "asindf2"
15785 [(set (match_dup 2)
15786 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15787 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15788 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15789 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15790 (parallel [(set (match_dup 7)
15791 (unspec:XF [(match_dup 6) (match_dup 2)]
15793 (clobber (match_scratch:XF 8 ""))])
15794 (set (match_operand:DF 0 "register_operand" "")
15795 (float_truncate:DF (match_dup 7)))]
15796 "TARGET_USE_FANCY_MATH_387
15797 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15798 && flag_unsafe_math_optimizations"
15802 for (i=2; i<8; i++)
15803 operands[i] = gen_reg_rtx (XFmode);
15805 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15808 (define_expand "asinsf2"
15809 [(set (match_dup 2)
15810 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15811 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15812 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15813 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15814 (parallel [(set (match_dup 7)
15815 (unspec:XF [(match_dup 6) (match_dup 2)]
15817 (clobber (match_scratch:XF 8 ""))])
15818 (set (match_operand:SF 0 "register_operand" "")
15819 (float_truncate:SF (match_dup 7)))]
15820 "TARGET_USE_FANCY_MATH_387
15821 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15822 && flag_unsafe_math_optimizations"
15826 for (i=2; i<8; i++)
15827 operands[i] = gen_reg_rtx (XFmode);
15829 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15832 (define_expand "asinxf2"
15833 [(set (match_dup 2)
15834 (mult:XF (match_operand:XF 1 "register_operand" "")
15836 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15837 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15838 (parallel [(set (match_operand:XF 0 "register_operand" "")
15839 (unspec:XF [(match_dup 5) (match_dup 1)]
15841 (clobber (match_scratch:XF 6 ""))])]
15842 "TARGET_USE_FANCY_MATH_387
15843 && flag_unsafe_math_optimizations"
15847 for (i=2; i<6; i++)
15848 operands[i] = gen_reg_rtx (XFmode);
15850 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15853 (define_expand "acosdf2"
15854 [(set (match_dup 2)
15855 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15856 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15857 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15858 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15859 (parallel [(set (match_dup 7)
15860 (unspec:XF [(match_dup 2) (match_dup 6)]
15862 (clobber (match_scratch:XF 8 ""))])
15863 (set (match_operand:DF 0 "register_operand" "")
15864 (float_truncate:DF (match_dup 7)))]
15865 "TARGET_USE_FANCY_MATH_387
15866 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15867 && flag_unsafe_math_optimizations"
15871 for (i=2; i<8; i++)
15872 operands[i] = gen_reg_rtx (XFmode);
15874 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15877 (define_expand "acossf2"
15878 [(set (match_dup 2)
15879 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15880 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15881 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15882 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15883 (parallel [(set (match_dup 7)
15884 (unspec:XF [(match_dup 2) (match_dup 6)]
15886 (clobber (match_scratch:XF 8 ""))])
15887 (set (match_operand:SF 0 "register_operand" "")
15888 (float_truncate:SF (match_dup 7)))]
15889 "TARGET_USE_FANCY_MATH_387
15890 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15891 && flag_unsafe_math_optimizations"
15895 for (i=2; i<8; i++)
15896 operands[i] = gen_reg_rtx (XFmode);
15898 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15901 (define_expand "acosxf2"
15902 [(set (match_dup 2)
15903 (mult:XF (match_operand:XF 1 "register_operand" "")
15905 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15906 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15907 (parallel [(set (match_operand:XF 0 "register_operand" "")
15908 (unspec:XF [(match_dup 1) (match_dup 5)]
15910 (clobber (match_scratch:XF 6 ""))])]
15911 "TARGET_USE_FANCY_MATH_387
15912 && flag_unsafe_math_optimizations"
15916 for (i=2; i<6; i++)
15917 operands[i] = gen_reg_rtx (XFmode);
15919 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15922 (define_insn "fyl2x_xf3"
15923 [(set (match_operand:XF 0 "register_operand" "=f")
15924 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15925 (match_operand:XF 1 "register_operand" "u")]
15927 (clobber (match_scratch:XF 3 "=1"))]
15928 "TARGET_USE_FANCY_MATH_387
15929 && flag_unsafe_math_optimizations"
15931 [(set_attr "type" "fpspc")
15932 (set_attr "mode" "XF")])
15934 (define_expand "logsf2"
15935 [(set (match_dup 2)
15936 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15937 (parallel [(set (match_dup 4)
15938 (unspec:XF [(match_dup 2)
15939 (match_dup 3)] UNSPEC_FYL2X))
15940 (clobber (match_scratch:XF 5 ""))])
15941 (set (match_operand:SF 0 "register_operand" "")
15942 (float_truncate:SF (match_dup 4)))]
15943 "TARGET_USE_FANCY_MATH_387
15944 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15945 && flag_unsafe_math_optimizations"
15949 operands[2] = gen_reg_rtx (XFmode);
15950 operands[3] = gen_reg_rtx (XFmode);
15951 operands[4] = gen_reg_rtx (XFmode);
15953 temp = standard_80387_constant_rtx (4); /* fldln2 */
15954 emit_move_insn (operands[3], temp);
15957 (define_expand "logdf2"
15958 [(set (match_dup 2)
15959 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15960 (parallel [(set (match_dup 4)
15961 (unspec:XF [(match_dup 2)
15962 (match_dup 3)] UNSPEC_FYL2X))
15963 (clobber (match_scratch:XF 5 ""))])
15964 (set (match_operand:DF 0 "register_operand" "")
15965 (float_truncate:DF (match_dup 4)))]
15966 "TARGET_USE_FANCY_MATH_387
15967 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15968 && flag_unsafe_math_optimizations"
15972 operands[2] = gen_reg_rtx (XFmode);
15973 operands[3] = gen_reg_rtx (XFmode);
15974 operands[4] = gen_reg_rtx (XFmode);
15976 temp = standard_80387_constant_rtx (4); /* fldln2 */
15977 emit_move_insn (operands[3], temp);
15980 (define_expand "logxf2"
15981 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15982 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15983 (match_dup 2)] UNSPEC_FYL2X))
15984 (clobber (match_scratch:XF 3 ""))])]
15985 "TARGET_USE_FANCY_MATH_387
15986 && flag_unsafe_math_optimizations"
15990 operands[2] = gen_reg_rtx (XFmode);
15991 temp = standard_80387_constant_rtx (4); /* fldln2 */
15992 emit_move_insn (operands[2], temp);
15995 (define_expand "log10sf2"
15996 [(set (match_dup 2)
15997 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15998 (parallel [(set (match_dup 4)
15999 (unspec:XF [(match_dup 2)
16000 (match_dup 3)] UNSPEC_FYL2X))
16001 (clobber (match_scratch:XF 5 ""))])
16002 (set (match_operand:SF 0 "register_operand" "")
16003 (float_truncate:SF (match_dup 4)))]
16004 "TARGET_USE_FANCY_MATH_387
16005 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16006 && flag_unsafe_math_optimizations"
16010 operands[2] = gen_reg_rtx (XFmode);
16011 operands[3] = gen_reg_rtx (XFmode);
16012 operands[4] = gen_reg_rtx (XFmode);
16014 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16015 emit_move_insn (operands[3], temp);
16018 (define_expand "log10df2"
16019 [(set (match_dup 2)
16020 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16021 (parallel [(set (match_dup 4)
16022 (unspec:XF [(match_dup 2)
16023 (match_dup 3)] UNSPEC_FYL2X))
16024 (clobber (match_scratch:XF 5 ""))])
16025 (set (match_operand:DF 0 "register_operand" "")
16026 (float_truncate:DF (match_dup 4)))]
16027 "TARGET_USE_FANCY_MATH_387
16028 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16029 && flag_unsafe_math_optimizations"
16033 operands[2] = gen_reg_rtx (XFmode);
16034 operands[3] = gen_reg_rtx (XFmode);
16035 operands[4] = gen_reg_rtx (XFmode);
16037 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16038 emit_move_insn (operands[3], temp);
16041 (define_expand "log10xf2"
16042 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16043 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16044 (match_dup 2)] UNSPEC_FYL2X))
16045 (clobber (match_scratch:XF 3 ""))])]
16046 "TARGET_USE_FANCY_MATH_387
16047 && flag_unsafe_math_optimizations"
16051 operands[2] = gen_reg_rtx (XFmode);
16052 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16053 emit_move_insn (operands[2], temp);
16056 (define_expand "log2sf2"
16057 [(set (match_dup 2)
16058 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16059 (parallel [(set (match_dup 4)
16060 (unspec:XF [(match_dup 2)
16061 (match_dup 3)] UNSPEC_FYL2X))
16062 (clobber (match_scratch:XF 5 ""))])
16063 (set (match_operand:SF 0 "register_operand" "")
16064 (float_truncate:SF (match_dup 4)))]
16065 "TARGET_USE_FANCY_MATH_387
16066 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16067 && flag_unsafe_math_optimizations"
16069 operands[2] = gen_reg_rtx (XFmode);
16070 operands[3] = gen_reg_rtx (XFmode);
16071 operands[4] = gen_reg_rtx (XFmode);
16073 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16076 (define_expand "log2df2"
16077 [(set (match_dup 2)
16078 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16079 (parallel [(set (match_dup 4)
16080 (unspec:XF [(match_dup 2)
16081 (match_dup 3)] UNSPEC_FYL2X))
16082 (clobber (match_scratch:XF 5 ""))])
16083 (set (match_operand:DF 0 "register_operand" "")
16084 (float_truncate:DF (match_dup 4)))]
16085 "TARGET_USE_FANCY_MATH_387
16086 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16087 && flag_unsafe_math_optimizations"
16089 operands[2] = gen_reg_rtx (XFmode);
16090 operands[3] = gen_reg_rtx (XFmode);
16091 operands[4] = gen_reg_rtx (XFmode);
16093 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16096 (define_expand "log2xf2"
16097 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16098 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16099 (match_dup 2)] UNSPEC_FYL2X))
16100 (clobber (match_scratch:XF 3 ""))])]
16101 "TARGET_USE_FANCY_MATH_387
16102 && flag_unsafe_math_optimizations"
16104 operands[2] = gen_reg_rtx (XFmode);
16105 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16108 (define_insn "fyl2xp1_xf3"
16109 [(set (match_operand:XF 0 "register_operand" "=f")
16110 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16111 (match_operand:XF 1 "register_operand" "u")]
16113 (clobber (match_scratch:XF 3 "=1"))]
16114 "TARGET_USE_FANCY_MATH_387
16115 && flag_unsafe_math_optimizations"
16117 [(set_attr "type" "fpspc")
16118 (set_attr "mode" "XF")])
16120 (define_expand "log1psf2"
16121 [(use (match_operand:SF 0 "register_operand" ""))
16122 (use (match_operand:SF 1 "register_operand" ""))]
16123 "TARGET_USE_FANCY_MATH_387
16124 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16125 && flag_unsafe_math_optimizations"
16127 rtx op0 = gen_reg_rtx (XFmode);
16128 rtx op1 = gen_reg_rtx (XFmode);
16130 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16131 ix86_emit_i387_log1p (op0, op1);
16132 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16136 (define_expand "log1pdf2"
16137 [(use (match_operand:DF 0 "register_operand" ""))
16138 (use (match_operand:DF 1 "register_operand" ""))]
16139 "TARGET_USE_FANCY_MATH_387
16140 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16141 && flag_unsafe_math_optimizations"
16143 rtx op0 = gen_reg_rtx (XFmode);
16144 rtx op1 = gen_reg_rtx (XFmode);
16146 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16147 ix86_emit_i387_log1p (op0, op1);
16148 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16152 (define_expand "log1pxf2"
16153 [(use (match_operand:XF 0 "register_operand" ""))
16154 (use (match_operand:XF 1 "register_operand" ""))]
16155 "TARGET_USE_FANCY_MATH_387
16156 && flag_unsafe_math_optimizations"
16158 ix86_emit_i387_log1p (operands[0], operands[1]);
16162 (define_insn "*fxtractxf3"
16163 [(set (match_operand:XF 0 "register_operand" "=f")
16164 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16165 UNSPEC_XTRACT_FRACT))
16166 (set (match_operand:XF 1 "register_operand" "=u")
16167 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16168 "TARGET_USE_FANCY_MATH_387
16169 && flag_unsafe_math_optimizations"
16171 [(set_attr "type" "fpspc")
16172 (set_attr "mode" "XF")])
16174 (define_expand "logbsf2"
16175 [(set (match_dup 2)
16176 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16177 (parallel [(set (match_dup 3)
16178 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16180 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16181 (set (match_operand:SF 0 "register_operand" "")
16182 (float_truncate:SF (match_dup 4)))]
16183 "TARGET_USE_FANCY_MATH_387
16184 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16185 && flag_unsafe_math_optimizations"
16187 operands[2] = gen_reg_rtx (XFmode);
16188 operands[3] = gen_reg_rtx (XFmode);
16189 operands[4] = gen_reg_rtx (XFmode);
16192 (define_expand "logbdf2"
16193 [(set (match_dup 2)
16194 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16195 (parallel [(set (match_dup 3)
16196 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16198 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16199 (set (match_operand:DF 0 "register_operand" "")
16200 (float_truncate:DF (match_dup 4)))]
16201 "TARGET_USE_FANCY_MATH_387
16202 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16203 && flag_unsafe_math_optimizations"
16205 operands[2] = gen_reg_rtx (XFmode);
16206 operands[3] = gen_reg_rtx (XFmode);
16207 operands[4] = gen_reg_rtx (XFmode);
16210 (define_expand "logbxf2"
16211 [(parallel [(set (match_dup 2)
16212 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16213 UNSPEC_XTRACT_FRACT))
16214 (set (match_operand:XF 0 "register_operand" "")
16215 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16216 "TARGET_USE_FANCY_MATH_387
16217 && flag_unsafe_math_optimizations"
16219 operands[2] = gen_reg_rtx (XFmode);
16222 (define_expand "ilogbsi2"
16223 [(parallel [(set (match_dup 2)
16224 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16225 UNSPEC_XTRACT_FRACT))
16226 (set (match_operand:XF 3 "register_operand" "")
16227 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16228 (parallel [(set (match_operand:SI 0 "register_operand" "")
16229 (fix:SI (match_dup 3)))
16230 (clobber (reg:CC FLAGS_REG))])]
16231 "TARGET_USE_FANCY_MATH_387
16232 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16233 && flag_unsafe_math_optimizations"
16235 operands[2] = gen_reg_rtx (XFmode);
16236 operands[3] = gen_reg_rtx (XFmode);
16239 (define_insn "*f2xm1xf2"
16240 [(set (match_operand:XF 0 "register_operand" "=f")
16241 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16243 "TARGET_USE_FANCY_MATH_387
16244 && flag_unsafe_math_optimizations"
16246 [(set_attr "type" "fpspc")
16247 (set_attr "mode" "XF")])
16249 (define_insn "*fscalexf4"
16250 [(set (match_operand:XF 0 "register_operand" "=f")
16251 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16252 (match_operand:XF 3 "register_operand" "1")]
16253 UNSPEC_FSCALE_FRACT))
16254 (set (match_operand:XF 1 "register_operand" "=u")
16255 (unspec:XF [(match_dup 2) (match_dup 3)]
16256 UNSPEC_FSCALE_EXP))]
16257 "TARGET_USE_FANCY_MATH_387
16258 && flag_unsafe_math_optimizations"
16260 [(set_attr "type" "fpspc")
16261 (set_attr "mode" "XF")])
16263 (define_expand "expsf2"
16264 [(set (match_dup 2)
16265 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16266 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16267 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16268 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16269 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16270 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16271 (parallel [(set (match_dup 10)
16272 (unspec:XF [(match_dup 9) (match_dup 5)]
16273 UNSPEC_FSCALE_FRACT))
16274 (set (match_dup 11)
16275 (unspec:XF [(match_dup 9) (match_dup 5)]
16276 UNSPEC_FSCALE_EXP))])
16277 (set (match_operand:SF 0 "register_operand" "")
16278 (float_truncate:SF (match_dup 10)))]
16279 "TARGET_USE_FANCY_MATH_387
16280 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16281 && flag_unsafe_math_optimizations"
16286 for (i=2; i<12; i++)
16287 operands[i] = gen_reg_rtx (XFmode);
16288 temp = standard_80387_constant_rtx (5); /* fldl2e */
16289 emit_move_insn (operands[3], temp);
16290 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16293 (define_expand "expdf2"
16294 [(set (match_dup 2)
16295 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16296 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16297 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16298 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16299 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16300 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16301 (parallel [(set (match_dup 10)
16302 (unspec:XF [(match_dup 9) (match_dup 5)]
16303 UNSPEC_FSCALE_FRACT))
16304 (set (match_dup 11)
16305 (unspec:XF [(match_dup 9) (match_dup 5)]
16306 UNSPEC_FSCALE_EXP))])
16307 (set (match_operand:DF 0 "register_operand" "")
16308 (float_truncate:DF (match_dup 10)))]
16309 "TARGET_USE_FANCY_MATH_387
16310 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16311 && flag_unsafe_math_optimizations"
16316 for (i=2; i<12; i++)
16317 operands[i] = gen_reg_rtx (XFmode);
16318 temp = standard_80387_constant_rtx (5); /* fldl2e */
16319 emit_move_insn (operands[3], temp);
16320 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16323 (define_expand "expxf2"
16324 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16326 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16327 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16328 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16329 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16330 (parallel [(set (match_operand:XF 0 "register_operand" "")
16331 (unspec:XF [(match_dup 8) (match_dup 4)]
16332 UNSPEC_FSCALE_FRACT))
16334 (unspec:XF [(match_dup 8) (match_dup 4)]
16335 UNSPEC_FSCALE_EXP))])]
16336 "TARGET_USE_FANCY_MATH_387
16337 && flag_unsafe_math_optimizations"
16342 for (i=2; i<10; i++)
16343 operands[i] = gen_reg_rtx (XFmode);
16344 temp = standard_80387_constant_rtx (5); /* fldl2e */
16345 emit_move_insn (operands[2], temp);
16346 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16349 (define_expand "exp10sf2"
16350 [(set (match_dup 2)
16351 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16352 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16353 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16354 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16355 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16356 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16357 (parallel [(set (match_dup 10)
16358 (unspec:XF [(match_dup 9) (match_dup 5)]
16359 UNSPEC_FSCALE_FRACT))
16360 (set (match_dup 11)
16361 (unspec:XF [(match_dup 9) (match_dup 5)]
16362 UNSPEC_FSCALE_EXP))])
16363 (set (match_operand:SF 0 "register_operand" "")
16364 (float_truncate:SF (match_dup 10)))]
16365 "TARGET_USE_FANCY_MATH_387
16366 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16367 && flag_unsafe_math_optimizations"
16372 for (i=2; i<12; i++)
16373 operands[i] = gen_reg_rtx (XFmode);
16374 temp = standard_80387_constant_rtx (6); /* fldl2t */
16375 emit_move_insn (operands[3], temp);
16376 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16379 (define_expand "exp10df2"
16380 [(set (match_dup 2)
16381 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16382 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16383 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16384 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16385 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16386 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16387 (parallel [(set (match_dup 10)
16388 (unspec:XF [(match_dup 9) (match_dup 5)]
16389 UNSPEC_FSCALE_FRACT))
16390 (set (match_dup 11)
16391 (unspec:XF [(match_dup 9) (match_dup 5)]
16392 UNSPEC_FSCALE_EXP))])
16393 (set (match_operand:DF 0 "register_operand" "")
16394 (float_truncate:DF (match_dup 10)))]
16395 "TARGET_USE_FANCY_MATH_387
16396 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16397 && flag_unsafe_math_optimizations"
16402 for (i=2; i<12; i++)
16403 operands[i] = gen_reg_rtx (XFmode);
16404 temp = standard_80387_constant_rtx (6); /* fldl2t */
16405 emit_move_insn (operands[3], temp);
16406 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16409 (define_expand "exp10xf2"
16410 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16412 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16413 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16414 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16415 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16416 (parallel [(set (match_operand:XF 0 "register_operand" "")
16417 (unspec:XF [(match_dup 8) (match_dup 4)]
16418 UNSPEC_FSCALE_FRACT))
16420 (unspec:XF [(match_dup 8) (match_dup 4)]
16421 UNSPEC_FSCALE_EXP))])]
16422 "TARGET_USE_FANCY_MATH_387
16423 && flag_unsafe_math_optimizations"
16428 for (i=2; i<10; i++)
16429 operands[i] = gen_reg_rtx (XFmode);
16430 temp = standard_80387_constant_rtx (6); /* fldl2t */
16431 emit_move_insn (operands[2], temp);
16432 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16435 (define_expand "exp2sf2"
16436 [(set (match_dup 2)
16437 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16438 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16439 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16440 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16441 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16442 (parallel [(set (match_dup 8)
16443 (unspec:XF [(match_dup 7) (match_dup 3)]
16444 UNSPEC_FSCALE_FRACT))
16446 (unspec:XF [(match_dup 7) (match_dup 3)]
16447 UNSPEC_FSCALE_EXP))])
16448 (set (match_operand:SF 0 "register_operand" "")
16449 (float_truncate:SF (match_dup 8)))]
16450 "TARGET_USE_FANCY_MATH_387
16451 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16452 && flag_unsafe_math_optimizations"
16456 for (i=2; i<10; i++)
16457 operands[i] = gen_reg_rtx (XFmode);
16458 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16461 (define_expand "exp2df2"
16462 [(set (match_dup 2)
16463 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16464 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16465 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16466 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16467 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16468 (parallel [(set (match_dup 8)
16469 (unspec:XF [(match_dup 7) (match_dup 3)]
16470 UNSPEC_FSCALE_FRACT))
16472 (unspec:XF [(match_dup 7) (match_dup 3)]
16473 UNSPEC_FSCALE_EXP))])
16474 (set (match_operand:DF 0 "register_operand" "")
16475 (float_truncate:DF (match_dup 8)))]
16476 "TARGET_USE_FANCY_MATH_387
16477 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16478 && flag_unsafe_math_optimizations"
16482 for (i=2; i<10; i++)
16483 operands[i] = gen_reg_rtx (XFmode);
16484 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16487 (define_expand "exp2xf2"
16488 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16489 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16490 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16491 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16492 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16493 (parallel [(set (match_operand:XF 0 "register_operand" "")
16494 (unspec:XF [(match_dup 7) (match_dup 3)]
16495 UNSPEC_FSCALE_FRACT))
16497 (unspec:XF [(match_dup 7) (match_dup 3)]
16498 UNSPEC_FSCALE_EXP))])]
16499 "TARGET_USE_FANCY_MATH_387
16500 && flag_unsafe_math_optimizations"
16504 for (i=2; i<9; i++)
16505 operands[i] = gen_reg_rtx (XFmode);
16506 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16509 (define_expand "expm1df2"
16510 [(set (match_dup 2)
16511 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16512 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16513 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16514 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16515 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16516 (parallel [(set (match_dup 8)
16517 (unspec:XF [(match_dup 7) (match_dup 5)]
16518 UNSPEC_FSCALE_FRACT))
16520 (unspec:XF [(match_dup 7) (match_dup 5)]
16521 UNSPEC_FSCALE_EXP))])
16522 (parallel [(set (match_dup 11)
16523 (unspec:XF [(match_dup 10) (match_dup 9)]
16524 UNSPEC_FSCALE_FRACT))
16525 (set (match_dup 12)
16526 (unspec:XF [(match_dup 10) (match_dup 9)]
16527 UNSPEC_FSCALE_EXP))])
16528 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16529 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16530 (set (match_operand:DF 0 "register_operand" "")
16531 (float_truncate:DF (match_dup 14)))]
16532 "TARGET_USE_FANCY_MATH_387
16533 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16534 && flag_unsafe_math_optimizations"
16539 for (i=2; i<15; i++)
16540 operands[i] = gen_reg_rtx (XFmode);
16541 temp = standard_80387_constant_rtx (5); /* fldl2e */
16542 emit_move_insn (operands[3], temp);
16543 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16546 (define_expand "expm1sf2"
16547 [(set (match_dup 2)
16548 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16549 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16550 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16551 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16552 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16553 (parallel [(set (match_dup 8)
16554 (unspec:XF [(match_dup 7) (match_dup 5)]
16555 UNSPEC_FSCALE_FRACT))
16557 (unspec:XF [(match_dup 7) (match_dup 5)]
16558 UNSPEC_FSCALE_EXP))])
16559 (parallel [(set (match_dup 11)
16560 (unspec:XF [(match_dup 10) (match_dup 9)]
16561 UNSPEC_FSCALE_FRACT))
16562 (set (match_dup 12)
16563 (unspec:XF [(match_dup 10) (match_dup 9)]
16564 UNSPEC_FSCALE_EXP))])
16565 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16566 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16567 (set (match_operand:SF 0 "register_operand" "")
16568 (float_truncate:SF (match_dup 14)))]
16569 "TARGET_USE_FANCY_MATH_387
16570 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16571 && flag_unsafe_math_optimizations"
16576 for (i=2; i<15; i++)
16577 operands[i] = gen_reg_rtx (XFmode);
16578 temp = standard_80387_constant_rtx (5); /* fldl2e */
16579 emit_move_insn (operands[3], temp);
16580 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16583 (define_expand "expm1xf2"
16584 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16586 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16587 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16588 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16589 (parallel [(set (match_dup 7)
16590 (unspec:XF [(match_dup 6) (match_dup 4)]
16591 UNSPEC_FSCALE_FRACT))
16593 (unspec:XF [(match_dup 6) (match_dup 4)]
16594 UNSPEC_FSCALE_EXP))])
16595 (parallel [(set (match_dup 10)
16596 (unspec:XF [(match_dup 9) (match_dup 8)]
16597 UNSPEC_FSCALE_FRACT))
16598 (set (match_dup 11)
16599 (unspec:XF [(match_dup 9) (match_dup 8)]
16600 UNSPEC_FSCALE_EXP))])
16601 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16602 (set (match_operand:XF 0 "register_operand" "")
16603 (plus:XF (match_dup 12) (match_dup 7)))]
16604 "TARGET_USE_FANCY_MATH_387
16605 && flag_unsafe_math_optimizations"
16610 for (i=2; i<13; i++)
16611 operands[i] = gen_reg_rtx (XFmode);
16612 temp = standard_80387_constant_rtx (5); /* fldl2e */
16613 emit_move_insn (operands[2], temp);
16614 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16617 (define_expand "ldexpdf3"
16618 [(set (match_dup 3)
16619 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16621 (float:XF (match_operand:SI 2 "register_operand" "")))
16622 (parallel [(set (match_dup 5)
16623 (unspec:XF [(match_dup 3) (match_dup 4)]
16624 UNSPEC_FSCALE_FRACT))
16626 (unspec:XF [(match_dup 3) (match_dup 4)]
16627 UNSPEC_FSCALE_EXP))])
16628 (set (match_operand:DF 0 "register_operand" "")
16629 (float_truncate:DF (match_dup 5)))]
16630 "TARGET_USE_FANCY_MATH_387
16631 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16632 && flag_unsafe_math_optimizations"
16636 for (i=3; i<7; i++)
16637 operands[i] = gen_reg_rtx (XFmode);
16640 (define_expand "ldexpsf3"
16641 [(set (match_dup 3)
16642 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16644 (float:XF (match_operand:SI 2 "register_operand" "")))
16645 (parallel [(set (match_dup 5)
16646 (unspec:XF [(match_dup 3) (match_dup 4)]
16647 UNSPEC_FSCALE_FRACT))
16649 (unspec:XF [(match_dup 3) (match_dup 4)]
16650 UNSPEC_FSCALE_EXP))])
16651 (set (match_operand:SF 0 "register_operand" "")
16652 (float_truncate:SF (match_dup 5)))]
16653 "TARGET_USE_FANCY_MATH_387
16654 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16655 && flag_unsafe_math_optimizations"
16659 for (i=3; i<7; i++)
16660 operands[i] = gen_reg_rtx (XFmode);
16663 (define_expand "ldexpxf3"
16664 [(set (match_dup 3)
16665 (float:XF (match_operand:SI 2 "register_operand" "")))
16666 (parallel [(set (match_operand:XF 0 " register_operand" "")
16667 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16669 UNSPEC_FSCALE_FRACT))
16671 (unspec:XF [(match_dup 1) (match_dup 3)]
16672 UNSPEC_FSCALE_EXP))])]
16673 "TARGET_USE_FANCY_MATH_387
16674 && flag_unsafe_math_optimizations"
16678 for (i=3; i<5; i++)
16679 operands[i] = gen_reg_rtx (XFmode);
16683 (define_insn "frndintxf2"
16684 [(set (match_operand:XF 0 "register_operand" "=f")
16685 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16687 "TARGET_USE_FANCY_MATH_387
16688 && flag_unsafe_math_optimizations"
16690 [(set_attr "type" "fpspc")
16691 (set_attr "mode" "XF")])
16693 (define_expand "rintdf2"
16694 [(use (match_operand:DF 0 "register_operand" ""))
16695 (use (match_operand:DF 1 "register_operand" ""))]
16696 "TARGET_USE_FANCY_MATH_387
16697 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16698 && flag_unsafe_math_optimizations"
16700 rtx op0 = gen_reg_rtx (XFmode);
16701 rtx op1 = gen_reg_rtx (XFmode);
16703 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16704 emit_insn (gen_frndintxf2 (op0, op1));
16706 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16710 (define_expand "rintsf2"
16711 [(use (match_operand:SF 0 "register_operand" ""))
16712 (use (match_operand:SF 1 "register_operand" ""))]
16713 "TARGET_USE_FANCY_MATH_387
16714 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16715 && flag_unsafe_math_optimizations"
16717 rtx op0 = gen_reg_rtx (XFmode);
16718 rtx op1 = gen_reg_rtx (XFmode);
16720 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16721 emit_insn (gen_frndintxf2 (op0, op1));
16723 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16727 (define_expand "rintxf2"
16728 [(use (match_operand:XF 0 "register_operand" ""))
16729 (use (match_operand:XF 1 "register_operand" ""))]
16730 "TARGET_USE_FANCY_MATH_387
16731 && flag_unsafe_math_optimizations"
16733 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16737 (define_insn_and_split "*fistdi2_1"
16738 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16739 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16741 "TARGET_USE_FANCY_MATH_387
16742 && flag_unsafe_math_optimizations
16743 && !(reload_completed || reload_in_progress)"
16748 if (memory_operand (operands[0], VOIDmode))
16749 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16752 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16753 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16758 [(set_attr "type" "fpspc")
16759 (set_attr "mode" "DI")])
16761 (define_insn "fistdi2"
16762 [(set (match_operand:DI 0 "memory_operand" "=m")
16763 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16765 (clobber (match_scratch:XF 2 "=&1f"))]
16766 "TARGET_USE_FANCY_MATH_387
16767 && flag_unsafe_math_optimizations"
16768 "* return output_fix_trunc (insn, operands, 0);"
16769 [(set_attr "type" "fpspc")
16770 (set_attr "mode" "DI")])
16772 (define_insn "fistdi2_with_temp"
16773 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16774 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16776 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16777 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16778 "TARGET_USE_FANCY_MATH_387
16779 && flag_unsafe_math_optimizations"
16781 [(set_attr "type" "fpspc")
16782 (set_attr "mode" "DI")])
16785 [(set (match_operand:DI 0 "register_operand" "")
16786 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16788 (clobber (match_operand:DI 2 "memory_operand" ""))
16789 (clobber (match_scratch 3 ""))]
16791 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16792 (clobber (match_dup 3))])
16793 (set (match_dup 0) (match_dup 2))]
16797 [(set (match_operand:DI 0 "memory_operand" "")
16798 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16800 (clobber (match_operand:DI 2 "memory_operand" ""))
16801 (clobber (match_scratch 3 ""))]
16803 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16804 (clobber (match_dup 3))])]
16807 (define_insn_and_split "*fist<mode>2_1"
16808 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16809 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16811 "TARGET_USE_FANCY_MATH_387
16812 && flag_unsafe_math_optimizations
16813 && !(reload_completed || reload_in_progress)"
16818 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16819 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16823 [(set_attr "type" "fpspc")
16824 (set_attr "mode" "<MODE>")])
16826 (define_insn "fist<mode>2"
16827 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16828 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16830 "TARGET_USE_FANCY_MATH_387
16831 && flag_unsafe_math_optimizations"
16832 "* return output_fix_trunc (insn, operands, 0);"
16833 [(set_attr "type" "fpspc")
16834 (set_attr "mode" "<MODE>")])
16836 (define_insn "fist<mode>2_with_temp"
16837 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16838 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16840 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16841 "TARGET_USE_FANCY_MATH_387
16842 && flag_unsafe_math_optimizations"
16844 [(set_attr "type" "fpspc")
16845 (set_attr "mode" "<MODE>")])
16848 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16849 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16851 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16853 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16855 (set (match_dup 0) (match_dup 2))]
16859 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16860 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16862 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16864 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16868 (define_expand "lrint<mode>2"
16869 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16870 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16872 "TARGET_USE_FANCY_MATH_387
16873 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16874 && flag_unsafe_math_optimizations"
16877 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16878 (define_insn_and_split "frndintxf2_floor"
16879 [(set (match_operand:XF 0 "register_operand" "=f")
16880 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16881 UNSPEC_FRNDINT_FLOOR))
16882 (clobber (reg:CC FLAGS_REG))]
16883 "TARGET_USE_FANCY_MATH_387
16884 && flag_unsafe_math_optimizations
16885 && !(reload_completed || reload_in_progress)"
16890 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16892 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16893 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16895 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16896 operands[2], operands[3]));
16899 [(set_attr "type" "frndint")
16900 (set_attr "i387_cw" "floor")
16901 (set_attr "mode" "XF")])
16903 (define_insn "frndintxf2_floor_i387"
16904 [(set (match_operand:XF 0 "register_operand" "=f")
16905 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16906 UNSPEC_FRNDINT_FLOOR))
16907 (use (match_operand:HI 2 "memory_operand" "m"))
16908 (use (match_operand:HI 3 "memory_operand" "m"))]
16909 "TARGET_USE_FANCY_MATH_387
16910 && flag_unsafe_math_optimizations"
16911 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16912 [(set_attr "type" "frndint")
16913 (set_attr "i387_cw" "floor")
16914 (set_attr "mode" "XF")])
16916 (define_expand "floorxf2"
16917 [(use (match_operand:XF 0 "register_operand" ""))
16918 (use (match_operand:XF 1 "register_operand" ""))]
16919 "TARGET_USE_FANCY_MATH_387
16920 && flag_unsafe_math_optimizations"
16922 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16926 (define_expand "floordf2"
16927 [(use (match_operand:DF 0 "register_operand" ""))
16928 (use (match_operand:DF 1 "register_operand" ""))]
16929 "TARGET_USE_FANCY_MATH_387
16930 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16931 && flag_unsafe_math_optimizations"
16933 rtx op0 = gen_reg_rtx (XFmode);
16934 rtx op1 = gen_reg_rtx (XFmode);
16936 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16937 emit_insn (gen_frndintxf2_floor (op0, op1));
16939 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16943 (define_expand "floorsf2"
16944 [(use (match_operand:SF 0 "register_operand" ""))
16945 (use (match_operand:SF 1 "register_operand" ""))]
16946 "TARGET_USE_FANCY_MATH_387
16947 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16948 && flag_unsafe_math_optimizations"
16950 rtx op0 = gen_reg_rtx (XFmode);
16951 rtx op1 = gen_reg_rtx (XFmode);
16953 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16954 emit_insn (gen_frndintxf2_floor (op0, op1));
16956 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16960 (define_insn_and_split "*fist<mode>2_floor_1"
16961 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16962 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16963 UNSPEC_FIST_FLOOR))
16964 (clobber (reg:CC FLAGS_REG))]
16965 "TARGET_USE_FANCY_MATH_387
16966 && flag_unsafe_math_optimizations
16967 && !(reload_completed || reload_in_progress)"
16972 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16974 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16975 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16976 if (memory_operand (operands[0], VOIDmode))
16977 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16978 operands[2], operands[3]));
16981 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16982 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16983 operands[2], operands[3],
16988 [(set_attr "type" "fistp")
16989 (set_attr "i387_cw" "floor")
16990 (set_attr "mode" "<MODE>")])
16992 (define_insn "fistdi2_floor"
16993 [(set (match_operand:DI 0 "memory_operand" "=m")
16994 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16995 UNSPEC_FIST_FLOOR))
16996 (use (match_operand:HI 2 "memory_operand" "m"))
16997 (use (match_operand:HI 3 "memory_operand" "m"))
16998 (clobber (match_scratch:XF 4 "=&1f"))]
16999 "TARGET_USE_FANCY_MATH_387
17000 && flag_unsafe_math_optimizations"
17001 "* return output_fix_trunc (insn, operands, 0);"
17002 [(set_attr "type" "fistp")
17003 (set_attr "i387_cw" "floor")
17004 (set_attr "mode" "DI")])
17006 (define_insn "fistdi2_floor_with_temp"
17007 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17008 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17009 UNSPEC_FIST_FLOOR))
17010 (use (match_operand:HI 2 "memory_operand" "m,m"))
17011 (use (match_operand:HI 3 "memory_operand" "m,m"))
17012 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17013 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17014 "TARGET_USE_FANCY_MATH_387
17015 && flag_unsafe_math_optimizations"
17017 [(set_attr "type" "fistp")
17018 (set_attr "i387_cw" "floor")
17019 (set_attr "mode" "DI")])
17022 [(set (match_operand:DI 0 "register_operand" "")
17023 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17024 UNSPEC_FIST_FLOOR))
17025 (use (match_operand:HI 2 "memory_operand" ""))
17026 (use (match_operand:HI 3 "memory_operand" ""))
17027 (clobber (match_operand:DI 4 "memory_operand" ""))
17028 (clobber (match_scratch 5 ""))]
17030 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17031 (use (match_dup 2))
17032 (use (match_dup 3))
17033 (clobber (match_dup 5))])
17034 (set (match_dup 0) (match_dup 4))]
17038 [(set (match_operand:DI 0 "memory_operand" "")
17039 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17040 UNSPEC_FIST_FLOOR))
17041 (use (match_operand:HI 2 "memory_operand" ""))
17042 (use (match_operand:HI 3 "memory_operand" ""))
17043 (clobber (match_operand:DI 4 "memory_operand" ""))
17044 (clobber (match_scratch 5 ""))]
17046 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17047 (use (match_dup 2))
17048 (use (match_dup 3))
17049 (clobber (match_dup 5))])]
17052 (define_insn "fist<mode>2_floor"
17053 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17054 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17055 UNSPEC_FIST_FLOOR))
17056 (use (match_operand:HI 2 "memory_operand" "m"))
17057 (use (match_operand:HI 3 "memory_operand" "m"))]
17058 "TARGET_USE_FANCY_MATH_387
17059 && flag_unsafe_math_optimizations"
17060 "* return output_fix_trunc (insn, operands, 0);"
17061 [(set_attr "type" "fistp")
17062 (set_attr "i387_cw" "floor")
17063 (set_attr "mode" "<MODE>")])
17065 (define_insn "fist<mode>2_floor_with_temp"
17066 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17067 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17068 UNSPEC_FIST_FLOOR))
17069 (use (match_operand:HI 2 "memory_operand" "m,m"))
17070 (use (match_operand:HI 3 "memory_operand" "m,m"))
17071 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17072 "TARGET_USE_FANCY_MATH_387
17073 && flag_unsafe_math_optimizations"
17075 [(set_attr "type" "fistp")
17076 (set_attr "i387_cw" "floor")
17077 (set_attr "mode" "<MODE>")])
17080 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17081 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17082 UNSPEC_FIST_FLOOR))
17083 (use (match_operand:HI 2 "memory_operand" ""))
17084 (use (match_operand:HI 3 "memory_operand" ""))
17085 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17087 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17088 UNSPEC_FIST_FLOOR))
17089 (use (match_dup 2))
17090 (use (match_dup 3))])
17091 (set (match_dup 0) (match_dup 4))]
17095 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17096 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17097 UNSPEC_FIST_FLOOR))
17098 (use (match_operand:HI 2 "memory_operand" ""))
17099 (use (match_operand:HI 3 "memory_operand" ""))
17100 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17102 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17103 UNSPEC_FIST_FLOOR))
17104 (use (match_dup 2))
17105 (use (match_dup 3))])]
17108 (define_expand "lfloor<mode>2"
17109 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17110 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17111 UNSPEC_FIST_FLOOR))
17112 (clobber (reg:CC FLAGS_REG))])]
17113 "TARGET_USE_FANCY_MATH_387
17114 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17115 && flag_unsafe_math_optimizations"
17118 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17119 (define_insn_and_split "frndintxf2_ceil"
17120 [(set (match_operand:XF 0 "register_operand" "=f")
17121 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17122 UNSPEC_FRNDINT_CEIL))
17123 (clobber (reg:CC FLAGS_REG))]
17124 "TARGET_USE_FANCY_MATH_387
17125 && flag_unsafe_math_optimizations
17126 && !(reload_completed || reload_in_progress)"
17131 ix86_optimize_mode_switching[I387_CEIL] = 1;
17133 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17134 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17136 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17137 operands[2], operands[3]));
17140 [(set_attr "type" "frndint")
17141 (set_attr "i387_cw" "ceil")
17142 (set_attr "mode" "XF")])
17144 (define_insn "frndintxf2_ceil_i387"
17145 [(set (match_operand:XF 0 "register_operand" "=f")
17146 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17147 UNSPEC_FRNDINT_CEIL))
17148 (use (match_operand:HI 2 "memory_operand" "m"))
17149 (use (match_operand:HI 3 "memory_operand" "m"))]
17150 "TARGET_USE_FANCY_MATH_387
17151 && flag_unsafe_math_optimizations"
17152 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17153 [(set_attr "type" "frndint")
17154 (set_attr "i387_cw" "ceil")
17155 (set_attr "mode" "XF")])
17157 (define_expand "ceilxf2"
17158 [(use (match_operand:XF 0 "register_operand" ""))
17159 (use (match_operand:XF 1 "register_operand" ""))]
17160 "TARGET_USE_FANCY_MATH_387
17161 && flag_unsafe_math_optimizations"
17163 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17167 (define_expand "ceildf2"
17168 [(use (match_operand:DF 0 "register_operand" ""))
17169 (use (match_operand:DF 1 "register_operand" ""))]
17170 "TARGET_USE_FANCY_MATH_387
17171 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17172 && flag_unsafe_math_optimizations"
17174 rtx op0 = gen_reg_rtx (XFmode);
17175 rtx op1 = gen_reg_rtx (XFmode);
17177 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17178 emit_insn (gen_frndintxf2_ceil (op0, op1));
17180 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17184 (define_expand "ceilsf2"
17185 [(use (match_operand:SF 0 "register_operand" ""))
17186 (use (match_operand:SF 1 "register_operand" ""))]
17187 "TARGET_USE_FANCY_MATH_387
17188 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17189 && flag_unsafe_math_optimizations"
17191 rtx op0 = gen_reg_rtx (XFmode);
17192 rtx op1 = gen_reg_rtx (XFmode);
17194 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17195 emit_insn (gen_frndintxf2_ceil (op0, op1));
17197 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17201 (define_insn_and_split "*fist<mode>2_ceil_1"
17202 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17203 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17205 (clobber (reg:CC FLAGS_REG))]
17206 "TARGET_USE_FANCY_MATH_387
17207 && flag_unsafe_math_optimizations
17208 && !(reload_completed || reload_in_progress)"
17213 ix86_optimize_mode_switching[I387_CEIL] = 1;
17215 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17216 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17217 if (memory_operand (operands[0], VOIDmode))
17218 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17219 operands[2], operands[3]));
17222 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17223 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17224 operands[2], operands[3],
17229 [(set_attr "type" "fistp")
17230 (set_attr "i387_cw" "ceil")
17231 (set_attr "mode" "<MODE>")])
17233 (define_insn "fistdi2_ceil"
17234 [(set (match_operand:DI 0 "memory_operand" "=m")
17235 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17237 (use (match_operand:HI 2 "memory_operand" "m"))
17238 (use (match_operand:HI 3 "memory_operand" "m"))
17239 (clobber (match_scratch:XF 4 "=&1f"))]
17240 "TARGET_USE_FANCY_MATH_387
17241 && flag_unsafe_math_optimizations"
17242 "* return output_fix_trunc (insn, operands, 0);"
17243 [(set_attr "type" "fistp")
17244 (set_attr "i387_cw" "ceil")
17245 (set_attr "mode" "DI")])
17247 (define_insn "fistdi2_ceil_with_temp"
17248 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17249 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17251 (use (match_operand:HI 2 "memory_operand" "m,m"))
17252 (use (match_operand:HI 3 "memory_operand" "m,m"))
17253 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17254 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17255 "TARGET_USE_FANCY_MATH_387
17256 && flag_unsafe_math_optimizations"
17258 [(set_attr "type" "fistp")
17259 (set_attr "i387_cw" "ceil")
17260 (set_attr "mode" "DI")])
17263 [(set (match_operand:DI 0 "register_operand" "")
17264 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17266 (use (match_operand:HI 2 "memory_operand" ""))
17267 (use (match_operand:HI 3 "memory_operand" ""))
17268 (clobber (match_operand:DI 4 "memory_operand" ""))
17269 (clobber (match_scratch 5 ""))]
17271 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17272 (use (match_dup 2))
17273 (use (match_dup 3))
17274 (clobber (match_dup 5))])
17275 (set (match_dup 0) (match_dup 4))]
17279 [(set (match_operand:DI 0 "memory_operand" "")
17280 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17282 (use (match_operand:HI 2 "memory_operand" ""))
17283 (use (match_operand:HI 3 "memory_operand" ""))
17284 (clobber (match_operand:DI 4 "memory_operand" ""))
17285 (clobber (match_scratch 5 ""))]
17287 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17288 (use (match_dup 2))
17289 (use (match_dup 3))
17290 (clobber (match_dup 5))])]
17293 (define_insn "fist<mode>2_ceil"
17294 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17295 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17297 (use (match_operand:HI 2 "memory_operand" "m"))
17298 (use (match_operand:HI 3 "memory_operand" "m"))]
17299 "TARGET_USE_FANCY_MATH_387
17300 && flag_unsafe_math_optimizations"
17301 "* return output_fix_trunc (insn, operands, 0);"
17302 [(set_attr "type" "fistp")
17303 (set_attr "i387_cw" "ceil")
17304 (set_attr "mode" "<MODE>")])
17306 (define_insn "fist<mode>2_ceil_with_temp"
17307 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17308 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17310 (use (match_operand:HI 2 "memory_operand" "m,m"))
17311 (use (match_operand:HI 3 "memory_operand" "m,m"))
17312 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17313 "TARGET_USE_FANCY_MATH_387
17314 && flag_unsafe_math_optimizations"
17316 [(set_attr "type" "fistp")
17317 (set_attr "i387_cw" "ceil")
17318 (set_attr "mode" "<MODE>")])
17321 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17322 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17324 (use (match_operand:HI 2 "memory_operand" ""))
17325 (use (match_operand:HI 3 "memory_operand" ""))
17326 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17328 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17330 (use (match_dup 2))
17331 (use (match_dup 3))])
17332 (set (match_dup 0) (match_dup 4))]
17336 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17337 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17339 (use (match_operand:HI 2 "memory_operand" ""))
17340 (use (match_operand:HI 3 "memory_operand" ""))
17341 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17343 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17345 (use (match_dup 2))
17346 (use (match_dup 3))])]
17349 (define_expand "lceil<mode>2"
17350 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17351 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17353 (clobber (reg:CC FLAGS_REG))])]
17354 "TARGET_USE_FANCY_MATH_387
17355 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17356 && flag_unsafe_math_optimizations"
17359 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17360 (define_insn_and_split "frndintxf2_trunc"
17361 [(set (match_operand:XF 0 "register_operand" "=f")
17362 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17363 UNSPEC_FRNDINT_TRUNC))
17364 (clobber (reg:CC FLAGS_REG))]
17365 "TARGET_USE_FANCY_MATH_387
17366 && flag_unsafe_math_optimizations
17367 && !(reload_completed || reload_in_progress)"
17372 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17374 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17375 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17377 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17378 operands[2], operands[3]));
17381 [(set_attr "type" "frndint")
17382 (set_attr "i387_cw" "trunc")
17383 (set_attr "mode" "XF")])
17385 (define_insn "frndintxf2_trunc_i387"
17386 [(set (match_operand:XF 0 "register_operand" "=f")
17387 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17388 UNSPEC_FRNDINT_TRUNC))
17389 (use (match_operand:HI 2 "memory_operand" "m"))
17390 (use (match_operand:HI 3 "memory_operand" "m"))]
17391 "TARGET_USE_FANCY_MATH_387
17392 && flag_unsafe_math_optimizations"
17393 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17394 [(set_attr "type" "frndint")
17395 (set_attr "i387_cw" "trunc")
17396 (set_attr "mode" "XF")])
17398 (define_expand "btruncxf2"
17399 [(use (match_operand:XF 0 "register_operand" ""))
17400 (use (match_operand:XF 1 "register_operand" ""))]
17401 "TARGET_USE_FANCY_MATH_387
17402 && flag_unsafe_math_optimizations"
17404 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17408 (define_expand "btruncdf2"
17409 [(use (match_operand:DF 0 "register_operand" ""))
17410 (use (match_operand:DF 1 "register_operand" ""))]
17411 "TARGET_USE_FANCY_MATH_387
17412 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17413 && flag_unsafe_math_optimizations"
17415 rtx op0 = gen_reg_rtx (XFmode);
17416 rtx op1 = gen_reg_rtx (XFmode);
17418 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17419 emit_insn (gen_frndintxf2_trunc (op0, op1));
17421 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17425 (define_expand "btruncsf2"
17426 [(use (match_operand:SF 0 "register_operand" ""))
17427 (use (match_operand:SF 1 "register_operand" ""))]
17428 "TARGET_USE_FANCY_MATH_387
17429 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17430 && flag_unsafe_math_optimizations"
17432 rtx op0 = gen_reg_rtx (XFmode);
17433 rtx op1 = gen_reg_rtx (XFmode);
17435 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17436 emit_insn (gen_frndintxf2_trunc (op0, op1));
17438 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17442 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17443 (define_insn_and_split "frndintxf2_mask_pm"
17444 [(set (match_operand:XF 0 "register_operand" "=f")
17445 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17446 UNSPEC_FRNDINT_MASK_PM))
17447 (clobber (reg:CC FLAGS_REG))]
17448 "TARGET_USE_FANCY_MATH_387
17449 && flag_unsafe_math_optimizations
17450 && !(reload_completed || reload_in_progress)"
17455 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17457 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17458 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17460 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17461 operands[2], operands[3]));
17464 [(set_attr "type" "frndint")
17465 (set_attr "i387_cw" "mask_pm")
17466 (set_attr "mode" "XF")])
17468 (define_insn "frndintxf2_mask_pm_i387"
17469 [(set (match_operand:XF 0 "register_operand" "=f")
17470 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17471 UNSPEC_FRNDINT_MASK_PM))
17472 (use (match_operand:HI 2 "memory_operand" "m"))
17473 (use (match_operand:HI 3 "memory_operand" "m"))]
17474 "TARGET_USE_FANCY_MATH_387
17475 && flag_unsafe_math_optimizations"
17476 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17477 [(set_attr "type" "frndint")
17478 (set_attr "i387_cw" "mask_pm")
17479 (set_attr "mode" "XF")])
17481 (define_expand "nearbyintxf2"
17482 [(use (match_operand:XF 0 "register_operand" ""))
17483 (use (match_operand:XF 1 "register_operand" ""))]
17484 "TARGET_USE_FANCY_MATH_387
17485 && flag_unsafe_math_optimizations"
17487 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17492 (define_expand "nearbyintdf2"
17493 [(use (match_operand:DF 0 "register_operand" ""))
17494 (use (match_operand:DF 1 "register_operand" ""))]
17495 "TARGET_USE_FANCY_MATH_387
17496 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17497 && flag_unsafe_math_optimizations"
17499 rtx op0 = gen_reg_rtx (XFmode);
17500 rtx op1 = gen_reg_rtx (XFmode);
17502 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17503 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17505 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17509 (define_expand "nearbyintsf2"
17510 [(use (match_operand:SF 0 "register_operand" ""))
17511 (use (match_operand:SF 1 "register_operand" ""))]
17512 "TARGET_USE_FANCY_MATH_387
17513 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17514 && flag_unsafe_math_optimizations"
17516 rtx op0 = gen_reg_rtx (XFmode);
17517 rtx op1 = gen_reg_rtx (XFmode);
17519 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17520 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17522 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17527 ;; Block operation instructions
17530 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17533 [(set_attr "type" "cld")])
17535 (define_expand "movmemsi"
17536 [(use (match_operand:BLK 0 "memory_operand" ""))
17537 (use (match_operand:BLK 1 "memory_operand" ""))
17538 (use (match_operand:SI 2 "nonmemory_operand" ""))
17539 (use (match_operand:SI 3 "const_int_operand" ""))]
17540 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17542 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17548 (define_expand "movmemdi"
17549 [(use (match_operand:BLK 0 "memory_operand" ""))
17550 (use (match_operand:BLK 1 "memory_operand" ""))
17551 (use (match_operand:DI 2 "nonmemory_operand" ""))
17552 (use (match_operand:DI 3 "const_int_operand" ""))]
17555 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17561 ;; Most CPUs don't like single string operations
17562 ;; Handle this case here to simplify previous expander.
17564 (define_expand "strmov"
17565 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17566 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17567 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17568 (clobber (reg:CC FLAGS_REG))])
17569 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17570 (clobber (reg:CC FLAGS_REG))])]
17573 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17575 /* If .md ever supports :P for Pmode, these can be directly
17576 in the pattern above. */
17577 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17578 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17580 if (TARGET_SINGLE_STRINGOP || optimize_size)
17582 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17583 operands[2], operands[3],
17584 operands[5], operands[6]));
17588 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17591 (define_expand "strmov_singleop"
17592 [(parallel [(set (match_operand 1 "memory_operand" "")
17593 (match_operand 3 "memory_operand" ""))
17594 (set (match_operand 0 "register_operand" "")
17595 (match_operand 4 "" ""))
17596 (set (match_operand 2 "register_operand" "")
17597 (match_operand 5 "" ""))
17598 (use (reg:SI DIRFLAG_REG))])]
17599 "TARGET_SINGLE_STRINGOP || optimize_size"
17602 (define_insn "*strmovdi_rex_1"
17603 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17604 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17605 (set (match_operand:DI 0 "register_operand" "=D")
17606 (plus:DI (match_dup 2)
17608 (set (match_operand:DI 1 "register_operand" "=S")
17609 (plus:DI (match_dup 3)
17611 (use (reg:SI DIRFLAG_REG))]
17612 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17614 [(set_attr "type" "str")
17615 (set_attr "mode" "DI")
17616 (set_attr "memory" "both")])
17618 (define_insn "*strmovsi_1"
17619 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17620 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17621 (set (match_operand:SI 0 "register_operand" "=D")
17622 (plus:SI (match_dup 2)
17624 (set (match_operand:SI 1 "register_operand" "=S")
17625 (plus:SI (match_dup 3)
17627 (use (reg:SI DIRFLAG_REG))]
17628 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17630 [(set_attr "type" "str")
17631 (set_attr "mode" "SI")
17632 (set_attr "memory" "both")])
17634 (define_insn "*strmovsi_rex_1"
17635 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17636 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17637 (set (match_operand:DI 0 "register_operand" "=D")
17638 (plus:DI (match_dup 2)
17640 (set (match_operand:DI 1 "register_operand" "=S")
17641 (plus:DI (match_dup 3)
17643 (use (reg:SI DIRFLAG_REG))]
17644 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17646 [(set_attr "type" "str")
17647 (set_attr "mode" "SI")
17648 (set_attr "memory" "both")])
17650 (define_insn "*strmovhi_1"
17651 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17652 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17653 (set (match_operand:SI 0 "register_operand" "=D")
17654 (plus:SI (match_dup 2)
17656 (set (match_operand:SI 1 "register_operand" "=S")
17657 (plus:SI (match_dup 3)
17659 (use (reg:SI DIRFLAG_REG))]
17660 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17662 [(set_attr "type" "str")
17663 (set_attr "memory" "both")
17664 (set_attr "mode" "HI")])
17666 (define_insn "*strmovhi_rex_1"
17667 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17668 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17669 (set (match_operand:DI 0 "register_operand" "=D")
17670 (plus:DI (match_dup 2)
17672 (set (match_operand:DI 1 "register_operand" "=S")
17673 (plus:DI (match_dup 3)
17675 (use (reg:SI DIRFLAG_REG))]
17676 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17678 [(set_attr "type" "str")
17679 (set_attr "memory" "both")
17680 (set_attr "mode" "HI")])
17682 (define_insn "*strmovqi_1"
17683 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17684 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17685 (set (match_operand:SI 0 "register_operand" "=D")
17686 (plus:SI (match_dup 2)
17688 (set (match_operand:SI 1 "register_operand" "=S")
17689 (plus:SI (match_dup 3)
17691 (use (reg:SI DIRFLAG_REG))]
17692 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17694 [(set_attr "type" "str")
17695 (set_attr "memory" "both")
17696 (set_attr "mode" "QI")])
17698 (define_insn "*strmovqi_rex_1"
17699 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17700 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17701 (set (match_operand:DI 0 "register_operand" "=D")
17702 (plus:DI (match_dup 2)
17704 (set (match_operand:DI 1 "register_operand" "=S")
17705 (plus:DI (match_dup 3)
17707 (use (reg:SI DIRFLAG_REG))]
17708 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17710 [(set_attr "type" "str")
17711 (set_attr "memory" "both")
17712 (set_attr "mode" "QI")])
17714 (define_expand "rep_mov"
17715 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17716 (set (match_operand 0 "register_operand" "")
17717 (match_operand 5 "" ""))
17718 (set (match_operand 2 "register_operand" "")
17719 (match_operand 6 "" ""))
17720 (set (match_operand 1 "memory_operand" "")
17721 (match_operand 3 "memory_operand" ""))
17722 (use (match_dup 4))
17723 (use (reg:SI DIRFLAG_REG))])]
17727 (define_insn "*rep_movdi_rex64"
17728 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17729 (set (match_operand:DI 0 "register_operand" "=D")
17730 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17732 (match_operand:DI 3 "register_operand" "0")))
17733 (set (match_operand:DI 1 "register_operand" "=S")
17734 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17735 (match_operand:DI 4 "register_operand" "1")))
17736 (set (mem:BLK (match_dup 3))
17737 (mem:BLK (match_dup 4)))
17738 (use (match_dup 5))
17739 (use (reg:SI DIRFLAG_REG))]
17741 "{rep\;movsq|rep movsq}"
17742 [(set_attr "type" "str")
17743 (set_attr "prefix_rep" "1")
17744 (set_attr "memory" "both")
17745 (set_attr "mode" "DI")])
17747 (define_insn "*rep_movsi"
17748 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17749 (set (match_operand:SI 0 "register_operand" "=D")
17750 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17752 (match_operand:SI 3 "register_operand" "0")))
17753 (set (match_operand:SI 1 "register_operand" "=S")
17754 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17755 (match_operand:SI 4 "register_operand" "1")))
17756 (set (mem:BLK (match_dup 3))
17757 (mem:BLK (match_dup 4)))
17758 (use (match_dup 5))
17759 (use (reg:SI DIRFLAG_REG))]
17761 "{rep\;movsl|rep movsd}"
17762 [(set_attr "type" "str")
17763 (set_attr "prefix_rep" "1")
17764 (set_attr "memory" "both")
17765 (set_attr "mode" "SI")])
17767 (define_insn "*rep_movsi_rex64"
17768 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17769 (set (match_operand:DI 0 "register_operand" "=D")
17770 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17772 (match_operand:DI 3 "register_operand" "0")))
17773 (set (match_operand:DI 1 "register_operand" "=S")
17774 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17775 (match_operand:DI 4 "register_operand" "1")))
17776 (set (mem:BLK (match_dup 3))
17777 (mem:BLK (match_dup 4)))
17778 (use (match_dup 5))
17779 (use (reg:SI DIRFLAG_REG))]
17781 "{rep\;movsl|rep movsd}"
17782 [(set_attr "type" "str")
17783 (set_attr "prefix_rep" "1")
17784 (set_attr "memory" "both")
17785 (set_attr "mode" "SI")])
17787 (define_insn "*rep_movqi"
17788 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17789 (set (match_operand:SI 0 "register_operand" "=D")
17790 (plus:SI (match_operand:SI 3 "register_operand" "0")
17791 (match_operand:SI 5 "register_operand" "2")))
17792 (set (match_operand:SI 1 "register_operand" "=S")
17793 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17794 (set (mem:BLK (match_dup 3))
17795 (mem:BLK (match_dup 4)))
17796 (use (match_dup 5))
17797 (use (reg:SI DIRFLAG_REG))]
17799 "{rep\;movsb|rep movsb}"
17800 [(set_attr "type" "str")
17801 (set_attr "prefix_rep" "1")
17802 (set_attr "memory" "both")
17803 (set_attr "mode" "SI")])
17805 (define_insn "*rep_movqi_rex64"
17806 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17807 (set (match_operand:DI 0 "register_operand" "=D")
17808 (plus:DI (match_operand:DI 3 "register_operand" "0")
17809 (match_operand:DI 5 "register_operand" "2")))
17810 (set (match_operand:DI 1 "register_operand" "=S")
17811 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17812 (set (mem:BLK (match_dup 3))
17813 (mem:BLK (match_dup 4)))
17814 (use (match_dup 5))
17815 (use (reg:SI DIRFLAG_REG))]
17817 "{rep\;movsb|rep movsb}"
17818 [(set_attr "type" "str")
17819 (set_attr "prefix_rep" "1")
17820 (set_attr "memory" "both")
17821 (set_attr "mode" "SI")])
17823 (define_expand "setmemsi"
17824 [(use (match_operand:BLK 0 "memory_operand" ""))
17825 (use (match_operand:SI 1 "nonmemory_operand" ""))
17826 (use (match_operand 2 "const_int_operand" ""))
17827 (use (match_operand 3 "const_int_operand" ""))]
17830 /* If value to set is not zero, use the library routine. */
17831 if (operands[2] != const0_rtx)
17834 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17840 (define_expand "setmemdi"
17841 [(use (match_operand:BLK 0 "memory_operand" ""))
17842 (use (match_operand:DI 1 "nonmemory_operand" ""))
17843 (use (match_operand 2 "const_int_operand" ""))
17844 (use (match_operand 3 "const_int_operand" ""))]
17847 /* If value to set is not zero, use the library routine. */
17848 if (operands[2] != const0_rtx)
17851 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17857 ;; Most CPUs don't like single string operations
17858 ;; Handle this case here to simplify previous expander.
17860 (define_expand "strset"
17861 [(set (match_operand 1 "memory_operand" "")
17862 (match_operand 2 "register_operand" ""))
17863 (parallel [(set (match_operand 0 "register_operand" "")
17865 (clobber (reg:CC FLAGS_REG))])]
17868 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17869 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17871 /* If .md ever supports :P for Pmode, this can be directly
17872 in the pattern above. */
17873 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17874 GEN_INT (GET_MODE_SIZE (GET_MODE
17876 if (TARGET_SINGLE_STRINGOP || optimize_size)
17878 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17884 (define_expand "strset_singleop"
17885 [(parallel [(set (match_operand 1 "memory_operand" "")
17886 (match_operand 2 "register_operand" ""))
17887 (set (match_operand 0 "register_operand" "")
17888 (match_operand 3 "" ""))
17889 (use (reg:SI DIRFLAG_REG))])]
17890 "TARGET_SINGLE_STRINGOP || optimize_size"
17893 (define_insn "*strsetdi_rex_1"
17894 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17895 (match_operand:DI 2 "register_operand" "a"))
17896 (set (match_operand:DI 0 "register_operand" "=D")
17897 (plus:DI (match_dup 1)
17899 (use (reg:SI DIRFLAG_REG))]
17900 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17902 [(set_attr "type" "str")
17903 (set_attr "memory" "store")
17904 (set_attr "mode" "DI")])
17906 (define_insn "*strsetsi_1"
17907 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17908 (match_operand:SI 2 "register_operand" "a"))
17909 (set (match_operand:SI 0 "register_operand" "=D")
17910 (plus:SI (match_dup 1)
17912 (use (reg:SI DIRFLAG_REG))]
17913 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17915 [(set_attr "type" "str")
17916 (set_attr "memory" "store")
17917 (set_attr "mode" "SI")])
17919 (define_insn "*strsetsi_rex_1"
17920 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17921 (match_operand:SI 2 "register_operand" "a"))
17922 (set (match_operand:DI 0 "register_operand" "=D")
17923 (plus:DI (match_dup 1)
17925 (use (reg:SI DIRFLAG_REG))]
17926 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17928 [(set_attr "type" "str")
17929 (set_attr "memory" "store")
17930 (set_attr "mode" "SI")])
17932 (define_insn "*strsethi_1"
17933 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17934 (match_operand:HI 2 "register_operand" "a"))
17935 (set (match_operand:SI 0 "register_operand" "=D")
17936 (plus:SI (match_dup 1)
17938 (use (reg:SI DIRFLAG_REG))]
17939 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17941 [(set_attr "type" "str")
17942 (set_attr "memory" "store")
17943 (set_attr "mode" "HI")])
17945 (define_insn "*strsethi_rex_1"
17946 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17947 (match_operand:HI 2 "register_operand" "a"))
17948 (set (match_operand:DI 0 "register_operand" "=D")
17949 (plus:DI (match_dup 1)
17951 (use (reg:SI DIRFLAG_REG))]
17952 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17954 [(set_attr "type" "str")
17955 (set_attr "memory" "store")
17956 (set_attr "mode" "HI")])
17958 (define_insn "*strsetqi_1"
17959 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17960 (match_operand:QI 2 "register_operand" "a"))
17961 (set (match_operand:SI 0 "register_operand" "=D")
17962 (plus:SI (match_dup 1)
17964 (use (reg:SI DIRFLAG_REG))]
17965 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17967 [(set_attr "type" "str")
17968 (set_attr "memory" "store")
17969 (set_attr "mode" "QI")])
17971 (define_insn "*strsetqi_rex_1"
17972 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17973 (match_operand:QI 2 "register_operand" "a"))
17974 (set (match_operand:DI 0 "register_operand" "=D")
17975 (plus:DI (match_dup 1)
17977 (use (reg:SI DIRFLAG_REG))]
17978 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17980 [(set_attr "type" "str")
17981 (set_attr "memory" "store")
17982 (set_attr "mode" "QI")])
17984 (define_expand "rep_stos"
17985 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17986 (set (match_operand 0 "register_operand" "")
17987 (match_operand 4 "" ""))
17988 (set (match_operand 2 "memory_operand" "") (const_int 0))
17989 (use (match_operand 3 "register_operand" ""))
17990 (use (match_dup 1))
17991 (use (reg:SI DIRFLAG_REG))])]
17995 (define_insn "*rep_stosdi_rex64"
17996 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17997 (set (match_operand:DI 0 "register_operand" "=D")
17998 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18000 (match_operand:DI 3 "register_operand" "0")))
18001 (set (mem:BLK (match_dup 3))
18003 (use (match_operand:DI 2 "register_operand" "a"))
18004 (use (match_dup 4))
18005 (use (reg:SI DIRFLAG_REG))]
18007 "{rep\;stosq|rep stosq}"
18008 [(set_attr "type" "str")
18009 (set_attr "prefix_rep" "1")
18010 (set_attr "memory" "store")
18011 (set_attr "mode" "DI")])
18013 (define_insn "*rep_stossi"
18014 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18015 (set (match_operand:SI 0 "register_operand" "=D")
18016 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18018 (match_operand:SI 3 "register_operand" "0")))
18019 (set (mem:BLK (match_dup 3))
18021 (use (match_operand:SI 2 "register_operand" "a"))
18022 (use (match_dup 4))
18023 (use (reg:SI DIRFLAG_REG))]
18025 "{rep\;stosl|rep stosd}"
18026 [(set_attr "type" "str")
18027 (set_attr "prefix_rep" "1")
18028 (set_attr "memory" "store")
18029 (set_attr "mode" "SI")])
18031 (define_insn "*rep_stossi_rex64"
18032 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18033 (set (match_operand:DI 0 "register_operand" "=D")
18034 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18036 (match_operand:DI 3 "register_operand" "0")))
18037 (set (mem:BLK (match_dup 3))
18039 (use (match_operand:SI 2 "register_operand" "a"))
18040 (use (match_dup 4))
18041 (use (reg:SI DIRFLAG_REG))]
18043 "{rep\;stosl|rep stosd}"
18044 [(set_attr "type" "str")
18045 (set_attr "prefix_rep" "1")
18046 (set_attr "memory" "store")
18047 (set_attr "mode" "SI")])
18049 (define_insn "*rep_stosqi"
18050 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18051 (set (match_operand:SI 0 "register_operand" "=D")
18052 (plus:SI (match_operand:SI 3 "register_operand" "0")
18053 (match_operand:SI 4 "register_operand" "1")))
18054 (set (mem:BLK (match_dup 3))
18056 (use (match_operand:QI 2 "register_operand" "a"))
18057 (use (match_dup 4))
18058 (use (reg:SI DIRFLAG_REG))]
18060 "{rep\;stosb|rep stosb}"
18061 [(set_attr "type" "str")
18062 (set_attr "prefix_rep" "1")
18063 (set_attr "memory" "store")
18064 (set_attr "mode" "QI")])
18066 (define_insn "*rep_stosqi_rex64"
18067 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18068 (set (match_operand:DI 0 "register_operand" "=D")
18069 (plus:DI (match_operand:DI 3 "register_operand" "0")
18070 (match_operand:DI 4 "register_operand" "1")))
18071 (set (mem:BLK (match_dup 3))
18073 (use (match_operand:QI 2 "register_operand" "a"))
18074 (use (match_dup 4))
18075 (use (reg:SI DIRFLAG_REG))]
18077 "{rep\;stosb|rep stosb}"
18078 [(set_attr "type" "str")
18079 (set_attr "prefix_rep" "1")
18080 (set_attr "memory" "store")
18081 (set_attr "mode" "QI")])
18083 (define_expand "cmpstrnsi"
18084 [(set (match_operand:SI 0 "register_operand" "")
18085 (compare:SI (match_operand:BLK 1 "general_operand" "")
18086 (match_operand:BLK 2 "general_operand" "")))
18087 (use (match_operand 3 "general_operand" ""))
18088 (use (match_operand 4 "immediate_operand" ""))]
18089 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18091 rtx addr1, addr2, out, outlow, count, countreg, align;
18093 /* Can't use this if the user has appropriated esi or edi. */
18094 if (global_regs[4] || global_regs[5])
18098 if (GET_CODE (out) != REG)
18099 out = gen_reg_rtx (SImode);
18101 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18102 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18103 if (addr1 != XEXP (operands[1], 0))
18104 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18105 if (addr2 != XEXP (operands[2], 0))
18106 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18108 count = operands[3];
18109 countreg = ix86_zero_extend_to_Pmode (count);
18111 /* %%% Iff we are testing strict equality, we can use known alignment
18112 to good advantage. This may be possible with combine, particularly
18113 once cc0 is dead. */
18114 align = operands[4];
18116 emit_insn (gen_cld ());
18117 if (GET_CODE (count) == CONST_INT)
18119 if (INTVAL (count) == 0)
18121 emit_move_insn (operands[0], const0_rtx);
18124 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18125 operands[1], operands[2]));
18130 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18132 emit_insn (gen_cmpsi_1 (countreg, countreg));
18133 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18134 operands[1], operands[2]));
18137 outlow = gen_lowpart (QImode, out);
18138 emit_insn (gen_cmpintqi (outlow));
18139 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18141 if (operands[0] != out)
18142 emit_move_insn (operands[0], out);
18147 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18149 (define_expand "cmpintqi"
18150 [(set (match_dup 1)
18151 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18153 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18154 (parallel [(set (match_operand:QI 0 "register_operand" "")
18155 (minus:QI (match_dup 1)
18157 (clobber (reg:CC FLAGS_REG))])]
18159 "operands[1] = gen_reg_rtx (QImode);
18160 operands[2] = gen_reg_rtx (QImode);")
18162 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18163 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18165 (define_expand "cmpstrnqi_nz_1"
18166 [(parallel [(set (reg:CC FLAGS_REG)
18167 (compare:CC (match_operand 4 "memory_operand" "")
18168 (match_operand 5 "memory_operand" "")))
18169 (use (match_operand 2 "register_operand" ""))
18170 (use (match_operand:SI 3 "immediate_operand" ""))
18171 (use (reg:SI DIRFLAG_REG))
18172 (clobber (match_operand 0 "register_operand" ""))
18173 (clobber (match_operand 1 "register_operand" ""))
18174 (clobber (match_dup 2))])]
18178 (define_insn "*cmpstrnqi_nz_1"
18179 [(set (reg:CC FLAGS_REG)
18180 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18181 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18182 (use (match_operand:SI 6 "register_operand" "2"))
18183 (use (match_operand:SI 3 "immediate_operand" "i"))
18184 (use (reg:SI DIRFLAG_REG))
18185 (clobber (match_operand:SI 0 "register_operand" "=S"))
18186 (clobber (match_operand:SI 1 "register_operand" "=D"))
18187 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18190 [(set_attr "type" "str")
18191 (set_attr "mode" "QI")
18192 (set_attr "prefix_rep" "1")])
18194 (define_insn "*cmpstrnqi_nz_rex_1"
18195 [(set (reg:CC FLAGS_REG)
18196 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18197 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18198 (use (match_operand:DI 6 "register_operand" "2"))
18199 (use (match_operand:SI 3 "immediate_operand" "i"))
18200 (use (reg:SI DIRFLAG_REG))
18201 (clobber (match_operand:DI 0 "register_operand" "=S"))
18202 (clobber (match_operand:DI 1 "register_operand" "=D"))
18203 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18206 [(set_attr "type" "str")
18207 (set_attr "mode" "QI")
18208 (set_attr "prefix_rep" "1")])
18210 ;; The same, but the count is not known to not be zero.
18212 (define_expand "cmpstrnqi_1"
18213 [(parallel [(set (reg:CC FLAGS_REG)
18214 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18216 (compare:CC (match_operand 4 "memory_operand" "")
18217 (match_operand 5 "memory_operand" ""))
18219 (use (match_operand:SI 3 "immediate_operand" ""))
18220 (use (reg:CC FLAGS_REG))
18221 (use (reg:SI DIRFLAG_REG))
18222 (clobber (match_operand 0 "register_operand" ""))
18223 (clobber (match_operand 1 "register_operand" ""))
18224 (clobber (match_dup 2))])]
18228 (define_insn "*cmpstrnqi_1"
18229 [(set (reg:CC FLAGS_REG)
18230 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18232 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18233 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18235 (use (match_operand:SI 3 "immediate_operand" "i"))
18236 (use (reg:CC FLAGS_REG))
18237 (use (reg:SI DIRFLAG_REG))
18238 (clobber (match_operand:SI 0 "register_operand" "=S"))
18239 (clobber (match_operand:SI 1 "register_operand" "=D"))
18240 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18243 [(set_attr "type" "str")
18244 (set_attr "mode" "QI")
18245 (set_attr "prefix_rep" "1")])
18247 (define_insn "*cmpstrnqi_rex_1"
18248 [(set (reg:CC FLAGS_REG)
18249 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18251 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18252 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18254 (use (match_operand:SI 3 "immediate_operand" "i"))
18255 (use (reg:CC FLAGS_REG))
18256 (use (reg:SI DIRFLAG_REG))
18257 (clobber (match_operand:DI 0 "register_operand" "=S"))
18258 (clobber (match_operand:DI 1 "register_operand" "=D"))
18259 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18262 [(set_attr "type" "str")
18263 (set_attr "mode" "QI")
18264 (set_attr "prefix_rep" "1")])
18266 (define_expand "strlensi"
18267 [(set (match_operand:SI 0 "register_operand" "")
18268 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18269 (match_operand:QI 2 "immediate_operand" "")
18270 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18273 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18279 (define_expand "strlendi"
18280 [(set (match_operand:DI 0 "register_operand" "")
18281 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18282 (match_operand:QI 2 "immediate_operand" "")
18283 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18286 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18292 (define_expand "strlenqi_1"
18293 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18294 (use (reg:SI DIRFLAG_REG))
18295 (clobber (match_operand 1 "register_operand" ""))
18296 (clobber (reg:CC FLAGS_REG))])]
18300 (define_insn "*strlenqi_1"
18301 [(set (match_operand:SI 0 "register_operand" "=&c")
18302 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18303 (match_operand:QI 2 "register_operand" "a")
18304 (match_operand:SI 3 "immediate_operand" "i")
18305 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18306 (use (reg:SI DIRFLAG_REG))
18307 (clobber (match_operand:SI 1 "register_operand" "=D"))
18308 (clobber (reg:CC FLAGS_REG))]
18311 [(set_attr "type" "str")
18312 (set_attr "mode" "QI")
18313 (set_attr "prefix_rep" "1")])
18315 (define_insn "*strlenqi_rex_1"
18316 [(set (match_operand:DI 0 "register_operand" "=&c")
18317 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18318 (match_operand:QI 2 "register_operand" "a")
18319 (match_operand:DI 3 "immediate_operand" "i")
18320 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18321 (use (reg:SI DIRFLAG_REG))
18322 (clobber (match_operand:DI 1 "register_operand" "=D"))
18323 (clobber (reg:CC FLAGS_REG))]
18326 [(set_attr "type" "str")
18327 (set_attr "mode" "QI")
18328 (set_attr "prefix_rep" "1")])
18330 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18331 ;; handled in combine, but it is not currently up to the task.
18332 ;; When used for their truth value, the cmpstrn* expanders generate
18341 ;; The intermediate three instructions are unnecessary.
18343 ;; This one handles cmpstrn*_nz_1...
18346 (set (reg:CC FLAGS_REG)
18347 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18348 (mem:BLK (match_operand 5 "register_operand" ""))))
18349 (use (match_operand 6 "register_operand" ""))
18350 (use (match_operand:SI 3 "immediate_operand" ""))
18351 (use (reg:SI DIRFLAG_REG))
18352 (clobber (match_operand 0 "register_operand" ""))
18353 (clobber (match_operand 1 "register_operand" ""))
18354 (clobber (match_operand 2 "register_operand" ""))])
18355 (set (match_operand:QI 7 "register_operand" "")
18356 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18357 (set (match_operand:QI 8 "register_operand" "")
18358 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18359 (set (reg FLAGS_REG)
18360 (compare (match_dup 7) (match_dup 8)))
18362 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18364 (set (reg:CC FLAGS_REG)
18365 (compare:CC (mem:BLK (match_dup 4))
18366 (mem:BLK (match_dup 5))))
18367 (use (match_dup 6))
18368 (use (match_dup 3))
18369 (use (reg:SI DIRFLAG_REG))
18370 (clobber (match_dup 0))
18371 (clobber (match_dup 1))
18372 (clobber (match_dup 2))])]
18375 ;; ...and this one handles cmpstrn*_1.
18378 (set (reg:CC FLAGS_REG)
18379 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18381 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18382 (mem:BLK (match_operand 5 "register_operand" "")))
18384 (use (match_operand:SI 3 "immediate_operand" ""))
18385 (use (reg:CC FLAGS_REG))
18386 (use (reg:SI DIRFLAG_REG))
18387 (clobber (match_operand 0 "register_operand" ""))
18388 (clobber (match_operand 1 "register_operand" ""))
18389 (clobber (match_operand 2 "register_operand" ""))])
18390 (set (match_operand:QI 7 "register_operand" "")
18391 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18392 (set (match_operand:QI 8 "register_operand" "")
18393 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18394 (set (reg FLAGS_REG)
18395 (compare (match_dup 7) (match_dup 8)))
18397 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18399 (set (reg:CC FLAGS_REG)
18400 (if_then_else:CC (ne (match_dup 6)
18402 (compare:CC (mem:BLK (match_dup 4))
18403 (mem:BLK (match_dup 5)))
18405 (use (match_dup 3))
18406 (use (reg:CC FLAGS_REG))
18407 (use (reg:SI DIRFLAG_REG))
18408 (clobber (match_dup 0))
18409 (clobber (match_dup 1))
18410 (clobber (match_dup 2))])]
18415 ;; Conditional move instructions.
18417 (define_expand "movdicc"
18418 [(set (match_operand:DI 0 "register_operand" "")
18419 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18420 (match_operand:DI 2 "general_operand" "")
18421 (match_operand:DI 3 "general_operand" "")))]
18423 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18425 (define_insn "x86_movdicc_0_m1_rex64"
18426 [(set (match_operand:DI 0 "register_operand" "=r")
18427 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18430 (clobber (reg:CC FLAGS_REG))]
18433 ; Since we don't have the proper number of operands for an alu insn,
18434 ; fill in all the blanks.
18435 [(set_attr "type" "alu")
18436 (set_attr "pent_pair" "pu")
18437 (set_attr "memory" "none")
18438 (set_attr "imm_disp" "false")
18439 (set_attr "mode" "DI")
18440 (set_attr "length_immediate" "0")])
18442 (define_insn "*movdicc_c_rex64"
18443 [(set (match_operand:DI 0 "register_operand" "=r,r")
18444 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18445 [(reg FLAGS_REG) (const_int 0)])
18446 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18447 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18448 "TARGET_64BIT && TARGET_CMOVE
18449 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18451 cmov%O2%C1\t{%2, %0|%0, %2}
18452 cmov%O2%c1\t{%3, %0|%0, %3}"
18453 [(set_attr "type" "icmov")
18454 (set_attr "mode" "DI")])
18456 (define_expand "movsicc"
18457 [(set (match_operand:SI 0 "register_operand" "")
18458 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18459 (match_operand:SI 2 "general_operand" "")
18460 (match_operand:SI 3 "general_operand" "")))]
18462 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18464 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18465 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18466 ;; So just document what we're doing explicitly.
18468 (define_insn "x86_movsicc_0_m1"
18469 [(set (match_operand:SI 0 "register_operand" "=r")
18470 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18473 (clobber (reg:CC FLAGS_REG))]
18476 ; Since we don't have the proper number of operands for an alu insn,
18477 ; fill in all the blanks.
18478 [(set_attr "type" "alu")
18479 (set_attr "pent_pair" "pu")
18480 (set_attr "memory" "none")
18481 (set_attr "imm_disp" "false")
18482 (set_attr "mode" "SI")
18483 (set_attr "length_immediate" "0")])
18485 (define_insn "*movsicc_noc"
18486 [(set (match_operand:SI 0 "register_operand" "=r,r")
18487 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18488 [(reg FLAGS_REG) (const_int 0)])
18489 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18490 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18492 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18494 cmov%O2%C1\t{%2, %0|%0, %2}
18495 cmov%O2%c1\t{%3, %0|%0, %3}"
18496 [(set_attr "type" "icmov")
18497 (set_attr "mode" "SI")])
18499 (define_expand "movhicc"
18500 [(set (match_operand:HI 0 "register_operand" "")
18501 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18502 (match_operand:HI 2 "general_operand" "")
18503 (match_operand:HI 3 "general_operand" "")))]
18504 "TARGET_HIMODE_MATH"
18505 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18507 (define_insn "*movhicc_noc"
18508 [(set (match_operand:HI 0 "register_operand" "=r,r")
18509 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18510 [(reg FLAGS_REG) (const_int 0)])
18511 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18512 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18514 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18516 cmov%O2%C1\t{%2, %0|%0, %2}
18517 cmov%O2%c1\t{%3, %0|%0, %3}"
18518 [(set_attr "type" "icmov")
18519 (set_attr "mode" "HI")])
18521 (define_expand "movqicc"
18522 [(set (match_operand:QI 0 "register_operand" "")
18523 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18524 (match_operand:QI 2 "general_operand" "")
18525 (match_operand:QI 3 "general_operand" "")))]
18526 "TARGET_QIMODE_MATH"
18527 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18529 (define_insn_and_split "*movqicc_noc"
18530 [(set (match_operand:QI 0 "register_operand" "=r,r")
18531 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18532 [(match_operand 4 "flags_reg_operand" "")
18534 (match_operand:QI 2 "register_operand" "r,0")
18535 (match_operand:QI 3 "register_operand" "0,r")))]
18536 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18538 "&& reload_completed"
18539 [(set (match_dup 0)
18540 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18543 "operands[0] = gen_lowpart (SImode, operands[0]);
18544 operands[2] = gen_lowpart (SImode, operands[2]);
18545 operands[3] = gen_lowpart (SImode, operands[3]);"
18546 [(set_attr "type" "icmov")
18547 (set_attr "mode" "SI")])
18549 (define_expand "movsfcc"
18550 [(set (match_operand:SF 0 "register_operand" "")
18551 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18552 (match_operand:SF 2 "register_operand" "")
18553 (match_operand:SF 3 "register_operand" "")))]
18554 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18555 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18557 (define_insn "*movsfcc_1_387"
18558 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18559 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18560 [(reg FLAGS_REG) (const_int 0)])
18561 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18562 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18563 "TARGET_80387 && TARGET_CMOVE
18564 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18566 fcmov%F1\t{%2, %0|%0, %2}
18567 fcmov%f1\t{%3, %0|%0, %3}
18568 cmov%O2%C1\t{%2, %0|%0, %2}
18569 cmov%O2%c1\t{%3, %0|%0, %3}"
18570 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18571 (set_attr "mode" "SF,SF,SI,SI")])
18573 (define_expand "movdfcc"
18574 [(set (match_operand:DF 0 "register_operand" "")
18575 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18576 (match_operand:DF 2 "register_operand" "")
18577 (match_operand:DF 3 "register_operand" "")))]
18578 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18579 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18581 (define_insn "*movdfcc_1"
18582 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18583 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18584 [(reg FLAGS_REG) (const_int 0)])
18585 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18586 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18587 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18588 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18590 fcmov%F1\t{%2, %0|%0, %2}
18591 fcmov%f1\t{%3, %0|%0, %3}
18594 [(set_attr "type" "fcmov,fcmov,multi,multi")
18595 (set_attr "mode" "DF")])
18597 (define_insn "*movdfcc_1_rex64"
18598 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18599 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18600 [(reg FLAGS_REG) (const_int 0)])
18601 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18602 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18603 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18604 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18606 fcmov%F1\t{%2, %0|%0, %2}
18607 fcmov%f1\t{%3, %0|%0, %3}
18608 cmov%O2%C1\t{%2, %0|%0, %2}
18609 cmov%O2%c1\t{%3, %0|%0, %3}"
18610 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18611 (set_attr "mode" "DF")])
18614 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18615 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18616 [(match_operand 4 "flags_reg_operand" "")
18618 (match_operand:DF 2 "nonimmediate_operand" "")
18619 (match_operand:DF 3 "nonimmediate_operand" "")))]
18620 "!TARGET_64BIT && reload_completed"
18621 [(set (match_dup 2)
18622 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18626 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18629 "split_di (operands+2, 1, operands+5, operands+6);
18630 split_di (operands+3, 1, operands+7, operands+8);
18631 split_di (operands, 1, operands+2, operands+3);")
18633 (define_expand "movxfcc"
18634 [(set (match_operand:XF 0 "register_operand" "")
18635 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18636 (match_operand:XF 2 "register_operand" "")
18637 (match_operand:XF 3 "register_operand" "")))]
18638 "TARGET_80387 && TARGET_CMOVE"
18639 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18641 (define_insn "*movxfcc_1"
18642 [(set (match_operand:XF 0 "register_operand" "=f,f")
18643 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18644 [(reg FLAGS_REG) (const_int 0)])
18645 (match_operand:XF 2 "register_operand" "f,0")
18646 (match_operand:XF 3 "register_operand" "0,f")))]
18647 "TARGET_80387 && TARGET_CMOVE"
18649 fcmov%F1\t{%2, %0|%0, %2}
18650 fcmov%f1\t{%3, %0|%0, %3}"
18651 [(set_attr "type" "fcmov")
18652 (set_attr "mode" "XF")])
18654 ;; These versions of the min/max patterns are intentionally ignorant of
18655 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18656 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18657 ;; are undefined in this condition, we're certain this is correct.
18659 (define_insn "sminsf3"
18660 [(set (match_operand:SF 0 "register_operand" "=x")
18661 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18662 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18664 "minss\t{%2, %0|%0, %2}"
18665 [(set_attr "type" "sseadd")
18666 (set_attr "mode" "SF")])
18668 (define_insn "smaxsf3"
18669 [(set (match_operand:SF 0 "register_operand" "=x")
18670 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18671 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18673 "maxss\t{%2, %0|%0, %2}"
18674 [(set_attr "type" "sseadd")
18675 (set_attr "mode" "SF")])
18677 (define_insn "smindf3"
18678 [(set (match_operand:DF 0 "register_operand" "=x")
18679 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18680 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18681 "TARGET_SSE2 && TARGET_SSE_MATH"
18682 "minsd\t{%2, %0|%0, %2}"
18683 [(set_attr "type" "sseadd")
18684 (set_attr "mode" "DF")])
18686 (define_insn "smaxdf3"
18687 [(set (match_operand:DF 0 "register_operand" "=x")
18688 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18689 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18690 "TARGET_SSE2 && TARGET_SSE_MATH"
18691 "maxsd\t{%2, %0|%0, %2}"
18692 [(set_attr "type" "sseadd")
18693 (set_attr "mode" "DF")])
18695 ;; These versions of the min/max patterns implement exactly the operations
18696 ;; min = (op1 < op2 ? op1 : op2)
18697 ;; max = (!(op1 < op2) ? op1 : op2)
18698 ;; Their operands are not commutative, and thus they may be used in the
18699 ;; presence of -0.0 and NaN.
18701 (define_insn "*ieee_sminsf3"
18702 [(set (match_operand:SF 0 "register_operand" "=x")
18703 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18704 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18707 "minss\t{%2, %0|%0, %2}"
18708 [(set_attr "type" "sseadd")
18709 (set_attr "mode" "SF")])
18711 (define_insn "*ieee_smaxsf3"
18712 [(set (match_operand:SF 0 "register_operand" "=x")
18713 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18714 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18717 "maxss\t{%2, %0|%0, %2}"
18718 [(set_attr "type" "sseadd")
18719 (set_attr "mode" "SF")])
18721 (define_insn "*ieee_smindf3"
18722 [(set (match_operand:DF 0 "register_operand" "=x")
18723 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18724 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18726 "TARGET_SSE2 && TARGET_SSE_MATH"
18727 "minsd\t{%2, %0|%0, %2}"
18728 [(set_attr "type" "sseadd")
18729 (set_attr "mode" "DF")])
18731 (define_insn "*ieee_smaxdf3"
18732 [(set (match_operand:DF 0 "register_operand" "=x")
18733 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18734 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18736 "TARGET_SSE2 && TARGET_SSE_MATH"
18737 "maxsd\t{%2, %0|%0, %2}"
18738 [(set_attr "type" "sseadd")
18739 (set_attr "mode" "DF")])
18741 ;; Conditional addition patterns
18742 (define_expand "addqicc"
18743 [(match_operand:QI 0 "register_operand" "")
18744 (match_operand 1 "comparison_operator" "")
18745 (match_operand:QI 2 "register_operand" "")
18746 (match_operand:QI 3 "const_int_operand" "")]
18748 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18750 (define_expand "addhicc"
18751 [(match_operand:HI 0 "register_operand" "")
18752 (match_operand 1 "comparison_operator" "")
18753 (match_operand:HI 2 "register_operand" "")
18754 (match_operand:HI 3 "const_int_operand" "")]
18756 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18758 (define_expand "addsicc"
18759 [(match_operand:SI 0 "register_operand" "")
18760 (match_operand 1 "comparison_operator" "")
18761 (match_operand:SI 2 "register_operand" "")
18762 (match_operand:SI 3 "const_int_operand" "")]
18764 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18766 (define_expand "adddicc"
18767 [(match_operand:DI 0 "register_operand" "")
18768 (match_operand 1 "comparison_operator" "")
18769 (match_operand:DI 2 "register_operand" "")
18770 (match_operand:DI 3 "const_int_operand" "")]
18772 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18775 ;; Misc patterns (?)
18777 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18778 ;; Otherwise there will be nothing to keep
18780 ;; [(set (reg ebp) (reg esp))]
18781 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18782 ;; (clobber (eflags)]
18783 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18785 ;; in proper program order.
18786 (define_insn "pro_epilogue_adjust_stack_1"
18787 [(set (match_operand:SI 0 "register_operand" "=r,r")
18788 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18789 (match_operand:SI 2 "immediate_operand" "i,i")))
18790 (clobber (reg:CC FLAGS_REG))
18791 (clobber (mem:BLK (scratch)))]
18794 switch (get_attr_type (insn))
18797 return "mov{l}\t{%1, %0|%0, %1}";
18800 if (GET_CODE (operands[2]) == CONST_INT
18801 && (INTVAL (operands[2]) == 128
18802 || (INTVAL (operands[2]) < 0
18803 && INTVAL (operands[2]) != -128)))
18805 operands[2] = GEN_INT (-INTVAL (operands[2]));
18806 return "sub{l}\t{%2, %0|%0, %2}";
18808 return "add{l}\t{%2, %0|%0, %2}";
18811 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18812 return "lea{l}\t{%a2, %0|%0, %a2}";
18815 gcc_unreachable ();
18818 [(set (attr "type")
18819 (cond [(eq_attr "alternative" "0")
18820 (const_string "alu")
18821 (match_operand:SI 2 "const0_operand" "")
18822 (const_string "imov")
18824 (const_string "lea")))
18825 (set_attr "mode" "SI")])
18827 (define_insn "pro_epilogue_adjust_stack_rex64"
18828 [(set (match_operand:DI 0 "register_operand" "=r,r")
18829 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18830 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18831 (clobber (reg:CC FLAGS_REG))
18832 (clobber (mem:BLK (scratch)))]
18835 switch (get_attr_type (insn))
18838 return "mov{q}\t{%1, %0|%0, %1}";
18841 if (GET_CODE (operands[2]) == CONST_INT
18842 /* Avoid overflows. */
18843 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18844 && (INTVAL (operands[2]) == 128
18845 || (INTVAL (operands[2]) < 0
18846 && INTVAL (operands[2]) != -128)))
18848 operands[2] = GEN_INT (-INTVAL (operands[2]));
18849 return "sub{q}\t{%2, %0|%0, %2}";
18851 return "add{q}\t{%2, %0|%0, %2}";
18854 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18855 return "lea{q}\t{%a2, %0|%0, %a2}";
18858 gcc_unreachable ();
18861 [(set (attr "type")
18862 (cond [(eq_attr "alternative" "0")
18863 (const_string "alu")
18864 (match_operand:DI 2 "const0_operand" "")
18865 (const_string "imov")
18867 (const_string "lea")))
18868 (set_attr "mode" "DI")])
18870 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18871 [(set (match_operand:DI 0 "register_operand" "=r,r")
18872 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18873 (match_operand:DI 3 "immediate_operand" "i,i")))
18874 (use (match_operand:DI 2 "register_operand" "r,r"))
18875 (clobber (reg:CC FLAGS_REG))
18876 (clobber (mem:BLK (scratch)))]
18879 switch (get_attr_type (insn))
18882 return "add{q}\t{%2, %0|%0, %2}";
18885 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18886 return "lea{q}\t{%a2, %0|%0, %a2}";
18889 gcc_unreachable ();
18892 [(set_attr "type" "alu,lea")
18893 (set_attr "mode" "DI")])
18895 (define_expand "allocate_stack_worker"
18896 [(match_operand:SI 0 "register_operand" "")]
18897 "TARGET_STACK_PROBE"
18899 if (reload_completed)
18902 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18904 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18909 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18911 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18916 (define_insn "allocate_stack_worker_1"
18917 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18918 UNSPECV_STACK_PROBE)
18919 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18920 (clobber (match_scratch:SI 1 "=0"))
18921 (clobber (reg:CC FLAGS_REG))]
18922 "!TARGET_64BIT && TARGET_STACK_PROBE"
18924 [(set_attr "type" "multi")
18925 (set_attr "length" "5")])
18927 (define_expand "allocate_stack_worker_postreload"
18928 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18929 UNSPECV_STACK_PROBE)
18930 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18931 (clobber (match_dup 0))
18932 (clobber (reg:CC FLAGS_REG))])]
18936 (define_insn "allocate_stack_worker_rex64"
18937 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18938 UNSPECV_STACK_PROBE)
18939 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18940 (clobber (match_scratch:DI 1 "=0"))
18941 (clobber (reg:CC FLAGS_REG))]
18942 "TARGET_64BIT && TARGET_STACK_PROBE"
18944 [(set_attr "type" "multi")
18945 (set_attr "length" "5")])
18947 (define_expand "allocate_stack_worker_rex64_postreload"
18948 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18949 UNSPECV_STACK_PROBE)
18950 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18951 (clobber (match_dup 0))
18952 (clobber (reg:CC FLAGS_REG))])]
18956 (define_expand "allocate_stack"
18957 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18958 (minus:SI (reg:SI SP_REG)
18959 (match_operand:SI 1 "general_operand" "")))
18960 (clobber (reg:CC FLAGS_REG))])
18961 (parallel [(set (reg:SI SP_REG)
18962 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18963 (clobber (reg:CC FLAGS_REG))])]
18964 "TARGET_STACK_PROBE"
18966 #ifdef CHECK_STACK_LIMIT
18967 if (GET_CODE (operands[1]) == CONST_INT
18968 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18969 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18973 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18976 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18980 (define_expand "builtin_setjmp_receiver"
18981 [(label_ref (match_operand 0 "" ""))]
18982 "!TARGET_64BIT && flag_pic"
18987 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
18988 rtx label_rtx = gen_label_rtx ();
18989 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18990 emit_label (label_rtx);
18991 xops[0] = xops[1] = picreg;
18992 xops[2] = gen_rtx_CONST (SImode,
18993 gen_rtx_MINUS (SImode,
18994 gen_rtx_LABEL_REF (SImode, label_rtx),
18995 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
18996 ix86_expand_binary_operator (MINUS, SImode, xops);
18999 emit_insn (gen_set_got (pic_offset_table_rtx));
19003 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19006 [(set (match_operand 0 "register_operand" "")
19007 (match_operator 3 "promotable_binary_operator"
19008 [(match_operand 1 "register_operand" "")
19009 (match_operand 2 "aligned_operand" "")]))
19010 (clobber (reg:CC FLAGS_REG))]
19011 "! TARGET_PARTIAL_REG_STALL && reload_completed
19012 && ((GET_MODE (operands[0]) == HImode
19013 && ((!optimize_size && !TARGET_FAST_PREFIX)
19014 || GET_CODE (operands[2]) != CONST_INT
19015 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
19016 || (GET_MODE (operands[0]) == QImode
19017 && (TARGET_PROMOTE_QImode || optimize_size)))"
19018 [(parallel [(set (match_dup 0)
19019 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19020 (clobber (reg:CC FLAGS_REG))])]
19021 "operands[0] = gen_lowpart (SImode, operands[0]);
19022 operands[1] = gen_lowpart (SImode, operands[1]);
19023 if (GET_CODE (operands[3]) != ASHIFT)
19024 operands[2] = gen_lowpart (SImode, operands[2]);
19025 PUT_MODE (operands[3], SImode);")
19027 ; Promote the QImode tests, as i386 has encoding of the AND
19028 ; instruction with 32-bit sign-extended immediate and thus the
19029 ; instruction size is unchanged, except in the %eax case for
19030 ; which it is increased by one byte, hence the ! optimize_size.
19032 [(set (match_operand 0 "flags_reg_operand" "")
19033 (match_operator 2 "compare_operator"
19034 [(and (match_operand 3 "aligned_operand" "")
19035 (match_operand 4 "const_int_operand" ""))
19037 (set (match_operand 1 "register_operand" "")
19038 (and (match_dup 3) (match_dup 4)))]
19039 "! TARGET_PARTIAL_REG_STALL && reload_completed
19040 /* Ensure that the operand will remain sign-extended immediate. */
19041 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19043 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19044 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19045 [(parallel [(set (match_dup 0)
19046 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19049 (and:SI (match_dup 3) (match_dup 4)))])]
19052 = gen_int_mode (INTVAL (operands[4])
19053 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19054 operands[1] = gen_lowpart (SImode, operands[1]);
19055 operands[3] = gen_lowpart (SImode, operands[3]);
19058 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19059 ; the TEST instruction with 32-bit sign-extended immediate and thus
19060 ; the instruction size would at least double, which is not what we
19061 ; want even with ! optimize_size.
19063 [(set (match_operand 0 "flags_reg_operand" "")
19064 (match_operator 1 "compare_operator"
19065 [(and (match_operand:HI 2 "aligned_operand" "")
19066 (match_operand:HI 3 "const_int_operand" ""))
19068 "! TARGET_PARTIAL_REG_STALL && reload_completed
19069 /* Ensure that the operand will remain sign-extended immediate. */
19070 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19071 && ! TARGET_FAST_PREFIX
19072 && ! optimize_size"
19073 [(set (match_dup 0)
19074 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19078 = gen_int_mode (INTVAL (operands[3])
19079 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19080 operands[2] = gen_lowpart (SImode, operands[2]);
19084 [(set (match_operand 0 "register_operand" "")
19085 (neg (match_operand 1 "register_operand" "")))
19086 (clobber (reg:CC FLAGS_REG))]
19087 "! TARGET_PARTIAL_REG_STALL && reload_completed
19088 && (GET_MODE (operands[0]) == HImode
19089 || (GET_MODE (operands[0]) == QImode
19090 && (TARGET_PROMOTE_QImode || optimize_size)))"
19091 [(parallel [(set (match_dup 0)
19092 (neg:SI (match_dup 1)))
19093 (clobber (reg:CC FLAGS_REG))])]
19094 "operands[0] = gen_lowpart (SImode, operands[0]);
19095 operands[1] = gen_lowpart (SImode, operands[1]);")
19098 [(set (match_operand 0 "register_operand" "")
19099 (not (match_operand 1 "register_operand" "")))]
19100 "! TARGET_PARTIAL_REG_STALL && reload_completed
19101 && (GET_MODE (operands[0]) == HImode
19102 || (GET_MODE (operands[0]) == QImode
19103 && (TARGET_PROMOTE_QImode || optimize_size)))"
19104 [(set (match_dup 0)
19105 (not:SI (match_dup 1)))]
19106 "operands[0] = gen_lowpart (SImode, operands[0]);
19107 operands[1] = gen_lowpart (SImode, operands[1]);")
19110 [(set (match_operand 0 "register_operand" "")
19111 (if_then_else (match_operator 1 "comparison_operator"
19112 [(reg FLAGS_REG) (const_int 0)])
19113 (match_operand 2 "register_operand" "")
19114 (match_operand 3 "register_operand" "")))]
19115 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19116 && (GET_MODE (operands[0]) == HImode
19117 || (GET_MODE (operands[0]) == QImode
19118 && (TARGET_PROMOTE_QImode || optimize_size)))"
19119 [(set (match_dup 0)
19120 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19121 "operands[0] = gen_lowpart (SImode, operands[0]);
19122 operands[2] = gen_lowpart (SImode, operands[2]);
19123 operands[3] = gen_lowpart (SImode, operands[3]);")
19126 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19127 ;; transform a complex memory operation into two memory to register operations.
19129 ;; Don't push memory operands
19131 [(set (match_operand:SI 0 "push_operand" "")
19132 (match_operand:SI 1 "memory_operand" ""))
19133 (match_scratch:SI 2 "r")]
19134 "!optimize_size && !TARGET_PUSH_MEMORY
19135 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19136 [(set (match_dup 2) (match_dup 1))
19137 (set (match_dup 0) (match_dup 2))]
19141 [(set (match_operand:DI 0 "push_operand" "")
19142 (match_operand:DI 1 "memory_operand" ""))
19143 (match_scratch:DI 2 "r")]
19144 "!optimize_size && !TARGET_PUSH_MEMORY
19145 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19146 [(set (match_dup 2) (match_dup 1))
19147 (set (match_dup 0) (match_dup 2))]
19150 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19153 [(set (match_operand:SF 0 "push_operand" "")
19154 (match_operand:SF 1 "memory_operand" ""))
19155 (match_scratch:SF 2 "r")]
19156 "!optimize_size && !TARGET_PUSH_MEMORY
19157 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19158 [(set (match_dup 2) (match_dup 1))
19159 (set (match_dup 0) (match_dup 2))]
19163 [(set (match_operand:HI 0 "push_operand" "")
19164 (match_operand:HI 1 "memory_operand" ""))
19165 (match_scratch:HI 2 "r")]
19166 "!optimize_size && !TARGET_PUSH_MEMORY
19167 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19168 [(set (match_dup 2) (match_dup 1))
19169 (set (match_dup 0) (match_dup 2))]
19173 [(set (match_operand:QI 0 "push_operand" "")
19174 (match_operand:QI 1 "memory_operand" ""))
19175 (match_scratch:QI 2 "q")]
19176 "!optimize_size && !TARGET_PUSH_MEMORY
19177 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19178 [(set (match_dup 2) (match_dup 1))
19179 (set (match_dup 0) (match_dup 2))]
19182 ;; Don't move an immediate directly to memory when the instruction
19185 [(match_scratch:SI 1 "r")
19186 (set (match_operand:SI 0 "memory_operand" "")
19189 && ! TARGET_USE_MOV0
19190 && TARGET_SPLIT_LONG_MOVES
19191 && get_attr_length (insn) >= ix86_cost->large_insn
19192 && peep2_regno_dead_p (0, FLAGS_REG)"
19193 [(parallel [(set (match_dup 1) (const_int 0))
19194 (clobber (reg:CC FLAGS_REG))])
19195 (set (match_dup 0) (match_dup 1))]
19199 [(match_scratch:HI 1 "r")
19200 (set (match_operand:HI 0 "memory_operand" "")
19203 && ! TARGET_USE_MOV0
19204 && TARGET_SPLIT_LONG_MOVES
19205 && get_attr_length (insn) >= ix86_cost->large_insn
19206 && peep2_regno_dead_p (0, FLAGS_REG)"
19207 [(parallel [(set (match_dup 2) (const_int 0))
19208 (clobber (reg:CC FLAGS_REG))])
19209 (set (match_dup 0) (match_dup 1))]
19210 "operands[2] = gen_lowpart (SImode, operands[1]);")
19213 [(match_scratch:QI 1 "q")
19214 (set (match_operand:QI 0 "memory_operand" "")
19217 && ! TARGET_USE_MOV0
19218 && TARGET_SPLIT_LONG_MOVES
19219 && get_attr_length (insn) >= ix86_cost->large_insn
19220 && peep2_regno_dead_p (0, FLAGS_REG)"
19221 [(parallel [(set (match_dup 2) (const_int 0))
19222 (clobber (reg:CC FLAGS_REG))])
19223 (set (match_dup 0) (match_dup 1))]
19224 "operands[2] = gen_lowpart (SImode, operands[1]);")
19227 [(match_scratch:SI 2 "r")
19228 (set (match_operand:SI 0 "memory_operand" "")
19229 (match_operand:SI 1 "immediate_operand" ""))]
19231 && get_attr_length (insn) >= ix86_cost->large_insn
19232 && TARGET_SPLIT_LONG_MOVES"
19233 [(set (match_dup 2) (match_dup 1))
19234 (set (match_dup 0) (match_dup 2))]
19238 [(match_scratch:HI 2 "r")
19239 (set (match_operand:HI 0 "memory_operand" "")
19240 (match_operand:HI 1 "immediate_operand" ""))]
19241 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19242 && TARGET_SPLIT_LONG_MOVES"
19243 [(set (match_dup 2) (match_dup 1))
19244 (set (match_dup 0) (match_dup 2))]
19248 [(match_scratch:QI 2 "q")
19249 (set (match_operand:QI 0 "memory_operand" "")
19250 (match_operand:QI 1 "immediate_operand" ""))]
19251 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19252 && TARGET_SPLIT_LONG_MOVES"
19253 [(set (match_dup 2) (match_dup 1))
19254 (set (match_dup 0) (match_dup 2))]
19257 ;; Don't compare memory with zero, load and use a test instead.
19259 [(set (match_operand 0 "flags_reg_operand" "")
19260 (match_operator 1 "compare_operator"
19261 [(match_operand:SI 2 "memory_operand" "")
19263 (match_scratch:SI 3 "r")]
19264 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19265 [(set (match_dup 3) (match_dup 2))
19266 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19269 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19270 ;; Don't split NOTs with a displacement operand, because resulting XOR
19271 ;; will not be pairable anyway.
19273 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19274 ;; represented using a modRM byte. The XOR replacement is long decoded,
19275 ;; so this split helps here as well.
19277 ;; Note: Can't do this as a regular split because we can't get proper
19278 ;; lifetime information then.
19281 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19282 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19284 && peep2_regno_dead_p (0, FLAGS_REG)
19285 && ((TARGET_PENTIUM
19286 && (GET_CODE (operands[0]) != MEM
19287 || !memory_displacement_operand (operands[0], SImode)))
19288 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19289 [(parallel [(set (match_dup 0)
19290 (xor:SI (match_dup 1) (const_int -1)))
19291 (clobber (reg:CC FLAGS_REG))])]
19295 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19296 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19298 && peep2_regno_dead_p (0, FLAGS_REG)
19299 && ((TARGET_PENTIUM
19300 && (GET_CODE (operands[0]) != MEM
19301 || !memory_displacement_operand (operands[0], HImode)))
19302 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19303 [(parallel [(set (match_dup 0)
19304 (xor:HI (match_dup 1) (const_int -1)))
19305 (clobber (reg:CC FLAGS_REG))])]
19309 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19310 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19312 && peep2_regno_dead_p (0, FLAGS_REG)
19313 && ((TARGET_PENTIUM
19314 && (GET_CODE (operands[0]) != MEM
19315 || !memory_displacement_operand (operands[0], QImode)))
19316 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19317 [(parallel [(set (match_dup 0)
19318 (xor:QI (match_dup 1) (const_int -1)))
19319 (clobber (reg:CC FLAGS_REG))])]
19322 ;; Non pairable "test imm, reg" instructions can be translated to
19323 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19324 ;; byte opcode instead of two, have a short form for byte operands),
19325 ;; so do it for other CPUs as well. Given that the value was dead,
19326 ;; this should not create any new dependencies. Pass on the sub-word
19327 ;; versions if we're concerned about partial register stalls.
19330 [(set (match_operand 0 "flags_reg_operand" "")
19331 (match_operator 1 "compare_operator"
19332 [(and:SI (match_operand:SI 2 "register_operand" "")
19333 (match_operand:SI 3 "immediate_operand" ""))
19335 "ix86_match_ccmode (insn, CCNOmode)
19336 && (true_regnum (operands[2]) != 0
19337 || (GET_CODE (operands[3]) == CONST_INT
19338 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19339 && peep2_reg_dead_p (1, operands[2])"
19341 [(set (match_dup 0)
19342 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19345 (and:SI (match_dup 2) (match_dup 3)))])]
19348 ;; We don't need to handle HImode case, because it will be promoted to SImode
19349 ;; on ! TARGET_PARTIAL_REG_STALL
19352 [(set (match_operand 0 "flags_reg_operand" "")
19353 (match_operator 1 "compare_operator"
19354 [(and:QI (match_operand:QI 2 "register_operand" "")
19355 (match_operand:QI 3 "immediate_operand" ""))
19357 "! TARGET_PARTIAL_REG_STALL
19358 && ix86_match_ccmode (insn, CCNOmode)
19359 && true_regnum (operands[2]) != 0
19360 && peep2_reg_dead_p (1, operands[2])"
19362 [(set (match_dup 0)
19363 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19366 (and:QI (match_dup 2) (match_dup 3)))])]
19370 [(set (match_operand 0 "flags_reg_operand" "")
19371 (match_operator 1 "compare_operator"
19374 (match_operand 2 "ext_register_operand" "")
19377 (match_operand 3 "const_int_operand" ""))
19379 "! TARGET_PARTIAL_REG_STALL
19380 && ix86_match_ccmode (insn, CCNOmode)
19381 && true_regnum (operands[2]) != 0
19382 && peep2_reg_dead_p (1, operands[2])"
19383 [(parallel [(set (match_dup 0)
19392 (set (zero_extract:SI (match_dup 2)
19403 ;; Don't do logical operations with memory inputs.
19405 [(match_scratch:SI 2 "r")
19406 (parallel [(set (match_operand:SI 0 "register_operand" "")
19407 (match_operator:SI 3 "arith_or_logical_operator"
19409 (match_operand:SI 1 "memory_operand" "")]))
19410 (clobber (reg:CC FLAGS_REG))])]
19411 "! optimize_size && ! TARGET_READ_MODIFY"
19412 [(set (match_dup 2) (match_dup 1))
19413 (parallel [(set (match_dup 0)
19414 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19415 (clobber (reg:CC FLAGS_REG))])]
19419 [(match_scratch:SI 2 "r")
19420 (parallel [(set (match_operand:SI 0 "register_operand" "")
19421 (match_operator:SI 3 "arith_or_logical_operator"
19422 [(match_operand:SI 1 "memory_operand" "")
19424 (clobber (reg:CC FLAGS_REG))])]
19425 "! optimize_size && ! TARGET_READ_MODIFY"
19426 [(set (match_dup 2) (match_dup 1))
19427 (parallel [(set (match_dup 0)
19428 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19429 (clobber (reg:CC FLAGS_REG))])]
19432 ; Don't do logical operations with memory outputs
19434 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19435 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19436 ; the same decoder scheduling characteristics as the original.
19439 [(match_scratch:SI 2 "r")
19440 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19441 (match_operator:SI 3 "arith_or_logical_operator"
19443 (match_operand:SI 1 "nonmemory_operand" "")]))
19444 (clobber (reg:CC FLAGS_REG))])]
19445 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19446 [(set (match_dup 2) (match_dup 0))
19447 (parallel [(set (match_dup 2)
19448 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19449 (clobber (reg:CC FLAGS_REG))])
19450 (set (match_dup 0) (match_dup 2))]
19454 [(match_scratch:SI 2 "r")
19455 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19456 (match_operator:SI 3 "arith_or_logical_operator"
19457 [(match_operand:SI 1 "nonmemory_operand" "")
19459 (clobber (reg:CC FLAGS_REG))])]
19460 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19461 [(set (match_dup 2) (match_dup 0))
19462 (parallel [(set (match_dup 2)
19463 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19464 (clobber (reg:CC FLAGS_REG))])
19465 (set (match_dup 0) (match_dup 2))]
19468 ;; Attempt to always use XOR for zeroing registers.
19470 [(set (match_operand 0 "register_operand" "")
19471 (match_operand 1 "const0_operand" ""))]
19472 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19473 && (! TARGET_USE_MOV0 || optimize_size)
19474 && GENERAL_REG_P (operands[0])
19475 && peep2_regno_dead_p (0, FLAGS_REG)"
19476 [(parallel [(set (match_dup 0) (const_int 0))
19477 (clobber (reg:CC FLAGS_REG))])]
19479 operands[0] = gen_lowpart (word_mode, operands[0]);
19483 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19485 "(GET_MODE (operands[0]) == QImode
19486 || GET_MODE (operands[0]) == HImode)
19487 && (! TARGET_USE_MOV0 || optimize_size)
19488 && peep2_regno_dead_p (0, FLAGS_REG)"
19489 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19490 (clobber (reg:CC FLAGS_REG))])])
19492 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19494 [(set (match_operand 0 "register_operand" "")
19496 "(GET_MODE (operands[0]) == HImode
19497 || GET_MODE (operands[0]) == SImode
19498 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19499 && (optimize_size || TARGET_PENTIUM)
19500 && peep2_regno_dead_p (0, FLAGS_REG)"
19501 [(parallel [(set (match_dup 0) (const_int -1))
19502 (clobber (reg:CC FLAGS_REG))])]
19503 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19506 ;; Attempt to convert simple leas to adds. These can be created by
19509 [(set (match_operand:SI 0 "register_operand" "")
19510 (plus:SI (match_dup 0)
19511 (match_operand:SI 1 "nonmemory_operand" "")))]
19512 "peep2_regno_dead_p (0, FLAGS_REG)"
19513 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19514 (clobber (reg:CC FLAGS_REG))])]
19518 [(set (match_operand:SI 0 "register_operand" "")
19519 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19520 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19521 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19522 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19523 (clobber (reg:CC FLAGS_REG))])]
19524 "operands[2] = gen_lowpart (SImode, operands[2]);")
19527 [(set (match_operand:DI 0 "register_operand" "")
19528 (plus:DI (match_dup 0)
19529 (match_operand:DI 1 "x86_64_general_operand" "")))]
19530 "peep2_regno_dead_p (0, FLAGS_REG)"
19531 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19532 (clobber (reg:CC FLAGS_REG))])]
19536 [(set (match_operand:SI 0 "register_operand" "")
19537 (mult:SI (match_dup 0)
19538 (match_operand:SI 1 "const_int_operand" "")))]
19539 "exact_log2 (INTVAL (operands[1])) >= 0
19540 && peep2_regno_dead_p (0, FLAGS_REG)"
19541 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19542 (clobber (reg:CC FLAGS_REG))])]
19543 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19546 [(set (match_operand:DI 0 "register_operand" "")
19547 (mult:DI (match_dup 0)
19548 (match_operand:DI 1 "const_int_operand" "")))]
19549 "exact_log2 (INTVAL (operands[1])) >= 0
19550 && peep2_regno_dead_p (0, FLAGS_REG)"
19551 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19552 (clobber (reg:CC FLAGS_REG))])]
19553 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19556 [(set (match_operand:SI 0 "register_operand" "")
19557 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19558 (match_operand:DI 2 "const_int_operand" "")) 0))]
19559 "exact_log2 (INTVAL (operands[2])) >= 0
19560 && REGNO (operands[0]) == REGNO (operands[1])
19561 && peep2_regno_dead_p (0, FLAGS_REG)"
19562 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19563 (clobber (reg:CC FLAGS_REG))])]
19564 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19566 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19567 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19568 ;; many CPUs it is also faster, since special hardware to avoid esp
19569 ;; dependencies is present.
19571 ;; While some of these conversions may be done using splitters, we use peepholes
19572 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19574 ;; Convert prologue esp subtractions to push.
19575 ;; We need register to push. In order to keep verify_flow_info happy we have
19577 ;; - use scratch and clobber it in order to avoid dependencies
19578 ;; - use already live register
19579 ;; We can't use the second way right now, since there is no reliable way how to
19580 ;; verify that given register is live. First choice will also most likely in
19581 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19582 ;; call clobbered registers are dead. We may want to use base pointer as an
19583 ;; alternative when no register is available later.
19586 [(match_scratch:SI 0 "r")
19587 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19588 (clobber (reg:CC FLAGS_REG))
19589 (clobber (mem:BLK (scratch)))])]
19590 "optimize_size || !TARGET_SUB_ESP_4"
19591 [(clobber (match_dup 0))
19592 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19593 (clobber (mem:BLK (scratch)))])])
19596 [(match_scratch:SI 0 "r")
19597 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19598 (clobber (reg:CC FLAGS_REG))
19599 (clobber (mem:BLK (scratch)))])]
19600 "optimize_size || !TARGET_SUB_ESP_8"
19601 [(clobber (match_dup 0))
19602 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19603 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19604 (clobber (mem:BLK (scratch)))])])
19606 ;; Convert esp subtractions to push.
19608 [(match_scratch:SI 0 "r")
19609 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19610 (clobber (reg:CC FLAGS_REG))])]
19611 "optimize_size || !TARGET_SUB_ESP_4"
19612 [(clobber (match_dup 0))
19613 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19616 [(match_scratch:SI 0 "r")
19617 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19618 (clobber (reg:CC FLAGS_REG))])]
19619 "optimize_size || !TARGET_SUB_ESP_8"
19620 [(clobber (match_dup 0))
19621 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19622 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19624 ;; Convert epilogue deallocator to pop.
19626 [(match_scratch:SI 0 "r")
19627 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19628 (clobber (reg:CC FLAGS_REG))
19629 (clobber (mem:BLK (scratch)))])]
19630 "optimize_size || !TARGET_ADD_ESP_4"
19631 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19632 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19633 (clobber (mem:BLK (scratch)))])]
19636 ;; Two pops case is tricky, since pop causes dependency on destination register.
19637 ;; We use two registers if available.
19639 [(match_scratch:SI 0 "r")
19640 (match_scratch:SI 1 "r")
19641 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19642 (clobber (reg:CC FLAGS_REG))
19643 (clobber (mem:BLK (scratch)))])]
19644 "optimize_size || !TARGET_ADD_ESP_8"
19645 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19646 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19647 (clobber (mem:BLK (scratch)))])
19648 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19649 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19653 [(match_scratch:SI 0 "r")
19654 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19655 (clobber (reg:CC FLAGS_REG))
19656 (clobber (mem:BLK (scratch)))])]
19658 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19659 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19660 (clobber (mem:BLK (scratch)))])
19661 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19662 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19665 ;; Convert esp additions to pop.
19667 [(match_scratch:SI 0 "r")
19668 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19669 (clobber (reg:CC FLAGS_REG))])]
19671 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19672 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19675 ;; Two pops case is tricky, since pop causes dependency on destination register.
19676 ;; We use two registers if available.
19678 [(match_scratch:SI 0 "r")
19679 (match_scratch:SI 1 "r")
19680 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19681 (clobber (reg:CC FLAGS_REG))])]
19683 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19684 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19685 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19686 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19690 [(match_scratch:SI 0 "r")
19691 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19692 (clobber (reg:CC FLAGS_REG))])]
19694 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19695 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19696 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19697 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19700 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19701 ;; required and register dies. Similarly for 128 to plus -128.
19703 [(set (match_operand 0 "flags_reg_operand" "")
19704 (match_operator 1 "compare_operator"
19705 [(match_operand 2 "register_operand" "")
19706 (match_operand 3 "const_int_operand" "")]))]
19707 "(INTVAL (operands[3]) == -1
19708 || INTVAL (operands[3]) == 1
19709 || INTVAL (operands[3]) == 128)
19710 && ix86_match_ccmode (insn, CCGCmode)
19711 && peep2_reg_dead_p (1, operands[2])"
19712 [(parallel [(set (match_dup 0)
19713 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19714 (clobber (match_dup 2))])]
19718 [(match_scratch:DI 0 "r")
19719 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19720 (clobber (reg:CC FLAGS_REG))
19721 (clobber (mem:BLK (scratch)))])]
19722 "optimize_size || !TARGET_SUB_ESP_4"
19723 [(clobber (match_dup 0))
19724 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19725 (clobber (mem:BLK (scratch)))])])
19728 [(match_scratch:DI 0 "r")
19729 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19730 (clobber (reg:CC FLAGS_REG))
19731 (clobber (mem:BLK (scratch)))])]
19732 "optimize_size || !TARGET_SUB_ESP_8"
19733 [(clobber (match_dup 0))
19734 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19735 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19736 (clobber (mem:BLK (scratch)))])])
19738 ;; Convert esp subtractions to push.
19740 [(match_scratch:DI 0 "r")
19741 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19742 (clobber (reg:CC FLAGS_REG))])]
19743 "optimize_size || !TARGET_SUB_ESP_4"
19744 [(clobber (match_dup 0))
19745 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19748 [(match_scratch:DI 0 "r")
19749 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19750 (clobber (reg:CC FLAGS_REG))])]
19751 "optimize_size || !TARGET_SUB_ESP_8"
19752 [(clobber (match_dup 0))
19753 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19754 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19756 ;; Convert epilogue deallocator to pop.
19758 [(match_scratch:DI 0 "r")
19759 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19760 (clobber (reg:CC FLAGS_REG))
19761 (clobber (mem:BLK (scratch)))])]
19762 "optimize_size || !TARGET_ADD_ESP_4"
19763 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19764 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19765 (clobber (mem:BLK (scratch)))])]
19768 ;; Two pops case is tricky, since pop causes dependency on destination register.
19769 ;; We use two registers if available.
19771 [(match_scratch:DI 0 "r")
19772 (match_scratch:DI 1 "r")
19773 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19774 (clobber (reg:CC FLAGS_REG))
19775 (clobber (mem:BLK (scratch)))])]
19776 "optimize_size || !TARGET_ADD_ESP_8"
19777 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19778 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19779 (clobber (mem:BLK (scratch)))])
19780 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19781 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19785 [(match_scratch:DI 0 "r")
19786 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19787 (clobber (reg:CC FLAGS_REG))
19788 (clobber (mem:BLK (scratch)))])]
19790 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19791 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19792 (clobber (mem:BLK (scratch)))])
19793 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19794 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19797 ;; Convert esp additions to pop.
19799 [(match_scratch:DI 0 "r")
19800 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19801 (clobber (reg:CC FLAGS_REG))])]
19803 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19804 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19807 ;; Two pops case is tricky, since pop causes dependency on destination register.
19808 ;; We use two registers if available.
19810 [(match_scratch:DI 0 "r")
19811 (match_scratch:DI 1 "r")
19812 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19813 (clobber (reg:CC FLAGS_REG))])]
19815 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19816 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19817 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19818 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19822 [(match_scratch:DI 0 "r")
19823 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19824 (clobber (reg:CC FLAGS_REG))])]
19826 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19827 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19828 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19829 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19832 ;; Convert imul by three, five and nine into lea
19835 [(set (match_operand:SI 0 "register_operand" "")
19836 (mult:SI (match_operand:SI 1 "register_operand" "")
19837 (match_operand:SI 2 "const_int_operand" "")))
19838 (clobber (reg:CC FLAGS_REG))])]
19839 "INTVAL (operands[2]) == 3
19840 || INTVAL (operands[2]) == 5
19841 || INTVAL (operands[2]) == 9"
19842 [(set (match_dup 0)
19843 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19845 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19849 [(set (match_operand:SI 0 "register_operand" "")
19850 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19851 (match_operand:SI 2 "const_int_operand" "")))
19852 (clobber (reg:CC FLAGS_REG))])]
19854 && (INTVAL (operands[2]) == 3
19855 || INTVAL (operands[2]) == 5
19856 || INTVAL (operands[2]) == 9)"
19857 [(set (match_dup 0) (match_dup 1))
19859 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19861 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19865 [(set (match_operand:DI 0 "register_operand" "")
19866 (mult:DI (match_operand:DI 1 "register_operand" "")
19867 (match_operand:DI 2 "const_int_operand" "")))
19868 (clobber (reg:CC FLAGS_REG))])]
19870 && (INTVAL (operands[2]) == 3
19871 || INTVAL (operands[2]) == 5
19872 || INTVAL (operands[2]) == 9)"
19873 [(set (match_dup 0)
19874 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19876 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19880 [(set (match_operand:DI 0 "register_operand" "")
19881 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19882 (match_operand:DI 2 "const_int_operand" "")))
19883 (clobber (reg:CC FLAGS_REG))])]
19886 && (INTVAL (operands[2]) == 3
19887 || INTVAL (operands[2]) == 5
19888 || INTVAL (operands[2]) == 9)"
19889 [(set (match_dup 0) (match_dup 1))
19891 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19893 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19895 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19896 ;; imul $32bit_imm, reg, reg is direct decoded.
19898 [(match_scratch:DI 3 "r")
19899 (parallel [(set (match_operand:DI 0 "register_operand" "")
19900 (mult:DI (match_operand:DI 1 "memory_operand" "")
19901 (match_operand:DI 2 "immediate_operand" "")))
19902 (clobber (reg:CC FLAGS_REG))])]
19903 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19904 && (GET_CODE (operands[2]) != CONST_INT
19905 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19906 [(set (match_dup 3) (match_dup 1))
19907 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19908 (clobber (reg:CC FLAGS_REG))])]
19912 [(match_scratch:SI 3 "r")
19913 (parallel [(set (match_operand:SI 0 "register_operand" "")
19914 (mult:SI (match_operand:SI 1 "memory_operand" "")
19915 (match_operand:SI 2 "immediate_operand" "")))
19916 (clobber (reg:CC FLAGS_REG))])]
19917 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19918 && (GET_CODE (operands[2]) != CONST_INT
19919 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19920 [(set (match_dup 3) (match_dup 1))
19921 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19922 (clobber (reg:CC FLAGS_REG))])]
19926 [(match_scratch:SI 3 "r")
19927 (parallel [(set (match_operand:DI 0 "register_operand" "")
19929 (mult:SI (match_operand:SI 1 "memory_operand" "")
19930 (match_operand:SI 2 "immediate_operand" ""))))
19931 (clobber (reg:CC FLAGS_REG))])]
19932 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19933 && (GET_CODE (operands[2]) != CONST_INT
19934 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19935 [(set (match_dup 3) (match_dup 1))
19936 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19937 (clobber (reg:CC FLAGS_REG))])]
19940 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19941 ;; Convert it into imul reg, reg
19942 ;; It would be better to force assembler to encode instruction using long
19943 ;; immediate, but there is apparently no way to do so.
19945 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19946 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19947 (match_operand:DI 2 "const_int_operand" "")))
19948 (clobber (reg:CC FLAGS_REG))])
19949 (match_scratch:DI 3 "r")]
19950 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19951 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19952 [(set (match_dup 3) (match_dup 2))
19953 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19954 (clobber (reg:CC FLAGS_REG))])]
19956 if (!rtx_equal_p (operands[0], operands[1]))
19957 emit_move_insn (operands[0], operands[1]);
19961 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19962 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19963 (match_operand:SI 2 "const_int_operand" "")))
19964 (clobber (reg:CC FLAGS_REG))])
19965 (match_scratch:SI 3 "r")]
19966 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19967 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19968 [(set (match_dup 3) (match_dup 2))
19969 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19970 (clobber (reg:CC FLAGS_REG))])]
19972 if (!rtx_equal_p (operands[0], operands[1]))
19973 emit_move_insn (operands[0], operands[1]);
19977 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19978 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19979 (match_operand:HI 2 "immediate_operand" "")))
19980 (clobber (reg:CC FLAGS_REG))])
19981 (match_scratch:HI 3 "r")]
19982 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
19983 [(set (match_dup 3) (match_dup 2))
19984 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19985 (clobber (reg:CC FLAGS_REG))])]
19987 if (!rtx_equal_p (operands[0], operands[1]))
19988 emit_move_insn (operands[0], operands[1]);
19991 ;; After splitting up read-modify operations, array accesses with memory
19992 ;; operands might end up in form:
19994 ;; movl 4(%esp), %edx
19996 ;; instead of pre-splitting:
19998 ;; addl 4(%esp), %eax
20000 ;; movl 4(%esp), %edx
20001 ;; leal (%edx,%eax,4), %eax
20004 [(parallel [(set (match_operand 0 "register_operand" "")
20005 (ashift (match_operand 1 "register_operand" "")
20006 (match_operand 2 "const_int_operand" "")))
20007 (clobber (reg:CC FLAGS_REG))])
20008 (set (match_operand 3 "register_operand")
20009 (match_operand 4 "x86_64_general_operand" ""))
20010 (parallel [(set (match_operand 5 "register_operand" "")
20011 (plus (match_operand 6 "register_operand" "")
20012 (match_operand 7 "register_operand" "")))
20013 (clobber (reg:CC FLAGS_REG))])]
20014 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20015 /* Validate MODE for lea. */
20016 && ((!TARGET_PARTIAL_REG_STALL
20017 && (GET_MODE (operands[0]) == QImode
20018 || GET_MODE (operands[0]) == HImode))
20019 || GET_MODE (operands[0]) == SImode
20020 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20021 /* We reorder load and the shift. */
20022 && !rtx_equal_p (operands[1], operands[3])
20023 && !reg_overlap_mentioned_p (operands[0], operands[4])
20024 /* Last PLUS must consist of operand 0 and 3. */
20025 && !rtx_equal_p (operands[0], operands[3])
20026 && (rtx_equal_p (operands[3], operands[6])
20027 || rtx_equal_p (operands[3], operands[7]))
20028 && (rtx_equal_p (operands[0], operands[6])
20029 || rtx_equal_p (operands[0], operands[7]))
20030 /* The intermediate operand 0 must die or be same as output. */
20031 && (rtx_equal_p (operands[0], operands[5])
20032 || peep2_reg_dead_p (3, operands[0]))"
20033 [(set (match_dup 3) (match_dup 4))
20034 (set (match_dup 0) (match_dup 1))]
20036 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20037 int scale = 1 << INTVAL (operands[2]);
20038 rtx index = gen_lowpart (Pmode, operands[1]);
20039 rtx base = gen_lowpart (Pmode, operands[3]);
20040 rtx dest = gen_lowpart (mode, operands[5]);
20042 operands[1] = gen_rtx_PLUS (Pmode, base,
20043 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20045 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20046 operands[0] = dest;
20049 ;; Call-value patterns last so that the wildcard operand does not
20050 ;; disrupt insn-recog's switch tables.
20052 (define_insn "*call_value_pop_0"
20053 [(set (match_operand 0 "" "")
20054 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20055 (match_operand:SI 2 "" "")))
20056 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20057 (match_operand:SI 3 "immediate_operand" "")))]
20060 if (SIBLING_CALL_P (insn))
20063 return "call\t%P1";
20065 [(set_attr "type" "callv")])
20067 (define_insn "*call_value_pop_1"
20068 [(set (match_operand 0 "" "")
20069 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20070 (match_operand:SI 2 "" "")))
20071 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20072 (match_operand:SI 3 "immediate_operand" "i")))]
20075 if (constant_call_address_operand (operands[1], Pmode))
20077 if (SIBLING_CALL_P (insn))
20080 return "call\t%P1";
20082 if (SIBLING_CALL_P (insn))
20085 return "call\t%A1";
20087 [(set_attr "type" "callv")])
20089 (define_insn "*call_value_0"
20090 [(set (match_operand 0 "" "")
20091 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20092 (match_operand:SI 2 "" "")))]
20095 if (SIBLING_CALL_P (insn))
20098 return "call\t%P1";
20100 [(set_attr "type" "callv")])
20102 (define_insn "*call_value_0_rex64"
20103 [(set (match_operand 0 "" "")
20104 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20105 (match_operand:DI 2 "const_int_operand" "")))]
20108 if (SIBLING_CALL_P (insn))
20111 return "call\t%P1";
20113 [(set_attr "type" "callv")])
20115 (define_insn "*call_value_1"
20116 [(set (match_operand 0 "" "")
20117 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20118 (match_operand:SI 2 "" "")))]
20119 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20121 if (constant_call_address_operand (operands[1], Pmode))
20122 return "call\t%P1";
20123 return "call\t%A1";
20125 [(set_attr "type" "callv")])
20127 (define_insn "*sibcall_value_1"
20128 [(set (match_operand 0 "" "")
20129 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20130 (match_operand:SI 2 "" "")))]
20131 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20133 if (constant_call_address_operand (operands[1], Pmode))
20137 [(set_attr "type" "callv")])
20139 (define_insn "*call_value_1_rex64"
20140 [(set (match_operand 0 "" "")
20141 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20142 (match_operand:DI 2 "" "")))]
20143 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20145 if (constant_call_address_operand (operands[1], Pmode))
20146 return "call\t%P1";
20147 return "call\t%A1";
20149 [(set_attr "type" "callv")])
20151 (define_insn "*sibcall_value_1_rex64"
20152 [(set (match_operand 0 "" "")
20153 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20154 (match_operand:DI 2 "" "")))]
20155 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20157 [(set_attr "type" "callv")])
20159 (define_insn "*sibcall_value_1_rex64_v"
20160 [(set (match_operand 0 "" "")
20161 (call (mem:QI (reg:DI 40))
20162 (match_operand:DI 1 "" "")))]
20163 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20165 [(set_attr "type" "callv")])
20167 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20168 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20169 ;; caught for use by garbage collectors and the like. Using an insn that
20170 ;; maps to SIGILL makes it more likely the program will rightfully die.
20171 ;; Keeping with tradition, "6" is in honor of #UD.
20172 (define_insn "trap"
20173 [(trap_if (const_int 1) (const_int 6))]
20176 [(set_attr "length" "2")])
20178 (define_expand "sse_prologue_save"
20179 [(parallel [(set (match_operand:BLK 0 "" "")
20180 (unspec:BLK [(reg:DI 21)
20187 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20188 (use (match_operand:DI 1 "register_operand" ""))
20189 (use (match_operand:DI 2 "immediate_operand" ""))
20190 (use (label_ref:DI (match_operand 3 "" "")))])]
20194 (define_insn "*sse_prologue_save_insn"
20195 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20196 (match_operand:DI 4 "const_int_operand" "n")))
20197 (unspec:BLK [(reg:DI 21)
20204 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20205 (use (match_operand:DI 1 "register_operand" "r"))
20206 (use (match_operand:DI 2 "const_int_operand" "i"))
20207 (use (label_ref:DI (match_operand 3 "" "X")))]
20209 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20210 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20214 operands[0] = gen_rtx_MEM (Pmode,
20215 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20216 output_asm_insn (\"jmp\\t%A1\", operands);
20217 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20219 operands[4] = adjust_address (operands[0], DImode, i*16);
20220 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20221 PUT_MODE (operands[4], TImode);
20222 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20223 output_asm_insn (\"rex\", operands);
20224 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20226 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20227 CODE_LABEL_NUMBER (operands[3]));
20231 [(set_attr "type" "other")
20232 (set_attr "length_immediate" "0")
20233 (set_attr "length_address" "0")
20234 (set_attr "length" "135")
20235 (set_attr "memory" "store")
20236 (set_attr "modrm" "0")
20237 (set_attr "mode" "DI")])
20239 (define_expand "prefetch"
20240 [(prefetch (match_operand 0 "address_operand" "")
20241 (match_operand:SI 1 "const_int_operand" "")
20242 (match_operand:SI 2 "const_int_operand" ""))]
20243 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20245 int rw = INTVAL (operands[1]);
20246 int locality = INTVAL (operands[2]);
20248 gcc_assert (rw == 0 || rw == 1);
20249 gcc_assert (locality >= 0 && locality <= 3);
20250 gcc_assert (GET_MODE (operands[0]) == Pmode
20251 || GET_MODE (operands[0]) == VOIDmode);
20253 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20254 supported by SSE counterpart or the SSE prefetch is not available
20255 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20257 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20258 operands[2] = GEN_INT (3);
20260 operands[1] = const0_rtx;
20263 (define_insn "*prefetch_sse"
20264 [(prefetch (match_operand:SI 0 "address_operand" "p")
20266 (match_operand:SI 1 "const_int_operand" ""))]
20267 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20269 static const char * const patterns[4] = {
20270 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20273 int locality = INTVAL (operands[1]);
20274 gcc_assert (locality >= 0 && locality <= 3);
20276 return patterns[locality];
20278 [(set_attr "type" "sse")
20279 (set_attr "memory" "none")])
20281 (define_insn "*prefetch_sse_rex"
20282 [(prefetch (match_operand:DI 0 "address_operand" "p")
20284 (match_operand:SI 1 "const_int_operand" ""))]
20285 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20287 static const char * const patterns[4] = {
20288 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20291 int locality = INTVAL (operands[1]);
20292 gcc_assert (locality >= 0 && locality <= 3);
20294 return patterns[locality];
20296 [(set_attr "type" "sse")
20297 (set_attr "memory" "none")])
20299 (define_insn "*prefetch_3dnow"
20300 [(prefetch (match_operand:SI 0 "address_operand" "p")
20301 (match_operand:SI 1 "const_int_operand" "n")
20303 "TARGET_3DNOW && !TARGET_64BIT"
20305 if (INTVAL (operands[1]) == 0)
20306 return "prefetch\t%a0";
20308 return "prefetchw\t%a0";
20310 [(set_attr "type" "mmx")
20311 (set_attr "memory" "none")])
20313 (define_insn "*prefetch_3dnow_rex"
20314 [(prefetch (match_operand:DI 0 "address_operand" "p")
20315 (match_operand:SI 1 "const_int_operand" "n")
20317 "TARGET_3DNOW && TARGET_64BIT"
20319 if (INTVAL (operands[1]) == 0)
20320 return "prefetch\t%a0";
20322 return "prefetchw\t%a0";
20324 [(set_attr "type" "mmx")
20325 (set_attr "memory" "none")])
20327 (define_expand "stack_protect_set"
20328 [(match_operand 0 "memory_operand" "")
20329 (match_operand 1 "memory_operand" "")]
20332 #ifdef TARGET_THREAD_SSP_OFFSET
20334 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20335 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20337 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20338 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20341 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20343 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20348 (define_insn "stack_protect_set_si"
20349 [(set (match_operand:SI 0 "memory_operand" "=m")
20350 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20351 (set (match_scratch:SI 2 "=&r") (const_int 0))
20352 (clobber (reg:CC FLAGS_REG))]
20354 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20355 [(set_attr "type" "multi")])
20357 (define_insn "stack_protect_set_di"
20358 [(set (match_operand:DI 0 "memory_operand" "=m")
20359 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20360 (set (match_scratch:DI 2 "=&r") (const_int 0))
20361 (clobber (reg:CC FLAGS_REG))]
20363 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20364 [(set_attr "type" "multi")])
20366 (define_insn "stack_tls_protect_set_si"
20367 [(set (match_operand:SI 0 "memory_operand" "=m")
20368 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20369 (set (match_scratch:SI 2 "=&r") (const_int 0))
20370 (clobber (reg:CC FLAGS_REG))]
20372 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20373 [(set_attr "type" "multi")])
20375 (define_insn "stack_tls_protect_set_di"
20376 [(set (match_operand:DI 0 "memory_operand" "=m")
20377 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20378 (set (match_scratch:DI 2 "=&r") (const_int 0))
20379 (clobber (reg:CC FLAGS_REG))]
20381 "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20382 [(set_attr "type" "multi")])
20384 (define_expand "stack_protect_test"
20385 [(match_operand 0 "memory_operand" "")
20386 (match_operand 1 "memory_operand" "")
20387 (match_operand 2 "" "")]
20390 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20391 ix86_compare_op0 = operands[0];
20392 ix86_compare_op1 = operands[1];
20393 ix86_compare_emitted = flags;
20395 #ifdef TARGET_THREAD_SSP_OFFSET
20397 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20398 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20400 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20401 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20404 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20406 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20408 emit_jump_insn (gen_beq (operands[2]));
20412 (define_insn "stack_protect_test_si"
20413 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20414 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20415 (match_operand:SI 2 "memory_operand" "m")]
20417 (clobber (match_scratch:SI 3 "=&r"))]
20419 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20420 [(set_attr "type" "multi")])
20422 (define_insn "stack_protect_test_di"
20423 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20424 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20425 (match_operand:DI 2 "memory_operand" "m")]
20427 (clobber (match_scratch:DI 3 "=&r"))]
20429 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20430 [(set_attr "type" "multi")])
20432 (define_insn "stack_tls_protect_test_si"
20433 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20434 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20435 (match_operand:SI 2 "const_int_operand" "i")]
20436 UNSPEC_SP_TLS_TEST))
20437 (clobber (match_scratch:SI 3 "=r"))]
20439 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20440 [(set_attr "type" "multi")])
20442 (define_insn "stack_tls_protect_test_di"
20443 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20444 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20445 (match_operand:DI 2 "const_int_operand" "i")]
20446 UNSPEC_SP_TLS_TEST))
20447 (clobber (match_scratch:DI 3 "=r"))]
20449 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20450 [(set_attr "type" "multi")])
20454 (include "sync.md")