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 and constraints
480 (include "predicates.md")
481 (include "constraints.md")
484 ;; Compare instructions.
486 ;; All compare insns have expanders that save the operands away without
487 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
488 ;; after the cmp) will actually emit the cmpM.
490 (define_expand "cmpti"
491 [(set (reg:CC FLAGS_REG)
492 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
493 (match_operand:TI 1 "x86_64_general_operand" "")))]
496 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
497 operands[0] = force_reg (TImode, operands[0]);
498 ix86_compare_op0 = operands[0];
499 ix86_compare_op1 = operands[1];
503 (define_expand "cmpdi"
504 [(set (reg:CC FLAGS_REG)
505 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
506 (match_operand:DI 1 "x86_64_general_operand" "")))]
509 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
510 operands[0] = force_reg (DImode, operands[0]);
511 ix86_compare_op0 = operands[0];
512 ix86_compare_op1 = operands[1];
516 (define_expand "cmpsi"
517 [(set (reg:CC FLAGS_REG)
518 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
519 (match_operand:SI 1 "general_operand" "")))]
522 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
523 operands[0] = force_reg (SImode, operands[0]);
524 ix86_compare_op0 = operands[0];
525 ix86_compare_op1 = operands[1];
529 (define_expand "cmphi"
530 [(set (reg:CC FLAGS_REG)
531 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
532 (match_operand:HI 1 "general_operand" "")))]
535 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
536 operands[0] = force_reg (HImode, operands[0]);
537 ix86_compare_op0 = operands[0];
538 ix86_compare_op1 = operands[1];
542 (define_expand "cmpqi"
543 [(set (reg:CC FLAGS_REG)
544 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
545 (match_operand:QI 1 "general_operand" "")))]
548 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
549 operands[0] = force_reg (QImode, operands[0]);
550 ix86_compare_op0 = operands[0];
551 ix86_compare_op1 = operands[1];
555 (define_insn "cmpdi_ccno_1_rex64"
556 [(set (reg FLAGS_REG)
557 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
558 (match_operand:DI 1 "const0_operand" "n,n")))]
559 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
561 test{q}\t{%0, %0|%0, %0}
562 cmp{q}\t{%1, %0|%0, %1}"
563 [(set_attr "type" "test,icmp")
564 (set_attr "length_immediate" "0,1")
565 (set_attr "mode" "DI")])
567 (define_insn "*cmpdi_minus_1_rex64"
568 [(set (reg FLAGS_REG)
569 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
570 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
572 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
573 "cmp{q}\t{%1, %0|%0, %1}"
574 [(set_attr "type" "icmp")
575 (set_attr "mode" "DI")])
577 (define_expand "cmpdi_1_rex64"
578 [(set (reg:CC FLAGS_REG)
579 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
580 (match_operand:DI 1 "general_operand" "")))]
584 (define_insn "cmpdi_1_insn_rex64"
585 [(set (reg FLAGS_REG)
586 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
587 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
588 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
589 "cmp{q}\t{%1, %0|%0, %1}"
590 [(set_attr "type" "icmp")
591 (set_attr "mode" "DI")])
594 (define_insn "*cmpsi_ccno_1"
595 [(set (reg FLAGS_REG)
596 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
597 (match_operand:SI 1 "const0_operand" "n,n")))]
598 "ix86_match_ccmode (insn, CCNOmode)"
600 test{l}\t{%0, %0|%0, %0}
601 cmp{l}\t{%1, %0|%0, %1}"
602 [(set_attr "type" "test,icmp")
603 (set_attr "length_immediate" "0,1")
604 (set_attr "mode" "SI")])
606 (define_insn "*cmpsi_minus_1"
607 [(set (reg FLAGS_REG)
608 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
609 (match_operand:SI 1 "general_operand" "ri,mr"))
611 "ix86_match_ccmode (insn, CCGOCmode)"
612 "cmp{l}\t{%1, %0|%0, %1}"
613 [(set_attr "type" "icmp")
614 (set_attr "mode" "SI")])
616 (define_expand "cmpsi_1"
617 [(set (reg:CC FLAGS_REG)
618 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
619 (match_operand:SI 1 "general_operand" "ri,mr")))]
623 (define_insn "*cmpsi_1_insn"
624 [(set (reg FLAGS_REG)
625 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
626 (match_operand:SI 1 "general_operand" "ri,mr")))]
627 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
628 && ix86_match_ccmode (insn, CCmode)"
629 "cmp{l}\t{%1, %0|%0, %1}"
630 [(set_attr "type" "icmp")
631 (set_attr "mode" "SI")])
633 (define_insn "*cmphi_ccno_1"
634 [(set (reg FLAGS_REG)
635 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
636 (match_operand:HI 1 "const0_operand" "n,n")))]
637 "ix86_match_ccmode (insn, CCNOmode)"
639 test{w}\t{%0, %0|%0, %0}
640 cmp{w}\t{%1, %0|%0, %1}"
641 [(set_attr "type" "test,icmp")
642 (set_attr "length_immediate" "0,1")
643 (set_attr "mode" "HI")])
645 (define_insn "*cmphi_minus_1"
646 [(set (reg FLAGS_REG)
647 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
648 (match_operand:HI 1 "general_operand" "ri,mr"))
650 "ix86_match_ccmode (insn, CCGOCmode)"
651 "cmp{w}\t{%1, %0|%0, %1}"
652 [(set_attr "type" "icmp")
653 (set_attr "mode" "HI")])
655 (define_insn "*cmphi_1"
656 [(set (reg FLAGS_REG)
657 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
658 (match_operand:HI 1 "general_operand" "ri,mr")))]
659 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
660 && ix86_match_ccmode (insn, CCmode)"
661 "cmp{w}\t{%1, %0|%0, %1}"
662 [(set_attr "type" "icmp")
663 (set_attr "mode" "HI")])
665 (define_insn "*cmpqi_ccno_1"
666 [(set (reg FLAGS_REG)
667 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
668 (match_operand:QI 1 "const0_operand" "n,n")))]
669 "ix86_match_ccmode (insn, CCNOmode)"
671 test{b}\t{%0, %0|%0, %0}
672 cmp{b}\t{$0, %0|%0, 0}"
673 [(set_attr "type" "test,icmp")
674 (set_attr "length_immediate" "0,1")
675 (set_attr "mode" "QI")])
677 (define_insn "*cmpqi_1"
678 [(set (reg FLAGS_REG)
679 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
680 (match_operand:QI 1 "general_operand" "qi,mq")))]
681 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
682 && ix86_match_ccmode (insn, CCmode)"
683 "cmp{b}\t{%1, %0|%0, %1}"
684 [(set_attr "type" "icmp")
685 (set_attr "mode" "QI")])
687 (define_insn "*cmpqi_minus_1"
688 [(set (reg FLAGS_REG)
689 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
690 (match_operand:QI 1 "general_operand" "qi,mq"))
692 "ix86_match_ccmode (insn, CCGOCmode)"
693 "cmp{b}\t{%1, %0|%0, %1}"
694 [(set_attr "type" "icmp")
695 (set_attr "mode" "QI")])
697 (define_insn "*cmpqi_ext_1"
698 [(set (reg FLAGS_REG)
700 (match_operand:QI 0 "general_operand" "Qm")
703 (match_operand 1 "ext_register_operand" "Q")
706 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
707 "cmp{b}\t{%h1, %0|%0, %h1}"
708 [(set_attr "type" "icmp")
709 (set_attr "mode" "QI")])
711 (define_insn "*cmpqi_ext_1_rex64"
712 [(set (reg FLAGS_REG)
714 (match_operand:QI 0 "register_operand" "Q")
717 (match_operand 1 "ext_register_operand" "Q")
720 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721 "cmp{b}\t{%h1, %0|%0, %h1}"
722 [(set_attr "type" "icmp")
723 (set_attr "mode" "QI")])
725 (define_insn "*cmpqi_ext_2"
726 [(set (reg FLAGS_REG)
730 (match_operand 0 "ext_register_operand" "Q")
733 (match_operand:QI 1 "const0_operand" "n")))]
734 "ix86_match_ccmode (insn, CCNOmode)"
736 [(set_attr "type" "test")
737 (set_attr "length_immediate" "0")
738 (set_attr "mode" "QI")])
740 (define_expand "cmpqi_ext_3"
741 [(set (reg:CC FLAGS_REG)
745 (match_operand 0 "ext_register_operand" "")
748 (match_operand:QI 1 "general_operand" "")))]
752 (define_insn "cmpqi_ext_3_insn"
753 [(set (reg FLAGS_REG)
757 (match_operand 0 "ext_register_operand" "Q")
760 (match_operand:QI 1 "general_operand" "Qmn")))]
761 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
762 "cmp{b}\t{%1, %h0|%h0, %1}"
763 [(set_attr "type" "icmp")
764 (set_attr "mode" "QI")])
766 (define_insn "cmpqi_ext_3_insn_rex64"
767 [(set (reg FLAGS_REG)
771 (match_operand 0 "ext_register_operand" "Q")
774 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
775 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776 "cmp{b}\t{%1, %h0|%h0, %1}"
777 [(set_attr "type" "icmp")
778 (set_attr "mode" "QI")])
780 (define_insn "*cmpqi_ext_4"
781 [(set (reg FLAGS_REG)
785 (match_operand 0 "ext_register_operand" "Q")
790 (match_operand 1 "ext_register_operand" "Q")
793 "ix86_match_ccmode (insn, CCmode)"
794 "cmp{b}\t{%h1, %h0|%h0, %h1}"
795 [(set_attr "type" "icmp")
796 (set_attr "mode" "QI")])
798 ;; These implement float point compares.
799 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
800 ;; which would allow mix and match FP modes on the compares. Which is what
801 ;; the old patterns did, but with many more of them.
803 (define_expand "cmpxf"
804 [(set (reg:CC FLAGS_REG)
805 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
806 (match_operand:XF 1 "nonmemory_operand" "")))]
809 ix86_compare_op0 = operands[0];
810 ix86_compare_op1 = operands[1];
814 (define_expand "cmpdf"
815 [(set (reg:CC FLAGS_REG)
816 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
817 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
818 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
820 ix86_compare_op0 = operands[0];
821 ix86_compare_op1 = operands[1];
825 (define_expand "cmpsf"
826 [(set (reg:CC FLAGS_REG)
827 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
828 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
829 "TARGET_80387 || TARGET_SSE_MATH"
831 ix86_compare_op0 = operands[0];
832 ix86_compare_op1 = operands[1];
836 ;; FP compares, step 1:
837 ;; Set the FP condition codes.
839 ;; CCFPmode compare with exceptions
840 ;; CCFPUmode compare with no exceptions
842 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
843 ;; used to manage the reg stack popping would not be preserved.
845 (define_insn "*cmpfp_0"
846 [(set (match_operand:HI 0 "register_operand" "=a")
849 (match_operand 1 "register_operand" "f")
850 (match_operand 2 "const0_operand" "X"))]
853 && FLOAT_MODE_P (GET_MODE (operands[1]))
854 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
855 "* return output_fp_compare (insn, operands, 0, 0);"
856 [(set_attr "type" "multi")
857 (set_attr "unit" "i387")
859 (cond [(match_operand:SF 1 "" "")
861 (match_operand:DF 1 "" "")
864 (const_string "XF")))])
866 (define_insn "*cmpfp_sf"
867 [(set (match_operand:HI 0 "register_operand" "=a")
870 (match_operand:SF 1 "register_operand" "f")
871 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
874 "* return output_fp_compare (insn, operands, 0, 0);"
875 [(set_attr "type" "multi")
876 (set_attr "unit" "i387")
877 (set_attr "mode" "SF")])
879 (define_insn "*cmpfp_df"
880 [(set (match_operand:HI 0 "register_operand" "=a")
883 (match_operand:DF 1 "register_operand" "f")
884 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
887 "* return output_fp_compare (insn, operands, 0, 0);"
888 [(set_attr "type" "multi")
889 (set_attr "unit" "i387")
890 (set_attr "mode" "DF")])
892 (define_insn "*cmpfp_xf"
893 [(set (match_operand:HI 0 "register_operand" "=a")
896 (match_operand:XF 1 "register_operand" "f")
897 (match_operand:XF 2 "register_operand" "f"))]
900 "* return output_fp_compare (insn, operands, 0, 0);"
901 [(set_attr "type" "multi")
902 (set_attr "unit" "i387")
903 (set_attr "mode" "XF")])
905 (define_insn "*cmpfp_u"
906 [(set (match_operand:HI 0 "register_operand" "=a")
909 (match_operand 1 "register_operand" "f")
910 (match_operand 2 "register_operand" "f"))]
913 && FLOAT_MODE_P (GET_MODE (operands[1]))
914 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
915 "* return output_fp_compare (insn, operands, 0, 1);"
916 [(set_attr "type" "multi")
917 (set_attr "unit" "i387")
919 (cond [(match_operand:SF 1 "" "")
921 (match_operand:DF 1 "" "")
924 (const_string "XF")))])
926 (define_insn "*cmpfp_<mode>"
927 [(set (match_operand:HI 0 "register_operand" "=a")
930 (match_operand 1 "register_operand" "f")
931 (match_operator 3 "float_operator"
932 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
934 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
935 && FLOAT_MODE_P (GET_MODE (operands[1]))
936 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
937 "* return output_fp_compare (insn, operands, 0, 0);"
938 [(set_attr "type" "multi")
939 (set_attr "unit" "i387")
940 (set_attr "fp_int_src" "true")
941 (set_attr "mode" "<MODE>")])
943 ;; FP compares, step 2
944 ;; Move the fpsw to ax.
946 (define_insn "x86_fnstsw_1"
947 [(set (match_operand:HI 0 "register_operand" "=a")
948 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
951 [(set_attr "length" "2")
952 (set_attr "mode" "SI")
953 (set_attr "unit" "i387")])
955 ;; FP compares, step 3
956 ;; Get ax into flags, general case.
958 (define_insn "x86_sahf_1"
959 [(set (reg:CC FLAGS_REG)
960 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
963 [(set_attr "length" "1")
964 (set_attr "athlon_decode" "vector")
965 (set_attr "mode" "SI")])
967 ;; Pentium Pro can do steps 1 through 3 in one go.
969 (define_insn "*cmpfp_i_mixed"
970 [(set (reg:CCFP FLAGS_REG)
971 (compare:CCFP (match_operand 0 "register_operand" "f,x")
972 (match_operand 1 "nonimmediate_operand" "f,xm")))]
974 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
975 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
976 "* return output_fp_compare (insn, operands, 1, 0);"
977 [(set_attr "type" "fcmp,ssecomi")
979 (if_then_else (match_operand:SF 1 "" "")
981 (const_string "DF")))
982 (set_attr "athlon_decode" "vector")])
984 (define_insn "*cmpfp_i_sse"
985 [(set (reg:CCFP FLAGS_REG)
986 (compare:CCFP (match_operand 0 "register_operand" "x")
987 (match_operand 1 "nonimmediate_operand" "xm")))]
989 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991 "* return output_fp_compare (insn, operands, 1, 0);"
992 [(set_attr "type" "ssecomi")
994 (if_then_else (match_operand:SF 1 "" "")
996 (const_string "DF")))
997 (set_attr "athlon_decode" "vector")])
999 (define_insn "*cmpfp_i_i387"
1000 [(set (reg:CCFP FLAGS_REG)
1001 (compare:CCFP (match_operand 0 "register_operand" "f")
1002 (match_operand 1 "register_operand" "f")))]
1003 "TARGET_80387 && TARGET_CMOVE
1004 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1005 && FLOAT_MODE_P (GET_MODE (operands[0]))
1006 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007 "* return output_fp_compare (insn, operands, 1, 0);"
1008 [(set_attr "type" "fcmp")
1010 (cond [(match_operand:SF 1 "" "")
1012 (match_operand:DF 1 "" "")
1015 (const_string "XF")))
1016 (set_attr "athlon_decode" "vector")])
1018 (define_insn "*cmpfp_iu_mixed"
1019 [(set (reg:CCFPU FLAGS_REG)
1020 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1021 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1022 "TARGET_MIX_SSE_I387
1023 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025 "* return output_fp_compare (insn, operands, 1, 1);"
1026 [(set_attr "type" "fcmp,ssecomi")
1028 (if_then_else (match_operand:SF 1 "" "")
1030 (const_string "DF")))
1031 (set_attr "athlon_decode" "vector")])
1033 (define_insn "*cmpfp_iu_sse"
1034 [(set (reg:CCFPU FLAGS_REG)
1035 (compare:CCFPU (match_operand 0 "register_operand" "x")
1036 (match_operand 1 "nonimmediate_operand" "xm")))]
1038 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040 "* return output_fp_compare (insn, operands, 1, 1);"
1041 [(set_attr "type" "ssecomi")
1043 (if_then_else (match_operand:SF 1 "" "")
1045 (const_string "DF")))
1046 (set_attr "athlon_decode" "vector")])
1048 (define_insn "*cmpfp_iu_387"
1049 [(set (reg:CCFPU FLAGS_REG)
1050 (compare:CCFPU (match_operand 0 "register_operand" "f")
1051 (match_operand 1 "register_operand" "f")))]
1052 "TARGET_80387 && TARGET_CMOVE
1053 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1054 && FLOAT_MODE_P (GET_MODE (operands[0]))
1055 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1056 "* return output_fp_compare (insn, operands, 1, 1);"
1057 [(set_attr "type" "fcmp")
1059 (cond [(match_operand:SF 1 "" "")
1061 (match_operand:DF 1 "" "")
1064 (const_string "XF")))
1065 (set_attr "athlon_decode" "vector")])
1067 ;; Move instructions.
1069 ;; General case of fullword move.
1071 (define_expand "movsi"
1072 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1073 (match_operand:SI 1 "general_operand" ""))]
1075 "ix86_expand_move (SImode, operands); DONE;")
1077 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1080 ;; %%% We don't use a post-inc memory reference because x86 is not a
1081 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1082 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1083 ;; targets without our curiosities, and it is just as easy to represent
1084 ;; this differently.
1086 (define_insn "*pushsi2"
1087 [(set (match_operand:SI 0 "push_operand" "=<")
1088 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1091 [(set_attr "type" "push")
1092 (set_attr "mode" "SI")])
1094 ;; For 64BIT abi we always round up to 8 bytes.
1095 (define_insn "*pushsi2_rex64"
1096 [(set (match_operand:SI 0 "push_operand" "=X")
1097 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1100 [(set_attr "type" "push")
1101 (set_attr "mode" "SI")])
1103 (define_insn "*pushsi2_prologue"
1104 [(set (match_operand:SI 0 "push_operand" "=<")
1105 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1106 (clobber (mem:BLK (scratch)))]
1109 [(set_attr "type" "push")
1110 (set_attr "mode" "SI")])
1112 (define_insn "*popsi1_epilogue"
1113 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1114 (mem:SI (reg:SI SP_REG)))
1115 (set (reg:SI SP_REG)
1116 (plus:SI (reg:SI SP_REG) (const_int 4)))
1117 (clobber (mem:BLK (scratch)))]
1120 [(set_attr "type" "pop")
1121 (set_attr "mode" "SI")])
1123 (define_insn "popsi1"
1124 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1125 (mem:SI (reg:SI SP_REG)))
1126 (set (reg:SI SP_REG)
1127 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1130 [(set_attr "type" "pop")
1131 (set_attr "mode" "SI")])
1133 (define_insn "*movsi_xor"
1134 [(set (match_operand:SI 0 "register_operand" "=r")
1135 (match_operand:SI 1 "const0_operand" "i"))
1136 (clobber (reg:CC FLAGS_REG))]
1137 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1138 "xor{l}\t{%0, %0|%0, %0}"
1139 [(set_attr "type" "alu1")
1140 (set_attr "mode" "SI")
1141 (set_attr "length_immediate" "0")])
1143 (define_insn "*movsi_or"
1144 [(set (match_operand:SI 0 "register_operand" "=r")
1145 (match_operand:SI 1 "immediate_operand" "i"))
1146 (clobber (reg:CC FLAGS_REG))]
1148 && operands[1] == constm1_rtx
1149 && (TARGET_PENTIUM || optimize_size)"
1151 operands[1] = constm1_rtx;
1152 return "or{l}\t{%1, %0|%0, %1}";
1154 [(set_attr "type" "alu1")
1155 (set_attr "mode" "SI")
1156 (set_attr "length_immediate" "1")])
1158 (define_insn "*movsi_1"
1159 [(set (match_operand:SI 0 "nonimmediate_operand"
1160 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1161 (match_operand:SI 1 "general_operand"
1162 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1163 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1165 switch (get_attr_type (insn))
1168 if (get_attr_mode (insn) == MODE_TI)
1169 return "pxor\t%0, %0";
1170 return "xorps\t%0, %0";
1173 switch (get_attr_mode (insn))
1176 return "movdqa\t{%1, %0|%0, %1}";
1178 return "movaps\t{%1, %0|%0, %1}";
1180 return "movd\t{%1, %0|%0, %1}";
1182 return "movss\t{%1, %0|%0, %1}";
1188 return "pxor\t%0, %0";
1191 if (get_attr_mode (insn) == MODE_DI)
1192 return "movq\t{%1, %0|%0, %1}";
1193 return "movd\t{%1, %0|%0, %1}";
1196 return "lea{l}\t{%1, %0|%0, %1}";
1199 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1200 return "mov{l}\t{%1, %0|%0, %1}";
1204 (cond [(eq_attr "alternative" "2")
1205 (const_string "mmxadd")
1206 (eq_attr "alternative" "3,4,5")
1207 (const_string "mmxmov")
1208 (eq_attr "alternative" "6")
1209 (const_string "sselog1")
1210 (eq_attr "alternative" "7,8,9,10,11")
1211 (const_string "ssemov")
1212 (match_operand:DI 1 "pic_32bit_operand" "")
1213 (const_string "lea")
1215 (const_string "imov")))
1217 (cond [(eq_attr "alternative" "2,3")
1219 (eq_attr "alternative" "6,7")
1221 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1222 (const_string "V4SF")
1223 (const_string "TI"))
1224 (and (eq_attr "alternative" "8,9,10,11")
1225 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1228 (const_string "SI")))])
1230 ;; Stores and loads of ax to arbitrary constant address.
1231 ;; We fake an second form of instruction to force reload to load address
1232 ;; into register when rax is not available
1233 (define_insn "*movabssi_1_rex64"
1234 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1235 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1236 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1238 movabs{l}\t{%1, %P0|%P0, %1}
1239 mov{l}\t{%1, %a0|%a0, %1}"
1240 [(set_attr "type" "imov")
1241 (set_attr "modrm" "0,*")
1242 (set_attr "length_address" "8,0")
1243 (set_attr "length_immediate" "0,*")
1244 (set_attr "memory" "store")
1245 (set_attr "mode" "SI")])
1247 (define_insn "*movabssi_2_rex64"
1248 [(set (match_operand:SI 0 "register_operand" "=a,r")
1249 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1250 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1252 movabs{l}\t{%P1, %0|%0, %P1}
1253 mov{l}\t{%a1, %0|%0, %a1}"
1254 [(set_attr "type" "imov")
1255 (set_attr "modrm" "0,*")
1256 (set_attr "length_address" "8,0")
1257 (set_attr "length_immediate" "0")
1258 (set_attr "memory" "load")
1259 (set_attr "mode" "SI")])
1261 (define_insn "*swapsi"
1262 [(set (match_operand:SI 0 "register_operand" "+r")
1263 (match_operand:SI 1 "register_operand" "+r"))
1268 [(set_attr "type" "imov")
1269 (set_attr "mode" "SI")
1270 (set_attr "pent_pair" "np")
1271 (set_attr "athlon_decode" "vector")])
1273 (define_expand "movhi"
1274 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1275 (match_operand:HI 1 "general_operand" ""))]
1277 "ix86_expand_move (HImode, operands); DONE;")
1279 (define_insn "*pushhi2"
1280 [(set (match_operand:HI 0 "push_operand" "=X")
1281 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1284 [(set_attr "type" "push")
1285 (set_attr "mode" "SI")])
1287 ;; For 64BIT abi we always round up to 8 bytes.
1288 (define_insn "*pushhi2_rex64"
1289 [(set (match_operand:HI 0 "push_operand" "=X")
1290 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1293 [(set_attr "type" "push")
1294 (set_attr "mode" "DI")])
1296 (define_insn "*movhi_1"
1297 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1298 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1299 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1301 switch (get_attr_type (insn))
1304 /* movzwl is faster than movw on p2 due to partial word stalls,
1305 though not as fast as an aligned movl. */
1306 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1308 if (get_attr_mode (insn) == MODE_SI)
1309 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1311 return "mov{w}\t{%1, %0|%0, %1}";
1315 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1316 (const_string "imov")
1317 (and (eq_attr "alternative" "0")
1318 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1320 (eq (symbol_ref "TARGET_HIMODE_MATH")
1322 (const_string "imov")
1323 (and (eq_attr "alternative" "1,2")
1324 (match_operand:HI 1 "aligned_operand" ""))
1325 (const_string "imov")
1326 (and (ne (symbol_ref "TARGET_MOVX")
1328 (eq_attr "alternative" "0,2"))
1329 (const_string "imovx")
1331 (const_string "imov")))
1333 (cond [(eq_attr "type" "imovx")
1335 (and (eq_attr "alternative" "1,2")
1336 (match_operand:HI 1 "aligned_operand" ""))
1338 (and (eq_attr "alternative" "0")
1339 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1341 (eq (symbol_ref "TARGET_HIMODE_MATH")
1345 (const_string "HI")))])
1347 ;; Stores and loads of ax to arbitrary constant address.
1348 ;; We fake an second form of instruction to force reload to load address
1349 ;; into register when rax is not available
1350 (define_insn "*movabshi_1_rex64"
1351 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1352 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1353 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1355 movabs{w}\t{%1, %P0|%P0, %1}
1356 mov{w}\t{%1, %a0|%a0, %1}"
1357 [(set_attr "type" "imov")
1358 (set_attr "modrm" "0,*")
1359 (set_attr "length_address" "8,0")
1360 (set_attr "length_immediate" "0,*")
1361 (set_attr "memory" "store")
1362 (set_attr "mode" "HI")])
1364 (define_insn "*movabshi_2_rex64"
1365 [(set (match_operand:HI 0 "register_operand" "=a,r")
1366 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1367 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1369 movabs{w}\t{%P1, %0|%0, %P1}
1370 mov{w}\t{%a1, %0|%0, %a1}"
1371 [(set_attr "type" "imov")
1372 (set_attr "modrm" "0,*")
1373 (set_attr "length_address" "8,0")
1374 (set_attr "length_immediate" "0")
1375 (set_attr "memory" "load")
1376 (set_attr "mode" "HI")])
1378 (define_insn "*swaphi_1"
1379 [(set (match_operand:HI 0 "register_operand" "+r")
1380 (match_operand:HI 1 "register_operand" "+r"))
1383 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1385 [(set_attr "type" "imov")
1386 (set_attr "mode" "SI")
1387 (set_attr "pent_pair" "np")
1388 (set_attr "athlon_decode" "vector")])
1390 (define_insn "*swaphi_2"
1391 [(set (match_operand:HI 0 "register_operand" "+r")
1392 (match_operand:HI 1 "register_operand" "+r"))
1395 "TARGET_PARTIAL_REG_STALL"
1397 [(set_attr "type" "imov")
1398 (set_attr "mode" "HI")
1399 (set_attr "pent_pair" "np")
1400 (set_attr "athlon_decode" "vector")])
1402 (define_expand "movstricthi"
1403 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1404 (match_operand:HI 1 "general_operand" ""))]
1405 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1407 /* Don't generate memory->memory moves, go through a register */
1408 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1409 operands[1] = force_reg (HImode, operands[1]);
1412 (define_insn "*movstricthi_1"
1413 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1414 (match_operand:HI 1 "general_operand" "rn,m"))]
1415 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1416 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1417 "mov{w}\t{%1, %0|%0, %1}"
1418 [(set_attr "type" "imov")
1419 (set_attr "mode" "HI")])
1421 (define_insn "*movstricthi_xor"
1422 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1423 (match_operand:HI 1 "const0_operand" "i"))
1424 (clobber (reg:CC FLAGS_REG))]
1426 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1427 "xor{w}\t{%0, %0|%0, %0}"
1428 [(set_attr "type" "alu1")
1429 (set_attr "mode" "HI")
1430 (set_attr "length_immediate" "0")])
1432 (define_expand "movqi"
1433 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1434 (match_operand:QI 1 "general_operand" ""))]
1436 "ix86_expand_move (QImode, operands); DONE;")
1438 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1439 ;; "push a byte". But actually we use pushl, which has the effect
1440 ;; of rounding the amount pushed up to a word.
1442 (define_insn "*pushqi2"
1443 [(set (match_operand:QI 0 "push_operand" "=X")
1444 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1447 [(set_attr "type" "push")
1448 (set_attr "mode" "SI")])
1450 ;; For 64BIT abi we always round up to 8 bytes.
1451 (define_insn "*pushqi2_rex64"
1452 [(set (match_operand:QI 0 "push_operand" "=X")
1453 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1456 [(set_attr "type" "push")
1457 (set_attr "mode" "DI")])
1459 ;; Situation is quite tricky about when to choose full sized (SImode) move
1460 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1461 ;; partial register dependency machines (such as AMD Athlon), where QImode
1462 ;; moves issue extra dependency and for partial register stalls machines
1463 ;; that don't use QImode patterns (and QImode move cause stall on the next
1466 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1467 ;; register stall machines with, where we use QImode instructions, since
1468 ;; partial register stall can be caused there. Then we use movzx.
1469 (define_insn "*movqi_1"
1470 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1471 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1472 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1474 switch (get_attr_type (insn))
1477 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1478 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1480 if (get_attr_mode (insn) == MODE_SI)
1481 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1483 return "mov{b}\t{%1, %0|%0, %1}";
1487 (cond [(and (eq_attr "alternative" "5")
1488 (not (match_operand:QI 1 "aligned_operand" "")))
1489 (const_string "imovx")
1490 (ne (symbol_ref "optimize_size") (const_int 0))
1491 (const_string "imov")
1492 (and (eq_attr "alternative" "3")
1493 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1495 (eq (symbol_ref "TARGET_QIMODE_MATH")
1497 (const_string "imov")
1498 (eq_attr "alternative" "3,5")
1499 (const_string "imovx")
1500 (and (ne (symbol_ref "TARGET_MOVX")
1502 (eq_attr "alternative" "2"))
1503 (const_string "imovx")
1505 (const_string "imov")))
1507 (cond [(eq_attr "alternative" "3,4,5")
1509 (eq_attr "alternative" "6")
1511 (eq_attr "type" "imovx")
1513 (and (eq_attr "type" "imov")
1514 (and (eq_attr "alternative" "0,1")
1515 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1517 (and (eq (symbol_ref "optimize_size")
1519 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1522 ;; Avoid partial register stalls when not using QImode arithmetic
1523 (and (eq_attr "type" "imov")
1524 (and (eq_attr "alternative" "0,1")
1525 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1527 (eq (symbol_ref "TARGET_QIMODE_MATH")
1531 (const_string "QI")))])
1533 (define_expand "reload_outqi"
1534 [(parallel [(match_operand:QI 0 "" "=m")
1535 (match_operand:QI 1 "register_operand" "r")
1536 (match_operand:QI 2 "register_operand" "=&q")])]
1540 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1542 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1543 if (! q_regs_operand (op1, QImode))
1545 emit_insn (gen_movqi (op2, op1));
1548 emit_insn (gen_movqi (op0, op1));
1552 (define_insn "*swapqi_1"
1553 [(set (match_operand:QI 0 "register_operand" "+r")
1554 (match_operand:QI 1 "register_operand" "+r"))
1557 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1559 [(set_attr "type" "imov")
1560 (set_attr "mode" "SI")
1561 (set_attr "pent_pair" "np")
1562 (set_attr "athlon_decode" "vector")])
1564 (define_insn "*swapqi_2"
1565 [(set (match_operand:QI 0 "register_operand" "+q")
1566 (match_operand:QI 1 "register_operand" "+q"))
1569 "TARGET_PARTIAL_REG_STALL"
1571 [(set_attr "type" "imov")
1572 (set_attr "mode" "QI")
1573 (set_attr "pent_pair" "np")
1574 (set_attr "athlon_decode" "vector")])
1576 (define_expand "movstrictqi"
1577 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1578 (match_operand:QI 1 "general_operand" ""))]
1579 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1581 /* Don't generate memory->memory moves, go through a register. */
1582 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1583 operands[1] = force_reg (QImode, operands[1]);
1586 (define_insn "*movstrictqi_1"
1587 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1588 (match_operand:QI 1 "general_operand" "*qn,m"))]
1589 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1590 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1591 "mov{b}\t{%1, %0|%0, %1}"
1592 [(set_attr "type" "imov")
1593 (set_attr "mode" "QI")])
1595 (define_insn "*movstrictqi_xor"
1596 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1597 (match_operand:QI 1 "const0_operand" "i"))
1598 (clobber (reg:CC FLAGS_REG))]
1599 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1600 "xor{b}\t{%0, %0|%0, %0}"
1601 [(set_attr "type" "alu1")
1602 (set_attr "mode" "QI")
1603 (set_attr "length_immediate" "0")])
1605 (define_insn "*movsi_extv_1"
1606 [(set (match_operand:SI 0 "register_operand" "=R")
1607 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1611 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1612 [(set_attr "type" "imovx")
1613 (set_attr "mode" "SI")])
1615 (define_insn "*movhi_extv_1"
1616 [(set (match_operand:HI 0 "register_operand" "=R")
1617 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1621 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1622 [(set_attr "type" "imovx")
1623 (set_attr "mode" "SI")])
1625 (define_insn "*movqi_extv_1"
1626 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1627 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1632 switch (get_attr_type (insn))
1635 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1637 return "mov{b}\t{%h1, %0|%0, %h1}";
1641 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1642 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1643 (ne (symbol_ref "TARGET_MOVX")
1645 (const_string "imovx")
1646 (const_string "imov")))
1648 (if_then_else (eq_attr "type" "imovx")
1650 (const_string "QI")))])
1652 (define_insn "*movqi_extv_1_rex64"
1653 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1654 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1659 switch (get_attr_type (insn))
1662 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1664 return "mov{b}\t{%h1, %0|%0, %h1}";
1668 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1669 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1670 (ne (symbol_ref "TARGET_MOVX")
1672 (const_string "imovx")
1673 (const_string "imov")))
1675 (if_then_else (eq_attr "type" "imovx")
1677 (const_string "QI")))])
1679 ;; Stores and loads of ax to arbitrary constant address.
1680 ;; We fake an second form of instruction to force reload to load address
1681 ;; into register when rax is not available
1682 (define_insn "*movabsqi_1_rex64"
1683 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1684 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1685 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1687 movabs{b}\t{%1, %P0|%P0, %1}
1688 mov{b}\t{%1, %a0|%a0, %1}"
1689 [(set_attr "type" "imov")
1690 (set_attr "modrm" "0,*")
1691 (set_attr "length_address" "8,0")
1692 (set_attr "length_immediate" "0,*")
1693 (set_attr "memory" "store")
1694 (set_attr "mode" "QI")])
1696 (define_insn "*movabsqi_2_rex64"
1697 [(set (match_operand:QI 0 "register_operand" "=a,r")
1698 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1699 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1701 movabs{b}\t{%P1, %0|%0, %P1}
1702 mov{b}\t{%a1, %0|%0, %a1}"
1703 [(set_attr "type" "imov")
1704 (set_attr "modrm" "0,*")
1705 (set_attr "length_address" "8,0")
1706 (set_attr "length_immediate" "0")
1707 (set_attr "memory" "load")
1708 (set_attr "mode" "QI")])
1710 (define_insn "*movdi_extzv_1"
1711 [(set (match_operand:DI 0 "register_operand" "=R")
1712 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1716 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1717 [(set_attr "type" "imovx")
1718 (set_attr "mode" "DI")])
1720 (define_insn "*movsi_extzv_1"
1721 [(set (match_operand:SI 0 "register_operand" "=R")
1722 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1726 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1727 [(set_attr "type" "imovx")
1728 (set_attr "mode" "SI")])
1730 (define_insn "*movqi_extzv_2"
1731 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1732 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1737 switch (get_attr_type (insn))
1740 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1742 return "mov{b}\t{%h1, %0|%0, %h1}";
1746 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1747 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1748 (ne (symbol_ref "TARGET_MOVX")
1750 (const_string "imovx")
1751 (const_string "imov")))
1753 (if_then_else (eq_attr "type" "imovx")
1755 (const_string "QI")))])
1757 (define_insn "*movqi_extzv_2_rex64"
1758 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1759 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1764 switch (get_attr_type (insn))
1767 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1769 return "mov{b}\t{%h1, %0|%0, %h1}";
1773 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774 (ne (symbol_ref "TARGET_MOVX")
1776 (const_string "imovx")
1777 (const_string "imov")))
1779 (if_then_else (eq_attr "type" "imovx")
1781 (const_string "QI")))])
1783 (define_insn "movsi_insv_1"
1784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1787 (match_operand:SI 1 "general_operand" "Qmn"))]
1789 "mov{b}\t{%b1, %h0|%h0, %b1}"
1790 [(set_attr "type" "imov")
1791 (set_attr "mode" "QI")])
1793 (define_insn "movdi_insv_1_rex64"
1794 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1797 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1799 "mov{b}\t{%b1, %h0|%h0, %b1}"
1800 [(set_attr "type" "imov")
1801 (set_attr "mode" "QI")])
1803 (define_insn "*movqi_insv_2"
1804 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1807 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1810 "mov{b}\t{%h1, %h0|%h0, %h1}"
1811 [(set_attr "type" "imov")
1812 (set_attr "mode" "QI")])
1814 (define_expand "movdi"
1815 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1816 (match_operand:DI 1 "general_operand" ""))]
1818 "ix86_expand_move (DImode, operands); DONE;")
1820 (define_insn "*pushdi"
1821 [(set (match_operand:DI 0 "push_operand" "=<")
1822 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1826 (define_insn "*pushdi2_rex64"
1827 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1828 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1833 [(set_attr "type" "push,multi")
1834 (set_attr "mode" "DI")])
1836 ;; Convert impossible pushes of immediate to existing instructions.
1837 ;; First try to get scratch register and go through it. In case this
1838 ;; fails, push sign extended lower part first and then overwrite
1839 ;; upper part by 32bit move.
1841 [(match_scratch:DI 2 "r")
1842 (set (match_operand:DI 0 "push_operand" "")
1843 (match_operand:DI 1 "immediate_operand" ""))]
1844 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1845 && !x86_64_immediate_operand (operands[1], DImode)"
1846 [(set (match_dup 2) (match_dup 1))
1847 (set (match_dup 0) (match_dup 2))]
1850 ;; We need to define this as both peepholer and splitter for case
1851 ;; peephole2 pass is not run.
1852 ;; "&& 1" is needed to keep it from matching the previous pattern.
1854 [(set (match_operand:DI 0 "push_operand" "")
1855 (match_operand:DI 1 "immediate_operand" ""))]
1856 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1857 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1858 [(set (match_dup 0) (match_dup 1))
1859 (set (match_dup 2) (match_dup 3))]
1860 "split_di (operands + 1, 1, operands + 2, operands + 3);
1861 operands[1] = gen_lowpart (DImode, operands[2]);
1862 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1867 [(set (match_operand:DI 0 "push_operand" "")
1868 (match_operand:DI 1 "immediate_operand" ""))]
1869 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1870 ? flow2_completed : reload_completed)
1871 && !symbolic_operand (operands[1], DImode)
1872 && !x86_64_immediate_operand (operands[1], DImode)"
1873 [(set (match_dup 0) (match_dup 1))
1874 (set (match_dup 2) (match_dup 3))]
1875 "split_di (operands + 1, 1, operands + 2, operands + 3);
1876 operands[1] = gen_lowpart (DImode, operands[2]);
1877 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1881 (define_insn "*pushdi2_prologue_rex64"
1882 [(set (match_operand:DI 0 "push_operand" "=<")
1883 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1884 (clobber (mem:BLK (scratch)))]
1887 [(set_attr "type" "push")
1888 (set_attr "mode" "DI")])
1890 (define_insn "*popdi1_epilogue_rex64"
1891 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1892 (mem:DI (reg:DI SP_REG)))
1893 (set (reg:DI SP_REG)
1894 (plus:DI (reg:DI SP_REG) (const_int 8)))
1895 (clobber (mem:BLK (scratch)))]
1898 [(set_attr "type" "pop")
1899 (set_attr "mode" "DI")])
1901 (define_insn "popdi1"
1902 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1903 (mem:DI (reg:DI SP_REG)))
1904 (set (reg:DI SP_REG)
1905 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1908 [(set_attr "type" "pop")
1909 (set_attr "mode" "DI")])
1911 (define_insn "*movdi_xor_rex64"
1912 [(set (match_operand:DI 0 "register_operand" "=r")
1913 (match_operand:DI 1 "const0_operand" "i"))
1914 (clobber (reg:CC FLAGS_REG))]
1915 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1916 && reload_completed"
1917 "xor{l}\t{%k0, %k0|%k0, %k0}"
1918 [(set_attr "type" "alu1")
1919 (set_attr "mode" "SI")
1920 (set_attr "length_immediate" "0")])
1922 (define_insn "*movdi_or_rex64"
1923 [(set (match_operand:DI 0 "register_operand" "=r")
1924 (match_operand:DI 1 "const_int_operand" "i"))
1925 (clobber (reg:CC FLAGS_REG))]
1926 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1928 && operands[1] == constm1_rtx"
1930 operands[1] = constm1_rtx;
1931 return "or{q}\t{%1, %0|%0, %1}";
1933 [(set_attr "type" "alu1")
1934 (set_attr "mode" "DI")
1935 (set_attr "length_immediate" "1")])
1937 (define_insn "*movdi_2"
1938 [(set (match_operand:DI 0 "nonimmediate_operand"
1939 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1940 (match_operand:DI 1 "general_operand"
1941 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1942 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1947 movq\t{%1, %0|%0, %1}
1948 movq\t{%1, %0|%0, %1}
1950 movq\t{%1, %0|%0, %1}
1951 movdqa\t{%1, %0|%0, %1}
1952 movq\t{%1, %0|%0, %1}
1954 movlps\t{%1, %0|%0, %1}
1955 movaps\t{%1, %0|%0, %1}
1956 movlps\t{%1, %0|%0, %1}"
1957 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1958 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1961 [(set (match_operand:DI 0 "push_operand" "")
1962 (match_operand:DI 1 "general_operand" ""))]
1963 "!TARGET_64BIT && reload_completed
1964 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1966 "ix86_split_long_move (operands); DONE;")
1968 ;; %%% This multiword shite has got to go.
1970 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1971 (match_operand:DI 1 "general_operand" ""))]
1972 "!TARGET_64BIT && reload_completed
1973 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1974 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1976 "ix86_split_long_move (operands); DONE;")
1978 (define_insn "*movdi_1_rex64"
1979 [(set (match_operand:DI 0 "nonimmediate_operand"
1980 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1981 (match_operand:DI 1 "general_operand"
1982 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1983 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1985 switch (get_attr_type (insn))
1988 if (which_alternative == 13)
1989 return "movq2dq\t{%1, %0|%0, %1}";
1991 return "movdq2q\t{%1, %0|%0, %1}";
1993 if (get_attr_mode (insn) == MODE_TI)
1994 return "movdqa\t{%1, %0|%0, %1}";
1997 /* Moves from and into integer register is done using movd opcode with
1999 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2000 return "movd\t{%1, %0|%0, %1}";
2001 return "movq\t{%1, %0|%0, %1}";
2004 return "pxor\t%0, %0";
2008 return "lea{q}\t{%a1, %0|%0, %a1}";
2010 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2011 if (get_attr_mode (insn) == MODE_SI)
2012 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2013 else if (which_alternative == 2)
2014 return "movabs{q}\t{%1, %0|%0, %1}";
2016 return "mov{q}\t{%1, %0|%0, %1}";
2020 (cond [(eq_attr "alternative" "5")
2021 (const_string "mmxadd")
2022 (eq_attr "alternative" "6,7,8")
2023 (const_string "mmxmov")
2024 (eq_attr "alternative" "9")
2025 (const_string "sselog1")
2026 (eq_attr "alternative" "10,11,12")
2027 (const_string "ssemov")
2028 (eq_attr "alternative" "13,14")
2029 (const_string "ssecvt")
2030 (eq_attr "alternative" "4")
2031 (const_string "multi")
2032 (match_operand:DI 1 "pic_32bit_operand" "")
2033 (const_string "lea")
2035 (const_string "imov")))
2036 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2037 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2038 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2040 ;; Stores and loads of ax to arbitrary constant address.
2041 ;; We fake an second form of instruction to force reload to load address
2042 ;; into register when rax is not available
2043 (define_insn "*movabsdi_1_rex64"
2044 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2045 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2046 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2048 movabs{q}\t{%1, %P0|%P0, %1}
2049 mov{q}\t{%1, %a0|%a0, %1}"
2050 [(set_attr "type" "imov")
2051 (set_attr "modrm" "0,*")
2052 (set_attr "length_address" "8,0")
2053 (set_attr "length_immediate" "0,*")
2054 (set_attr "memory" "store")
2055 (set_attr "mode" "DI")])
2057 (define_insn "*movabsdi_2_rex64"
2058 [(set (match_operand:DI 0 "register_operand" "=a,r")
2059 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2060 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2062 movabs{q}\t{%P1, %0|%0, %P1}
2063 mov{q}\t{%a1, %0|%0, %a1}"
2064 [(set_attr "type" "imov")
2065 (set_attr "modrm" "0,*")
2066 (set_attr "length_address" "8,0")
2067 (set_attr "length_immediate" "0")
2068 (set_attr "memory" "load")
2069 (set_attr "mode" "DI")])
2071 ;; Convert impossible stores of immediate to existing instructions.
2072 ;; First try to get scratch register and go through it. In case this
2073 ;; fails, move by 32bit parts.
2075 [(match_scratch:DI 2 "r")
2076 (set (match_operand:DI 0 "memory_operand" "")
2077 (match_operand:DI 1 "immediate_operand" ""))]
2078 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2079 && !x86_64_immediate_operand (operands[1], DImode)"
2080 [(set (match_dup 2) (match_dup 1))
2081 (set (match_dup 0) (match_dup 2))]
2084 ;; We need to define this as both peepholer and splitter for case
2085 ;; peephole2 pass is not run.
2086 ;; "&& 1" is needed to keep it from matching the previous pattern.
2088 [(set (match_operand:DI 0 "memory_operand" "")
2089 (match_operand:DI 1 "immediate_operand" ""))]
2090 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2091 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2092 [(set (match_dup 2) (match_dup 3))
2093 (set (match_dup 4) (match_dup 5))]
2094 "split_di (operands, 2, operands + 2, operands + 4);")
2097 [(set (match_operand:DI 0 "memory_operand" "")
2098 (match_operand:DI 1 "immediate_operand" ""))]
2099 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2100 ? flow2_completed : reload_completed)
2101 && !symbolic_operand (operands[1], DImode)
2102 && !x86_64_immediate_operand (operands[1], DImode)"
2103 [(set (match_dup 2) (match_dup 3))
2104 (set (match_dup 4) (match_dup 5))]
2105 "split_di (operands, 2, operands + 2, operands + 4);")
2107 (define_insn "*swapdi_rex64"
2108 [(set (match_operand:DI 0 "register_operand" "+r")
2109 (match_operand:DI 1 "register_operand" "+r"))
2114 [(set_attr "type" "imov")
2115 (set_attr "mode" "DI")
2116 (set_attr "pent_pair" "np")
2117 (set_attr "athlon_decode" "vector")])
2119 (define_expand "movti"
2120 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2121 (match_operand:TI 1 "nonimmediate_operand" ""))]
2122 "TARGET_SSE || TARGET_64BIT"
2125 ix86_expand_move (TImode, operands);
2127 ix86_expand_vector_move (TImode, operands);
2131 (define_insn "*movti_internal"
2132 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2133 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2134 "TARGET_SSE && !TARGET_64BIT
2135 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2137 switch (which_alternative)
2140 if (get_attr_mode (insn) == MODE_V4SF)
2141 return "xorps\t%0, %0";
2143 return "pxor\t%0, %0";
2146 if (get_attr_mode (insn) == MODE_V4SF)
2147 return "movaps\t{%1, %0|%0, %1}";
2149 return "movdqa\t{%1, %0|%0, %1}";
2154 [(set_attr "type" "sselog1,ssemov,ssemov")
2156 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2157 (ne (symbol_ref "optimize_size") (const_int 0)))
2158 (const_string "V4SF")
2159 (and (eq_attr "alternative" "2")
2160 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2162 (const_string "V4SF")]
2163 (const_string "TI")))])
2165 (define_insn "*movti_rex64"
2166 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2167 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2169 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2171 switch (which_alternative)
2177 if (get_attr_mode (insn) == MODE_V4SF)
2178 return "xorps\t%0, %0";
2180 return "pxor\t%0, %0";
2183 if (get_attr_mode (insn) == MODE_V4SF)
2184 return "movaps\t{%1, %0|%0, %1}";
2186 return "movdqa\t{%1, %0|%0, %1}";
2191 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2193 (cond [(eq_attr "alternative" "2,3")
2195 (ne (symbol_ref "optimize_size")
2197 (const_string "V4SF")
2198 (const_string "TI"))
2199 (eq_attr "alternative" "4")
2201 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2203 (ne (symbol_ref "optimize_size")
2205 (const_string "V4SF")
2206 (const_string "TI"))]
2207 (const_string "DI")))])
2210 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2211 (match_operand:TI 1 "general_operand" ""))]
2212 "reload_completed && !SSE_REG_P (operands[0])
2213 && !SSE_REG_P (operands[1])"
2215 "ix86_split_long_move (operands); DONE;")
2217 (define_expand "movsf"
2218 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2219 (match_operand:SF 1 "general_operand" ""))]
2221 "ix86_expand_move (SFmode, operands); DONE;")
2223 (define_insn "*pushsf"
2224 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2225 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2228 /* Anything else should be already split before reg-stack. */
2229 gcc_assert (which_alternative == 1);
2230 return "push{l}\t%1";
2232 [(set_attr "type" "multi,push,multi")
2233 (set_attr "unit" "i387,*,*")
2234 (set_attr "mode" "SF,SI,SF")])
2236 (define_insn "*pushsf_rex64"
2237 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2238 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2241 /* Anything else should be already split before reg-stack. */
2242 gcc_assert (which_alternative == 1);
2243 return "push{q}\t%q1";
2245 [(set_attr "type" "multi,push,multi")
2246 (set_attr "unit" "i387,*,*")
2247 (set_attr "mode" "SF,DI,SF")])
2250 [(set (match_operand:SF 0 "push_operand" "")
2251 (match_operand:SF 1 "memory_operand" ""))]
2253 && GET_CODE (operands[1]) == MEM
2254 && constant_pool_reference_p (operands[1])"
2257 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2260 ;; %%% Kill this when call knows how to work this out.
2262 [(set (match_operand:SF 0 "push_operand" "")
2263 (match_operand:SF 1 "any_fp_register_operand" ""))]
2265 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2266 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2269 [(set (match_operand:SF 0 "push_operand" "")
2270 (match_operand:SF 1 "any_fp_register_operand" ""))]
2272 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2273 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2275 (define_insn "*movsf_1"
2276 [(set (match_operand:SF 0 "nonimmediate_operand"
2277 "=f,m ,f,r,m ,x,x,x,m ,!*y,!rm,!*y")
2278 (match_operand:SF 1 "general_operand"
2279 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2280 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2281 && (reload_in_progress || reload_completed
2282 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2283 || GET_CODE (operands[1]) != CONST_DOUBLE
2284 || memory_operand (operands[0], SFmode))"
2286 switch (which_alternative)
2289 return output_387_reg_move (insn, operands);
2292 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2293 return "fstp%z0\t%y0";
2295 return "fst%z0\t%y0";
2298 return standard_80387_constant_opcode (operands[1]);
2302 return "mov{l}\t{%1, %0|%0, %1}";
2304 if (get_attr_mode (insn) == MODE_TI)
2305 return "pxor\t%0, %0";
2307 return "xorps\t%0, %0";
2309 if (get_attr_mode (insn) == MODE_V4SF)
2310 return "movaps\t{%1, %0|%0, %1}";
2312 return "movss\t{%1, %0|%0, %1}";
2315 return "movss\t{%1, %0|%0, %1}";
2319 return "movd\t{%1, %0|%0, %1}";
2322 return "movq\t{%1, %0|%0, %1}";
2328 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2330 (cond [(eq_attr "alternative" "3,4,9,10")
2332 (eq_attr "alternative" "5")
2334 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2336 (ne (symbol_ref "TARGET_SSE2")
2338 (eq (symbol_ref "optimize_size")
2341 (const_string "V4SF"))
2342 /* For architectures resolving dependencies on
2343 whole SSE registers use APS move to break dependency
2344 chains, otherwise use short move to avoid extra work.
2346 Do the same for architectures resolving dependencies on
2347 the parts. While in DF mode it is better to always handle
2348 just register parts, the SF mode is different due to lack
2349 of instructions to load just part of the register. It is
2350 better to maintain the whole registers in single format
2351 to avoid problems on using packed logical operations. */
2352 (eq_attr "alternative" "6")
2354 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2356 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2358 (const_string "V4SF")
2359 (const_string "SF"))
2360 (eq_attr "alternative" "11")
2361 (const_string "DI")]
2362 (const_string "SF")))])
2364 (define_insn "*swapsf"
2365 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2366 (match_operand:SF 1 "fp_register_operand" "+f"))
2369 "reload_completed || TARGET_80387"
2371 if (STACK_TOP_P (operands[0]))
2376 [(set_attr "type" "fxch")
2377 (set_attr "mode" "SF")])
2379 (define_expand "movdf"
2380 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2381 (match_operand:DF 1 "general_operand" ""))]
2383 "ix86_expand_move (DFmode, operands); DONE;")
2385 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2386 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2387 ;; On the average, pushdf using integers can be still shorter. Allow this
2388 ;; pattern for optimize_size too.
2390 (define_insn "*pushdf_nointeger"
2391 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2392 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2393 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2395 /* This insn should be already split before reg-stack. */
2398 [(set_attr "type" "multi")
2399 (set_attr "unit" "i387,*,*,*")
2400 (set_attr "mode" "DF,SI,SI,DF")])
2402 (define_insn "*pushdf_integer"
2403 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2404 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2405 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2407 /* This insn should be already split before reg-stack. */
2410 [(set_attr "type" "multi")
2411 (set_attr "unit" "i387,*,*")
2412 (set_attr "mode" "DF,SI,DF")])
2414 ;; %%% Kill this when call knows how to work this out.
2416 [(set (match_operand:DF 0 "push_operand" "")
2417 (match_operand:DF 1 "any_fp_register_operand" ""))]
2418 "!TARGET_64BIT && reload_completed"
2419 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2420 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2424 [(set (match_operand:DF 0 "push_operand" "")
2425 (match_operand:DF 1 "any_fp_register_operand" ""))]
2426 "TARGET_64BIT && reload_completed"
2427 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2428 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2432 [(set (match_operand:DF 0 "push_operand" "")
2433 (match_operand:DF 1 "general_operand" ""))]
2436 "ix86_split_long_move (operands); DONE;")
2438 ;; Moving is usually shorter when only FP registers are used. This separate
2439 ;; movdf pattern avoids the use of integer registers for FP operations
2440 ;; when optimizing for size.
2442 (define_insn "*movdf_nointeger"
2443 [(set (match_operand:DF 0 "nonimmediate_operand"
2444 "=f,m ,f,*r ,o ,Y*x,Y*x,Y*x,m ")
2445 (match_operand:DF 1 "general_operand"
2446 "fm,f,G ,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2447 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2448 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2449 && (reload_in_progress || reload_completed
2450 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2451 || GET_CODE (operands[1]) != CONST_DOUBLE
2452 || memory_operand (operands[0], DFmode))"
2454 switch (which_alternative)
2457 return output_387_reg_move (insn, operands);
2460 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2461 return "fstp%z0\t%y0";
2463 return "fst%z0\t%y0";
2466 return standard_80387_constant_opcode (operands[1]);
2472 switch (get_attr_mode (insn))
2475 return "xorps\t%0, %0";
2477 return "xorpd\t%0, %0";
2479 return "pxor\t%0, %0";
2486 switch (get_attr_mode (insn))
2489 return "movaps\t{%1, %0|%0, %1}";
2491 return "movapd\t{%1, %0|%0, %1}";
2493 return "movdqa\t{%1, %0|%0, %1}";
2495 return "movq\t{%1, %0|%0, %1}";
2497 return "movsd\t{%1, %0|%0, %1}";
2499 return "movlpd\t{%1, %0|%0, %1}";
2501 return "movlps\t{%1, %0|%0, %1}";
2510 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2512 (cond [(eq_attr "alternative" "0,1,2")
2514 (eq_attr "alternative" "3,4")
2517 /* For SSE1, we have many fewer alternatives. */
2518 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2519 (cond [(eq_attr "alternative" "5,6")
2520 (const_string "V4SF")
2522 (const_string "V2SF"))
2524 /* xorps is one byte shorter. */
2525 (eq_attr "alternative" "5")
2526 (cond [(ne (symbol_ref "optimize_size")
2528 (const_string "V4SF")
2529 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2533 (const_string "V2DF"))
2535 /* For architectures resolving dependencies on
2536 whole SSE registers use APD move to break dependency
2537 chains, otherwise use short move to avoid extra work.
2539 movaps encodes one byte shorter. */
2540 (eq_attr "alternative" "6")
2542 [(ne (symbol_ref "optimize_size")
2544 (const_string "V4SF")
2545 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2547 (const_string "V2DF")
2549 (const_string "DF"))
2550 /* For architectures resolving dependencies on register
2551 parts we may avoid extra work to zero out upper part
2553 (eq_attr "alternative" "7")
2555 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2557 (const_string "V1DF")
2558 (const_string "DF"))
2560 (const_string "DF")))])
2562 (define_insn "*movdf_integer"
2563 [(set (match_operand:DF 0 "nonimmediate_operand"
2564 "=f,m ,f,r,o ,Y*x,Y*x,Y*x,m")
2565 (match_operand:DF 1 "general_operand"
2566 "fm,f,G ,roF,Fr,C ,Y*x,m ,Y*x"))]
2567 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2568 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2569 && (reload_in_progress || reload_completed
2570 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2571 || GET_CODE (operands[1]) != CONST_DOUBLE
2572 || memory_operand (operands[0], DFmode))"
2574 switch (which_alternative)
2577 return output_387_reg_move (insn, operands);
2580 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2581 return "fstp%z0\t%y0";
2583 return "fst%z0\t%y0";
2586 return standard_80387_constant_opcode (operands[1]);
2593 switch (get_attr_mode (insn))
2596 return "xorps\t%0, %0";
2598 return "xorpd\t%0, %0";
2600 return "pxor\t%0, %0";
2607 switch (get_attr_mode (insn))
2610 return "movaps\t{%1, %0|%0, %1}";
2612 return "movapd\t{%1, %0|%0, %1}";
2614 return "movdqa\t{%1, %0|%0, %1}";
2616 return "movq\t{%1, %0|%0, %1}";
2618 return "movsd\t{%1, %0|%0, %1}";
2620 return "movlpd\t{%1, %0|%0, %1}";
2622 return "movlps\t{%1, %0|%0, %1}";
2631 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2633 (cond [(eq_attr "alternative" "0,1,2")
2635 (eq_attr "alternative" "3,4")
2638 /* For SSE1, we have many fewer alternatives. */
2639 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2640 (cond [(eq_attr "alternative" "5,6")
2641 (const_string "V4SF")
2643 (const_string "V2SF"))
2645 /* xorps is one byte shorter. */
2646 (eq_attr "alternative" "5")
2647 (cond [(ne (symbol_ref "optimize_size")
2649 (const_string "V4SF")
2650 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2654 (const_string "V2DF"))
2656 /* For architectures resolving dependencies on
2657 whole SSE registers use APD move to break dependency
2658 chains, otherwise use short move to avoid extra work.
2660 movaps encodes one byte shorter. */
2661 (eq_attr "alternative" "6")
2663 [(ne (symbol_ref "optimize_size")
2665 (const_string "V4SF")
2666 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2668 (const_string "V2DF")
2670 (const_string "DF"))
2671 /* For architectures resolving dependencies on register
2672 parts we may avoid extra work to zero out upper part
2674 (eq_attr "alternative" "7")
2676 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2678 (const_string "V1DF")
2679 (const_string "DF"))
2681 (const_string "DF")))])
2684 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2685 (match_operand:DF 1 "general_operand" ""))]
2687 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2688 && ! (ANY_FP_REG_P (operands[0]) ||
2689 (GET_CODE (operands[0]) == SUBREG
2690 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2691 && ! (ANY_FP_REG_P (operands[1]) ||
2692 (GET_CODE (operands[1]) == SUBREG
2693 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2695 "ix86_split_long_move (operands); DONE;")
2697 (define_insn "*swapdf"
2698 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2699 (match_operand:DF 1 "fp_register_operand" "+f"))
2702 "reload_completed || TARGET_80387"
2704 if (STACK_TOP_P (operands[0]))
2709 [(set_attr "type" "fxch")
2710 (set_attr "mode" "DF")])
2712 (define_expand "movxf"
2713 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2714 (match_operand:XF 1 "general_operand" ""))]
2716 "ix86_expand_move (XFmode, operands); DONE;")
2718 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2719 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2720 ;; Pushing using integer instructions is longer except for constants
2721 ;; and direct memory references.
2722 ;; (assuming that any given constant is pushed only once, but this ought to be
2723 ;; handled elsewhere).
2725 (define_insn "*pushxf_nointeger"
2726 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2727 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2730 /* This insn should be already split before reg-stack. */
2733 [(set_attr "type" "multi")
2734 (set_attr "unit" "i387,*,*")
2735 (set_attr "mode" "XF,SI,SI")])
2737 (define_insn "*pushxf_integer"
2738 [(set (match_operand:XF 0 "push_operand" "=<,<")
2739 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2742 /* This insn should be already split before reg-stack. */
2745 [(set_attr "type" "multi")
2746 (set_attr "unit" "i387,*")
2747 (set_attr "mode" "XF,SI")])
2750 [(set (match_operand 0 "push_operand" "")
2751 (match_operand 1 "general_operand" ""))]
2753 && (GET_MODE (operands[0]) == XFmode
2754 || GET_MODE (operands[0]) == DFmode)
2755 && !ANY_FP_REG_P (operands[1])"
2757 "ix86_split_long_move (operands); DONE;")
2760 [(set (match_operand:XF 0 "push_operand" "")
2761 (match_operand:XF 1 "any_fp_register_operand" ""))]
2763 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2764 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2765 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2768 [(set (match_operand:XF 0 "push_operand" "")
2769 (match_operand:XF 1 "any_fp_register_operand" ""))]
2771 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2772 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2773 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2775 ;; Do not use integer registers when optimizing for size
2776 (define_insn "*movxf_nointeger"
2777 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2778 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2780 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2781 && (reload_in_progress || reload_completed
2782 || GET_CODE (operands[1]) != CONST_DOUBLE
2783 || memory_operand (operands[0], XFmode))"
2785 switch (which_alternative)
2788 return output_387_reg_move (insn, operands);
2791 /* There is no non-popping store to memory for XFmode. So if
2792 we need one, follow the store with a load. */
2793 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2794 return "fstp%z0\t%y0\;fld%z0\t%y0";
2796 return "fstp%z0\t%y0";
2799 return standard_80387_constant_opcode (operands[1]);
2807 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2808 (set_attr "mode" "XF,XF,XF,SI,SI")])
2810 (define_insn "*movxf_integer"
2811 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2812 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2814 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2815 && (reload_in_progress || reload_completed
2816 || GET_CODE (operands[1]) != CONST_DOUBLE
2817 || memory_operand (operands[0], XFmode))"
2819 switch (which_alternative)
2822 return output_387_reg_move (insn, operands);
2825 /* There is no non-popping store to memory for XFmode. So if
2826 we need one, follow the store with a load. */
2827 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2828 return "fstp%z0\t%y0\;fld%z0\t%y0";
2830 return "fstp%z0\t%y0";
2833 return standard_80387_constant_opcode (operands[1]);
2842 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2843 (set_attr "mode" "XF,XF,XF,SI,SI")])
2846 [(set (match_operand 0 "nonimmediate_operand" "")
2847 (match_operand 1 "general_operand" ""))]
2849 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2850 && GET_MODE (operands[0]) == XFmode
2851 && ! (ANY_FP_REG_P (operands[0]) ||
2852 (GET_CODE (operands[0]) == SUBREG
2853 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2854 && ! (ANY_FP_REG_P (operands[1]) ||
2855 (GET_CODE (operands[1]) == SUBREG
2856 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2858 "ix86_split_long_move (operands); DONE;")
2861 [(set (match_operand 0 "register_operand" "")
2862 (match_operand 1 "memory_operand" ""))]
2864 && GET_CODE (operands[1]) == MEM
2865 && (GET_MODE (operands[0]) == XFmode
2866 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2867 && constant_pool_reference_p (operands[1])"
2868 [(set (match_dup 0) (match_dup 1))]
2870 rtx c = avoid_constant_pool_reference (operands[1]);
2871 rtx r = operands[0];
2873 if (GET_CODE (r) == SUBREG)
2878 if (!standard_sse_constant_p (c))
2881 else if (FP_REG_P (r))
2883 if (!standard_80387_constant_p (c))
2886 else if (MMX_REG_P (r))
2892 (define_insn "swapxf"
2893 [(set (match_operand:XF 0 "register_operand" "+f")
2894 (match_operand:XF 1 "register_operand" "+f"))
2899 if (STACK_TOP_P (operands[0]))
2904 [(set_attr "type" "fxch")
2905 (set_attr "mode" "XF")])
2907 (define_expand "movtf"
2908 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2909 (match_operand:TF 1 "nonimmediate_operand" ""))]
2912 ix86_expand_move (TFmode, operands);
2916 (define_insn "*movtf_internal"
2917 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2918 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2920 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2922 switch (which_alternative)
2928 if (get_attr_mode (insn) == MODE_V4SF)
2929 return "xorps\t%0, %0";
2931 return "pxor\t%0, %0";
2934 if (get_attr_mode (insn) == MODE_V4SF)
2935 return "movaps\t{%1, %0|%0, %1}";
2937 return "movdqa\t{%1, %0|%0, %1}";
2942 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2944 (cond [(eq_attr "alternative" "2,3")
2946 (ne (symbol_ref "optimize_size")
2948 (const_string "V4SF")
2949 (const_string "TI"))
2950 (eq_attr "alternative" "4")
2952 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2954 (ne (symbol_ref "optimize_size")
2956 (const_string "V4SF")
2957 (const_string "TI"))]
2958 (const_string "DI")))])
2961 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2962 (match_operand:TF 1 "general_operand" ""))]
2963 "reload_completed && !SSE_REG_P (operands[0])
2964 && !SSE_REG_P (operands[1])"
2966 "ix86_split_long_move (operands); DONE;")
2968 ;; Zero extension instructions
2970 (define_expand "zero_extendhisi2"
2971 [(set (match_operand:SI 0 "register_operand" "")
2972 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2975 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2977 operands[1] = force_reg (HImode, operands[1]);
2978 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2983 (define_insn "zero_extendhisi2_and"
2984 [(set (match_operand:SI 0 "register_operand" "=r")
2985 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2986 (clobber (reg:CC FLAGS_REG))]
2987 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2989 [(set_attr "type" "alu1")
2990 (set_attr "mode" "SI")])
2993 [(set (match_operand:SI 0 "register_operand" "")
2994 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2995 (clobber (reg:CC FLAGS_REG))]
2996 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2998 (clobber (reg:CC FLAGS_REG))])]
3001 (define_insn "*zero_extendhisi2_movzwl"
3002 [(set (match_operand:SI 0 "register_operand" "=r")
3003 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3004 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3005 "movz{wl|x}\t{%1, %0|%0, %1}"
3006 [(set_attr "type" "imovx")
3007 (set_attr "mode" "SI")])
3009 (define_expand "zero_extendqihi2"
3011 [(set (match_operand:HI 0 "register_operand" "")
3012 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3013 (clobber (reg:CC FLAGS_REG))])]
3017 (define_insn "*zero_extendqihi2_and"
3018 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3019 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3020 (clobber (reg:CC FLAGS_REG))]
3021 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3023 [(set_attr "type" "alu1")
3024 (set_attr "mode" "HI")])
3026 (define_insn "*zero_extendqihi2_movzbw_and"
3027 [(set (match_operand:HI 0 "register_operand" "=r,r")
3028 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3029 (clobber (reg:CC FLAGS_REG))]
3030 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3032 [(set_attr "type" "imovx,alu1")
3033 (set_attr "mode" "HI")])
3035 ; zero extend to SImode here to avoid partial register stalls
3036 (define_insn "*zero_extendqihi2_movzbl"
3037 [(set (match_operand:HI 0 "register_operand" "=r")
3038 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3039 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3040 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3041 [(set_attr "type" "imovx")
3042 (set_attr "mode" "SI")])
3044 ;; For the movzbw case strip only the clobber
3046 [(set (match_operand:HI 0 "register_operand" "")
3047 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3048 (clobber (reg:CC FLAGS_REG))]
3050 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3051 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3052 [(set (match_operand:HI 0 "register_operand" "")
3053 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3055 ;; When source and destination does not overlap, clear destination
3056 ;; first and then do the movb
3058 [(set (match_operand:HI 0 "register_operand" "")
3059 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3060 (clobber (reg:CC FLAGS_REG))]
3062 && ANY_QI_REG_P (operands[0])
3063 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3064 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3065 [(set (match_dup 0) (const_int 0))
3066 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3067 "operands[2] = gen_lowpart (QImode, operands[0]);")
3069 ;; Rest is handled by single and.
3071 [(set (match_operand:HI 0 "register_operand" "")
3072 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3073 (clobber (reg:CC FLAGS_REG))]
3075 && true_regnum (operands[0]) == true_regnum (operands[1])"
3076 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3077 (clobber (reg:CC FLAGS_REG))])]
3080 (define_expand "zero_extendqisi2"
3082 [(set (match_operand:SI 0 "register_operand" "")
3083 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3084 (clobber (reg:CC FLAGS_REG))])]
3088 (define_insn "*zero_extendqisi2_and"
3089 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3090 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3091 (clobber (reg:CC FLAGS_REG))]
3092 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3094 [(set_attr "type" "alu1")
3095 (set_attr "mode" "SI")])
3097 (define_insn "*zero_extendqisi2_movzbw_and"
3098 [(set (match_operand:SI 0 "register_operand" "=r,r")
3099 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3100 (clobber (reg:CC FLAGS_REG))]
3101 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3103 [(set_attr "type" "imovx,alu1")
3104 (set_attr "mode" "SI")])
3106 (define_insn "*zero_extendqisi2_movzbw"
3107 [(set (match_operand:SI 0 "register_operand" "=r")
3108 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3109 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3110 "movz{bl|x}\t{%1, %0|%0, %1}"
3111 [(set_attr "type" "imovx")
3112 (set_attr "mode" "SI")])
3114 ;; For the movzbl case strip only the clobber
3116 [(set (match_operand:SI 0 "register_operand" "")
3117 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3118 (clobber (reg:CC FLAGS_REG))]
3120 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3121 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3123 (zero_extend:SI (match_dup 1)))])
3125 ;; When source and destination does not overlap, clear destination
3126 ;; first and then do the movb
3128 [(set (match_operand:SI 0 "register_operand" "")
3129 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3130 (clobber (reg:CC FLAGS_REG))]
3132 && ANY_QI_REG_P (operands[0])
3133 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3134 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3135 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3136 [(set (match_dup 0) (const_int 0))
3137 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3138 "operands[2] = gen_lowpart (QImode, operands[0]);")
3140 ;; Rest is handled by single and.
3142 [(set (match_operand:SI 0 "register_operand" "")
3143 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3144 (clobber (reg:CC FLAGS_REG))]
3146 && true_regnum (operands[0]) == true_regnum (operands[1])"
3147 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3148 (clobber (reg:CC FLAGS_REG))])]
3151 ;; %%% Kill me once multi-word ops are sane.
3152 (define_expand "zero_extendsidi2"
3153 [(set (match_operand:DI 0 "register_operand" "=r")
3154 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3158 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3163 (define_insn "zero_extendsidi2_32"
3164 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3165 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3166 (clobber (reg:CC FLAGS_REG))]
3172 movd\t{%1, %0|%0, %1}
3173 movd\t{%1, %0|%0, %1}"
3174 [(set_attr "mode" "SI,SI,SI,DI,TI")
3175 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3177 (define_insn "zero_extendsidi2_rex64"
3178 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3179 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3182 mov\t{%k1, %k0|%k0, %k1}
3184 movd\t{%1, %0|%0, %1}
3185 movd\t{%1, %0|%0, %1}"
3186 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3187 (set_attr "mode" "SI,DI,SI,SI")])
3190 [(set (match_operand:DI 0 "memory_operand" "")
3191 (zero_extend:DI (match_dup 0)))]
3193 [(set (match_dup 4) (const_int 0))]
3194 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3197 [(set (match_operand:DI 0 "register_operand" "")
3198 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3199 (clobber (reg:CC FLAGS_REG))]
3200 "!TARGET_64BIT && reload_completed
3201 && true_regnum (operands[0]) == true_regnum (operands[1])"
3202 [(set (match_dup 4) (const_int 0))]
3203 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3206 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3207 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3208 (clobber (reg:CC FLAGS_REG))]
3209 "!TARGET_64BIT && reload_completed
3210 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3211 [(set (match_dup 3) (match_dup 1))
3212 (set (match_dup 4) (const_int 0))]
3213 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3215 (define_insn "zero_extendhidi2"
3216 [(set (match_operand:DI 0 "register_operand" "=r")
3217 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3219 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3220 [(set_attr "type" "imovx")
3221 (set_attr "mode" "DI")])
3223 (define_insn "zero_extendqidi2"
3224 [(set (match_operand:DI 0 "register_operand" "=r")
3225 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3227 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3228 [(set_attr "type" "imovx")
3229 (set_attr "mode" "DI")])
3231 ;; Sign extension instructions
3233 (define_expand "extendsidi2"
3234 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3235 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3236 (clobber (reg:CC FLAGS_REG))
3237 (clobber (match_scratch:SI 2 ""))])]
3242 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3247 (define_insn "*extendsidi2_1"
3248 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3249 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3250 (clobber (reg:CC FLAGS_REG))
3251 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3255 (define_insn "extendsidi2_rex64"
3256 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3257 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3261 movs{lq|x}\t{%1,%0|%0, %1}"
3262 [(set_attr "type" "imovx")
3263 (set_attr "mode" "DI")
3264 (set_attr "prefix_0f" "0")
3265 (set_attr "modrm" "0,1")])
3267 (define_insn "extendhidi2"
3268 [(set (match_operand:DI 0 "register_operand" "=r")
3269 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3271 "movs{wq|x}\t{%1,%0|%0, %1}"
3272 [(set_attr "type" "imovx")
3273 (set_attr "mode" "DI")])
3275 (define_insn "extendqidi2"
3276 [(set (match_operand:DI 0 "register_operand" "=r")
3277 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3279 "movs{bq|x}\t{%1,%0|%0, %1}"
3280 [(set_attr "type" "imovx")
3281 (set_attr "mode" "DI")])
3283 ;; Extend to memory case when source register does die.
3285 [(set (match_operand:DI 0 "memory_operand" "")
3286 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3287 (clobber (reg:CC FLAGS_REG))
3288 (clobber (match_operand:SI 2 "register_operand" ""))]
3290 && dead_or_set_p (insn, operands[1])
3291 && !reg_mentioned_p (operands[1], operands[0]))"
3292 [(set (match_dup 3) (match_dup 1))
3293 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3294 (clobber (reg:CC FLAGS_REG))])
3295 (set (match_dup 4) (match_dup 1))]
3296 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3298 ;; Extend to memory case when source register does not die.
3300 [(set (match_operand:DI 0 "memory_operand" "")
3301 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3302 (clobber (reg:CC FLAGS_REG))
3303 (clobber (match_operand:SI 2 "register_operand" ""))]
3307 split_di (&operands[0], 1, &operands[3], &operands[4]);
3309 emit_move_insn (operands[3], operands[1]);
3311 /* Generate a cltd if possible and doing so it profitable. */
3312 if (true_regnum (operands[1]) == 0
3313 && true_regnum (operands[2]) == 1
3314 && (optimize_size || TARGET_USE_CLTD))
3316 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3320 emit_move_insn (operands[2], operands[1]);
3321 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3323 emit_move_insn (operands[4], operands[2]);
3327 ;; Extend to register case. Optimize case where source and destination
3328 ;; registers match and cases where we can use cltd.
3330 [(set (match_operand:DI 0 "register_operand" "")
3331 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3332 (clobber (reg:CC FLAGS_REG))
3333 (clobber (match_scratch:SI 2 ""))]
3337 split_di (&operands[0], 1, &operands[3], &operands[4]);
3339 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3340 emit_move_insn (operands[3], operands[1]);
3342 /* Generate a cltd if possible and doing so it profitable. */
3343 if (true_regnum (operands[3]) == 0
3344 && (optimize_size || TARGET_USE_CLTD))
3346 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3350 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3351 emit_move_insn (operands[4], operands[1]);
3353 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3357 (define_insn "extendhisi2"
3358 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3359 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3362 switch (get_attr_prefix_0f (insn))
3365 return "{cwtl|cwde}";
3367 return "movs{wl|x}\t{%1,%0|%0, %1}";
3370 [(set_attr "type" "imovx")
3371 (set_attr "mode" "SI")
3372 (set (attr "prefix_0f")
3373 ;; movsx is short decodable while cwtl is vector decoded.
3374 (if_then_else (and (eq_attr "cpu" "!k6")
3375 (eq_attr "alternative" "0"))
3377 (const_string "1")))
3379 (if_then_else (eq_attr "prefix_0f" "0")
3381 (const_string "1")))])
3383 (define_insn "*extendhisi2_zext"
3384 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3386 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3389 switch (get_attr_prefix_0f (insn))
3392 return "{cwtl|cwde}";
3394 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3397 [(set_attr "type" "imovx")
3398 (set_attr "mode" "SI")
3399 (set (attr "prefix_0f")
3400 ;; movsx is short decodable while cwtl is vector decoded.
3401 (if_then_else (and (eq_attr "cpu" "!k6")
3402 (eq_attr "alternative" "0"))
3404 (const_string "1")))
3406 (if_then_else (eq_attr "prefix_0f" "0")
3408 (const_string "1")))])
3410 (define_insn "extendqihi2"
3411 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3412 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3415 switch (get_attr_prefix_0f (insn))
3418 return "{cbtw|cbw}";
3420 return "movs{bw|x}\t{%1,%0|%0, %1}";
3423 [(set_attr "type" "imovx")
3424 (set_attr "mode" "HI")
3425 (set (attr "prefix_0f")
3426 ;; movsx is short decodable while cwtl is vector decoded.
3427 (if_then_else (and (eq_attr "cpu" "!k6")
3428 (eq_attr "alternative" "0"))
3430 (const_string "1")))
3432 (if_then_else (eq_attr "prefix_0f" "0")
3434 (const_string "1")))])
3436 (define_insn "extendqisi2"
3437 [(set (match_operand:SI 0 "register_operand" "=r")
3438 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3440 "movs{bl|x}\t{%1,%0|%0, %1}"
3441 [(set_attr "type" "imovx")
3442 (set_attr "mode" "SI")])
3444 (define_insn "*extendqisi2_zext"
3445 [(set (match_operand:DI 0 "register_operand" "=r")
3447 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3449 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3450 [(set_attr "type" "imovx")
3451 (set_attr "mode" "SI")])
3453 ;; Conversions between float and double.
3455 ;; These are all no-ops in the model used for the 80387. So just
3458 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3459 (define_insn "*dummy_extendsfdf2"
3460 [(set (match_operand:DF 0 "push_operand" "=<")
3461 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3466 [(set (match_operand:DF 0 "push_operand" "")
3467 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3469 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3470 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3473 [(set (match_operand:DF 0 "push_operand" "")
3474 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3476 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3477 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3479 (define_insn "*dummy_extendsfxf2"
3480 [(set (match_operand:XF 0 "push_operand" "=<")
3481 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3486 [(set (match_operand:XF 0 "push_operand" "")
3487 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3489 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3490 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3491 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3494 [(set (match_operand:XF 0 "push_operand" "")
3495 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3497 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3498 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3499 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3502 [(set (match_operand:XF 0 "push_operand" "")
3503 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3505 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3506 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3507 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3510 [(set (match_operand:XF 0 "push_operand" "")
3511 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3513 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3514 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3515 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3517 (define_expand "extendsfdf2"
3518 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3519 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3520 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3522 /* ??? Needed for compress_float_constant since all fp constants
3523 are LEGITIMATE_CONSTANT_P. */
3524 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3526 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3527 && standard_80387_constant_p (operands[1]) > 0)
3529 operands[1] = simplify_const_unary_operation
3530 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3531 emit_move_insn_1 (operands[0], operands[1]);
3534 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3536 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3537 operands[1] = force_reg (SFmode, operands[1]);
3540 (define_insn "*extendsfdf2_mixed"
3541 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3542 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3543 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3544 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3546 switch (which_alternative)
3549 return output_387_reg_move (insn, operands);
3552 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3553 return "fstp%z0\t%y0";
3555 return "fst%z0\t%y0";
3558 return "cvtss2sd\t{%1, %0|%0, %1}";
3564 [(set_attr "type" "fmov,fmov,ssecvt")
3565 (set_attr "mode" "SF,XF,DF")])
3567 (define_insn "*extendsfdf2_sse"
3568 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3569 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3570 "TARGET_SSE2 && TARGET_SSE_MATH
3571 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3572 "cvtss2sd\t{%1, %0|%0, %1}"
3573 [(set_attr "type" "ssecvt")
3574 (set_attr "mode" "DF")])
3576 (define_insn "*extendsfdf2_i387"
3577 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3578 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3580 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3582 switch (which_alternative)
3585 return output_387_reg_move (insn, operands);
3588 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3589 return "fstp%z0\t%y0";
3591 return "fst%z0\t%y0";
3597 [(set_attr "type" "fmov")
3598 (set_attr "mode" "SF,XF")])
3600 (define_expand "extendsfxf2"
3601 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3602 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3605 /* ??? Needed for compress_float_constant since all fp constants
3606 are LEGITIMATE_CONSTANT_P. */
3607 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3609 if (standard_80387_constant_p (operands[1]) > 0)
3611 operands[1] = simplify_const_unary_operation
3612 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3613 emit_move_insn_1 (operands[0], operands[1]);
3616 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3618 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3619 operands[1] = force_reg (SFmode, operands[1]);
3622 (define_insn "*extendsfxf2_i387"
3623 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3624 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3626 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3628 switch (which_alternative)
3631 return output_387_reg_move (insn, operands);
3634 /* There is no non-popping store to memory for XFmode. So if
3635 we need one, follow the store with a load. */
3636 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3637 return "fstp%z0\t%y0";
3639 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3645 [(set_attr "type" "fmov")
3646 (set_attr "mode" "SF,XF")])
3648 (define_expand "extenddfxf2"
3649 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3650 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3653 /* ??? Needed for compress_float_constant since all fp constants
3654 are LEGITIMATE_CONSTANT_P. */
3655 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3657 if (standard_80387_constant_p (operands[1]) > 0)
3659 operands[1] = simplify_const_unary_operation
3660 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3661 emit_move_insn_1 (operands[0], operands[1]);
3664 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3666 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3667 operands[1] = force_reg (DFmode, operands[1]);
3670 (define_insn "*extenddfxf2_i387"
3671 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3672 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3674 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3676 switch (which_alternative)
3679 return output_387_reg_move (insn, operands);
3682 /* There is no non-popping store to memory for XFmode. So if
3683 we need one, follow the store with a load. */
3684 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3685 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3687 return "fstp%z0\t%y0";
3693 [(set_attr "type" "fmov")
3694 (set_attr "mode" "DF,XF")])
3696 ;; %%% This seems bad bad news.
3697 ;; This cannot output into an f-reg because there is no way to be sure
3698 ;; of truncating in that case. Otherwise this is just like a simple move
3699 ;; insn. So we pretend we can output to a reg in order to get better
3700 ;; register preferencing, but we really use a stack slot.
3702 ;; Conversion from DFmode to SFmode.
3704 (define_expand "truncdfsf2"
3705 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3707 (match_operand:DF 1 "nonimmediate_operand" "")))]
3708 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3710 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3711 operands[1] = force_reg (DFmode, operands[1]);
3713 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3715 else if (flag_unsafe_math_optimizations)
3719 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3720 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3725 (define_expand "truncdfsf2_with_temp"
3726 [(parallel [(set (match_operand:SF 0 "" "")
3727 (float_truncate:SF (match_operand:DF 1 "" "")))
3728 (clobber (match_operand:SF 2 "" ""))])]
3731 (define_insn "*truncdfsf_fast_mixed"
3732 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3734 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3735 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3737 switch (which_alternative)
3740 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3741 return "fstp%z0\t%y0";
3743 return "fst%z0\t%y0";
3745 return output_387_reg_move (insn, operands);
3747 return "cvtsd2ss\t{%1, %0|%0, %1}";
3752 [(set_attr "type" "fmov,fmov,ssecvt")
3753 (set_attr "mode" "SF")])
3755 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3756 ;; because nothing we do here is unsafe.
3757 (define_insn "*truncdfsf_fast_sse"
3758 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3760 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3761 "TARGET_SSE2 && TARGET_SSE_MATH"
3762 "cvtsd2ss\t{%1, %0|%0, %1}"
3763 [(set_attr "type" "ssecvt")
3764 (set_attr "mode" "SF")])
3766 (define_insn "*truncdfsf_fast_i387"
3767 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3769 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3770 "TARGET_80387 && flag_unsafe_math_optimizations"
3771 "* return output_387_reg_move (insn, operands);"
3772 [(set_attr "type" "fmov")
3773 (set_attr "mode" "SF")])
3775 (define_insn "*truncdfsf_mixed"
3776 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3778 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3779 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3780 "TARGET_MIX_SSE_I387"
3782 switch (which_alternative)
3785 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3786 return "fstp%z0\t%y0";
3788 return "fst%z0\t%y0";
3792 return "cvtsd2ss\t{%1, %0|%0, %1}";
3797 [(set_attr "type" "fmov,multi,ssecvt")
3798 (set_attr "unit" "*,i387,*")
3799 (set_attr "mode" "SF")])
3801 (define_insn "*truncdfsf_i387"
3802 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3804 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3805 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3808 switch (which_alternative)
3811 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3812 return "fstp%z0\t%y0";
3814 return "fst%z0\t%y0";
3821 [(set_attr "type" "fmov,multi")
3822 (set_attr "unit" "*,i387")
3823 (set_attr "mode" "SF")])
3825 (define_insn "*truncdfsf2_i387_1"
3826 [(set (match_operand:SF 0 "memory_operand" "=m")
3828 (match_operand:DF 1 "register_operand" "f")))]
3830 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3831 && !TARGET_MIX_SSE_I387"
3833 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3834 return "fstp%z0\t%y0";
3836 return "fst%z0\t%y0";
3838 [(set_attr "type" "fmov")
3839 (set_attr "mode" "SF")])
3842 [(set (match_operand:SF 0 "register_operand" "")
3844 (match_operand:DF 1 "fp_register_operand" "")))
3845 (clobber (match_operand 2 "" ""))]
3847 [(set (match_dup 2) (match_dup 1))
3848 (set (match_dup 0) (match_dup 2))]
3850 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3853 ;; Conversion from XFmode to SFmode.
3855 (define_expand "truncxfsf2"
3856 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3858 (match_operand:XF 1 "register_operand" "")))
3859 (clobber (match_dup 2))])]
3862 if (flag_unsafe_math_optimizations)
3864 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3865 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3866 if (reg != operands[0])
3867 emit_move_insn (operands[0], reg);
3871 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3874 (define_insn "*truncxfsf2_mixed"
3875 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3877 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3878 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3879 "TARGET_MIX_SSE_I387"
3881 gcc_assert (!which_alternative);
3882 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3883 return "fstp%z0\t%y0";
3885 return "fst%z0\t%y0";
3887 [(set_attr "type" "fmov,multi,multi,multi")
3888 (set_attr "unit" "*,i387,i387,i387")
3889 (set_attr "mode" "SF")])
3891 (define_insn "truncxfsf2_i387_noop"
3892 [(set (match_operand:SF 0 "register_operand" "=f")
3893 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3894 "TARGET_80387 && flag_unsafe_math_optimizations"
3896 return output_387_reg_move (insn, operands);
3898 [(set_attr "type" "fmov")
3899 (set_attr "mode" "SF")])
3901 (define_insn "*truncxfsf2_i387"
3902 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3904 (match_operand:XF 1 "register_operand" "f,f,f")))
3905 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3908 gcc_assert (!which_alternative);
3909 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3910 return "fstp%z0\t%y0";
3912 return "fst%z0\t%y0";
3914 [(set_attr "type" "fmov,multi,multi")
3915 (set_attr "unit" "*,i387,i387")
3916 (set_attr "mode" "SF")])
3918 (define_insn "*truncxfsf2_i387_1"
3919 [(set (match_operand:SF 0 "memory_operand" "=m")
3921 (match_operand:XF 1 "register_operand" "f")))]
3924 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3925 return "fstp%z0\t%y0";
3927 return "fst%z0\t%y0";
3929 [(set_attr "type" "fmov")
3930 (set_attr "mode" "SF")])
3933 [(set (match_operand:SF 0 "register_operand" "")
3935 (match_operand:XF 1 "register_operand" "")))
3936 (clobber (match_operand:SF 2 "memory_operand" ""))]
3937 "TARGET_80387 && reload_completed"
3938 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3939 (set (match_dup 0) (match_dup 2))]
3943 [(set (match_operand:SF 0 "memory_operand" "")
3945 (match_operand:XF 1 "register_operand" "")))
3946 (clobber (match_operand:SF 2 "memory_operand" ""))]
3948 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3951 ;; Conversion from XFmode to DFmode.
3953 (define_expand "truncxfdf2"
3954 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3956 (match_operand:XF 1 "register_operand" "")))
3957 (clobber (match_dup 2))])]
3960 if (flag_unsafe_math_optimizations)
3962 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3963 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3964 if (reg != operands[0])
3965 emit_move_insn (operands[0], reg);
3969 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3972 (define_insn "*truncxfdf2_mixed"
3973 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3975 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3976 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3977 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3979 gcc_assert (!which_alternative);
3980 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3981 return "fstp%z0\t%y0";
3983 return "fst%z0\t%y0";
3985 [(set_attr "type" "fmov,multi,multi,multi")
3986 (set_attr "unit" "*,i387,i387,i387")
3987 (set_attr "mode" "DF")])
3989 (define_insn "truncxfdf2_i387_noop"
3990 [(set (match_operand:DF 0 "register_operand" "=f")
3991 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3992 "TARGET_80387 && flag_unsafe_math_optimizations"
3994 return output_387_reg_move (insn, operands);
3996 [(set_attr "type" "fmov")
3997 (set_attr "mode" "DF")])
3999 (define_insn "*truncxfdf2_i387"
4000 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4002 (match_operand:XF 1 "register_operand" "f,f,f")))
4003 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4006 gcc_assert (!which_alternative);
4007 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4008 return "fstp%z0\t%y0";
4010 return "fst%z0\t%y0";
4012 [(set_attr "type" "fmov,multi,multi")
4013 (set_attr "unit" "*,i387,i387")
4014 (set_attr "mode" "DF")])
4016 (define_insn "*truncxfdf2_i387_1"
4017 [(set (match_operand:DF 0 "memory_operand" "=m")
4019 (match_operand:XF 1 "register_operand" "f")))]
4022 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4023 return "fstp%z0\t%y0";
4025 return "fst%z0\t%y0";
4027 [(set_attr "type" "fmov")
4028 (set_attr "mode" "DF")])
4031 [(set (match_operand:DF 0 "register_operand" "")
4033 (match_operand:XF 1 "register_operand" "")))
4034 (clobber (match_operand:DF 2 "memory_operand" ""))]
4035 "TARGET_80387 && reload_completed"
4036 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4037 (set (match_dup 0) (match_dup 2))]
4041 [(set (match_operand:DF 0 "memory_operand" "")
4043 (match_operand:XF 1 "register_operand" "")))
4044 (clobber (match_operand:DF 2 "memory_operand" ""))]
4046 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4049 ;; Signed conversion to DImode.
4051 (define_expand "fix_truncxfdi2"
4052 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4053 (fix:DI (match_operand:XF 1 "register_operand" "")))
4054 (clobber (reg:CC FLAGS_REG))])]
4059 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4064 (define_expand "fix_trunc<mode>di2"
4065 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4066 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4067 (clobber (reg:CC FLAGS_REG))])]
4068 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4071 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4073 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4076 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4078 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4079 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4080 if (out != operands[0])
4081 emit_move_insn (operands[0], out);
4086 ;; Signed conversion to SImode.
4088 (define_expand "fix_truncxfsi2"
4089 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4090 (fix:SI (match_operand:XF 1 "register_operand" "")))
4091 (clobber (reg:CC FLAGS_REG))])]
4096 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4101 (define_expand "fix_trunc<mode>si2"
4102 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4103 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4104 (clobber (reg:CC FLAGS_REG))])]
4105 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4108 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4110 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4113 if (SSE_FLOAT_MODE_P (<MODE>mode))
4115 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4116 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4117 if (out != operands[0])
4118 emit_move_insn (operands[0], out);
4123 ;; Signed conversion to HImode.
4125 (define_expand "fix_trunc<mode>hi2"
4126 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4127 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4128 (clobber (reg:CC FLAGS_REG))])]
4130 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4134 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4139 ;; When SSE is available, it is always faster to use it!
4140 (define_insn "fix_truncsfdi_sse"
4141 [(set (match_operand:DI 0 "register_operand" "=r,r")
4142 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4143 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4144 "cvttss2si{q}\t{%1, %0|%0, %1}"
4145 [(set_attr "type" "sseicvt")
4146 (set_attr "mode" "SF")
4147 (set_attr "athlon_decode" "double,vector")])
4149 (define_insn "fix_truncdfdi_sse"
4150 [(set (match_operand:DI 0 "register_operand" "=r,r")
4151 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4152 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4153 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4154 [(set_attr "type" "sseicvt")
4155 (set_attr "mode" "DF")
4156 (set_attr "athlon_decode" "double,vector")])
4158 (define_insn "fix_truncsfsi_sse"
4159 [(set (match_operand:SI 0 "register_operand" "=r,r")
4160 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4161 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4162 "cvttss2si\t{%1, %0|%0, %1}"
4163 [(set_attr "type" "sseicvt")
4164 (set_attr "mode" "DF")
4165 (set_attr "athlon_decode" "double,vector")])
4167 (define_insn "fix_truncdfsi_sse"
4168 [(set (match_operand:SI 0 "register_operand" "=r,r")
4169 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4170 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4171 "cvttsd2si\t{%1, %0|%0, %1}"
4172 [(set_attr "type" "sseicvt")
4173 (set_attr "mode" "DF")
4174 (set_attr "athlon_decode" "double,vector")])
4176 ;; Avoid vector decoded forms of the instruction.
4178 [(match_scratch:DF 2 "Y")
4179 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4180 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4181 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4182 [(set (match_dup 2) (match_dup 1))
4183 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4187 [(match_scratch:SF 2 "x")
4188 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4189 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4190 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4191 [(set (match_dup 2) (match_dup 1))
4192 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4195 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4196 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4197 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4199 && FLOAT_MODE_P (GET_MODE (operands[1]))
4200 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4201 && (TARGET_64BIT || <MODE>mode != DImode))
4203 && !(reload_completed || reload_in_progress)"
4208 if (memory_operand (operands[0], VOIDmode))
4209 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4212 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4213 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4219 [(set_attr "type" "fisttp")
4220 (set_attr "mode" "<MODE>")])
4222 (define_insn "fix_trunc<mode>_i387_fisttp"
4223 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4224 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4225 (clobber (match_scratch:XF 2 "=&1f"))]
4227 && FLOAT_MODE_P (GET_MODE (operands[1]))
4228 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4229 && (TARGET_64BIT || <MODE>mode != DImode))
4230 && TARGET_SSE_MATH)"
4231 "* return output_fix_trunc (insn, operands, 1);"
4232 [(set_attr "type" "fisttp")
4233 (set_attr "mode" "<MODE>")])
4235 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4236 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4237 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4238 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4239 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4241 && FLOAT_MODE_P (GET_MODE (operands[1]))
4242 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4243 && (TARGET_64BIT || <MODE>mode != DImode))
4244 && TARGET_SSE_MATH)"
4246 [(set_attr "type" "fisttp")
4247 (set_attr "mode" "<MODE>")])
4250 [(set (match_operand:X87MODEI 0 "register_operand" "")
4251 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4252 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4253 (clobber (match_scratch 3 ""))]
4255 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4256 (clobber (match_dup 3))])
4257 (set (match_dup 0) (match_dup 2))]
4261 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4262 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4263 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4264 (clobber (match_scratch 3 ""))]
4266 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4267 (clobber (match_dup 3))])]
4270 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4271 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4272 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4273 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4274 ;; function in i386.c.
4275 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4276 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4277 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4278 (clobber (reg:CC FLAGS_REG))]
4279 "TARGET_80387 && !TARGET_FISTTP
4280 && FLOAT_MODE_P (GET_MODE (operands[1]))
4281 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4282 && (TARGET_64BIT || <MODE>mode != DImode))
4283 && !(reload_completed || reload_in_progress)"
4288 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4290 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4291 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4292 if (memory_operand (operands[0], VOIDmode))
4293 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4294 operands[2], operands[3]));
4297 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4298 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4299 operands[2], operands[3],
4304 [(set_attr "type" "fistp")
4305 (set_attr "i387_cw" "trunc")
4306 (set_attr "mode" "<MODE>")])
4308 (define_insn "fix_truncdi_i387"
4309 [(set (match_operand:DI 0 "memory_operand" "=m")
4310 (fix:DI (match_operand 1 "register_operand" "f")))
4311 (use (match_operand:HI 2 "memory_operand" "m"))
4312 (use (match_operand:HI 3 "memory_operand" "m"))
4313 (clobber (match_scratch:XF 4 "=&1f"))]
4314 "TARGET_80387 && !TARGET_FISTTP
4315 && FLOAT_MODE_P (GET_MODE (operands[1]))
4316 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4317 "* return output_fix_trunc (insn, operands, 0);"
4318 [(set_attr "type" "fistp")
4319 (set_attr "i387_cw" "trunc")
4320 (set_attr "mode" "DI")])
4322 (define_insn "fix_truncdi_i387_with_temp"
4323 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4324 (fix:DI (match_operand 1 "register_operand" "f,f")))
4325 (use (match_operand:HI 2 "memory_operand" "m,m"))
4326 (use (match_operand:HI 3 "memory_operand" "m,m"))
4327 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4328 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4329 "TARGET_80387 && !TARGET_FISTTP
4330 && FLOAT_MODE_P (GET_MODE (operands[1]))
4331 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4333 [(set_attr "type" "fistp")
4334 (set_attr "i387_cw" "trunc")
4335 (set_attr "mode" "DI")])
4338 [(set (match_operand:DI 0 "register_operand" "")
4339 (fix:DI (match_operand 1 "register_operand" "")))
4340 (use (match_operand:HI 2 "memory_operand" ""))
4341 (use (match_operand:HI 3 "memory_operand" ""))
4342 (clobber (match_operand:DI 4 "memory_operand" ""))
4343 (clobber (match_scratch 5 ""))]
4345 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4348 (clobber (match_dup 5))])
4349 (set (match_dup 0) (match_dup 4))]
4353 [(set (match_operand:DI 0 "memory_operand" "")
4354 (fix:DI (match_operand 1 "register_operand" "")))
4355 (use (match_operand:HI 2 "memory_operand" ""))
4356 (use (match_operand:HI 3 "memory_operand" ""))
4357 (clobber (match_operand:DI 4 "memory_operand" ""))
4358 (clobber (match_scratch 5 ""))]
4360 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4363 (clobber (match_dup 5))])]
4366 (define_insn "fix_trunc<mode>_i387"
4367 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4368 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4369 (use (match_operand:HI 2 "memory_operand" "m"))
4370 (use (match_operand:HI 3 "memory_operand" "m"))]
4371 "TARGET_80387 && !TARGET_FISTTP
4372 && FLOAT_MODE_P (GET_MODE (operands[1]))
4373 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4374 "* return output_fix_trunc (insn, operands, 0);"
4375 [(set_attr "type" "fistp")
4376 (set_attr "i387_cw" "trunc")
4377 (set_attr "mode" "<MODE>")])
4379 (define_insn "fix_trunc<mode>_i387_with_temp"
4380 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4381 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4382 (use (match_operand:HI 2 "memory_operand" "m,m"))
4383 (use (match_operand:HI 3 "memory_operand" "m,m"))
4384 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4385 "TARGET_80387 && !TARGET_FISTTP
4386 && FLOAT_MODE_P (GET_MODE (operands[1]))
4387 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4389 [(set_attr "type" "fistp")
4390 (set_attr "i387_cw" "trunc")
4391 (set_attr "mode" "<MODE>")])
4394 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4395 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4396 (use (match_operand:HI 2 "memory_operand" ""))
4397 (use (match_operand:HI 3 "memory_operand" ""))
4398 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4400 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4402 (use (match_dup 3))])
4403 (set (match_dup 0) (match_dup 4))]
4407 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4408 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4409 (use (match_operand:HI 2 "memory_operand" ""))
4410 (use (match_operand:HI 3 "memory_operand" ""))
4411 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4413 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4415 (use (match_dup 3))])]
4418 (define_insn "x86_fnstcw_1"
4419 [(set (match_operand:HI 0 "memory_operand" "=m")
4420 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4423 [(set_attr "length" "2")
4424 (set_attr "mode" "HI")
4425 (set_attr "unit" "i387")])
4427 (define_insn "x86_fldcw_1"
4428 [(set (reg:HI FPSR_REG)
4429 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4432 [(set_attr "length" "2")
4433 (set_attr "mode" "HI")
4434 (set_attr "unit" "i387")
4435 (set_attr "athlon_decode" "vector")])
4437 ;; Conversion between fixed point and floating point.
4439 ;; Even though we only accept memory inputs, the backend _really_
4440 ;; wants to be able to do this between registers.
4442 (define_expand "floathisf2"
4443 [(set (match_operand:SF 0 "register_operand" "")
4444 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4445 "TARGET_80387 || TARGET_SSE_MATH"
4447 if (TARGET_SSE_MATH)
4449 emit_insn (gen_floatsisf2 (operands[0],
4450 convert_to_mode (SImode, operands[1], 0)));
4455 (define_insn "*floathisf2_i387"
4456 [(set (match_operand:SF 0 "register_operand" "=f,f")
4457 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4458 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4462 [(set_attr "type" "fmov,multi")
4463 (set_attr "mode" "SF")
4464 (set_attr "unit" "*,i387")
4465 (set_attr "fp_int_src" "true")])
4467 (define_expand "floatsisf2"
4468 [(set (match_operand:SF 0 "register_operand" "")
4469 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4470 "TARGET_80387 || TARGET_SSE_MATH"
4473 (define_insn "*floatsisf2_mixed"
4474 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4475 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4476 "TARGET_MIX_SSE_I387"
4480 cvtsi2ss\t{%1, %0|%0, %1}
4481 cvtsi2ss\t{%1, %0|%0, %1}"
4482 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4483 (set_attr "mode" "SF")
4484 (set_attr "unit" "*,i387,*,*")
4485 (set_attr "athlon_decode" "*,*,vector,double")
4486 (set_attr "fp_int_src" "true")])
4488 (define_insn "*floatsisf2_sse"
4489 [(set (match_operand:SF 0 "register_operand" "=x,x")
4490 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4492 "cvtsi2ss\t{%1, %0|%0, %1}"
4493 [(set_attr "type" "sseicvt")
4494 (set_attr "mode" "SF")
4495 (set_attr "athlon_decode" "vector,double")
4496 (set_attr "fp_int_src" "true")])
4498 (define_insn "*floatsisf2_i387"
4499 [(set (match_operand:SF 0 "register_operand" "=f,f")
4500 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4505 [(set_attr "type" "fmov,multi")
4506 (set_attr "mode" "SF")
4507 (set_attr "unit" "*,i387")
4508 (set_attr "fp_int_src" "true")])
4510 (define_expand "floatdisf2"
4511 [(set (match_operand:SF 0 "register_operand" "")
4512 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4513 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4516 (define_insn "*floatdisf2_mixed"
4517 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4518 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4519 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4523 cvtsi2ss{q}\t{%1, %0|%0, %1}
4524 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4525 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4526 (set_attr "mode" "SF")
4527 (set_attr "unit" "*,i387,*,*")
4528 (set_attr "athlon_decode" "*,*,vector,double")
4529 (set_attr "fp_int_src" "true")])
4531 (define_insn "*floatdisf2_sse"
4532 [(set (match_operand:SF 0 "register_operand" "=x,x")
4533 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4534 "TARGET_64BIT && TARGET_SSE_MATH"
4535 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4536 [(set_attr "type" "sseicvt")
4537 (set_attr "mode" "SF")
4538 (set_attr "athlon_decode" "vector,double")
4539 (set_attr "fp_int_src" "true")])
4541 (define_insn "*floatdisf2_i387"
4542 [(set (match_operand:SF 0 "register_operand" "=f,f")
4543 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4548 [(set_attr "type" "fmov,multi")
4549 (set_attr "mode" "SF")
4550 (set_attr "unit" "*,i387")
4551 (set_attr "fp_int_src" "true")])
4553 (define_expand "floathidf2"
4554 [(set (match_operand:DF 0 "register_operand" "")
4555 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4556 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4558 if (TARGET_SSE2 && TARGET_SSE_MATH)
4560 emit_insn (gen_floatsidf2 (operands[0],
4561 convert_to_mode (SImode, operands[1], 0)));
4566 (define_insn "*floathidf2_i387"
4567 [(set (match_operand:DF 0 "register_operand" "=f,f")
4568 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4569 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4573 [(set_attr "type" "fmov,multi")
4574 (set_attr "mode" "DF")
4575 (set_attr "unit" "*,i387")
4576 (set_attr "fp_int_src" "true")])
4578 (define_expand "floatsidf2"
4579 [(set (match_operand:DF 0 "register_operand" "")
4580 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4581 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4584 (define_insn "*floatsidf2_mixed"
4585 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4586 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4587 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4591 cvtsi2sd\t{%1, %0|%0, %1}
4592 cvtsi2sd\t{%1, %0|%0, %1}"
4593 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4594 (set_attr "mode" "DF")
4595 (set_attr "unit" "*,i387,*,*")
4596 (set_attr "athlon_decode" "*,*,double,direct")
4597 (set_attr "fp_int_src" "true")])
4599 (define_insn "*floatsidf2_sse"
4600 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4601 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4602 "TARGET_SSE2 && TARGET_SSE_MATH"
4603 "cvtsi2sd\t{%1, %0|%0, %1}"
4604 [(set_attr "type" "sseicvt")
4605 (set_attr "mode" "DF")
4606 (set_attr "athlon_decode" "double,direct")
4607 (set_attr "fp_int_src" "true")])
4609 (define_insn "*floatsidf2_i387"
4610 [(set (match_operand:DF 0 "register_operand" "=f,f")
4611 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4616 [(set_attr "type" "fmov,multi")
4617 (set_attr "mode" "DF")
4618 (set_attr "unit" "*,i387")
4619 (set_attr "fp_int_src" "true")])
4621 (define_expand "floatdidf2"
4622 [(set (match_operand:DF 0 "register_operand" "")
4623 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4624 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4627 (define_insn "*floatdidf2_mixed"
4628 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4629 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4630 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4634 cvtsi2sd{q}\t{%1, %0|%0, %1}
4635 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4636 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4637 (set_attr "mode" "DF")
4638 (set_attr "unit" "*,i387,*,*")
4639 (set_attr "athlon_decode" "*,*,double,direct")
4640 (set_attr "fp_int_src" "true")])
4642 (define_insn "*floatdidf2_sse"
4643 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4644 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4645 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4646 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4647 [(set_attr "type" "sseicvt")
4648 (set_attr "mode" "DF")
4649 (set_attr "athlon_decode" "double,direct")
4650 (set_attr "fp_int_src" "true")])
4652 (define_insn "*floatdidf2_i387"
4653 [(set (match_operand:DF 0 "register_operand" "=f,f")
4654 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4659 [(set_attr "type" "fmov,multi")
4660 (set_attr "mode" "DF")
4661 (set_attr "unit" "*,i387")
4662 (set_attr "fp_int_src" "true")])
4664 (define_insn "floathixf2"
4665 [(set (match_operand:XF 0 "register_operand" "=f,f")
4666 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4671 [(set_attr "type" "fmov,multi")
4672 (set_attr "mode" "XF")
4673 (set_attr "unit" "*,i387")
4674 (set_attr "fp_int_src" "true")])
4676 (define_insn "floatsixf2"
4677 [(set (match_operand:XF 0 "register_operand" "=f,f")
4678 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4683 [(set_attr "type" "fmov,multi")
4684 (set_attr "mode" "XF")
4685 (set_attr "unit" "*,i387")
4686 (set_attr "fp_int_src" "true")])
4688 (define_insn "floatdixf2"
4689 [(set (match_operand:XF 0 "register_operand" "=f,f")
4690 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4695 [(set_attr "type" "fmov,multi")
4696 (set_attr "mode" "XF")
4697 (set_attr "unit" "*,i387")
4698 (set_attr "fp_int_src" "true")])
4700 ;; %%% Kill these when reload knows how to do it.
4702 [(set (match_operand 0 "fp_register_operand" "")
4703 (float (match_operand 1 "register_operand" "")))]
4706 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4709 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4710 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4711 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4712 ix86_free_from_memory (GET_MODE (operands[1]));
4716 (define_expand "floatunssisf2"
4717 [(use (match_operand:SF 0 "register_operand" ""))
4718 (use (match_operand:SI 1 "register_operand" ""))]
4719 "!TARGET_64BIT && TARGET_SSE_MATH"
4720 "x86_emit_floatuns (operands); DONE;")
4722 (define_expand "floatunsdisf2"
4723 [(use (match_operand:SF 0 "register_operand" ""))
4724 (use (match_operand:DI 1 "register_operand" ""))]
4725 "TARGET_64BIT && TARGET_SSE_MATH"
4726 "x86_emit_floatuns (operands); DONE;")
4728 (define_expand "floatunsdidf2"
4729 [(use (match_operand:DF 0 "register_operand" ""))
4730 (use (match_operand:DI 1 "register_operand" ""))]
4731 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4732 "x86_emit_floatuns (operands); DONE;")
4734 ;; SSE extract/set expanders
4739 ;; %%% splits for addditi3
4741 (define_expand "addti3"
4742 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4743 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4744 (match_operand:TI 2 "x86_64_general_operand" "")))
4745 (clobber (reg:CC FLAGS_REG))]
4747 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4749 (define_insn "*addti3_1"
4750 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4751 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4752 (match_operand:TI 2 "general_operand" "roiF,riF")))
4753 (clobber (reg:CC FLAGS_REG))]
4754 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4758 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4759 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4760 (match_operand:TI 2 "general_operand" "")))
4761 (clobber (reg:CC FLAGS_REG))]
4762 "TARGET_64BIT && reload_completed"
4763 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4765 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4766 (parallel [(set (match_dup 3)
4767 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4770 (clobber (reg:CC FLAGS_REG))])]
4771 "split_ti (operands+0, 1, operands+0, operands+3);
4772 split_ti (operands+1, 1, operands+1, operands+4);
4773 split_ti (operands+2, 1, operands+2, operands+5);")
4775 ;; %%% splits for addsidi3
4776 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4777 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4778 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4780 (define_expand "adddi3"
4781 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4782 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4783 (match_operand:DI 2 "x86_64_general_operand" "")))
4784 (clobber (reg:CC FLAGS_REG))]
4786 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4788 (define_insn "*adddi3_1"
4789 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4790 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4791 (match_operand:DI 2 "general_operand" "roiF,riF")))
4792 (clobber (reg:CC FLAGS_REG))]
4793 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4797 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4798 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4799 (match_operand:DI 2 "general_operand" "")))
4800 (clobber (reg:CC FLAGS_REG))]
4801 "!TARGET_64BIT && reload_completed"
4802 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4804 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4805 (parallel [(set (match_dup 3)
4806 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4809 (clobber (reg:CC FLAGS_REG))])]
4810 "split_di (operands+0, 1, operands+0, operands+3);
4811 split_di (operands+1, 1, operands+1, operands+4);
4812 split_di (operands+2, 1, operands+2, operands+5);")
4814 (define_insn "adddi3_carry_rex64"
4815 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4816 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4817 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4818 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4819 (clobber (reg:CC FLAGS_REG))]
4820 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4821 "adc{q}\t{%2, %0|%0, %2}"
4822 [(set_attr "type" "alu")
4823 (set_attr "pent_pair" "pu")
4824 (set_attr "mode" "DI")])
4826 (define_insn "*adddi3_cc_rex64"
4827 [(set (reg:CC FLAGS_REG)
4828 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4829 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4831 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4832 (plus:DI (match_dup 1) (match_dup 2)))]
4833 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4834 "add{q}\t{%2, %0|%0, %2}"
4835 [(set_attr "type" "alu")
4836 (set_attr "mode" "DI")])
4838 (define_insn "addqi3_carry"
4839 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4840 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4841 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4842 (match_operand:QI 2 "general_operand" "qi,qm")))
4843 (clobber (reg:CC FLAGS_REG))]
4844 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4845 "adc{b}\t{%2, %0|%0, %2}"
4846 [(set_attr "type" "alu")
4847 (set_attr "pent_pair" "pu")
4848 (set_attr "mode" "QI")])
4850 (define_insn "addhi3_carry"
4851 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4852 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4853 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4854 (match_operand:HI 2 "general_operand" "ri,rm")))
4855 (clobber (reg:CC FLAGS_REG))]
4856 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4857 "adc{w}\t{%2, %0|%0, %2}"
4858 [(set_attr "type" "alu")
4859 (set_attr "pent_pair" "pu")
4860 (set_attr "mode" "HI")])
4862 (define_insn "addsi3_carry"
4863 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4864 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4865 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4866 (match_operand:SI 2 "general_operand" "ri,rm")))
4867 (clobber (reg:CC FLAGS_REG))]
4868 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4869 "adc{l}\t{%2, %0|%0, %2}"
4870 [(set_attr "type" "alu")
4871 (set_attr "pent_pair" "pu")
4872 (set_attr "mode" "SI")])
4874 (define_insn "*addsi3_carry_zext"
4875 [(set (match_operand:DI 0 "register_operand" "=r")
4877 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4878 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4879 (match_operand:SI 2 "general_operand" "rim"))))
4880 (clobber (reg:CC FLAGS_REG))]
4881 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4882 "adc{l}\t{%2, %k0|%k0, %2}"
4883 [(set_attr "type" "alu")
4884 (set_attr "pent_pair" "pu")
4885 (set_attr "mode" "SI")])
4887 (define_insn "*addsi3_cc"
4888 [(set (reg:CC FLAGS_REG)
4889 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4890 (match_operand:SI 2 "general_operand" "ri,rm")]
4892 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4893 (plus:SI (match_dup 1) (match_dup 2)))]
4894 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4895 "add{l}\t{%2, %0|%0, %2}"
4896 [(set_attr "type" "alu")
4897 (set_attr "mode" "SI")])
4899 (define_insn "addqi3_cc"
4900 [(set (reg:CC FLAGS_REG)
4901 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4902 (match_operand:QI 2 "general_operand" "qi,qm")]
4904 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4905 (plus:QI (match_dup 1) (match_dup 2)))]
4906 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4907 "add{b}\t{%2, %0|%0, %2}"
4908 [(set_attr "type" "alu")
4909 (set_attr "mode" "QI")])
4911 (define_expand "addsi3"
4912 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4913 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4914 (match_operand:SI 2 "general_operand" "")))
4915 (clobber (reg:CC FLAGS_REG))])]
4917 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4919 (define_insn "*lea_1"
4920 [(set (match_operand:SI 0 "register_operand" "=r")
4921 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4923 "lea{l}\t{%a1, %0|%0, %a1}"
4924 [(set_attr "type" "lea")
4925 (set_attr "mode" "SI")])
4927 (define_insn "*lea_1_rex64"
4928 [(set (match_operand:SI 0 "register_operand" "=r")
4929 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4931 "lea{l}\t{%a1, %0|%0, %a1}"
4932 [(set_attr "type" "lea")
4933 (set_attr "mode" "SI")])
4935 (define_insn "*lea_1_zext"
4936 [(set (match_operand:DI 0 "register_operand" "=r")
4938 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4940 "lea{l}\t{%a1, %k0|%k0, %a1}"
4941 [(set_attr "type" "lea")
4942 (set_attr "mode" "SI")])
4944 (define_insn "*lea_2_rex64"
4945 [(set (match_operand:DI 0 "register_operand" "=r")
4946 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4948 "lea{q}\t{%a1, %0|%0, %a1}"
4949 [(set_attr "type" "lea")
4950 (set_attr "mode" "DI")])
4952 ;; The lea patterns for non-Pmodes needs to be matched by several
4953 ;; insns converted to real lea by splitters.
4955 (define_insn_and_split "*lea_general_1"
4956 [(set (match_operand 0 "register_operand" "=r")
4957 (plus (plus (match_operand 1 "index_register_operand" "l")
4958 (match_operand 2 "register_operand" "r"))
4959 (match_operand 3 "immediate_operand" "i")))]
4960 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4961 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4962 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4963 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4964 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4965 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4966 || GET_MODE (operands[3]) == VOIDmode)"
4968 "&& reload_completed"
4972 operands[0] = gen_lowpart (SImode, operands[0]);
4973 operands[1] = gen_lowpart (Pmode, operands[1]);
4974 operands[2] = gen_lowpart (Pmode, operands[2]);
4975 operands[3] = gen_lowpart (Pmode, operands[3]);
4976 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4978 if (Pmode != SImode)
4979 pat = gen_rtx_SUBREG (SImode, pat, 0);
4980 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4983 [(set_attr "type" "lea")
4984 (set_attr "mode" "SI")])
4986 (define_insn_and_split "*lea_general_1_zext"
4987 [(set (match_operand:DI 0 "register_operand" "=r")
4989 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4990 (match_operand:SI 2 "register_operand" "r"))
4991 (match_operand:SI 3 "immediate_operand" "i"))))]
4994 "&& reload_completed"
4996 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4998 (match_dup 3)) 0)))]
5000 operands[1] = gen_lowpart (Pmode, operands[1]);
5001 operands[2] = gen_lowpart (Pmode, operands[2]);
5002 operands[3] = gen_lowpart (Pmode, operands[3]);
5004 [(set_attr "type" "lea")
5005 (set_attr "mode" "SI")])
5007 (define_insn_and_split "*lea_general_2"
5008 [(set (match_operand 0 "register_operand" "=r")
5009 (plus (mult (match_operand 1 "index_register_operand" "l")
5010 (match_operand 2 "const248_operand" "i"))
5011 (match_operand 3 "nonmemory_operand" "ri")))]
5012 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5013 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5014 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5015 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5016 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5017 || GET_MODE (operands[3]) == VOIDmode)"
5019 "&& reload_completed"
5023 operands[0] = gen_lowpart (SImode, operands[0]);
5024 operands[1] = gen_lowpart (Pmode, operands[1]);
5025 operands[3] = gen_lowpart (Pmode, operands[3]);
5026 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5028 if (Pmode != SImode)
5029 pat = gen_rtx_SUBREG (SImode, pat, 0);
5030 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5033 [(set_attr "type" "lea")
5034 (set_attr "mode" "SI")])
5036 (define_insn_and_split "*lea_general_2_zext"
5037 [(set (match_operand:DI 0 "register_operand" "=r")
5039 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5040 (match_operand:SI 2 "const248_operand" "n"))
5041 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5044 "&& reload_completed"
5046 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5048 (match_dup 3)) 0)))]
5050 operands[1] = gen_lowpart (Pmode, operands[1]);
5051 operands[3] = gen_lowpart (Pmode, operands[3]);
5053 [(set_attr "type" "lea")
5054 (set_attr "mode" "SI")])
5056 (define_insn_and_split "*lea_general_3"
5057 [(set (match_operand 0 "register_operand" "=r")
5058 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5059 (match_operand 2 "const248_operand" "i"))
5060 (match_operand 3 "register_operand" "r"))
5061 (match_operand 4 "immediate_operand" "i")))]
5062 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5063 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5064 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5065 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5066 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5068 "&& reload_completed"
5072 operands[0] = gen_lowpart (SImode, operands[0]);
5073 operands[1] = gen_lowpart (Pmode, operands[1]);
5074 operands[3] = gen_lowpart (Pmode, operands[3]);
5075 operands[4] = gen_lowpart (Pmode, operands[4]);
5076 pat = gen_rtx_PLUS (Pmode,
5077 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5081 if (Pmode != SImode)
5082 pat = gen_rtx_SUBREG (SImode, pat, 0);
5083 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5086 [(set_attr "type" "lea")
5087 (set_attr "mode" "SI")])
5089 (define_insn_and_split "*lea_general_3_zext"
5090 [(set (match_operand:DI 0 "register_operand" "=r")
5092 (plus:SI (plus:SI (mult:SI
5093 (match_operand:SI 1 "index_register_operand" "l")
5094 (match_operand:SI 2 "const248_operand" "n"))
5095 (match_operand:SI 3 "register_operand" "r"))
5096 (match_operand:SI 4 "immediate_operand" "i"))))]
5099 "&& reload_completed"
5101 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5104 (match_dup 4)) 0)))]
5106 operands[1] = gen_lowpart (Pmode, operands[1]);
5107 operands[3] = gen_lowpart (Pmode, operands[3]);
5108 operands[4] = gen_lowpart (Pmode, operands[4]);
5110 [(set_attr "type" "lea")
5111 (set_attr "mode" "SI")])
5113 (define_insn "*adddi_1_rex64"
5114 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5115 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5116 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5117 (clobber (reg:CC FLAGS_REG))]
5118 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5120 switch (get_attr_type (insn))
5123 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5124 return "lea{q}\t{%a2, %0|%0, %a2}";
5127 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5128 if (operands[2] == const1_rtx)
5129 return "inc{q}\t%0";
5132 gcc_assert (operands[2] == constm1_rtx);
5133 return "dec{q}\t%0";
5137 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5139 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5140 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5141 if (GET_CODE (operands[2]) == CONST_INT
5142 /* Avoid overflows. */
5143 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5144 && (INTVAL (operands[2]) == 128
5145 || (INTVAL (operands[2]) < 0
5146 && INTVAL (operands[2]) != -128)))
5148 operands[2] = GEN_INT (-INTVAL (operands[2]));
5149 return "sub{q}\t{%2, %0|%0, %2}";
5151 return "add{q}\t{%2, %0|%0, %2}";
5155 (cond [(eq_attr "alternative" "2")
5156 (const_string "lea")
5157 ; Current assemblers are broken and do not allow @GOTOFF in
5158 ; ought but a memory context.
5159 (match_operand:DI 2 "pic_symbolic_operand" "")
5160 (const_string "lea")
5161 (match_operand:DI 2 "incdec_operand" "")
5162 (const_string "incdec")
5164 (const_string "alu")))
5165 (set_attr "mode" "DI")])
5167 ;; Convert lea to the lea pattern to avoid flags dependency.
5169 [(set (match_operand:DI 0 "register_operand" "")
5170 (plus:DI (match_operand:DI 1 "register_operand" "")
5171 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5172 (clobber (reg:CC FLAGS_REG))]
5173 "TARGET_64BIT && reload_completed
5174 && true_regnum (operands[0]) != true_regnum (operands[1])"
5176 (plus:DI (match_dup 1)
5180 (define_insn "*adddi_2_rex64"
5181 [(set (reg FLAGS_REG)
5183 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5184 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5186 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5187 (plus:DI (match_dup 1) (match_dup 2)))]
5188 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5189 && ix86_binary_operator_ok (PLUS, DImode, operands)
5190 /* Current assemblers are broken and do not allow @GOTOFF in
5191 ought but a memory context. */
5192 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5194 switch (get_attr_type (insn))
5197 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5198 if (operands[2] == const1_rtx)
5199 return "inc{q}\t%0";
5202 gcc_assert (operands[2] == constm1_rtx);
5203 return "dec{q}\t%0";
5207 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5208 /* ???? We ought to handle there the 32bit case too
5209 - do we need new constraint? */
5210 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5211 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5212 if (GET_CODE (operands[2]) == CONST_INT
5213 /* Avoid overflows. */
5214 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5215 && (INTVAL (operands[2]) == 128
5216 || (INTVAL (operands[2]) < 0
5217 && INTVAL (operands[2]) != -128)))
5219 operands[2] = GEN_INT (-INTVAL (operands[2]));
5220 return "sub{q}\t{%2, %0|%0, %2}";
5222 return "add{q}\t{%2, %0|%0, %2}";
5226 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5227 (const_string "incdec")
5228 (const_string "alu")))
5229 (set_attr "mode" "DI")])
5231 (define_insn "*adddi_3_rex64"
5232 [(set (reg FLAGS_REG)
5233 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5234 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5235 (clobber (match_scratch:DI 0 "=r"))]
5237 && ix86_match_ccmode (insn, CCZmode)
5238 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5239 /* Current assemblers are broken and do not allow @GOTOFF in
5240 ought but a memory context. */
5241 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5243 switch (get_attr_type (insn))
5246 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5247 if (operands[2] == const1_rtx)
5248 return "inc{q}\t%0";
5251 gcc_assert (operands[2] == constm1_rtx);
5252 return "dec{q}\t%0";
5256 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5257 /* ???? We ought to handle there the 32bit case too
5258 - do we need new constraint? */
5259 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5260 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5261 if (GET_CODE (operands[2]) == CONST_INT
5262 /* Avoid overflows. */
5263 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5264 && (INTVAL (operands[2]) == 128
5265 || (INTVAL (operands[2]) < 0
5266 && INTVAL (operands[2]) != -128)))
5268 operands[2] = GEN_INT (-INTVAL (operands[2]));
5269 return "sub{q}\t{%2, %0|%0, %2}";
5271 return "add{q}\t{%2, %0|%0, %2}";
5275 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5276 (const_string "incdec")
5277 (const_string "alu")))
5278 (set_attr "mode" "DI")])
5280 ; For comparisons against 1, -1 and 128, we may generate better code
5281 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5282 ; is matched then. We can't accept general immediate, because for
5283 ; case of overflows, the result is messed up.
5284 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5286 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5287 ; only for comparisons not depending on it.
5288 (define_insn "*adddi_4_rex64"
5289 [(set (reg FLAGS_REG)
5290 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5291 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5292 (clobber (match_scratch:DI 0 "=rm"))]
5294 && ix86_match_ccmode (insn, CCGCmode)"
5296 switch (get_attr_type (insn))
5299 if (operands[2] == constm1_rtx)
5300 return "inc{q}\t%0";
5303 gcc_assert (operands[2] == const1_rtx);
5304 return "dec{q}\t%0";
5308 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5309 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5310 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5311 if ((INTVAL (operands[2]) == -128
5312 || (INTVAL (operands[2]) > 0
5313 && INTVAL (operands[2]) != 128))
5314 /* Avoid overflows. */
5315 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5316 return "sub{q}\t{%2, %0|%0, %2}";
5317 operands[2] = GEN_INT (-INTVAL (operands[2]));
5318 return "add{q}\t{%2, %0|%0, %2}";
5322 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5323 (const_string "incdec")
5324 (const_string "alu")))
5325 (set_attr "mode" "DI")])
5327 (define_insn "*adddi_5_rex64"
5328 [(set (reg FLAGS_REG)
5330 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5331 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5333 (clobber (match_scratch:DI 0 "=r"))]
5335 && ix86_match_ccmode (insn, CCGOCmode)
5336 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5337 /* Current assemblers are broken and do not allow @GOTOFF in
5338 ought but a memory context. */
5339 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5341 switch (get_attr_type (insn))
5344 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5345 if (operands[2] == const1_rtx)
5346 return "inc{q}\t%0";
5349 gcc_assert (operands[2] == constm1_rtx);
5350 return "dec{q}\t%0";
5354 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5355 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5356 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5357 if (GET_CODE (operands[2]) == CONST_INT
5358 /* Avoid overflows. */
5359 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5360 && (INTVAL (operands[2]) == 128
5361 || (INTVAL (operands[2]) < 0
5362 && INTVAL (operands[2]) != -128)))
5364 operands[2] = GEN_INT (-INTVAL (operands[2]));
5365 return "sub{q}\t{%2, %0|%0, %2}";
5367 return "add{q}\t{%2, %0|%0, %2}";
5371 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5372 (const_string "incdec")
5373 (const_string "alu")))
5374 (set_attr "mode" "DI")])
5377 (define_insn "*addsi_1"
5378 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5379 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5380 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5381 (clobber (reg:CC FLAGS_REG))]
5382 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5384 switch (get_attr_type (insn))
5387 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5388 return "lea{l}\t{%a2, %0|%0, %a2}";
5391 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5392 if (operands[2] == const1_rtx)
5393 return "inc{l}\t%0";
5396 gcc_assert (operands[2] == constm1_rtx);
5397 return "dec{l}\t%0";
5401 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5403 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5404 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5405 if (GET_CODE (operands[2]) == CONST_INT
5406 && (INTVAL (operands[2]) == 128
5407 || (INTVAL (operands[2]) < 0
5408 && INTVAL (operands[2]) != -128)))
5410 operands[2] = GEN_INT (-INTVAL (operands[2]));
5411 return "sub{l}\t{%2, %0|%0, %2}";
5413 return "add{l}\t{%2, %0|%0, %2}";
5417 (cond [(eq_attr "alternative" "2")
5418 (const_string "lea")
5419 ; Current assemblers are broken and do not allow @GOTOFF in
5420 ; ought but a memory context.
5421 (match_operand:SI 2 "pic_symbolic_operand" "")
5422 (const_string "lea")
5423 (match_operand:SI 2 "incdec_operand" "")
5424 (const_string "incdec")
5426 (const_string "alu")))
5427 (set_attr "mode" "SI")])
5429 ;; Convert lea to the lea pattern to avoid flags dependency.
5431 [(set (match_operand 0 "register_operand" "")
5432 (plus (match_operand 1 "register_operand" "")
5433 (match_operand 2 "nonmemory_operand" "")))
5434 (clobber (reg:CC FLAGS_REG))]
5436 && true_regnum (operands[0]) != true_regnum (operands[1])"
5440 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5441 may confuse gen_lowpart. */
5442 if (GET_MODE (operands[0]) != Pmode)
5444 operands[1] = gen_lowpart (Pmode, operands[1]);
5445 operands[2] = gen_lowpart (Pmode, operands[2]);
5447 operands[0] = gen_lowpart (SImode, operands[0]);
5448 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5449 if (Pmode != SImode)
5450 pat = gen_rtx_SUBREG (SImode, pat, 0);
5451 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5455 ;; It may seem that nonimmediate operand is proper one for operand 1.
5456 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5457 ;; we take care in ix86_binary_operator_ok to not allow two memory
5458 ;; operands so proper swapping will be done in reload. This allow
5459 ;; patterns constructed from addsi_1 to match.
5460 (define_insn "addsi_1_zext"
5461 [(set (match_operand:DI 0 "register_operand" "=r,r")
5463 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5464 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5465 (clobber (reg:CC FLAGS_REG))]
5466 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5468 switch (get_attr_type (insn))
5471 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5472 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5475 if (operands[2] == const1_rtx)
5476 return "inc{l}\t%k0";
5479 gcc_assert (operands[2] == constm1_rtx);
5480 return "dec{l}\t%k0";
5484 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5485 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5486 if (GET_CODE (operands[2]) == CONST_INT
5487 && (INTVAL (operands[2]) == 128
5488 || (INTVAL (operands[2]) < 0
5489 && INTVAL (operands[2]) != -128)))
5491 operands[2] = GEN_INT (-INTVAL (operands[2]));
5492 return "sub{l}\t{%2, %k0|%k0, %2}";
5494 return "add{l}\t{%2, %k0|%k0, %2}";
5498 (cond [(eq_attr "alternative" "1")
5499 (const_string "lea")
5500 ; Current assemblers are broken and do not allow @GOTOFF in
5501 ; ought but a memory context.
5502 (match_operand:SI 2 "pic_symbolic_operand" "")
5503 (const_string "lea")
5504 (match_operand:SI 2 "incdec_operand" "")
5505 (const_string "incdec")
5507 (const_string "alu")))
5508 (set_attr "mode" "SI")])
5510 ;; Convert lea to the lea pattern to avoid flags dependency.
5512 [(set (match_operand:DI 0 "register_operand" "")
5514 (plus:SI (match_operand:SI 1 "register_operand" "")
5515 (match_operand:SI 2 "nonmemory_operand" ""))))
5516 (clobber (reg:CC FLAGS_REG))]
5517 "TARGET_64BIT && reload_completed
5518 && true_regnum (operands[0]) != true_regnum (operands[1])"
5520 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5522 operands[1] = gen_lowpart (Pmode, operands[1]);
5523 operands[2] = gen_lowpart (Pmode, operands[2]);
5526 (define_insn "*addsi_2"
5527 [(set (reg FLAGS_REG)
5529 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5530 (match_operand:SI 2 "general_operand" "rmni,rni"))
5532 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5533 (plus:SI (match_dup 1) (match_dup 2)))]
5534 "ix86_match_ccmode (insn, CCGOCmode)
5535 && ix86_binary_operator_ok (PLUS, SImode, operands)
5536 /* Current assemblers are broken and do not allow @GOTOFF in
5537 ought but a memory context. */
5538 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5540 switch (get_attr_type (insn))
5543 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5544 if (operands[2] == const1_rtx)
5545 return "inc{l}\t%0";
5548 gcc_assert (operands[2] == constm1_rtx);
5549 return "dec{l}\t%0";
5553 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5554 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5555 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5556 if (GET_CODE (operands[2]) == CONST_INT
5557 && (INTVAL (operands[2]) == 128
5558 || (INTVAL (operands[2]) < 0
5559 && INTVAL (operands[2]) != -128)))
5561 operands[2] = GEN_INT (-INTVAL (operands[2]));
5562 return "sub{l}\t{%2, %0|%0, %2}";
5564 return "add{l}\t{%2, %0|%0, %2}";
5568 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5569 (const_string "incdec")
5570 (const_string "alu")))
5571 (set_attr "mode" "SI")])
5573 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5574 (define_insn "*addsi_2_zext"
5575 [(set (reg FLAGS_REG)
5577 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5578 (match_operand:SI 2 "general_operand" "rmni"))
5580 (set (match_operand:DI 0 "register_operand" "=r")
5581 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5582 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5583 && ix86_binary_operator_ok (PLUS, SImode, operands)
5584 /* Current assemblers are broken and do not allow @GOTOFF in
5585 ought but a memory context. */
5586 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5588 switch (get_attr_type (insn))
5591 if (operands[2] == const1_rtx)
5592 return "inc{l}\t%k0";
5595 gcc_assert (operands[2] == constm1_rtx);
5596 return "dec{l}\t%k0";
5600 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5601 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5602 if (GET_CODE (operands[2]) == CONST_INT
5603 && (INTVAL (operands[2]) == 128
5604 || (INTVAL (operands[2]) < 0
5605 && INTVAL (operands[2]) != -128)))
5607 operands[2] = GEN_INT (-INTVAL (operands[2]));
5608 return "sub{l}\t{%2, %k0|%k0, %2}";
5610 return "add{l}\t{%2, %k0|%k0, %2}";
5614 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5615 (const_string "incdec")
5616 (const_string "alu")))
5617 (set_attr "mode" "SI")])
5619 (define_insn "*addsi_3"
5620 [(set (reg FLAGS_REG)
5621 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5622 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5623 (clobber (match_scratch:SI 0 "=r"))]
5624 "ix86_match_ccmode (insn, CCZmode)
5625 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5626 /* Current assemblers are broken and do not allow @GOTOFF in
5627 ought but a memory context. */
5628 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5630 switch (get_attr_type (insn))
5633 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5634 if (operands[2] == const1_rtx)
5635 return "inc{l}\t%0";
5638 gcc_assert (operands[2] == constm1_rtx);
5639 return "dec{l}\t%0";
5643 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5645 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5646 if (GET_CODE (operands[2]) == CONST_INT
5647 && (INTVAL (operands[2]) == 128
5648 || (INTVAL (operands[2]) < 0
5649 && INTVAL (operands[2]) != -128)))
5651 operands[2] = GEN_INT (-INTVAL (operands[2]));
5652 return "sub{l}\t{%2, %0|%0, %2}";
5654 return "add{l}\t{%2, %0|%0, %2}";
5658 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5659 (const_string "incdec")
5660 (const_string "alu")))
5661 (set_attr "mode" "SI")])
5663 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5664 (define_insn "*addsi_3_zext"
5665 [(set (reg FLAGS_REG)
5666 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5667 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5668 (set (match_operand:DI 0 "register_operand" "=r")
5669 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5670 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5671 && ix86_binary_operator_ok (PLUS, SImode, operands)
5672 /* Current assemblers are broken and do not allow @GOTOFF in
5673 ought but a memory context. */
5674 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5676 switch (get_attr_type (insn))
5679 if (operands[2] == const1_rtx)
5680 return "inc{l}\t%k0";
5683 gcc_assert (operands[2] == constm1_rtx);
5684 return "dec{l}\t%k0";
5688 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5689 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5690 if (GET_CODE (operands[2]) == CONST_INT
5691 && (INTVAL (operands[2]) == 128
5692 || (INTVAL (operands[2]) < 0
5693 && INTVAL (operands[2]) != -128)))
5695 operands[2] = GEN_INT (-INTVAL (operands[2]));
5696 return "sub{l}\t{%2, %k0|%k0, %2}";
5698 return "add{l}\t{%2, %k0|%k0, %2}";
5702 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5703 (const_string "incdec")
5704 (const_string "alu")))
5705 (set_attr "mode" "SI")])
5707 ; For comparisons against 1, -1 and 128, we may generate better code
5708 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5709 ; is matched then. We can't accept general immediate, because for
5710 ; case of overflows, the result is messed up.
5711 ; This pattern also don't hold of 0x80000000, since the value overflows
5713 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5714 ; only for comparisons not depending on it.
5715 (define_insn "*addsi_4"
5716 [(set (reg FLAGS_REG)
5717 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5718 (match_operand:SI 2 "const_int_operand" "n")))
5719 (clobber (match_scratch:SI 0 "=rm"))]
5720 "ix86_match_ccmode (insn, CCGCmode)
5721 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5723 switch (get_attr_type (insn))
5726 if (operands[2] == constm1_rtx)
5727 return "inc{l}\t%0";
5730 gcc_assert (operands[2] == const1_rtx);
5731 return "dec{l}\t%0";
5735 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5736 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5737 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5738 if ((INTVAL (operands[2]) == -128
5739 || (INTVAL (operands[2]) > 0
5740 && INTVAL (operands[2]) != 128)))
5741 return "sub{l}\t{%2, %0|%0, %2}";
5742 operands[2] = GEN_INT (-INTVAL (operands[2]));
5743 return "add{l}\t{%2, %0|%0, %2}";
5747 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5748 (const_string "incdec")
5749 (const_string "alu")))
5750 (set_attr "mode" "SI")])
5752 (define_insn "*addsi_5"
5753 [(set (reg FLAGS_REG)
5755 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5756 (match_operand:SI 2 "general_operand" "rmni"))
5758 (clobber (match_scratch:SI 0 "=r"))]
5759 "ix86_match_ccmode (insn, CCGOCmode)
5760 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5761 /* Current assemblers are broken and do not allow @GOTOFF in
5762 ought but a memory context. */
5763 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5765 switch (get_attr_type (insn))
5768 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5769 if (operands[2] == const1_rtx)
5770 return "inc{l}\t%0";
5773 gcc_assert (operands[2] == constm1_rtx);
5774 return "dec{l}\t%0";
5778 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5779 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5780 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5781 if (GET_CODE (operands[2]) == CONST_INT
5782 && (INTVAL (operands[2]) == 128
5783 || (INTVAL (operands[2]) < 0
5784 && INTVAL (operands[2]) != -128)))
5786 operands[2] = GEN_INT (-INTVAL (operands[2]));
5787 return "sub{l}\t{%2, %0|%0, %2}";
5789 return "add{l}\t{%2, %0|%0, %2}";
5793 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5794 (const_string "incdec")
5795 (const_string "alu")))
5796 (set_attr "mode" "SI")])
5798 (define_expand "addhi3"
5799 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5800 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5801 (match_operand:HI 2 "general_operand" "")))
5802 (clobber (reg:CC FLAGS_REG))])]
5803 "TARGET_HIMODE_MATH"
5804 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5806 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5807 ;; type optimizations enabled by define-splits. This is not important
5808 ;; for PII, and in fact harmful because of partial register stalls.
5810 (define_insn "*addhi_1_lea"
5811 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5812 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5813 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5814 (clobber (reg:CC FLAGS_REG))]
5815 "!TARGET_PARTIAL_REG_STALL
5816 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5818 switch (get_attr_type (insn))
5823 if (operands[2] == const1_rtx)
5824 return "inc{w}\t%0";
5827 gcc_assert (operands[2] == constm1_rtx);
5828 return "dec{w}\t%0";
5832 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5833 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5834 if (GET_CODE (operands[2]) == CONST_INT
5835 && (INTVAL (operands[2]) == 128
5836 || (INTVAL (operands[2]) < 0
5837 && INTVAL (operands[2]) != -128)))
5839 operands[2] = GEN_INT (-INTVAL (operands[2]));
5840 return "sub{w}\t{%2, %0|%0, %2}";
5842 return "add{w}\t{%2, %0|%0, %2}";
5846 (if_then_else (eq_attr "alternative" "2")
5847 (const_string "lea")
5848 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5849 (const_string "incdec")
5850 (const_string "alu"))))
5851 (set_attr "mode" "HI,HI,SI")])
5853 (define_insn "*addhi_1"
5854 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5855 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5856 (match_operand:HI 2 "general_operand" "ri,rm")))
5857 (clobber (reg:CC FLAGS_REG))]
5858 "TARGET_PARTIAL_REG_STALL
5859 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5861 switch (get_attr_type (insn))
5864 if (operands[2] == const1_rtx)
5865 return "inc{w}\t%0";
5868 gcc_assert (operands[2] == constm1_rtx);
5869 return "dec{w}\t%0";
5873 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5874 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5875 if (GET_CODE (operands[2]) == CONST_INT
5876 && (INTVAL (operands[2]) == 128
5877 || (INTVAL (operands[2]) < 0
5878 && INTVAL (operands[2]) != -128)))
5880 operands[2] = GEN_INT (-INTVAL (operands[2]));
5881 return "sub{w}\t{%2, %0|%0, %2}";
5883 return "add{w}\t{%2, %0|%0, %2}";
5887 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5888 (const_string "incdec")
5889 (const_string "alu")))
5890 (set_attr "mode" "HI")])
5892 (define_insn "*addhi_2"
5893 [(set (reg FLAGS_REG)
5895 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5896 (match_operand:HI 2 "general_operand" "rmni,rni"))
5898 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5899 (plus:HI (match_dup 1) (match_dup 2)))]
5900 "ix86_match_ccmode (insn, CCGOCmode)
5901 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5903 switch (get_attr_type (insn))
5906 if (operands[2] == const1_rtx)
5907 return "inc{w}\t%0";
5910 gcc_assert (operands[2] == constm1_rtx);
5911 return "dec{w}\t%0";
5915 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5916 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5917 if (GET_CODE (operands[2]) == CONST_INT
5918 && (INTVAL (operands[2]) == 128
5919 || (INTVAL (operands[2]) < 0
5920 && INTVAL (operands[2]) != -128)))
5922 operands[2] = GEN_INT (-INTVAL (operands[2]));
5923 return "sub{w}\t{%2, %0|%0, %2}";
5925 return "add{w}\t{%2, %0|%0, %2}";
5929 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5930 (const_string "incdec")
5931 (const_string "alu")))
5932 (set_attr "mode" "HI")])
5934 (define_insn "*addhi_3"
5935 [(set (reg FLAGS_REG)
5936 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5937 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5938 (clobber (match_scratch:HI 0 "=r"))]
5939 "ix86_match_ccmode (insn, CCZmode)
5940 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5942 switch (get_attr_type (insn))
5945 if (operands[2] == const1_rtx)
5946 return "inc{w}\t%0";
5949 gcc_assert (operands[2] == constm1_rtx);
5950 return "dec{w}\t%0";
5954 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5955 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5956 if (GET_CODE (operands[2]) == CONST_INT
5957 && (INTVAL (operands[2]) == 128
5958 || (INTVAL (operands[2]) < 0
5959 && INTVAL (operands[2]) != -128)))
5961 operands[2] = GEN_INT (-INTVAL (operands[2]));
5962 return "sub{w}\t{%2, %0|%0, %2}";
5964 return "add{w}\t{%2, %0|%0, %2}";
5968 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5969 (const_string "incdec")
5970 (const_string "alu")))
5971 (set_attr "mode" "HI")])
5973 ; See comments above addsi_4 for details.
5974 (define_insn "*addhi_4"
5975 [(set (reg FLAGS_REG)
5976 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5977 (match_operand:HI 2 "const_int_operand" "n")))
5978 (clobber (match_scratch:HI 0 "=rm"))]
5979 "ix86_match_ccmode (insn, CCGCmode)
5980 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5982 switch (get_attr_type (insn))
5985 if (operands[2] == constm1_rtx)
5986 return "inc{w}\t%0";
5989 gcc_assert (operands[2] == const1_rtx);
5990 return "dec{w}\t%0";
5994 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5995 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5996 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5997 if ((INTVAL (operands[2]) == -128
5998 || (INTVAL (operands[2]) > 0
5999 && INTVAL (operands[2]) != 128)))
6000 return "sub{w}\t{%2, %0|%0, %2}";
6001 operands[2] = GEN_INT (-INTVAL (operands[2]));
6002 return "add{w}\t{%2, %0|%0, %2}";
6006 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6007 (const_string "incdec")
6008 (const_string "alu")))
6009 (set_attr "mode" "SI")])
6012 (define_insn "*addhi_5"
6013 [(set (reg FLAGS_REG)
6015 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6016 (match_operand:HI 2 "general_operand" "rmni"))
6018 (clobber (match_scratch:HI 0 "=r"))]
6019 "ix86_match_ccmode (insn, CCGOCmode)
6020 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6022 switch (get_attr_type (insn))
6025 if (operands[2] == const1_rtx)
6026 return "inc{w}\t%0";
6029 gcc_assert (operands[2] == constm1_rtx);
6030 return "dec{w}\t%0";
6034 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6035 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6036 if (GET_CODE (operands[2]) == CONST_INT
6037 && (INTVAL (operands[2]) == 128
6038 || (INTVAL (operands[2]) < 0
6039 && INTVAL (operands[2]) != -128)))
6041 operands[2] = GEN_INT (-INTVAL (operands[2]));
6042 return "sub{w}\t{%2, %0|%0, %2}";
6044 return "add{w}\t{%2, %0|%0, %2}";
6048 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6049 (const_string "incdec")
6050 (const_string "alu")))
6051 (set_attr "mode" "HI")])
6053 (define_expand "addqi3"
6054 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6055 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6056 (match_operand:QI 2 "general_operand" "")))
6057 (clobber (reg:CC FLAGS_REG))])]
6058 "TARGET_QIMODE_MATH"
6059 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6061 ;; %%% Potential partial reg stall on alternative 2. What to do?
6062 (define_insn "*addqi_1_lea"
6063 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6064 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6065 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6066 (clobber (reg:CC FLAGS_REG))]
6067 "!TARGET_PARTIAL_REG_STALL
6068 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6070 int widen = (which_alternative == 2);
6071 switch (get_attr_type (insn))
6076 if (operands[2] == const1_rtx)
6077 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6080 gcc_assert (operands[2] == constm1_rtx);
6081 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6085 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6086 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6087 if (GET_CODE (operands[2]) == CONST_INT
6088 && (INTVAL (operands[2]) == 128
6089 || (INTVAL (operands[2]) < 0
6090 && INTVAL (operands[2]) != -128)))
6092 operands[2] = GEN_INT (-INTVAL (operands[2]));
6094 return "sub{l}\t{%2, %k0|%k0, %2}";
6096 return "sub{b}\t{%2, %0|%0, %2}";
6099 return "add{l}\t{%k2, %k0|%k0, %k2}";
6101 return "add{b}\t{%2, %0|%0, %2}";
6105 (if_then_else (eq_attr "alternative" "3")
6106 (const_string "lea")
6107 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6108 (const_string "incdec")
6109 (const_string "alu"))))
6110 (set_attr "mode" "QI,QI,SI,SI")])
6112 (define_insn "*addqi_1"
6113 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6114 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6115 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6116 (clobber (reg:CC FLAGS_REG))]
6117 "TARGET_PARTIAL_REG_STALL
6118 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6120 int widen = (which_alternative == 2);
6121 switch (get_attr_type (insn))
6124 if (operands[2] == const1_rtx)
6125 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6128 gcc_assert (operands[2] == constm1_rtx);
6129 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6133 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6134 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6135 if (GET_CODE (operands[2]) == CONST_INT
6136 && (INTVAL (operands[2]) == 128
6137 || (INTVAL (operands[2]) < 0
6138 && INTVAL (operands[2]) != -128)))
6140 operands[2] = GEN_INT (-INTVAL (operands[2]));
6142 return "sub{l}\t{%2, %k0|%k0, %2}";
6144 return "sub{b}\t{%2, %0|%0, %2}";
6147 return "add{l}\t{%k2, %k0|%k0, %k2}";
6149 return "add{b}\t{%2, %0|%0, %2}";
6153 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6154 (const_string "incdec")
6155 (const_string "alu")))
6156 (set_attr "mode" "QI,QI,SI")])
6158 (define_insn "*addqi_1_slp"
6159 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6160 (plus:QI (match_dup 0)
6161 (match_operand:QI 1 "general_operand" "qn,qnm")))
6162 (clobber (reg:CC FLAGS_REG))]
6163 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6164 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6166 switch (get_attr_type (insn))
6169 if (operands[1] == const1_rtx)
6170 return "inc{b}\t%0";
6173 gcc_assert (operands[1] == constm1_rtx);
6174 return "dec{b}\t%0";
6178 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6179 if (GET_CODE (operands[1]) == CONST_INT
6180 && INTVAL (operands[1]) < 0)
6182 operands[1] = GEN_INT (-INTVAL (operands[1]));
6183 return "sub{b}\t{%1, %0|%0, %1}";
6185 return "add{b}\t{%1, %0|%0, %1}";
6189 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6190 (const_string "incdec")
6191 (const_string "alu1")))
6192 (set (attr "memory")
6193 (if_then_else (match_operand 1 "memory_operand" "")
6194 (const_string "load")
6195 (const_string "none")))
6196 (set_attr "mode" "QI")])
6198 (define_insn "*addqi_2"
6199 [(set (reg FLAGS_REG)
6201 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6202 (match_operand:QI 2 "general_operand" "qmni,qni"))
6204 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6205 (plus:QI (match_dup 1) (match_dup 2)))]
6206 "ix86_match_ccmode (insn, CCGOCmode)
6207 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6209 switch (get_attr_type (insn))
6212 if (operands[2] == const1_rtx)
6213 return "inc{b}\t%0";
6216 gcc_assert (operands[2] == constm1_rtx
6217 || (GET_CODE (operands[2]) == CONST_INT
6218 && INTVAL (operands[2]) == 255));
6219 return "dec{b}\t%0";
6223 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6224 if (GET_CODE (operands[2]) == CONST_INT
6225 && INTVAL (operands[2]) < 0)
6227 operands[2] = GEN_INT (-INTVAL (operands[2]));
6228 return "sub{b}\t{%2, %0|%0, %2}";
6230 return "add{b}\t{%2, %0|%0, %2}";
6234 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6235 (const_string "incdec")
6236 (const_string "alu")))
6237 (set_attr "mode" "QI")])
6239 (define_insn "*addqi_3"
6240 [(set (reg FLAGS_REG)
6241 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6242 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6243 (clobber (match_scratch:QI 0 "=q"))]
6244 "ix86_match_ccmode (insn, CCZmode)
6245 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6247 switch (get_attr_type (insn))
6250 if (operands[2] == const1_rtx)
6251 return "inc{b}\t%0";
6254 gcc_assert (operands[2] == constm1_rtx
6255 || (GET_CODE (operands[2]) == CONST_INT
6256 && INTVAL (operands[2]) == 255));
6257 return "dec{b}\t%0";
6261 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6262 if (GET_CODE (operands[2]) == CONST_INT
6263 && INTVAL (operands[2]) < 0)
6265 operands[2] = GEN_INT (-INTVAL (operands[2]));
6266 return "sub{b}\t{%2, %0|%0, %2}";
6268 return "add{b}\t{%2, %0|%0, %2}";
6272 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6273 (const_string "incdec")
6274 (const_string "alu")))
6275 (set_attr "mode" "QI")])
6277 ; See comments above addsi_4 for details.
6278 (define_insn "*addqi_4"
6279 [(set (reg FLAGS_REG)
6280 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6281 (match_operand:QI 2 "const_int_operand" "n")))
6282 (clobber (match_scratch:QI 0 "=qm"))]
6283 "ix86_match_ccmode (insn, CCGCmode)
6284 && (INTVAL (operands[2]) & 0xff) != 0x80"
6286 switch (get_attr_type (insn))
6289 if (operands[2] == constm1_rtx
6290 || (GET_CODE (operands[2]) == CONST_INT
6291 && INTVAL (operands[2]) == 255))
6292 return "inc{b}\t%0";
6295 gcc_assert (operands[2] == const1_rtx);
6296 return "dec{b}\t%0";
6300 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6301 if (INTVAL (operands[2]) < 0)
6303 operands[2] = GEN_INT (-INTVAL (operands[2]));
6304 return "add{b}\t{%2, %0|%0, %2}";
6306 return "sub{b}\t{%2, %0|%0, %2}";
6310 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6311 (const_string "incdec")
6312 (const_string "alu")))
6313 (set_attr "mode" "QI")])
6316 (define_insn "*addqi_5"
6317 [(set (reg FLAGS_REG)
6319 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6320 (match_operand:QI 2 "general_operand" "qmni"))
6322 (clobber (match_scratch:QI 0 "=q"))]
6323 "ix86_match_ccmode (insn, CCGOCmode)
6324 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6326 switch (get_attr_type (insn))
6329 if (operands[2] == const1_rtx)
6330 return "inc{b}\t%0";
6333 gcc_assert (operands[2] == constm1_rtx
6334 || (GET_CODE (operands[2]) == CONST_INT
6335 && INTVAL (operands[2]) == 255));
6336 return "dec{b}\t%0";
6340 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6341 if (GET_CODE (operands[2]) == CONST_INT
6342 && INTVAL (operands[2]) < 0)
6344 operands[2] = GEN_INT (-INTVAL (operands[2]));
6345 return "sub{b}\t{%2, %0|%0, %2}";
6347 return "add{b}\t{%2, %0|%0, %2}";
6351 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6352 (const_string "incdec")
6353 (const_string "alu")))
6354 (set_attr "mode" "QI")])
6357 (define_insn "addqi_ext_1"
6358 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6363 (match_operand 1 "ext_register_operand" "0")
6366 (match_operand:QI 2 "general_operand" "Qmn")))
6367 (clobber (reg:CC FLAGS_REG))]
6370 switch (get_attr_type (insn))
6373 if (operands[2] == const1_rtx)
6374 return "inc{b}\t%h0";
6377 gcc_assert (operands[2] == constm1_rtx
6378 || (GET_CODE (operands[2]) == CONST_INT
6379 && INTVAL (operands[2]) == 255));
6380 return "dec{b}\t%h0";
6384 return "add{b}\t{%2, %h0|%h0, %2}";
6388 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6389 (const_string "incdec")
6390 (const_string "alu")))
6391 (set_attr "mode" "QI")])
6393 (define_insn "*addqi_ext_1_rex64"
6394 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6399 (match_operand 1 "ext_register_operand" "0")
6402 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6403 (clobber (reg:CC FLAGS_REG))]
6406 switch (get_attr_type (insn))
6409 if (operands[2] == const1_rtx)
6410 return "inc{b}\t%h0";
6413 gcc_assert (operands[2] == constm1_rtx
6414 || (GET_CODE (operands[2]) == CONST_INT
6415 && INTVAL (operands[2]) == 255));
6416 return "dec{b}\t%h0";
6420 return "add{b}\t{%2, %h0|%h0, %2}";
6424 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6425 (const_string "incdec")
6426 (const_string "alu")))
6427 (set_attr "mode" "QI")])
6429 (define_insn "*addqi_ext_2"
6430 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6435 (match_operand 1 "ext_register_operand" "%0")
6439 (match_operand 2 "ext_register_operand" "Q")
6442 (clobber (reg:CC FLAGS_REG))]
6444 "add{b}\t{%h2, %h0|%h0, %h2}"
6445 [(set_attr "type" "alu")
6446 (set_attr "mode" "QI")])
6448 ;; The patterns that match these are at the end of this file.
6450 (define_expand "addxf3"
6451 [(set (match_operand:XF 0 "register_operand" "")
6452 (plus:XF (match_operand:XF 1 "register_operand" "")
6453 (match_operand:XF 2 "register_operand" "")))]
6457 (define_expand "adddf3"
6458 [(set (match_operand:DF 0 "register_operand" "")
6459 (plus:DF (match_operand:DF 1 "register_operand" "")
6460 (match_operand:DF 2 "nonimmediate_operand" "")))]
6461 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6464 (define_expand "addsf3"
6465 [(set (match_operand:SF 0 "register_operand" "")
6466 (plus:SF (match_operand:SF 1 "register_operand" "")
6467 (match_operand:SF 2 "nonimmediate_operand" "")))]
6468 "TARGET_80387 || TARGET_SSE_MATH"
6471 ;; Subtract instructions
6473 ;; %%% splits for subditi3
6475 (define_expand "subti3"
6476 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6477 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6478 (match_operand:TI 2 "x86_64_general_operand" "")))
6479 (clobber (reg:CC FLAGS_REG))])]
6481 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6483 (define_insn "*subti3_1"
6484 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6485 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6486 (match_operand:TI 2 "general_operand" "roiF,riF")))
6487 (clobber (reg:CC FLAGS_REG))]
6488 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6492 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6493 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6494 (match_operand:TI 2 "general_operand" "")))
6495 (clobber (reg:CC FLAGS_REG))]
6496 "TARGET_64BIT && reload_completed"
6497 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6498 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6499 (parallel [(set (match_dup 3)
6500 (minus:DI (match_dup 4)
6501 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6503 (clobber (reg:CC FLAGS_REG))])]
6504 "split_ti (operands+0, 1, operands+0, operands+3);
6505 split_ti (operands+1, 1, operands+1, operands+4);
6506 split_ti (operands+2, 1, operands+2, operands+5);")
6508 ;; %%% splits for subsidi3
6510 (define_expand "subdi3"
6511 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6512 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6513 (match_operand:DI 2 "x86_64_general_operand" "")))
6514 (clobber (reg:CC FLAGS_REG))])]
6516 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6518 (define_insn "*subdi3_1"
6519 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6520 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6521 (match_operand:DI 2 "general_operand" "roiF,riF")))
6522 (clobber (reg:CC FLAGS_REG))]
6523 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6527 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6528 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6529 (match_operand:DI 2 "general_operand" "")))
6530 (clobber (reg:CC FLAGS_REG))]
6531 "!TARGET_64BIT && reload_completed"
6532 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6533 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6534 (parallel [(set (match_dup 3)
6535 (minus:SI (match_dup 4)
6536 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6538 (clobber (reg:CC FLAGS_REG))])]
6539 "split_di (operands+0, 1, operands+0, operands+3);
6540 split_di (operands+1, 1, operands+1, operands+4);
6541 split_di (operands+2, 1, operands+2, operands+5);")
6543 (define_insn "subdi3_carry_rex64"
6544 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6545 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6546 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6547 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6548 (clobber (reg:CC FLAGS_REG))]
6549 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6550 "sbb{q}\t{%2, %0|%0, %2}"
6551 [(set_attr "type" "alu")
6552 (set_attr "pent_pair" "pu")
6553 (set_attr "mode" "DI")])
6555 (define_insn "*subdi_1_rex64"
6556 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6557 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6558 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6559 (clobber (reg:CC FLAGS_REG))]
6560 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6561 "sub{q}\t{%2, %0|%0, %2}"
6562 [(set_attr "type" "alu")
6563 (set_attr "mode" "DI")])
6565 (define_insn "*subdi_2_rex64"
6566 [(set (reg FLAGS_REG)
6568 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6569 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6571 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6572 (minus:DI (match_dup 1) (match_dup 2)))]
6573 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6574 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6575 "sub{q}\t{%2, %0|%0, %2}"
6576 [(set_attr "type" "alu")
6577 (set_attr "mode" "DI")])
6579 (define_insn "*subdi_3_rex63"
6580 [(set (reg FLAGS_REG)
6581 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6582 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6583 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6584 (minus:DI (match_dup 1) (match_dup 2)))]
6585 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6586 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6587 "sub{q}\t{%2, %0|%0, %2}"
6588 [(set_attr "type" "alu")
6589 (set_attr "mode" "DI")])
6591 (define_insn "subqi3_carry"
6592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6593 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6594 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6595 (match_operand:QI 2 "general_operand" "qi,qm"))))
6596 (clobber (reg:CC FLAGS_REG))]
6597 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6598 "sbb{b}\t{%2, %0|%0, %2}"
6599 [(set_attr "type" "alu")
6600 (set_attr "pent_pair" "pu")
6601 (set_attr "mode" "QI")])
6603 (define_insn "subhi3_carry"
6604 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6605 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6606 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6607 (match_operand:HI 2 "general_operand" "ri,rm"))))
6608 (clobber (reg:CC FLAGS_REG))]
6609 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6610 "sbb{w}\t{%2, %0|%0, %2}"
6611 [(set_attr "type" "alu")
6612 (set_attr "pent_pair" "pu")
6613 (set_attr "mode" "HI")])
6615 (define_insn "subsi3_carry"
6616 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6617 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6618 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6619 (match_operand:SI 2 "general_operand" "ri,rm"))))
6620 (clobber (reg:CC FLAGS_REG))]
6621 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6622 "sbb{l}\t{%2, %0|%0, %2}"
6623 [(set_attr "type" "alu")
6624 (set_attr "pent_pair" "pu")
6625 (set_attr "mode" "SI")])
6627 (define_insn "subsi3_carry_zext"
6628 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6630 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6631 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6632 (match_operand:SI 2 "general_operand" "ri,rm")))))
6633 (clobber (reg:CC FLAGS_REG))]
6634 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6635 "sbb{l}\t{%2, %k0|%k0, %2}"
6636 [(set_attr "type" "alu")
6637 (set_attr "pent_pair" "pu")
6638 (set_attr "mode" "SI")])
6640 (define_expand "subsi3"
6641 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6642 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6643 (match_operand:SI 2 "general_operand" "")))
6644 (clobber (reg:CC FLAGS_REG))])]
6646 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6648 (define_insn "*subsi_1"
6649 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6650 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6651 (match_operand:SI 2 "general_operand" "ri,rm")))
6652 (clobber (reg:CC FLAGS_REG))]
6653 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6654 "sub{l}\t{%2, %0|%0, %2}"
6655 [(set_attr "type" "alu")
6656 (set_attr "mode" "SI")])
6658 (define_insn "*subsi_1_zext"
6659 [(set (match_operand:DI 0 "register_operand" "=r")
6661 (minus:SI (match_operand:SI 1 "register_operand" "0")
6662 (match_operand:SI 2 "general_operand" "rim"))))
6663 (clobber (reg:CC FLAGS_REG))]
6664 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6665 "sub{l}\t{%2, %k0|%k0, %2}"
6666 [(set_attr "type" "alu")
6667 (set_attr "mode" "SI")])
6669 (define_insn "*subsi_2"
6670 [(set (reg FLAGS_REG)
6672 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673 (match_operand:SI 2 "general_operand" "ri,rm"))
6675 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6676 (minus:SI (match_dup 1) (match_dup 2)))]
6677 "ix86_match_ccmode (insn, CCGOCmode)
6678 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6679 "sub{l}\t{%2, %0|%0, %2}"
6680 [(set_attr "type" "alu")
6681 (set_attr "mode" "SI")])
6683 (define_insn "*subsi_2_zext"
6684 [(set (reg FLAGS_REG)
6686 (minus:SI (match_operand:SI 1 "register_operand" "0")
6687 (match_operand:SI 2 "general_operand" "rim"))
6689 (set (match_operand:DI 0 "register_operand" "=r")
6691 (minus:SI (match_dup 1)
6693 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6694 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6695 "sub{l}\t{%2, %k0|%k0, %2}"
6696 [(set_attr "type" "alu")
6697 (set_attr "mode" "SI")])
6699 (define_insn "*subsi_3"
6700 [(set (reg FLAGS_REG)
6701 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6702 (match_operand:SI 2 "general_operand" "ri,rm")))
6703 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6704 (minus:SI (match_dup 1) (match_dup 2)))]
6705 "ix86_match_ccmode (insn, CCmode)
6706 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6707 "sub{l}\t{%2, %0|%0, %2}"
6708 [(set_attr "type" "alu")
6709 (set_attr "mode" "SI")])
6711 (define_insn "*subsi_3_zext"
6712 [(set (reg FLAGS_REG)
6713 (compare (match_operand:SI 1 "register_operand" "0")
6714 (match_operand:SI 2 "general_operand" "rim")))
6715 (set (match_operand:DI 0 "register_operand" "=r")
6717 (minus:SI (match_dup 1)
6719 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6720 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6721 "sub{q}\t{%2, %0|%0, %2}"
6722 [(set_attr "type" "alu")
6723 (set_attr "mode" "DI")])
6725 (define_expand "subhi3"
6726 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6727 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6728 (match_operand:HI 2 "general_operand" "")))
6729 (clobber (reg:CC FLAGS_REG))])]
6730 "TARGET_HIMODE_MATH"
6731 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6733 (define_insn "*subhi_1"
6734 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6735 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6736 (match_operand:HI 2 "general_operand" "ri,rm")))
6737 (clobber (reg:CC FLAGS_REG))]
6738 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6739 "sub{w}\t{%2, %0|%0, %2}"
6740 [(set_attr "type" "alu")
6741 (set_attr "mode" "HI")])
6743 (define_insn "*subhi_2"
6744 [(set (reg FLAGS_REG)
6746 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6747 (match_operand:HI 2 "general_operand" "ri,rm"))
6749 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6750 (minus:HI (match_dup 1) (match_dup 2)))]
6751 "ix86_match_ccmode (insn, CCGOCmode)
6752 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6753 "sub{w}\t{%2, %0|%0, %2}"
6754 [(set_attr "type" "alu")
6755 (set_attr "mode" "HI")])
6757 (define_insn "*subhi_3"
6758 [(set (reg FLAGS_REG)
6759 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6760 (match_operand:HI 2 "general_operand" "ri,rm")))
6761 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6762 (minus:HI (match_dup 1) (match_dup 2)))]
6763 "ix86_match_ccmode (insn, CCmode)
6764 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6765 "sub{w}\t{%2, %0|%0, %2}"
6766 [(set_attr "type" "alu")
6767 (set_attr "mode" "HI")])
6769 (define_expand "subqi3"
6770 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6771 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6772 (match_operand:QI 2 "general_operand" "")))
6773 (clobber (reg:CC FLAGS_REG))])]
6774 "TARGET_QIMODE_MATH"
6775 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6777 (define_insn "*subqi_1"
6778 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6779 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6780 (match_operand:QI 2 "general_operand" "qn,qmn")))
6781 (clobber (reg:CC FLAGS_REG))]
6782 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6783 "sub{b}\t{%2, %0|%0, %2}"
6784 [(set_attr "type" "alu")
6785 (set_attr "mode" "QI")])
6787 (define_insn "*subqi_1_slp"
6788 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6789 (minus:QI (match_dup 0)
6790 (match_operand:QI 1 "general_operand" "qn,qmn")))
6791 (clobber (reg:CC FLAGS_REG))]
6792 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6793 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6794 "sub{b}\t{%1, %0|%0, %1}"
6795 [(set_attr "type" "alu1")
6796 (set_attr "mode" "QI")])
6798 (define_insn "*subqi_2"
6799 [(set (reg FLAGS_REG)
6801 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6802 (match_operand:QI 2 "general_operand" "qi,qm"))
6804 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6805 (minus:HI (match_dup 1) (match_dup 2)))]
6806 "ix86_match_ccmode (insn, CCGOCmode)
6807 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6808 "sub{b}\t{%2, %0|%0, %2}"
6809 [(set_attr "type" "alu")
6810 (set_attr "mode" "QI")])
6812 (define_insn "*subqi_3"
6813 [(set (reg FLAGS_REG)
6814 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6815 (match_operand:QI 2 "general_operand" "qi,qm")))
6816 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6817 (minus:HI (match_dup 1) (match_dup 2)))]
6818 "ix86_match_ccmode (insn, CCmode)
6819 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6820 "sub{b}\t{%2, %0|%0, %2}"
6821 [(set_attr "type" "alu")
6822 (set_attr "mode" "QI")])
6824 ;; The patterns that match these are at the end of this file.
6826 (define_expand "subxf3"
6827 [(set (match_operand:XF 0 "register_operand" "")
6828 (minus:XF (match_operand:XF 1 "register_operand" "")
6829 (match_operand:XF 2 "register_operand" "")))]
6833 (define_expand "subdf3"
6834 [(set (match_operand:DF 0 "register_operand" "")
6835 (minus:DF (match_operand:DF 1 "register_operand" "")
6836 (match_operand:DF 2 "nonimmediate_operand" "")))]
6837 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6840 (define_expand "subsf3"
6841 [(set (match_operand:SF 0 "register_operand" "")
6842 (minus:SF (match_operand:SF 1 "register_operand" "")
6843 (match_operand:SF 2 "nonimmediate_operand" "")))]
6844 "TARGET_80387 || TARGET_SSE_MATH"
6847 ;; Multiply instructions
6849 (define_expand "muldi3"
6850 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6851 (mult:DI (match_operand:DI 1 "register_operand" "")
6852 (match_operand:DI 2 "x86_64_general_operand" "")))
6853 (clobber (reg:CC FLAGS_REG))])]
6857 (define_insn "*muldi3_1_rex64"
6858 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6859 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6860 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6861 (clobber (reg:CC FLAGS_REG))]
6863 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6865 imul{q}\t{%2, %1, %0|%0, %1, %2}
6866 imul{q}\t{%2, %1, %0|%0, %1, %2}
6867 imul{q}\t{%2, %0|%0, %2}"
6868 [(set_attr "type" "imul")
6869 (set_attr "prefix_0f" "0,0,1")
6870 (set (attr "athlon_decode")
6871 (cond [(eq_attr "cpu" "athlon")
6872 (const_string "vector")
6873 (eq_attr "alternative" "1")
6874 (const_string "vector")
6875 (and (eq_attr "alternative" "2")
6876 (match_operand 1 "memory_operand" ""))
6877 (const_string "vector")]
6878 (const_string "direct")))
6879 (set_attr "mode" "DI")])
6881 (define_expand "mulsi3"
6882 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6883 (mult:SI (match_operand:SI 1 "register_operand" "")
6884 (match_operand:SI 2 "general_operand" "")))
6885 (clobber (reg:CC FLAGS_REG))])]
6889 (define_insn "*mulsi3_1"
6890 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6891 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6892 (match_operand:SI 2 "general_operand" "K,i,mr")))
6893 (clobber (reg:CC FLAGS_REG))]
6894 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6896 imul{l}\t{%2, %1, %0|%0, %1, %2}
6897 imul{l}\t{%2, %1, %0|%0, %1, %2}
6898 imul{l}\t{%2, %0|%0, %2}"
6899 [(set_attr "type" "imul")
6900 (set_attr "prefix_0f" "0,0,1")
6901 (set (attr "athlon_decode")
6902 (cond [(eq_attr "cpu" "athlon")
6903 (const_string "vector")
6904 (eq_attr "alternative" "1")
6905 (const_string "vector")
6906 (and (eq_attr "alternative" "2")
6907 (match_operand 1 "memory_operand" ""))
6908 (const_string "vector")]
6909 (const_string "direct")))
6910 (set_attr "mode" "SI")])
6912 (define_insn "*mulsi3_1_zext"
6913 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6915 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6916 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6917 (clobber (reg:CC FLAGS_REG))]
6919 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6921 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6922 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6923 imul{l}\t{%2, %k0|%k0, %2}"
6924 [(set_attr "type" "imul")
6925 (set_attr "prefix_0f" "0,0,1")
6926 (set (attr "athlon_decode")
6927 (cond [(eq_attr "cpu" "athlon")
6928 (const_string "vector")
6929 (eq_attr "alternative" "1")
6930 (const_string "vector")
6931 (and (eq_attr "alternative" "2")
6932 (match_operand 1 "memory_operand" ""))
6933 (const_string "vector")]
6934 (const_string "direct")))
6935 (set_attr "mode" "SI")])
6937 (define_expand "mulhi3"
6938 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6939 (mult:HI (match_operand:HI 1 "register_operand" "")
6940 (match_operand:HI 2 "general_operand" "")))
6941 (clobber (reg:CC FLAGS_REG))])]
6942 "TARGET_HIMODE_MATH"
6945 (define_insn "*mulhi3_1"
6946 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6947 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6948 (match_operand:HI 2 "general_operand" "K,i,mr")))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6952 imul{w}\t{%2, %1, %0|%0, %1, %2}
6953 imul{w}\t{%2, %1, %0|%0, %1, %2}
6954 imul{w}\t{%2, %0|%0, %2}"
6955 [(set_attr "type" "imul")
6956 (set_attr "prefix_0f" "0,0,1")
6957 (set (attr "athlon_decode")
6958 (cond [(eq_attr "cpu" "athlon")
6959 (const_string "vector")
6960 (eq_attr "alternative" "1,2")
6961 (const_string "vector")]
6962 (const_string "direct")))
6963 (set_attr "mode" "HI")])
6965 (define_expand "mulqi3"
6966 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6967 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6968 (match_operand:QI 2 "register_operand" "")))
6969 (clobber (reg:CC FLAGS_REG))])]
6970 "TARGET_QIMODE_MATH"
6973 (define_insn "*mulqi3_1"
6974 [(set (match_operand:QI 0 "register_operand" "=a")
6975 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6976 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6977 (clobber (reg:CC FLAGS_REG))]
6979 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6981 [(set_attr "type" "imul")
6982 (set_attr "length_immediate" "0")
6983 (set (attr "athlon_decode")
6984 (if_then_else (eq_attr "cpu" "athlon")
6985 (const_string "vector")
6986 (const_string "direct")))
6987 (set_attr "mode" "QI")])
6989 (define_expand "umulqihi3"
6990 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6991 (mult:HI (zero_extend:HI
6992 (match_operand:QI 1 "nonimmediate_operand" ""))
6994 (match_operand:QI 2 "register_operand" ""))))
6995 (clobber (reg:CC FLAGS_REG))])]
6996 "TARGET_QIMODE_MATH"
6999 (define_insn "*umulqihi3_1"
7000 [(set (match_operand:HI 0 "register_operand" "=a")
7001 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7002 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7003 (clobber (reg:CC FLAGS_REG))]
7005 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7007 [(set_attr "type" "imul")
7008 (set_attr "length_immediate" "0")
7009 (set (attr "athlon_decode")
7010 (if_then_else (eq_attr "cpu" "athlon")
7011 (const_string "vector")
7012 (const_string "direct")))
7013 (set_attr "mode" "QI")])
7015 (define_expand "mulqihi3"
7016 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7017 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7018 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7019 (clobber (reg:CC FLAGS_REG))])]
7020 "TARGET_QIMODE_MATH"
7023 (define_insn "*mulqihi3_insn"
7024 [(set (match_operand:HI 0 "register_operand" "=a")
7025 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7026 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7027 (clobber (reg:CC FLAGS_REG))]
7029 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7031 [(set_attr "type" "imul")
7032 (set_attr "length_immediate" "0")
7033 (set (attr "athlon_decode")
7034 (if_then_else (eq_attr "cpu" "athlon")
7035 (const_string "vector")
7036 (const_string "direct")))
7037 (set_attr "mode" "QI")])
7039 (define_expand "umulditi3"
7040 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7041 (mult:TI (zero_extend:TI
7042 (match_operand:DI 1 "nonimmediate_operand" ""))
7044 (match_operand:DI 2 "register_operand" ""))))
7045 (clobber (reg:CC FLAGS_REG))])]
7049 (define_insn "*umulditi3_insn"
7050 [(set (match_operand:TI 0 "register_operand" "=A")
7051 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7052 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7053 (clobber (reg:CC FLAGS_REG))]
7055 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7057 [(set_attr "type" "imul")
7058 (set_attr "length_immediate" "0")
7059 (set (attr "athlon_decode")
7060 (if_then_else (eq_attr "cpu" "athlon")
7061 (const_string "vector")
7062 (const_string "double")))
7063 (set_attr "mode" "DI")])
7065 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7066 (define_expand "umulsidi3"
7067 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7068 (mult:DI (zero_extend:DI
7069 (match_operand:SI 1 "nonimmediate_operand" ""))
7071 (match_operand:SI 2 "register_operand" ""))))
7072 (clobber (reg:CC FLAGS_REG))])]
7076 (define_insn "*umulsidi3_insn"
7077 [(set (match_operand:DI 0 "register_operand" "=A")
7078 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7079 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7080 (clobber (reg:CC FLAGS_REG))]
7082 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7084 [(set_attr "type" "imul")
7085 (set_attr "length_immediate" "0")
7086 (set (attr "athlon_decode")
7087 (if_then_else (eq_attr "cpu" "athlon")
7088 (const_string "vector")
7089 (const_string "double")))
7090 (set_attr "mode" "SI")])
7092 (define_expand "mulditi3"
7093 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7094 (mult:TI (sign_extend:TI
7095 (match_operand:DI 1 "nonimmediate_operand" ""))
7097 (match_operand:DI 2 "register_operand" ""))))
7098 (clobber (reg:CC FLAGS_REG))])]
7102 (define_insn "*mulditi3_insn"
7103 [(set (match_operand:TI 0 "register_operand" "=A")
7104 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7105 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7106 (clobber (reg:CC FLAGS_REG))]
7108 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7110 [(set_attr "type" "imul")
7111 (set_attr "length_immediate" "0")
7112 (set (attr "athlon_decode")
7113 (if_then_else (eq_attr "cpu" "athlon")
7114 (const_string "vector")
7115 (const_string "double")))
7116 (set_attr "mode" "DI")])
7118 (define_expand "mulsidi3"
7119 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7120 (mult:DI (sign_extend:DI
7121 (match_operand:SI 1 "nonimmediate_operand" ""))
7123 (match_operand:SI 2 "register_operand" ""))))
7124 (clobber (reg:CC FLAGS_REG))])]
7128 (define_insn "*mulsidi3_insn"
7129 [(set (match_operand:DI 0 "register_operand" "=A")
7130 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7131 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7132 (clobber (reg:CC FLAGS_REG))]
7134 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7136 [(set_attr "type" "imul")
7137 (set_attr "length_immediate" "0")
7138 (set (attr "athlon_decode")
7139 (if_then_else (eq_attr "cpu" "athlon")
7140 (const_string "vector")
7141 (const_string "double")))
7142 (set_attr "mode" "SI")])
7144 (define_expand "umuldi3_highpart"
7145 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7148 (mult:TI (zero_extend:TI
7149 (match_operand:DI 1 "nonimmediate_operand" ""))
7151 (match_operand:DI 2 "register_operand" "")))
7153 (clobber (match_scratch:DI 3 ""))
7154 (clobber (reg:CC FLAGS_REG))])]
7158 (define_insn "*umuldi3_highpart_rex64"
7159 [(set (match_operand:DI 0 "register_operand" "=d")
7162 (mult:TI (zero_extend:TI
7163 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7165 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7167 (clobber (match_scratch:DI 3 "=1"))
7168 (clobber (reg:CC FLAGS_REG))]
7170 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7172 [(set_attr "type" "imul")
7173 (set_attr "length_immediate" "0")
7174 (set (attr "athlon_decode")
7175 (if_then_else (eq_attr "cpu" "athlon")
7176 (const_string "vector")
7177 (const_string "double")))
7178 (set_attr "mode" "DI")])
7180 (define_expand "umulsi3_highpart"
7181 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7184 (mult:DI (zero_extend:DI
7185 (match_operand:SI 1 "nonimmediate_operand" ""))
7187 (match_operand:SI 2 "register_operand" "")))
7189 (clobber (match_scratch:SI 3 ""))
7190 (clobber (reg:CC FLAGS_REG))])]
7194 (define_insn "*umulsi3_highpart_insn"
7195 [(set (match_operand:SI 0 "register_operand" "=d")
7198 (mult:DI (zero_extend:DI
7199 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7201 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7203 (clobber (match_scratch:SI 3 "=1"))
7204 (clobber (reg:CC FLAGS_REG))]
7205 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7207 [(set_attr "type" "imul")
7208 (set_attr "length_immediate" "0")
7209 (set (attr "athlon_decode")
7210 (if_then_else (eq_attr "cpu" "athlon")
7211 (const_string "vector")
7212 (const_string "double")))
7213 (set_attr "mode" "SI")])
7215 (define_insn "*umulsi3_highpart_zext"
7216 [(set (match_operand:DI 0 "register_operand" "=d")
7217 (zero_extend:DI (truncate:SI
7219 (mult:DI (zero_extend:DI
7220 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7222 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7224 (clobber (match_scratch:SI 3 "=1"))
7225 (clobber (reg:CC FLAGS_REG))]
7227 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7229 [(set_attr "type" "imul")
7230 (set_attr "length_immediate" "0")
7231 (set (attr "athlon_decode")
7232 (if_then_else (eq_attr "cpu" "athlon")
7233 (const_string "vector")
7234 (const_string "double")))
7235 (set_attr "mode" "SI")])
7237 (define_expand "smuldi3_highpart"
7238 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7241 (mult:TI (sign_extend:TI
7242 (match_operand:DI 1 "nonimmediate_operand" ""))
7244 (match_operand:DI 2 "register_operand" "")))
7246 (clobber (match_scratch:DI 3 ""))
7247 (clobber (reg:CC FLAGS_REG))])]
7251 (define_insn "*smuldi3_highpart_rex64"
7252 [(set (match_operand:DI 0 "register_operand" "=d")
7255 (mult:TI (sign_extend:TI
7256 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7258 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7260 (clobber (match_scratch:DI 3 "=1"))
7261 (clobber (reg:CC FLAGS_REG))]
7263 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7265 [(set_attr "type" "imul")
7266 (set (attr "athlon_decode")
7267 (if_then_else (eq_attr "cpu" "athlon")
7268 (const_string "vector")
7269 (const_string "double")))
7270 (set_attr "mode" "DI")])
7272 (define_expand "smulsi3_highpart"
7273 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7276 (mult:DI (sign_extend:DI
7277 (match_operand:SI 1 "nonimmediate_operand" ""))
7279 (match_operand:SI 2 "register_operand" "")))
7281 (clobber (match_scratch:SI 3 ""))
7282 (clobber (reg:CC FLAGS_REG))])]
7286 (define_insn "*smulsi3_highpart_insn"
7287 [(set (match_operand:SI 0 "register_operand" "=d")
7290 (mult:DI (sign_extend:DI
7291 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7293 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7295 (clobber (match_scratch:SI 3 "=1"))
7296 (clobber (reg:CC FLAGS_REG))]
7297 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7299 [(set_attr "type" "imul")
7300 (set (attr "athlon_decode")
7301 (if_then_else (eq_attr "cpu" "athlon")
7302 (const_string "vector")
7303 (const_string "double")))
7304 (set_attr "mode" "SI")])
7306 (define_insn "*smulsi3_highpart_zext"
7307 [(set (match_operand:DI 0 "register_operand" "=d")
7308 (zero_extend:DI (truncate:SI
7310 (mult:DI (sign_extend:DI
7311 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7313 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7315 (clobber (match_scratch:SI 3 "=1"))
7316 (clobber (reg:CC FLAGS_REG))]
7318 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7320 [(set_attr "type" "imul")
7321 (set (attr "athlon_decode")
7322 (if_then_else (eq_attr "cpu" "athlon")
7323 (const_string "vector")
7324 (const_string "double")))
7325 (set_attr "mode" "SI")])
7327 ;; The patterns that match these are at the end of this file.
7329 (define_expand "mulxf3"
7330 [(set (match_operand:XF 0 "register_operand" "")
7331 (mult:XF (match_operand:XF 1 "register_operand" "")
7332 (match_operand:XF 2 "register_operand" "")))]
7336 (define_expand "muldf3"
7337 [(set (match_operand:DF 0 "register_operand" "")
7338 (mult:DF (match_operand:DF 1 "register_operand" "")
7339 (match_operand:DF 2 "nonimmediate_operand" "")))]
7340 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7343 (define_expand "mulsf3"
7344 [(set (match_operand:SF 0 "register_operand" "")
7345 (mult:SF (match_operand:SF 1 "register_operand" "")
7346 (match_operand:SF 2 "nonimmediate_operand" "")))]
7347 "TARGET_80387 || TARGET_SSE_MATH"
7350 ;; Divide instructions
7352 (define_insn "divqi3"
7353 [(set (match_operand:QI 0 "register_operand" "=a")
7354 (div:QI (match_operand:HI 1 "register_operand" "0")
7355 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7356 (clobber (reg:CC FLAGS_REG))]
7357 "TARGET_QIMODE_MATH"
7359 [(set_attr "type" "idiv")
7360 (set_attr "mode" "QI")])
7362 (define_insn "udivqi3"
7363 [(set (match_operand:QI 0 "register_operand" "=a")
7364 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7365 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7366 (clobber (reg:CC FLAGS_REG))]
7367 "TARGET_QIMODE_MATH"
7369 [(set_attr "type" "idiv")
7370 (set_attr "mode" "QI")])
7372 ;; The patterns that match these are at the end of this file.
7374 (define_expand "divxf3"
7375 [(set (match_operand:XF 0 "register_operand" "")
7376 (div:XF (match_operand:XF 1 "register_operand" "")
7377 (match_operand:XF 2 "register_operand" "")))]
7381 (define_expand "divdf3"
7382 [(set (match_operand:DF 0 "register_operand" "")
7383 (div:DF (match_operand:DF 1 "register_operand" "")
7384 (match_operand:DF 2 "nonimmediate_operand" "")))]
7385 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7388 (define_expand "divsf3"
7389 [(set (match_operand:SF 0 "register_operand" "")
7390 (div:SF (match_operand:SF 1 "register_operand" "")
7391 (match_operand:SF 2 "nonimmediate_operand" "")))]
7392 "TARGET_80387 || TARGET_SSE_MATH"
7395 ;; Remainder instructions.
7397 (define_expand "divmoddi4"
7398 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7399 (div:DI (match_operand:DI 1 "register_operand" "")
7400 (match_operand:DI 2 "nonimmediate_operand" "")))
7401 (set (match_operand:DI 3 "register_operand" "")
7402 (mod:DI (match_dup 1) (match_dup 2)))
7403 (clobber (reg:CC FLAGS_REG))])]
7407 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7408 ;; Penalize eax case slightly because it results in worse scheduling
7410 (define_insn "*divmoddi4_nocltd_rex64"
7411 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7412 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7413 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7414 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7415 (mod:DI (match_dup 2) (match_dup 3)))
7416 (clobber (reg:CC FLAGS_REG))]
7417 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7419 [(set_attr "type" "multi")])
7421 (define_insn "*divmoddi4_cltd_rex64"
7422 [(set (match_operand:DI 0 "register_operand" "=a")
7423 (div:DI (match_operand:DI 2 "register_operand" "a")
7424 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7425 (set (match_operand:DI 1 "register_operand" "=&d")
7426 (mod:DI (match_dup 2) (match_dup 3)))
7427 (clobber (reg:CC FLAGS_REG))]
7428 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7430 [(set_attr "type" "multi")])
7432 (define_insn "*divmoddi_noext_rex64"
7433 [(set (match_operand:DI 0 "register_operand" "=a")
7434 (div:DI (match_operand:DI 1 "register_operand" "0")
7435 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7436 (set (match_operand:DI 3 "register_operand" "=d")
7437 (mod:DI (match_dup 1) (match_dup 2)))
7438 (use (match_operand:DI 4 "register_operand" "3"))
7439 (clobber (reg:CC FLAGS_REG))]
7442 [(set_attr "type" "idiv")
7443 (set_attr "mode" "DI")])
7446 [(set (match_operand:DI 0 "register_operand" "")
7447 (div:DI (match_operand:DI 1 "register_operand" "")
7448 (match_operand:DI 2 "nonimmediate_operand" "")))
7449 (set (match_operand:DI 3 "register_operand" "")
7450 (mod:DI (match_dup 1) (match_dup 2)))
7451 (clobber (reg:CC FLAGS_REG))]
7452 "TARGET_64BIT && reload_completed"
7453 [(parallel [(set (match_dup 3)
7454 (ashiftrt:DI (match_dup 4) (const_int 63)))
7455 (clobber (reg:CC FLAGS_REG))])
7456 (parallel [(set (match_dup 0)
7457 (div:DI (reg:DI 0) (match_dup 2)))
7459 (mod:DI (reg:DI 0) (match_dup 2)))
7461 (clobber (reg:CC FLAGS_REG))])]
7463 /* Avoid use of cltd in favor of a mov+shift. */
7464 if (!TARGET_USE_CLTD && !optimize_size)
7466 if (true_regnum (operands[1]))
7467 emit_move_insn (operands[0], operands[1]);
7469 emit_move_insn (operands[3], operands[1]);
7470 operands[4] = operands[3];
7474 gcc_assert (!true_regnum (operands[1]));
7475 operands[4] = operands[1];
7480 (define_expand "divmodsi4"
7481 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7482 (div:SI (match_operand:SI 1 "register_operand" "")
7483 (match_operand:SI 2 "nonimmediate_operand" "")))
7484 (set (match_operand:SI 3 "register_operand" "")
7485 (mod:SI (match_dup 1) (match_dup 2)))
7486 (clobber (reg:CC FLAGS_REG))])]
7490 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7491 ;; Penalize eax case slightly because it results in worse scheduling
7493 (define_insn "*divmodsi4_nocltd"
7494 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7495 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7496 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7497 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7498 (mod:SI (match_dup 2) (match_dup 3)))
7499 (clobber (reg:CC FLAGS_REG))]
7500 "!optimize_size && !TARGET_USE_CLTD"
7502 [(set_attr "type" "multi")])
7504 (define_insn "*divmodsi4_cltd"
7505 [(set (match_operand:SI 0 "register_operand" "=a")
7506 (div:SI (match_operand:SI 2 "register_operand" "a")
7507 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7508 (set (match_operand:SI 1 "register_operand" "=&d")
7509 (mod:SI (match_dup 2) (match_dup 3)))
7510 (clobber (reg:CC FLAGS_REG))]
7511 "optimize_size || TARGET_USE_CLTD"
7513 [(set_attr "type" "multi")])
7515 (define_insn "*divmodsi_noext"
7516 [(set (match_operand:SI 0 "register_operand" "=a")
7517 (div:SI (match_operand:SI 1 "register_operand" "0")
7518 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7519 (set (match_operand:SI 3 "register_operand" "=d")
7520 (mod:SI (match_dup 1) (match_dup 2)))
7521 (use (match_operand:SI 4 "register_operand" "3"))
7522 (clobber (reg:CC FLAGS_REG))]
7525 [(set_attr "type" "idiv")
7526 (set_attr "mode" "SI")])
7529 [(set (match_operand:SI 0 "register_operand" "")
7530 (div:SI (match_operand:SI 1 "register_operand" "")
7531 (match_operand:SI 2 "nonimmediate_operand" "")))
7532 (set (match_operand:SI 3 "register_operand" "")
7533 (mod:SI (match_dup 1) (match_dup 2)))
7534 (clobber (reg:CC FLAGS_REG))]
7536 [(parallel [(set (match_dup 3)
7537 (ashiftrt:SI (match_dup 4) (const_int 31)))
7538 (clobber (reg:CC FLAGS_REG))])
7539 (parallel [(set (match_dup 0)
7540 (div:SI (reg:SI 0) (match_dup 2)))
7542 (mod:SI (reg:SI 0) (match_dup 2)))
7544 (clobber (reg:CC FLAGS_REG))])]
7546 /* Avoid use of cltd in favor of a mov+shift. */
7547 if (!TARGET_USE_CLTD && !optimize_size)
7549 if (true_regnum (operands[1]))
7550 emit_move_insn (operands[0], operands[1]);
7552 emit_move_insn (operands[3], operands[1]);
7553 operands[4] = operands[3];
7557 gcc_assert (!true_regnum (operands[1]));
7558 operands[4] = operands[1];
7562 (define_insn "divmodhi4"
7563 [(set (match_operand:HI 0 "register_operand" "=a")
7564 (div:HI (match_operand:HI 1 "register_operand" "0")
7565 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7566 (set (match_operand:HI 3 "register_operand" "=&d")
7567 (mod:HI (match_dup 1) (match_dup 2)))
7568 (clobber (reg:CC FLAGS_REG))]
7569 "TARGET_HIMODE_MATH"
7571 [(set_attr "type" "multi")
7572 (set_attr "length_immediate" "0")
7573 (set_attr "mode" "SI")])
7575 (define_insn "udivmoddi4"
7576 [(set (match_operand:DI 0 "register_operand" "=a")
7577 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7578 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7579 (set (match_operand:DI 3 "register_operand" "=&d")
7580 (umod:DI (match_dup 1) (match_dup 2)))
7581 (clobber (reg:CC FLAGS_REG))]
7583 "xor{q}\t%3, %3\;div{q}\t%2"
7584 [(set_attr "type" "multi")
7585 (set_attr "length_immediate" "0")
7586 (set_attr "mode" "DI")])
7588 (define_insn "*udivmoddi4_noext"
7589 [(set (match_operand:DI 0 "register_operand" "=a")
7590 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7591 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7592 (set (match_operand:DI 3 "register_operand" "=d")
7593 (umod:DI (match_dup 1) (match_dup 2)))
7595 (clobber (reg:CC FLAGS_REG))]
7598 [(set_attr "type" "idiv")
7599 (set_attr "mode" "DI")])
7602 [(set (match_operand:DI 0 "register_operand" "")
7603 (udiv:DI (match_operand:DI 1 "register_operand" "")
7604 (match_operand:DI 2 "nonimmediate_operand" "")))
7605 (set (match_operand:DI 3 "register_operand" "")
7606 (umod:DI (match_dup 1) (match_dup 2)))
7607 (clobber (reg:CC FLAGS_REG))]
7608 "TARGET_64BIT && reload_completed"
7609 [(set (match_dup 3) (const_int 0))
7610 (parallel [(set (match_dup 0)
7611 (udiv:DI (match_dup 1) (match_dup 2)))
7613 (umod:DI (match_dup 1) (match_dup 2)))
7615 (clobber (reg:CC FLAGS_REG))])]
7618 (define_insn "udivmodsi4"
7619 [(set (match_operand:SI 0 "register_operand" "=a")
7620 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7621 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7622 (set (match_operand:SI 3 "register_operand" "=&d")
7623 (umod:SI (match_dup 1) (match_dup 2)))
7624 (clobber (reg:CC FLAGS_REG))]
7626 "xor{l}\t%3, %3\;div{l}\t%2"
7627 [(set_attr "type" "multi")
7628 (set_attr "length_immediate" "0")
7629 (set_attr "mode" "SI")])
7631 (define_insn "*udivmodsi4_noext"
7632 [(set (match_operand:SI 0 "register_operand" "=a")
7633 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7634 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7635 (set (match_operand:SI 3 "register_operand" "=d")
7636 (umod:SI (match_dup 1) (match_dup 2)))
7638 (clobber (reg:CC FLAGS_REG))]
7641 [(set_attr "type" "idiv")
7642 (set_attr "mode" "SI")])
7645 [(set (match_operand:SI 0 "register_operand" "")
7646 (udiv:SI (match_operand:SI 1 "register_operand" "")
7647 (match_operand:SI 2 "nonimmediate_operand" "")))
7648 (set (match_operand:SI 3 "register_operand" "")
7649 (umod:SI (match_dup 1) (match_dup 2)))
7650 (clobber (reg:CC FLAGS_REG))]
7652 [(set (match_dup 3) (const_int 0))
7653 (parallel [(set (match_dup 0)
7654 (udiv:SI (match_dup 1) (match_dup 2)))
7656 (umod:SI (match_dup 1) (match_dup 2)))
7658 (clobber (reg:CC FLAGS_REG))])]
7661 (define_expand "udivmodhi4"
7662 [(set (match_dup 4) (const_int 0))
7663 (parallel [(set (match_operand:HI 0 "register_operand" "")
7664 (udiv:HI (match_operand:HI 1 "register_operand" "")
7665 (match_operand:HI 2 "nonimmediate_operand" "")))
7666 (set (match_operand:HI 3 "register_operand" "")
7667 (umod:HI (match_dup 1) (match_dup 2)))
7669 (clobber (reg:CC FLAGS_REG))])]
7670 "TARGET_HIMODE_MATH"
7671 "operands[4] = gen_reg_rtx (HImode);")
7673 (define_insn "*udivmodhi_noext"
7674 [(set (match_operand:HI 0 "register_operand" "=a")
7675 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7676 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7677 (set (match_operand:HI 3 "register_operand" "=d")
7678 (umod:HI (match_dup 1) (match_dup 2)))
7679 (use (match_operand:HI 4 "register_operand" "3"))
7680 (clobber (reg:CC FLAGS_REG))]
7683 [(set_attr "type" "idiv")
7684 (set_attr "mode" "HI")])
7686 ;; We cannot use div/idiv for double division, because it causes
7687 ;; "division by zero" on the overflow and that's not what we expect
7688 ;; from truncate. Because true (non truncating) double division is
7689 ;; never generated, we can't create this insn anyway.
7692 ; [(set (match_operand:SI 0 "register_operand" "=a")
7694 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7696 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7697 ; (set (match_operand:SI 3 "register_operand" "=d")
7699 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7700 ; (clobber (reg:CC FLAGS_REG))]
7702 ; "div{l}\t{%2, %0|%0, %2}"
7703 ; [(set_attr "type" "idiv")])
7705 ;;- Logical AND instructions
7707 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7708 ;; Note that this excludes ah.
7710 (define_insn "*testdi_1_rex64"
7711 [(set (reg FLAGS_REG)
7713 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7714 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7716 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7717 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7719 test{l}\t{%k1, %k0|%k0, %k1}
7720 test{l}\t{%k1, %k0|%k0, %k1}
7721 test{q}\t{%1, %0|%0, %1}
7722 test{q}\t{%1, %0|%0, %1}
7723 test{q}\t{%1, %0|%0, %1}"
7724 [(set_attr "type" "test")
7725 (set_attr "modrm" "0,1,0,1,1")
7726 (set_attr "mode" "SI,SI,DI,DI,DI")
7727 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7729 (define_insn "testsi_1"
7730 [(set (reg FLAGS_REG)
7732 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7733 (match_operand:SI 1 "general_operand" "in,in,rin"))
7735 "ix86_match_ccmode (insn, CCNOmode)
7736 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7737 "test{l}\t{%1, %0|%0, %1}"
7738 [(set_attr "type" "test")
7739 (set_attr "modrm" "0,1,1")
7740 (set_attr "mode" "SI")
7741 (set_attr "pent_pair" "uv,np,uv")])
7743 (define_expand "testsi_ccno_1"
7744 [(set (reg:CCNO FLAGS_REG)
7746 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7747 (match_operand:SI 1 "nonmemory_operand" ""))
7752 (define_insn "*testhi_1"
7753 [(set (reg FLAGS_REG)
7754 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7755 (match_operand:HI 1 "general_operand" "n,n,rn"))
7757 "ix86_match_ccmode (insn, CCNOmode)
7758 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7759 "test{w}\t{%1, %0|%0, %1}"
7760 [(set_attr "type" "test")
7761 (set_attr "modrm" "0,1,1")
7762 (set_attr "mode" "HI")
7763 (set_attr "pent_pair" "uv,np,uv")])
7765 (define_expand "testqi_ccz_1"
7766 [(set (reg:CCZ FLAGS_REG)
7767 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7768 (match_operand:QI 1 "nonmemory_operand" ""))
7773 (define_insn "*testqi_1_maybe_si"
7774 [(set (reg FLAGS_REG)
7777 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7778 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7780 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7781 && ix86_match_ccmode (insn,
7782 GET_CODE (operands[1]) == CONST_INT
7783 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7785 if (which_alternative == 3)
7787 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7788 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7789 return "test{l}\t{%1, %k0|%k0, %1}";
7791 return "test{b}\t{%1, %0|%0, %1}";
7793 [(set_attr "type" "test")
7794 (set_attr "modrm" "0,1,1,1")
7795 (set_attr "mode" "QI,QI,QI,SI")
7796 (set_attr "pent_pair" "uv,np,uv,np")])
7798 (define_insn "*testqi_1"
7799 [(set (reg FLAGS_REG)
7802 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7803 (match_operand:QI 1 "general_operand" "n,n,qn"))
7805 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7806 && ix86_match_ccmode (insn, CCNOmode)"
7807 "test{b}\t{%1, %0|%0, %1}"
7808 [(set_attr "type" "test")
7809 (set_attr "modrm" "0,1,1")
7810 (set_attr "mode" "QI")
7811 (set_attr "pent_pair" "uv,np,uv")])
7813 (define_expand "testqi_ext_ccno_0"
7814 [(set (reg:CCNO FLAGS_REG)
7818 (match_operand 0 "ext_register_operand" "")
7821 (match_operand 1 "const_int_operand" ""))
7826 (define_insn "*testqi_ext_0"
7827 [(set (reg FLAGS_REG)
7831 (match_operand 0 "ext_register_operand" "Q")
7834 (match_operand 1 "const_int_operand" "n"))
7836 "ix86_match_ccmode (insn, CCNOmode)"
7837 "test{b}\t{%1, %h0|%h0, %1}"
7838 [(set_attr "type" "test")
7839 (set_attr "mode" "QI")
7840 (set_attr "length_immediate" "1")
7841 (set_attr "pent_pair" "np")])
7843 (define_insn "*testqi_ext_1"
7844 [(set (reg FLAGS_REG)
7848 (match_operand 0 "ext_register_operand" "Q")
7852 (match_operand:QI 1 "general_operand" "Qm")))
7854 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7855 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7856 "test{b}\t{%1, %h0|%h0, %1}"
7857 [(set_attr "type" "test")
7858 (set_attr "mode" "QI")])
7860 (define_insn "*testqi_ext_1_rex64"
7861 [(set (reg FLAGS_REG)
7865 (match_operand 0 "ext_register_operand" "Q")
7869 (match_operand:QI 1 "register_operand" "Q")))
7871 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7872 "test{b}\t{%1, %h0|%h0, %1}"
7873 [(set_attr "type" "test")
7874 (set_attr "mode" "QI")])
7876 (define_insn "*testqi_ext_2"
7877 [(set (reg FLAGS_REG)
7881 (match_operand 0 "ext_register_operand" "Q")
7885 (match_operand 1 "ext_register_operand" "Q")
7889 "ix86_match_ccmode (insn, CCNOmode)"
7890 "test{b}\t{%h1, %h0|%h0, %h1}"
7891 [(set_attr "type" "test")
7892 (set_attr "mode" "QI")])
7894 ;; Combine likes to form bit extractions for some tests. Humor it.
7895 (define_insn "*testqi_ext_3"
7896 [(set (reg FLAGS_REG)
7897 (compare (zero_extract:SI
7898 (match_operand 0 "nonimmediate_operand" "rm")
7899 (match_operand:SI 1 "const_int_operand" "")
7900 (match_operand:SI 2 "const_int_operand" ""))
7902 "ix86_match_ccmode (insn, CCNOmode)
7903 && INTVAL (operands[1]) > 0
7904 && INTVAL (operands[2]) >= 0
7905 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7906 && (GET_MODE (operands[0]) == SImode
7907 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7908 || GET_MODE (operands[0]) == HImode
7909 || GET_MODE (operands[0]) == QImode)"
7912 (define_insn "*testqi_ext_3_rex64"
7913 [(set (reg FLAGS_REG)
7914 (compare (zero_extract:DI
7915 (match_operand 0 "nonimmediate_operand" "rm")
7916 (match_operand:DI 1 "const_int_operand" "")
7917 (match_operand:DI 2 "const_int_operand" ""))
7920 && ix86_match_ccmode (insn, CCNOmode)
7921 && INTVAL (operands[1]) > 0
7922 && INTVAL (operands[2]) >= 0
7923 /* Ensure that resulting mask is zero or sign extended operand. */
7924 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7925 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7926 && INTVAL (operands[1]) > 32))
7927 && (GET_MODE (operands[0]) == SImode
7928 || GET_MODE (operands[0]) == DImode
7929 || GET_MODE (operands[0]) == HImode
7930 || GET_MODE (operands[0]) == QImode)"
7934 [(set (match_operand 0 "flags_reg_operand" "")
7935 (match_operator 1 "compare_operator"
7937 (match_operand 2 "nonimmediate_operand" "")
7938 (match_operand 3 "const_int_operand" "")
7939 (match_operand 4 "const_int_operand" ""))
7941 "ix86_match_ccmode (insn, CCNOmode)"
7942 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7944 rtx val = operands[2];
7945 HOST_WIDE_INT len = INTVAL (operands[3]);
7946 HOST_WIDE_INT pos = INTVAL (operands[4]);
7948 enum machine_mode mode, submode;
7950 mode = GET_MODE (val);
7951 if (GET_CODE (val) == MEM)
7953 /* ??? Combine likes to put non-volatile mem extractions in QImode
7954 no matter the size of the test. So find a mode that works. */
7955 if (! MEM_VOLATILE_P (val))
7957 mode = smallest_mode_for_size (pos + len, MODE_INT);
7958 val = adjust_address (val, mode, 0);
7961 else if (GET_CODE (val) == SUBREG
7962 && (submode = GET_MODE (SUBREG_REG (val)),
7963 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7964 && pos + len <= GET_MODE_BITSIZE (submode))
7966 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7968 val = SUBREG_REG (val);
7970 else if (mode == HImode && pos + len <= 8)
7972 /* Small HImode tests can be converted to QImode. */
7974 val = gen_lowpart (QImode, val);
7977 if (len == HOST_BITS_PER_WIDE_INT)
7980 mask = ((HOST_WIDE_INT)1 << len) - 1;
7983 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7986 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7987 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7988 ;; this is relatively important trick.
7989 ;; Do the conversion only post-reload to avoid limiting of the register class
7992 [(set (match_operand 0 "flags_reg_operand" "")
7993 (match_operator 1 "compare_operator"
7994 [(and (match_operand 2 "register_operand" "")
7995 (match_operand 3 "const_int_operand" ""))
7998 && QI_REG_P (operands[2])
7999 && GET_MODE (operands[2]) != QImode
8000 && ((ix86_match_ccmode (insn, CCZmode)
8001 && !(INTVAL (operands[3]) & ~(255 << 8)))
8002 || (ix86_match_ccmode (insn, CCNOmode)
8003 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8006 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8009 "operands[2] = gen_lowpart (SImode, operands[2]);
8010 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8013 [(set (match_operand 0 "flags_reg_operand" "")
8014 (match_operator 1 "compare_operator"
8015 [(and (match_operand 2 "nonimmediate_operand" "")
8016 (match_operand 3 "const_int_operand" ""))
8019 && GET_MODE (operands[2]) != QImode
8020 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8021 && ((ix86_match_ccmode (insn, CCZmode)
8022 && !(INTVAL (operands[3]) & ~255))
8023 || (ix86_match_ccmode (insn, CCNOmode)
8024 && !(INTVAL (operands[3]) & ~127)))"
8026 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8028 "operands[2] = gen_lowpart (QImode, operands[2]);
8029 operands[3] = gen_lowpart (QImode, operands[3]);")
8032 ;; %%% This used to optimize known byte-wide and operations to memory,
8033 ;; and sometimes to QImode registers. If this is considered useful,
8034 ;; it should be done with splitters.
8036 (define_expand "anddi3"
8037 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8038 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8039 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8040 (clobber (reg:CC FLAGS_REG))]
8042 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8044 (define_insn "*anddi_1_rex64"
8045 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8046 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8047 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8048 (clobber (reg:CC FLAGS_REG))]
8049 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8051 switch (get_attr_type (insn))
8055 enum machine_mode mode;
8057 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8058 if (INTVAL (operands[2]) == 0xff)
8062 gcc_assert (INTVAL (operands[2]) == 0xffff);
8066 operands[1] = gen_lowpart (mode, operands[1]);
8068 return "movz{bq|x}\t{%1,%0|%0, %1}";
8070 return "movz{wq|x}\t{%1,%0|%0, %1}";
8074 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8075 if (get_attr_mode (insn) == MODE_SI)
8076 return "and{l}\t{%k2, %k0|%k0, %k2}";
8078 return "and{q}\t{%2, %0|%0, %2}";
8081 [(set_attr "type" "alu,alu,alu,imovx")
8082 (set_attr "length_immediate" "*,*,*,0")
8083 (set_attr "mode" "SI,DI,DI,DI")])
8085 (define_insn "*anddi_2"
8086 [(set (reg FLAGS_REG)
8087 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8088 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8090 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8091 (and:DI (match_dup 1) (match_dup 2)))]
8092 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8093 && ix86_binary_operator_ok (AND, DImode, operands)"
8095 and{l}\t{%k2, %k0|%k0, %k2}
8096 and{q}\t{%2, %0|%0, %2}
8097 and{q}\t{%2, %0|%0, %2}"
8098 [(set_attr "type" "alu")
8099 (set_attr "mode" "SI,DI,DI")])
8101 (define_expand "andsi3"
8102 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8103 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8104 (match_operand:SI 2 "general_operand" "")))
8105 (clobber (reg:CC FLAGS_REG))]
8107 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8109 (define_insn "*andsi_1"
8110 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8111 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8112 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8113 (clobber (reg:CC FLAGS_REG))]
8114 "ix86_binary_operator_ok (AND, SImode, operands)"
8116 switch (get_attr_type (insn))
8120 enum machine_mode mode;
8122 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8123 if (INTVAL (operands[2]) == 0xff)
8127 gcc_assert (INTVAL (operands[2]) == 0xffff);
8131 operands[1] = gen_lowpart (mode, operands[1]);
8133 return "movz{bl|x}\t{%1,%0|%0, %1}";
8135 return "movz{wl|x}\t{%1,%0|%0, %1}";
8139 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8140 return "and{l}\t{%2, %0|%0, %2}";
8143 [(set_attr "type" "alu,alu,imovx")
8144 (set_attr "length_immediate" "*,*,0")
8145 (set_attr "mode" "SI")])
8148 [(set (match_operand 0 "register_operand" "")
8150 (const_int -65536)))
8151 (clobber (reg:CC FLAGS_REG))]
8152 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8153 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8154 "operands[1] = gen_lowpart (HImode, operands[0]);")
8157 [(set (match_operand 0 "ext_register_operand" "")
8160 (clobber (reg:CC FLAGS_REG))]
8161 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8162 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8163 "operands[1] = gen_lowpart (QImode, operands[0]);")
8166 [(set (match_operand 0 "ext_register_operand" "")
8168 (const_int -65281)))
8169 (clobber (reg:CC FLAGS_REG))]
8170 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8171 [(parallel [(set (zero_extract:SI (match_dup 0)
8175 (zero_extract:SI (match_dup 0)
8178 (zero_extract:SI (match_dup 0)
8181 (clobber (reg:CC FLAGS_REG))])]
8182 "operands[0] = gen_lowpart (SImode, operands[0]);")
8184 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8185 (define_insn "*andsi_1_zext"
8186 [(set (match_operand:DI 0 "register_operand" "=r")
8188 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8189 (match_operand:SI 2 "general_operand" "rim"))))
8190 (clobber (reg:CC FLAGS_REG))]
8191 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8192 "and{l}\t{%2, %k0|%k0, %2}"
8193 [(set_attr "type" "alu")
8194 (set_attr "mode" "SI")])
8196 (define_insn "*andsi_2"
8197 [(set (reg FLAGS_REG)
8198 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8199 (match_operand:SI 2 "general_operand" "rim,ri"))
8201 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8202 (and:SI (match_dup 1) (match_dup 2)))]
8203 "ix86_match_ccmode (insn, CCNOmode)
8204 && ix86_binary_operator_ok (AND, SImode, operands)"
8205 "and{l}\t{%2, %0|%0, %2}"
8206 [(set_attr "type" "alu")
8207 (set_attr "mode" "SI")])
8209 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8210 (define_insn "*andsi_2_zext"
8211 [(set (reg FLAGS_REG)
8212 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8213 (match_operand:SI 2 "general_operand" "rim"))
8215 (set (match_operand:DI 0 "register_operand" "=r")
8216 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8217 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8218 && ix86_binary_operator_ok (AND, SImode, operands)"
8219 "and{l}\t{%2, %k0|%k0, %2}"
8220 [(set_attr "type" "alu")
8221 (set_attr "mode" "SI")])
8223 (define_expand "andhi3"
8224 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8225 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8226 (match_operand:HI 2 "general_operand" "")))
8227 (clobber (reg:CC FLAGS_REG))]
8228 "TARGET_HIMODE_MATH"
8229 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8231 (define_insn "*andhi_1"
8232 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8233 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8234 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8235 (clobber (reg:CC FLAGS_REG))]
8236 "ix86_binary_operator_ok (AND, HImode, operands)"
8238 switch (get_attr_type (insn))
8241 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8242 gcc_assert (INTVAL (operands[2]) == 0xff);
8243 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8246 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8248 return "and{w}\t{%2, %0|%0, %2}";
8251 [(set_attr "type" "alu,alu,imovx")
8252 (set_attr "length_immediate" "*,*,0")
8253 (set_attr "mode" "HI,HI,SI")])
8255 (define_insn "*andhi_2"
8256 [(set (reg FLAGS_REG)
8257 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8258 (match_operand:HI 2 "general_operand" "rim,ri"))
8260 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8261 (and:HI (match_dup 1) (match_dup 2)))]
8262 "ix86_match_ccmode (insn, CCNOmode)
8263 && ix86_binary_operator_ok (AND, HImode, operands)"
8264 "and{w}\t{%2, %0|%0, %2}"
8265 [(set_attr "type" "alu")
8266 (set_attr "mode" "HI")])
8268 (define_expand "andqi3"
8269 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8270 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8271 (match_operand:QI 2 "general_operand" "")))
8272 (clobber (reg:CC FLAGS_REG))]
8273 "TARGET_QIMODE_MATH"
8274 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8276 ;; %%% Potential partial reg stall on alternative 2. What to do?
8277 (define_insn "*andqi_1"
8278 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8279 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8280 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8281 (clobber (reg:CC FLAGS_REG))]
8282 "ix86_binary_operator_ok (AND, QImode, operands)"
8284 and{b}\t{%2, %0|%0, %2}
8285 and{b}\t{%2, %0|%0, %2}
8286 and{l}\t{%k2, %k0|%k0, %k2}"
8287 [(set_attr "type" "alu")
8288 (set_attr "mode" "QI,QI,SI")])
8290 (define_insn "*andqi_1_slp"
8291 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8292 (and:QI (match_dup 0)
8293 (match_operand:QI 1 "general_operand" "qi,qmi")))
8294 (clobber (reg:CC FLAGS_REG))]
8295 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8296 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8297 "and{b}\t{%1, %0|%0, %1}"
8298 [(set_attr "type" "alu1")
8299 (set_attr "mode" "QI")])
8301 (define_insn "*andqi_2_maybe_si"
8302 [(set (reg FLAGS_REG)
8304 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8305 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8307 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8308 (and:QI (match_dup 1) (match_dup 2)))]
8309 "ix86_binary_operator_ok (AND, QImode, operands)
8310 && ix86_match_ccmode (insn,
8311 GET_CODE (operands[2]) == CONST_INT
8312 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8314 if (which_alternative == 2)
8316 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8317 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8318 return "and{l}\t{%2, %k0|%k0, %2}";
8320 return "and{b}\t{%2, %0|%0, %2}";
8322 [(set_attr "type" "alu")
8323 (set_attr "mode" "QI,QI,SI")])
8325 (define_insn "*andqi_2"
8326 [(set (reg FLAGS_REG)
8328 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8329 (match_operand:QI 2 "general_operand" "qim,qi"))
8331 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8332 (and:QI (match_dup 1) (match_dup 2)))]
8333 "ix86_match_ccmode (insn, CCNOmode)
8334 && ix86_binary_operator_ok (AND, QImode, operands)"
8335 "and{b}\t{%2, %0|%0, %2}"
8336 [(set_attr "type" "alu")
8337 (set_attr "mode" "QI")])
8339 (define_insn "*andqi_2_slp"
8340 [(set (reg FLAGS_REG)
8342 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8343 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8345 (set (strict_low_part (match_dup 0))
8346 (and:QI (match_dup 0) (match_dup 1)))]
8347 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8348 && ix86_match_ccmode (insn, CCNOmode)
8349 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8350 "and{b}\t{%1, %0|%0, %1}"
8351 [(set_attr "type" "alu1")
8352 (set_attr "mode" "QI")])
8354 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8355 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8356 ;; for a QImode operand, which of course failed.
8358 (define_insn "andqi_ext_0"
8359 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8364 (match_operand 1 "ext_register_operand" "0")
8367 (match_operand 2 "const_int_operand" "n")))
8368 (clobber (reg:CC FLAGS_REG))]
8370 "and{b}\t{%2, %h0|%h0, %2}"
8371 [(set_attr "type" "alu")
8372 (set_attr "length_immediate" "1")
8373 (set_attr "mode" "QI")])
8375 ;; Generated by peephole translating test to and. This shows up
8376 ;; often in fp comparisons.
8378 (define_insn "*andqi_ext_0_cc"
8379 [(set (reg FLAGS_REG)
8383 (match_operand 1 "ext_register_operand" "0")
8386 (match_operand 2 "const_int_operand" "n"))
8388 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8397 "ix86_match_ccmode (insn, CCNOmode)"
8398 "and{b}\t{%2, %h0|%h0, %2}"
8399 [(set_attr "type" "alu")
8400 (set_attr "length_immediate" "1")
8401 (set_attr "mode" "QI")])
8403 (define_insn "*andqi_ext_1"
8404 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8409 (match_operand 1 "ext_register_operand" "0")
8413 (match_operand:QI 2 "general_operand" "Qm"))))
8414 (clobber (reg:CC FLAGS_REG))]
8416 "and{b}\t{%2, %h0|%h0, %2}"
8417 [(set_attr "type" "alu")
8418 (set_attr "length_immediate" "0")
8419 (set_attr "mode" "QI")])
8421 (define_insn "*andqi_ext_1_rex64"
8422 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8427 (match_operand 1 "ext_register_operand" "0")
8431 (match_operand 2 "ext_register_operand" "Q"))))
8432 (clobber (reg:CC FLAGS_REG))]
8434 "and{b}\t{%2, %h0|%h0, %2}"
8435 [(set_attr "type" "alu")
8436 (set_attr "length_immediate" "0")
8437 (set_attr "mode" "QI")])
8439 (define_insn "*andqi_ext_2"
8440 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8445 (match_operand 1 "ext_register_operand" "%0")
8449 (match_operand 2 "ext_register_operand" "Q")
8452 (clobber (reg:CC FLAGS_REG))]
8454 "and{b}\t{%h2, %h0|%h0, %h2}"
8455 [(set_attr "type" "alu")
8456 (set_attr "length_immediate" "0")
8457 (set_attr "mode" "QI")])
8459 ;; Convert wide AND instructions with immediate operand to shorter QImode
8460 ;; equivalents when possible.
8461 ;; Don't do the splitting with memory operands, since it introduces risk
8462 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8463 ;; for size, but that can (should?) be handled by generic code instead.
8465 [(set (match_operand 0 "register_operand" "")
8466 (and (match_operand 1 "register_operand" "")
8467 (match_operand 2 "const_int_operand" "")))
8468 (clobber (reg:CC FLAGS_REG))]
8470 && QI_REG_P (operands[0])
8471 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8472 && !(~INTVAL (operands[2]) & ~(255 << 8))
8473 && GET_MODE (operands[0]) != QImode"
8474 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8475 (and:SI (zero_extract:SI (match_dup 1)
8476 (const_int 8) (const_int 8))
8478 (clobber (reg:CC FLAGS_REG))])]
8479 "operands[0] = gen_lowpart (SImode, operands[0]);
8480 operands[1] = gen_lowpart (SImode, operands[1]);
8481 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8483 ;; Since AND can be encoded with sign extended immediate, this is only
8484 ;; profitable when 7th bit is not set.
8486 [(set (match_operand 0 "register_operand" "")
8487 (and (match_operand 1 "general_operand" "")
8488 (match_operand 2 "const_int_operand" "")))
8489 (clobber (reg:CC FLAGS_REG))]
8491 && ANY_QI_REG_P (operands[0])
8492 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8493 && !(~INTVAL (operands[2]) & ~255)
8494 && !(INTVAL (operands[2]) & 128)
8495 && GET_MODE (operands[0]) != QImode"
8496 [(parallel [(set (strict_low_part (match_dup 0))
8497 (and:QI (match_dup 1)
8499 (clobber (reg:CC FLAGS_REG))])]
8500 "operands[0] = gen_lowpart (QImode, operands[0]);
8501 operands[1] = gen_lowpart (QImode, operands[1]);
8502 operands[2] = gen_lowpart (QImode, operands[2]);")
8504 ;; Logical inclusive OR instructions
8506 ;; %%% This used to optimize known byte-wide and operations to memory.
8507 ;; If this is considered useful, it should be done with splitters.
8509 (define_expand "iordi3"
8510 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8511 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8512 (match_operand:DI 2 "x86_64_general_operand" "")))
8513 (clobber (reg:CC FLAGS_REG))]
8515 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8517 (define_insn "*iordi_1_rex64"
8518 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8519 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8520 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8521 (clobber (reg:CC FLAGS_REG))]
8523 && ix86_binary_operator_ok (IOR, DImode, operands)"
8524 "or{q}\t{%2, %0|%0, %2}"
8525 [(set_attr "type" "alu")
8526 (set_attr "mode" "DI")])
8528 (define_insn "*iordi_2_rex64"
8529 [(set (reg FLAGS_REG)
8530 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8531 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8533 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8534 (ior:DI (match_dup 1) (match_dup 2)))]
8536 && ix86_match_ccmode (insn, CCNOmode)
8537 && ix86_binary_operator_ok (IOR, DImode, operands)"
8538 "or{q}\t{%2, %0|%0, %2}"
8539 [(set_attr "type" "alu")
8540 (set_attr "mode" "DI")])
8542 (define_insn "*iordi_3_rex64"
8543 [(set (reg FLAGS_REG)
8544 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8545 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8547 (clobber (match_scratch:DI 0 "=r"))]
8549 && ix86_match_ccmode (insn, CCNOmode)
8550 && ix86_binary_operator_ok (IOR, DImode, operands)"
8551 "or{q}\t{%2, %0|%0, %2}"
8552 [(set_attr "type" "alu")
8553 (set_attr "mode" "DI")])
8556 (define_expand "iorsi3"
8557 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8558 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8559 (match_operand:SI 2 "general_operand" "")))
8560 (clobber (reg:CC FLAGS_REG))]
8562 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8564 (define_insn "*iorsi_1"
8565 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8566 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8567 (match_operand:SI 2 "general_operand" "ri,rmi")))
8568 (clobber (reg:CC FLAGS_REG))]
8569 "ix86_binary_operator_ok (IOR, SImode, operands)"
8570 "or{l}\t{%2, %0|%0, %2}"
8571 [(set_attr "type" "alu")
8572 (set_attr "mode" "SI")])
8574 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8575 (define_insn "*iorsi_1_zext"
8576 [(set (match_operand:DI 0 "register_operand" "=rm")
8578 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8579 (match_operand:SI 2 "general_operand" "rim"))))
8580 (clobber (reg:CC FLAGS_REG))]
8581 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8582 "or{l}\t{%2, %k0|%k0, %2}"
8583 [(set_attr "type" "alu")
8584 (set_attr "mode" "SI")])
8586 (define_insn "*iorsi_1_zext_imm"
8587 [(set (match_operand:DI 0 "register_operand" "=rm")
8588 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8589 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8590 (clobber (reg:CC FLAGS_REG))]
8592 "or{l}\t{%2, %k0|%k0, %2}"
8593 [(set_attr "type" "alu")
8594 (set_attr "mode" "SI")])
8596 (define_insn "*iorsi_2"
8597 [(set (reg FLAGS_REG)
8598 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8599 (match_operand:SI 2 "general_operand" "rim,ri"))
8601 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8602 (ior:SI (match_dup 1) (match_dup 2)))]
8603 "ix86_match_ccmode (insn, CCNOmode)
8604 && ix86_binary_operator_ok (IOR, SImode, operands)"
8605 "or{l}\t{%2, %0|%0, %2}"
8606 [(set_attr "type" "alu")
8607 (set_attr "mode" "SI")])
8609 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8610 ;; ??? Special case for immediate operand is missing - it is tricky.
8611 (define_insn "*iorsi_2_zext"
8612 [(set (reg FLAGS_REG)
8613 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8614 (match_operand:SI 2 "general_operand" "rim"))
8616 (set (match_operand:DI 0 "register_operand" "=r")
8617 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8618 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8619 && ix86_binary_operator_ok (IOR, SImode, operands)"
8620 "or{l}\t{%2, %k0|%k0, %2}"
8621 [(set_attr "type" "alu")
8622 (set_attr "mode" "SI")])
8624 (define_insn "*iorsi_2_zext_imm"
8625 [(set (reg FLAGS_REG)
8626 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8627 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8629 (set (match_operand:DI 0 "register_operand" "=r")
8630 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8631 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8632 && ix86_binary_operator_ok (IOR, SImode, operands)"
8633 "or{l}\t{%2, %k0|%k0, %2}"
8634 [(set_attr "type" "alu")
8635 (set_attr "mode" "SI")])
8637 (define_insn "*iorsi_3"
8638 [(set (reg FLAGS_REG)
8639 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8640 (match_operand:SI 2 "general_operand" "rim"))
8642 (clobber (match_scratch:SI 0 "=r"))]
8643 "ix86_match_ccmode (insn, CCNOmode)
8644 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8645 "or{l}\t{%2, %0|%0, %2}"
8646 [(set_attr "type" "alu")
8647 (set_attr "mode" "SI")])
8649 (define_expand "iorhi3"
8650 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8651 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8652 (match_operand:HI 2 "general_operand" "")))
8653 (clobber (reg:CC FLAGS_REG))]
8654 "TARGET_HIMODE_MATH"
8655 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8657 (define_insn "*iorhi_1"
8658 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8659 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8660 (match_operand:HI 2 "general_operand" "rmi,ri")))
8661 (clobber (reg:CC FLAGS_REG))]
8662 "ix86_binary_operator_ok (IOR, HImode, operands)"
8663 "or{w}\t{%2, %0|%0, %2}"
8664 [(set_attr "type" "alu")
8665 (set_attr "mode" "HI")])
8667 (define_insn "*iorhi_2"
8668 [(set (reg FLAGS_REG)
8669 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8670 (match_operand:HI 2 "general_operand" "rim,ri"))
8672 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8673 (ior:HI (match_dup 1) (match_dup 2)))]
8674 "ix86_match_ccmode (insn, CCNOmode)
8675 && ix86_binary_operator_ok (IOR, HImode, operands)"
8676 "or{w}\t{%2, %0|%0, %2}"
8677 [(set_attr "type" "alu")
8678 (set_attr "mode" "HI")])
8680 (define_insn "*iorhi_3"
8681 [(set (reg FLAGS_REG)
8682 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8683 (match_operand:HI 2 "general_operand" "rim"))
8685 (clobber (match_scratch:HI 0 "=r"))]
8686 "ix86_match_ccmode (insn, CCNOmode)
8687 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8688 "or{w}\t{%2, %0|%0, %2}"
8689 [(set_attr "type" "alu")
8690 (set_attr "mode" "HI")])
8692 (define_expand "iorqi3"
8693 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8694 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8695 (match_operand:QI 2 "general_operand" "")))
8696 (clobber (reg:CC FLAGS_REG))]
8697 "TARGET_QIMODE_MATH"
8698 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8700 ;; %%% Potential partial reg stall on alternative 2. What to do?
8701 (define_insn "*iorqi_1"
8702 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8703 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8704 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8705 (clobber (reg:CC FLAGS_REG))]
8706 "ix86_binary_operator_ok (IOR, QImode, operands)"
8708 or{b}\t{%2, %0|%0, %2}
8709 or{b}\t{%2, %0|%0, %2}
8710 or{l}\t{%k2, %k0|%k0, %k2}"
8711 [(set_attr "type" "alu")
8712 (set_attr "mode" "QI,QI,SI")])
8714 (define_insn "*iorqi_1_slp"
8715 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8716 (ior:QI (match_dup 0)
8717 (match_operand:QI 1 "general_operand" "qmi,qi")))
8718 (clobber (reg:CC FLAGS_REG))]
8719 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8720 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8721 "or{b}\t{%1, %0|%0, %1}"
8722 [(set_attr "type" "alu1")
8723 (set_attr "mode" "QI")])
8725 (define_insn "*iorqi_2"
8726 [(set (reg FLAGS_REG)
8727 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8728 (match_operand:QI 2 "general_operand" "qim,qi"))
8730 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8731 (ior:QI (match_dup 1) (match_dup 2)))]
8732 "ix86_match_ccmode (insn, CCNOmode)
8733 && ix86_binary_operator_ok (IOR, QImode, operands)"
8734 "or{b}\t{%2, %0|%0, %2}"
8735 [(set_attr "type" "alu")
8736 (set_attr "mode" "QI")])
8738 (define_insn "*iorqi_2_slp"
8739 [(set (reg FLAGS_REG)
8740 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8741 (match_operand:QI 1 "general_operand" "qim,qi"))
8743 (set (strict_low_part (match_dup 0))
8744 (ior:QI (match_dup 0) (match_dup 1)))]
8745 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8746 && ix86_match_ccmode (insn, CCNOmode)
8747 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8748 "or{b}\t{%1, %0|%0, %1}"
8749 [(set_attr "type" "alu1")
8750 (set_attr "mode" "QI")])
8752 (define_insn "*iorqi_3"
8753 [(set (reg FLAGS_REG)
8754 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8755 (match_operand:QI 2 "general_operand" "qim"))
8757 (clobber (match_scratch:QI 0 "=q"))]
8758 "ix86_match_ccmode (insn, CCNOmode)
8759 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8760 "or{b}\t{%2, %0|%0, %2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "mode" "QI")])
8764 (define_insn "iorqi_ext_0"
8765 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8770 (match_operand 1 "ext_register_operand" "0")
8773 (match_operand 2 "const_int_operand" "n")))
8774 (clobber (reg:CC FLAGS_REG))]
8775 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8776 "or{b}\t{%2, %h0|%h0, %2}"
8777 [(set_attr "type" "alu")
8778 (set_attr "length_immediate" "1")
8779 (set_attr "mode" "QI")])
8781 (define_insn "*iorqi_ext_1"
8782 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8787 (match_operand 1 "ext_register_operand" "0")
8791 (match_operand:QI 2 "general_operand" "Qm"))))
8792 (clobber (reg:CC FLAGS_REG))]
8794 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8795 "or{b}\t{%2, %h0|%h0, %2}"
8796 [(set_attr "type" "alu")
8797 (set_attr "length_immediate" "0")
8798 (set_attr "mode" "QI")])
8800 (define_insn "*iorqi_ext_1_rex64"
8801 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8806 (match_operand 1 "ext_register_operand" "0")
8810 (match_operand 2 "ext_register_operand" "Q"))))
8811 (clobber (reg:CC FLAGS_REG))]
8813 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8814 "or{b}\t{%2, %h0|%h0, %2}"
8815 [(set_attr "type" "alu")
8816 (set_attr "length_immediate" "0")
8817 (set_attr "mode" "QI")])
8819 (define_insn "*iorqi_ext_2"
8820 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8824 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8827 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8830 (clobber (reg:CC FLAGS_REG))]
8831 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8832 "ior{b}\t{%h2, %h0|%h0, %h2}"
8833 [(set_attr "type" "alu")
8834 (set_attr "length_immediate" "0")
8835 (set_attr "mode" "QI")])
8838 [(set (match_operand 0 "register_operand" "")
8839 (ior (match_operand 1 "register_operand" "")
8840 (match_operand 2 "const_int_operand" "")))
8841 (clobber (reg:CC FLAGS_REG))]
8843 && QI_REG_P (operands[0])
8844 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8845 && !(INTVAL (operands[2]) & ~(255 << 8))
8846 && GET_MODE (operands[0]) != QImode"
8847 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8848 (ior:SI (zero_extract:SI (match_dup 1)
8849 (const_int 8) (const_int 8))
8851 (clobber (reg:CC FLAGS_REG))])]
8852 "operands[0] = gen_lowpart (SImode, operands[0]);
8853 operands[1] = gen_lowpart (SImode, operands[1]);
8854 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8856 ;; Since OR can be encoded with sign extended immediate, this is only
8857 ;; profitable when 7th bit is set.
8859 [(set (match_operand 0 "register_operand" "")
8860 (ior (match_operand 1 "general_operand" "")
8861 (match_operand 2 "const_int_operand" "")))
8862 (clobber (reg:CC FLAGS_REG))]
8864 && ANY_QI_REG_P (operands[0])
8865 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8866 && !(INTVAL (operands[2]) & ~255)
8867 && (INTVAL (operands[2]) & 128)
8868 && GET_MODE (operands[0]) != QImode"
8869 [(parallel [(set (strict_low_part (match_dup 0))
8870 (ior:QI (match_dup 1)
8872 (clobber (reg:CC FLAGS_REG))])]
8873 "operands[0] = gen_lowpart (QImode, operands[0]);
8874 operands[1] = gen_lowpart (QImode, operands[1]);
8875 operands[2] = gen_lowpart (QImode, operands[2]);")
8877 ;; Logical XOR instructions
8879 ;; %%% This used to optimize known byte-wide and operations to memory.
8880 ;; If this is considered useful, it should be done with splitters.
8882 (define_expand "xordi3"
8883 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8884 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8885 (match_operand:DI 2 "x86_64_general_operand" "")))
8886 (clobber (reg:CC FLAGS_REG))]
8888 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8890 (define_insn "*xordi_1_rex64"
8891 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8892 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8893 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8894 (clobber (reg:CC FLAGS_REG))]
8896 && ix86_binary_operator_ok (XOR, DImode, operands)"
8898 xor{q}\t{%2, %0|%0, %2}
8899 xor{q}\t{%2, %0|%0, %2}"
8900 [(set_attr "type" "alu")
8901 (set_attr "mode" "DI,DI")])
8903 (define_insn "*xordi_2_rex64"
8904 [(set (reg FLAGS_REG)
8905 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8906 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8908 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8909 (xor:DI (match_dup 1) (match_dup 2)))]
8911 && ix86_match_ccmode (insn, CCNOmode)
8912 && ix86_binary_operator_ok (XOR, DImode, operands)"
8914 xor{q}\t{%2, %0|%0, %2}
8915 xor{q}\t{%2, %0|%0, %2}"
8916 [(set_attr "type" "alu")
8917 (set_attr "mode" "DI,DI")])
8919 (define_insn "*xordi_3_rex64"
8920 [(set (reg FLAGS_REG)
8921 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8922 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8924 (clobber (match_scratch:DI 0 "=r"))]
8926 && ix86_match_ccmode (insn, CCNOmode)
8927 && ix86_binary_operator_ok (XOR, DImode, operands)"
8928 "xor{q}\t{%2, %0|%0, %2}"
8929 [(set_attr "type" "alu")
8930 (set_attr "mode" "DI")])
8932 (define_expand "xorsi3"
8933 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8934 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8935 (match_operand:SI 2 "general_operand" "")))
8936 (clobber (reg:CC FLAGS_REG))]
8938 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8940 (define_insn "*xorsi_1"
8941 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8942 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8943 (match_operand:SI 2 "general_operand" "ri,rm")))
8944 (clobber (reg:CC FLAGS_REG))]
8945 "ix86_binary_operator_ok (XOR, SImode, operands)"
8946 "xor{l}\t{%2, %0|%0, %2}"
8947 [(set_attr "type" "alu")
8948 (set_attr "mode" "SI")])
8950 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8951 ;; Add speccase for immediates
8952 (define_insn "*xorsi_1_zext"
8953 [(set (match_operand:DI 0 "register_operand" "=r")
8955 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8956 (match_operand:SI 2 "general_operand" "rim"))))
8957 (clobber (reg:CC FLAGS_REG))]
8958 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8959 "xor{l}\t{%2, %k0|%k0, %2}"
8960 [(set_attr "type" "alu")
8961 (set_attr "mode" "SI")])
8963 (define_insn "*xorsi_1_zext_imm"
8964 [(set (match_operand:DI 0 "register_operand" "=r")
8965 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8966 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8967 (clobber (reg:CC FLAGS_REG))]
8968 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8969 "xor{l}\t{%2, %k0|%k0, %2}"
8970 [(set_attr "type" "alu")
8971 (set_attr "mode" "SI")])
8973 (define_insn "*xorsi_2"
8974 [(set (reg FLAGS_REG)
8975 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8976 (match_operand:SI 2 "general_operand" "rim,ri"))
8978 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8979 (xor:SI (match_dup 1) (match_dup 2)))]
8980 "ix86_match_ccmode (insn, CCNOmode)
8981 && ix86_binary_operator_ok (XOR, SImode, operands)"
8982 "xor{l}\t{%2, %0|%0, %2}"
8983 [(set_attr "type" "alu")
8984 (set_attr "mode" "SI")])
8986 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8987 ;; ??? Special case for immediate operand is missing - it is tricky.
8988 (define_insn "*xorsi_2_zext"
8989 [(set (reg FLAGS_REG)
8990 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8991 (match_operand:SI 2 "general_operand" "rim"))
8993 (set (match_operand:DI 0 "register_operand" "=r")
8994 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8995 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8996 && ix86_binary_operator_ok (XOR, SImode, operands)"
8997 "xor{l}\t{%2, %k0|%k0, %2}"
8998 [(set_attr "type" "alu")
8999 (set_attr "mode" "SI")])
9001 (define_insn "*xorsi_2_zext_imm"
9002 [(set (reg FLAGS_REG)
9003 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9004 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9006 (set (match_operand:DI 0 "register_operand" "=r")
9007 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9008 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9009 && ix86_binary_operator_ok (XOR, SImode, operands)"
9010 "xor{l}\t{%2, %k0|%k0, %2}"
9011 [(set_attr "type" "alu")
9012 (set_attr "mode" "SI")])
9014 (define_insn "*xorsi_3"
9015 [(set (reg FLAGS_REG)
9016 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9017 (match_operand:SI 2 "general_operand" "rim"))
9019 (clobber (match_scratch:SI 0 "=r"))]
9020 "ix86_match_ccmode (insn, CCNOmode)
9021 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9022 "xor{l}\t{%2, %0|%0, %2}"
9023 [(set_attr "type" "alu")
9024 (set_attr "mode" "SI")])
9026 (define_expand "xorhi3"
9027 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9028 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9029 (match_operand:HI 2 "general_operand" "")))
9030 (clobber (reg:CC FLAGS_REG))]
9031 "TARGET_HIMODE_MATH"
9032 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9034 (define_insn "*xorhi_1"
9035 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9036 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9037 (match_operand:HI 2 "general_operand" "rmi,ri")))
9038 (clobber (reg:CC FLAGS_REG))]
9039 "ix86_binary_operator_ok (XOR, HImode, operands)"
9040 "xor{w}\t{%2, %0|%0, %2}"
9041 [(set_attr "type" "alu")
9042 (set_attr "mode" "HI")])
9044 (define_insn "*xorhi_2"
9045 [(set (reg FLAGS_REG)
9046 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9047 (match_operand:HI 2 "general_operand" "rim,ri"))
9049 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9050 (xor:HI (match_dup 1) (match_dup 2)))]
9051 "ix86_match_ccmode (insn, CCNOmode)
9052 && ix86_binary_operator_ok (XOR, HImode, operands)"
9053 "xor{w}\t{%2, %0|%0, %2}"
9054 [(set_attr "type" "alu")
9055 (set_attr "mode" "HI")])
9057 (define_insn "*xorhi_3"
9058 [(set (reg FLAGS_REG)
9059 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9060 (match_operand:HI 2 "general_operand" "rim"))
9062 (clobber (match_scratch:HI 0 "=r"))]
9063 "ix86_match_ccmode (insn, CCNOmode)
9064 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9065 "xor{w}\t{%2, %0|%0, %2}"
9066 [(set_attr "type" "alu")
9067 (set_attr "mode" "HI")])
9069 (define_expand "xorqi3"
9070 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9071 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9072 (match_operand:QI 2 "general_operand" "")))
9073 (clobber (reg:CC FLAGS_REG))]
9074 "TARGET_QIMODE_MATH"
9075 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9077 ;; %%% Potential partial reg stall on alternative 2. What to do?
9078 (define_insn "*xorqi_1"
9079 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9080 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9081 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9082 (clobber (reg:CC FLAGS_REG))]
9083 "ix86_binary_operator_ok (XOR, QImode, operands)"
9085 xor{b}\t{%2, %0|%0, %2}
9086 xor{b}\t{%2, %0|%0, %2}
9087 xor{l}\t{%k2, %k0|%k0, %k2}"
9088 [(set_attr "type" "alu")
9089 (set_attr "mode" "QI,QI,SI")])
9091 (define_insn "*xorqi_1_slp"
9092 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9093 (xor:QI (match_dup 0)
9094 (match_operand:QI 1 "general_operand" "qi,qmi")))
9095 (clobber (reg:CC FLAGS_REG))]
9096 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9097 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9098 "xor{b}\t{%1, %0|%0, %1}"
9099 [(set_attr "type" "alu1")
9100 (set_attr "mode" "QI")])
9102 (define_insn "xorqi_ext_0"
9103 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9108 (match_operand 1 "ext_register_operand" "0")
9111 (match_operand 2 "const_int_operand" "n")))
9112 (clobber (reg:CC FLAGS_REG))]
9113 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9114 "xor{b}\t{%2, %h0|%h0, %2}"
9115 [(set_attr "type" "alu")
9116 (set_attr "length_immediate" "1")
9117 (set_attr "mode" "QI")])
9119 (define_insn "*xorqi_ext_1"
9120 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9125 (match_operand 1 "ext_register_operand" "0")
9129 (match_operand:QI 2 "general_operand" "Qm"))))
9130 (clobber (reg:CC FLAGS_REG))]
9132 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9133 "xor{b}\t{%2, %h0|%h0, %2}"
9134 [(set_attr "type" "alu")
9135 (set_attr "length_immediate" "0")
9136 (set_attr "mode" "QI")])
9138 (define_insn "*xorqi_ext_1_rex64"
9139 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9144 (match_operand 1 "ext_register_operand" "0")
9148 (match_operand 2 "ext_register_operand" "Q"))))
9149 (clobber (reg:CC FLAGS_REG))]
9151 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9152 "xor{b}\t{%2, %h0|%h0, %2}"
9153 [(set_attr "type" "alu")
9154 (set_attr "length_immediate" "0")
9155 (set_attr "mode" "QI")])
9157 (define_insn "*xorqi_ext_2"
9158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9162 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9165 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9168 (clobber (reg:CC FLAGS_REG))]
9169 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9170 "xor{b}\t{%h2, %h0|%h0, %h2}"
9171 [(set_attr "type" "alu")
9172 (set_attr "length_immediate" "0")
9173 (set_attr "mode" "QI")])
9175 (define_insn "*xorqi_cc_1"
9176 [(set (reg FLAGS_REG)
9178 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9179 (match_operand:QI 2 "general_operand" "qim,qi"))
9181 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9182 (xor:QI (match_dup 1) (match_dup 2)))]
9183 "ix86_match_ccmode (insn, CCNOmode)
9184 && ix86_binary_operator_ok (XOR, QImode, operands)"
9185 "xor{b}\t{%2, %0|%0, %2}"
9186 [(set_attr "type" "alu")
9187 (set_attr "mode" "QI")])
9189 (define_insn "*xorqi_2_slp"
9190 [(set (reg FLAGS_REG)
9191 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9192 (match_operand:QI 1 "general_operand" "qim,qi"))
9194 (set (strict_low_part (match_dup 0))
9195 (xor:QI (match_dup 0) (match_dup 1)))]
9196 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9197 && ix86_match_ccmode (insn, CCNOmode)
9198 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9199 "xor{b}\t{%1, %0|%0, %1}"
9200 [(set_attr "type" "alu1")
9201 (set_attr "mode" "QI")])
9203 (define_insn "*xorqi_cc_2"
9204 [(set (reg FLAGS_REG)
9206 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9207 (match_operand:QI 2 "general_operand" "qim"))
9209 (clobber (match_scratch:QI 0 "=q"))]
9210 "ix86_match_ccmode (insn, CCNOmode)
9211 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9212 "xor{b}\t{%2, %0|%0, %2}"
9213 [(set_attr "type" "alu")
9214 (set_attr "mode" "QI")])
9216 (define_insn "*xorqi_cc_ext_1"
9217 [(set (reg FLAGS_REG)
9221 (match_operand 1 "ext_register_operand" "0")
9224 (match_operand:QI 2 "general_operand" "qmn"))
9226 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9230 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9232 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9233 "xor{b}\t{%2, %h0|%h0, %2}"
9234 [(set_attr "type" "alu")
9235 (set_attr "mode" "QI")])
9237 (define_insn "*xorqi_cc_ext_1_rex64"
9238 [(set (reg FLAGS_REG)
9242 (match_operand 1 "ext_register_operand" "0")
9245 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9247 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9251 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9253 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9254 "xor{b}\t{%2, %h0|%h0, %2}"
9255 [(set_attr "type" "alu")
9256 (set_attr "mode" "QI")])
9258 (define_expand "xorqi_cc_ext_1"
9260 (set (reg:CCNO FLAGS_REG)
9264 (match_operand 1 "ext_register_operand" "")
9267 (match_operand:QI 2 "general_operand" ""))
9269 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9273 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9279 [(set (match_operand 0 "register_operand" "")
9280 (xor (match_operand 1 "register_operand" "")
9281 (match_operand 2 "const_int_operand" "")))
9282 (clobber (reg:CC FLAGS_REG))]
9284 && QI_REG_P (operands[0])
9285 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9286 && !(INTVAL (operands[2]) & ~(255 << 8))
9287 && GET_MODE (operands[0]) != QImode"
9288 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9289 (xor:SI (zero_extract:SI (match_dup 1)
9290 (const_int 8) (const_int 8))
9292 (clobber (reg:CC FLAGS_REG))])]
9293 "operands[0] = gen_lowpart (SImode, operands[0]);
9294 operands[1] = gen_lowpart (SImode, operands[1]);
9295 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9297 ;; Since XOR can be encoded with sign extended immediate, this is only
9298 ;; profitable when 7th bit is set.
9300 [(set (match_operand 0 "register_operand" "")
9301 (xor (match_operand 1 "general_operand" "")
9302 (match_operand 2 "const_int_operand" "")))
9303 (clobber (reg:CC FLAGS_REG))]
9305 && ANY_QI_REG_P (operands[0])
9306 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9307 && !(INTVAL (operands[2]) & ~255)
9308 && (INTVAL (operands[2]) & 128)
9309 && GET_MODE (operands[0]) != QImode"
9310 [(parallel [(set (strict_low_part (match_dup 0))
9311 (xor:QI (match_dup 1)
9313 (clobber (reg:CC FLAGS_REG))])]
9314 "operands[0] = gen_lowpart (QImode, operands[0]);
9315 operands[1] = gen_lowpart (QImode, operands[1]);
9316 operands[2] = gen_lowpart (QImode, operands[2]);")
9318 ;; Negation instructions
9320 (define_expand "negti2"
9321 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9322 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9323 (clobber (reg:CC FLAGS_REG))])]
9325 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9327 (define_insn "*negti2_1"
9328 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9329 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9330 (clobber (reg:CC FLAGS_REG))]
9332 && ix86_unary_operator_ok (NEG, TImode, operands)"
9336 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9337 (neg:TI (match_operand:TI 1 "general_operand" "")))
9338 (clobber (reg:CC FLAGS_REG))]
9339 "TARGET_64BIT && reload_completed"
9341 [(set (reg:CCZ FLAGS_REG)
9342 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9343 (set (match_dup 0) (neg:DI (match_dup 2)))])
9346 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9349 (clobber (reg:CC FLAGS_REG))])
9352 (neg:DI (match_dup 1)))
9353 (clobber (reg:CC FLAGS_REG))])]
9354 "split_ti (operands+1, 1, operands+2, operands+3);
9355 split_ti (operands+0, 1, operands+0, operands+1);")
9357 (define_expand "negdi2"
9358 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9359 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9360 (clobber (reg:CC FLAGS_REG))])]
9362 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9364 (define_insn "*negdi2_1"
9365 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9366 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9367 (clobber (reg:CC FLAGS_REG))]
9369 && ix86_unary_operator_ok (NEG, DImode, operands)"
9373 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9374 (neg:DI (match_operand:DI 1 "general_operand" "")))
9375 (clobber (reg:CC FLAGS_REG))]
9376 "!TARGET_64BIT && reload_completed"
9378 [(set (reg:CCZ FLAGS_REG)
9379 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9380 (set (match_dup 0) (neg:SI (match_dup 2)))])
9383 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9386 (clobber (reg:CC FLAGS_REG))])
9389 (neg:SI (match_dup 1)))
9390 (clobber (reg:CC FLAGS_REG))])]
9391 "split_di (operands+1, 1, operands+2, operands+3);
9392 split_di (operands+0, 1, operands+0, operands+1);")
9394 (define_insn "*negdi2_1_rex64"
9395 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9396 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9397 (clobber (reg:CC FLAGS_REG))]
9398 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9400 [(set_attr "type" "negnot")
9401 (set_attr "mode" "DI")])
9403 ;; The problem with neg is that it does not perform (compare x 0),
9404 ;; it really performs (compare 0 x), which leaves us with the zero
9405 ;; flag being the only useful item.
9407 (define_insn "*negdi2_cmpz_rex64"
9408 [(set (reg:CCZ FLAGS_REG)
9409 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9411 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9412 (neg:DI (match_dup 1)))]
9413 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9415 [(set_attr "type" "negnot")
9416 (set_attr "mode" "DI")])
9419 (define_expand "negsi2"
9420 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9421 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9422 (clobber (reg:CC FLAGS_REG))])]
9424 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9426 (define_insn "*negsi2_1"
9427 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9428 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9429 (clobber (reg:CC FLAGS_REG))]
9430 "ix86_unary_operator_ok (NEG, SImode, operands)"
9432 [(set_attr "type" "negnot")
9433 (set_attr "mode" "SI")])
9435 ;; Combine is quite creative about this pattern.
9436 (define_insn "*negsi2_1_zext"
9437 [(set (match_operand:DI 0 "register_operand" "=r")
9438 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9441 (clobber (reg:CC FLAGS_REG))]
9442 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9444 [(set_attr "type" "negnot")
9445 (set_attr "mode" "SI")])
9447 ;; The problem with neg is that it does not perform (compare x 0),
9448 ;; it really performs (compare 0 x), which leaves us with the zero
9449 ;; flag being the only useful item.
9451 (define_insn "*negsi2_cmpz"
9452 [(set (reg:CCZ FLAGS_REG)
9453 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9455 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9456 (neg:SI (match_dup 1)))]
9457 "ix86_unary_operator_ok (NEG, SImode, operands)"
9459 [(set_attr "type" "negnot")
9460 (set_attr "mode" "SI")])
9462 (define_insn "*negsi2_cmpz_zext"
9463 [(set (reg:CCZ FLAGS_REG)
9464 (compare:CCZ (lshiftrt:DI
9466 (match_operand:DI 1 "register_operand" "0")
9470 (set (match_operand:DI 0 "register_operand" "=r")
9471 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9474 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9476 [(set_attr "type" "negnot")
9477 (set_attr "mode" "SI")])
9479 (define_expand "neghi2"
9480 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9481 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9482 (clobber (reg:CC FLAGS_REG))])]
9483 "TARGET_HIMODE_MATH"
9484 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9486 (define_insn "*neghi2_1"
9487 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9488 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9489 (clobber (reg:CC FLAGS_REG))]
9490 "ix86_unary_operator_ok (NEG, HImode, operands)"
9492 [(set_attr "type" "negnot")
9493 (set_attr "mode" "HI")])
9495 (define_insn "*neghi2_cmpz"
9496 [(set (reg:CCZ FLAGS_REG)
9497 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9499 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9500 (neg:HI (match_dup 1)))]
9501 "ix86_unary_operator_ok (NEG, HImode, operands)"
9503 [(set_attr "type" "negnot")
9504 (set_attr "mode" "HI")])
9506 (define_expand "negqi2"
9507 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9508 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9509 (clobber (reg:CC FLAGS_REG))])]
9510 "TARGET_QIMODE_MATH"
9511 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9513 (define_insn "*negqi2_1"
9514 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9515 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9516 (clobber (reg:CC FLAGS_REG))]
9517 "ix86_unary_operator_ok (NEG, QImode, operands)"
9519 [(set_attr "type" "negnot")
9520 (set_attr "mode" "QI")])
9522 (define_insn "*negqi2_cmpz"
9523 [(set (reg:CCZ FLAGS_REG)
9524 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9526 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9527 (neg:QI (match_dup 1)))]
9528 "ix86_unary_operator_ok (NEG, QImode, operands)"
9530 [(set_attr "type" "negnot")
9531 (set_attr "mode" "QI")])
9533 ;; Changing of sign for FP values is doable using integer unit too.
9535 (define_expand "negsf2"
9536 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9537 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9538 "TARGET_80387 || TARGET_SSE_MATH"
9539 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9541 (define_expand "abssf2"
9542 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9543 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9544 "TARGET_80387 || TARGET_SSE_MATH"
9545 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9547 (define_insn "*absnegsf2_mixed"
9548 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,f,rm")
9549 (match_operator:SF 3 "absneg_operator"
9550 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0 ,0")]))
9551 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9552 (clobber (reg:CC FLAGS_REG))]
9553 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9554 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9557 (define_insn "*absnegsf2_sse"
9558 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9559 (match_operator:SF 3 "absneg_operator"
9560 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9561 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9562 (clobber (reg:CC FLAGS_REG))]
9564 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9567 (define_insn "*absnegsf2_i387"
9568 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9569 (match_operator:SF 3 "absneg_operator"
9570 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9571 (use (match_operand 2 "" ""))
9572 (clobber (reg:CC FLAGS_REG))]
9573 "TARGET_80387 && !TARGET_SSE_MATH
9574 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9577 (define_expand "copysignsf3"
9578 [(match_operand:SF 0 "register_operand" "")
9579 (match_operand:SF 1 "nonmemory_operand" "")
9580 (match_operand:SF 2 "register_operand" "")]
9583 ix86_expand_copysign (operands);
9587 (define_insn_and_split "copysignsf3_const"
9588 [(set (match_operand:SF 0 "register_operand" "=x")
9590 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9591 (match_operand:SF 2 "register_operand" "0")
9592 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9596 "&& reload_completed"
9599 ix86_split_copysign_const (operands);
9603 (define_insn "copysignsf3_var"
9604 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9606 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9607 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9608 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9609 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9611 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9616 [(set (match_operand:SF 0 "register_operand" "")
9618 [(match_operand:SF 2 "register_operand" "")
9619 (match_operand:SF 3 "register_operand" "")
9620 (match_operand:V4SF 4 "" "")
9621 (match_operand:V4SF 5 "" "")]
9623 (clobber (match_scratch:V4SF 1 ""))]
9624 "TARGET_SSE_MATH && reload_completed"
9627 ix86_split_copysign_var (operands);
9631 (define_expand "negdf2"
9632 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9633 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9634 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9635 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9637 (define_expand "absdf2"
9638 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9639 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9640 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9641 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9643 (define_insn "*absnegdf2_mixed"
9644 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9645 (match_operator:DF 3 "absneg_operator"
9646 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ,0")]))
9647 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9648 (clobber (reg:CC FLAGS_REG))]
9649 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9650 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9653 (define_insn "*absnegdf2_sse"
9654 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9655 (match_operator:DF 3 "absneg_operator"
9656 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9657 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X"))
9658 (clobber (reg:CC FLAGS_REG))]
9659 "TARGET_SSE2 && TARGET_SSE_MATH
9660 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9663 (define_insn "*absnegdf2_i387"
9664 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9665 (match_operator:DF 3 "absneg_operator"
9666 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9667 (use (match_operand 2 "" ""))
9668 (clobber (reg:CC FLAGS_REG))]
9669 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9670 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9673 (define_expand "copysigndf3"
9674 [(match_operand:DF 0 "register_operand" "")
9675 (match_operand:DF 1 "nonmemory_operand" "")
9676 (match_operand:DF 2 "register_operand" "")]
9677 "TARGET_SSE2 && TARGET_SSE_MATH"
9679 ix86_expand_copysign (operands);
9683 (define_insn_and_split "copysigndf3_const"
9684 [(set (match_operand:DF 0 "register_operand" "=x")
9686 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9687 (match_operand:DF 2 "register_operand" "0")
9688 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9690 "TARGET_SSE2 && TARGET_SSE_MATH"
9692 "&& reload_completed"
9695 ix86_split_copysign_const (operands);
9699 (define_insn "copysigndf3_var"
9700 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9702 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9703 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9704 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9705 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9707 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9708 "TARGET_SSE2 && TARGET_SSE_MATH"
9712 [(set (match_operand:DF 0 "register_operand" "")
9714 [(match_operand:DF 2 "register_operand" "")
9715 (match_operand:DF 3 "register_operand" "")
9716 (match_operand:V2DF 4 "" "")
9717 (match_operand:V2DF 5 "" "")]
9719 (clobber (match_scratch:V2DF 1 ""))]
9720 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9723 ix86_split_copysign_var (operands);
9727 (define_expand "negxf2"
9728 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9729 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9731 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9733 (define_expand "absxf2"
9734 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9735 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9737 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9739 (define_insn "*absnegxf2_i387"
9740 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9741 (match_operator:XF 3 "absneg_operator"
9742 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9743 (use (match_operand 2 "" ""))
9744 (clobber (reg:CC FLAGS_REG))]
9746 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9749 ;; Splitters for fp abs and neg.
9752 [(set (match_operand 0 "fp_register_operand" "")
9753 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9754 (use (match_operand 2 "" ""))
9755 (clobber (reg:CC FLAGS_REG))]
9757 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9760 [(set (match_operand 0 "register_operand" "")
9761 (match_operator 3 "absneg_operator"
9762 [(match_operand 1 "register_operand" "")]))
9763 (use (match_operand 2 "nonimmediate_operand" ""))
9764 (clobber (reg:CC FLAGS_REG))]
9765 "reload_completed && SSE_REG_P (operands[0])"
9766 [(set (match_dup 0) (match_dup 3))]
9768 enum machine_mode mode = GET_MODE (operands[0]);
9769 enum machine_mode vmode = GET_MODE (operands[2]);
9772 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9773 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9774 if (operands_match_p (operands[0], operands[2]))
9777 operands[1] = operands[2];
9780 if (GET_CODE (operands[3]) == ABS)
9781 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9783 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9788 [(set (match_operand:SF 0 "register_operand" "")
9789 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9790 (use (match_operand:V4SF 2 "" ""))
9791 (clobber (reg:CC FLAGS_REG))]
9793 [(parallel [(set (match_dup 0) (match_dup 1))
9794 (clobber (reg:CC FLAGS_REG))])]
9797 operands[0] = gen_lowpart (SImode, operands[0]);
9798 if (GET_CODE (operands[1]) == ABS)
9800 tmp = gen_int_mode (0x7fffffff, SImode);
9801 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9805 tmp = gen_int_mode (0x80000000, SImode);
9806 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9812 [(set (match_operand:DF 0 "register_operand" "")
9813 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9814 (use (match_operand 2 "" ""))
9815 (clobber (reg:CC FLAGS_REG))]
9817 [(parallel [(set (match_dup 0) (match_dup 1))
9818 (clobber (reg:CC FLAGS_REG))])]
9823 tmp = gen_lowpart (DImode, operands[0]);
9824 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9827 if (GET_CODE (operands[1]) == ABS)
9830 tmp = gen_rtx_NOT (DImode, tmp);
9834 operands[0] = gen_highpart (SImode, operands[0]);
9835 if (GET_CODE (operands[1]) == ABS)
9837 tmp = gen_int_mode (0x7fffffff, SImode);
9838 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9842 tmp = gen_int_mode (0x80000000, SImode);
9843 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9850 [(set (match_operand:XF 0 "register_operand" "")
9851 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9852 (use (match_operand 2 "" ""))
9853 (clobber (reg:CC FLAGS_REG))]
9855 [(parallel [(set (match_dup 0) (match_dup 1))
9856 (clobber (reg:CC FLAGS_REG))])]
9859 operands[0] = gen_rtx_REG (SImode,
9860 true_regnum (operands[0])
9861 + (TARGET_64BIT ? 1 : 2));
9862 if (GET_CODE (operands[1]) == ABS)
9864 tmp = GEN_INT (0x7fff);
9865 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9869 tmp = GEN_INT (0x8000);
9870 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9876 [(set (match_operand 0 "memory_operand" "")
9877 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9878 (use (match_operand 2 "" ""))
9879 (clobber (reg:CC FLAGS_REG))]
9881 [(parallel [(set (match_dup 0) (match_dup 1))
9882 (clobber (reg:CC FLAGS_REG))])]
9884 enum machine_mode mode = GET_MODE (operands[0]);
9885 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9888 operands[0] = adjust_address (operands[0], QImode, size - 1);
9889 if (GET_CODE (operands[1]) == ABS)
9891 tmp = gen_int_mode (0x7f, QImode);
9892 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9896 tmp = gen_int_mode (0x80, QImode);
9897 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9902 ;; Conditionalize these after reload. If they match before reload, we
9903 ;; lose the clobber and ability to use integer instructions.
9905 (define_insn "*negsf2_1"
9906 [(set (match_operand:SF 0 "register_operand" "=f")
9907 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9908 "TARGET_80387 && reload_completed"
9910 [(set_attr "type" "fsgn")
9911 (set_attr "mode" "SF")])
9913 (define_insn "*negdf2_1"
9914 [(set (match_operand:DF 0 "register_operand" "=f")
9915 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9916 "TARGET_80387 && reload_completed"
9918 [(set_attr "type" "fsgn")
9919 (set_attr "mode" "DF")])
9921 (define_insn "*negxf2_1"
9922 [(set (match_operand:XF 0 "register_operand" "=f")
9923 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9924 "TARGET_80387 && reload_completed"
9926 [(set_attr "type" "fsgn")
9927 (set_attr "mode" "XF")])
9929 (define_insn "*abssf2_1"
9930 [(set (match_operand:SF 0 "register_operand" "=f")
9931 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9932 "TARGET_80387 && reload_completed"
9934 [(set_attr "type" "fsgn")
9935 (set_attr "mode" "SF")])
9937 (define_insn "*absdf2_1"
9938 [(set (match_operand:DF 0 "register_operand" "=f")
9939 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9940 "TARGET_80387 && reload_completed"
9942 [(set_attr "type" "fsgn")
9943 (set_attr "mode" "DF")])
9945 (define_insn "*absxf2_1"
9946 [(set (match_operand:XF 0 "register_operand" "=f")
9947 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9948 "TARGET_80387 && reload_completed"
9950 [(set_attr "type" "fsgn")
9951 (set_attr "mode" "DF")])
9953 (define_insn "*negextendsfdf2"
9954 [(set (match_operand:DF 0 "register_operand" "=f")
9955 (neg:DF (float_extend:DF
9956 (match_operand:SF 1 "register_operand" "0"))))]
9957 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9959 [(set_attr "type" "fsgn")
9960 (set_attr "mode" "DF")])
9962 (define_insn "*negextenddfxf2"
9963 [(set (match_operand:XF 0 "register_operand" "=f")
9964 (neg:XF (float_extend:XF
9965 (match_operand:DF 1 "register_operand" "0"))))]
9968 [(set_attr "type" "fsgn")
9969 (set_attr "mode" "XF")])
9971 (define_insn "*negextendsfxf2"
9972 [(set (match_operand:XF 0 "register_operand" "=f")
9973 (neg:XF (float_extend:XF
9974 (match_operand:SF 1 "register_operand" "0"))))]
9977 [(set_attr "type" "fsgn")
9978 (set_attr "mode" "XF")])
9980 (define_insn "*absextendsfdf2"
9981 [(set (match_operand:DF 0 "register_operand" "=f")
9982 (abs:DF (float_extend:DF
9983 (match_operand:SF 1 "register_operand" "0"))))]
9984 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9986 [(set_attr "type" "fsgn")
9987 (set_attr "mode" "DF")])
9989 (define_insn "*absextenddfxf2"
9990 [(set (match_operand:XF 0 "register_operand" "=f")
9991 (abs:XF (float_extend:XF
9992 (match_operand:DF 1 "register_operand" "0"))))]
9995 [(set_attr "type" "fsgn")
9996 (set_attr "mode" "XF")])
9998 (define_insn "*absextendsfxf2"
9999 [(set (match_operand:XF 0 "register_operand" "=f")
10000 (abs:XF (float_extend:XF
10001 (match_operand:SF 1 "register_operand" "0"))))]
10004 [(set_attr "type" "fsgn")
10005 (set_attr "mode" "XF")])
10007 ;; One complement instructions
10009 (define_expand "one_cmpldi2"
10010 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10011 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10013 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10015 (define_insn "*one_cmpldi2_1_rex64"
10016 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10017 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10018 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10020 [(set_attr "type" "negnot")
10021 (set_attr "mode" "DI")])
10023 (define_insn "*one_cmpldi2_2_rex64"
10024 [(set (reg FLAGS_REG)
10025 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10027 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10028 (not:DI (match_dup 1)))]
10029 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10030 && ix86_unary_operator_ok (NOT, DImode, operands)"
10032 [(set_attr "type" "alu1")
10033 (set_attr "mode" "DI")])
10036 [(set (match_operand 0 "flags_reg_operand" "")
10037 (match_operator 2 "compare_operator"
10038 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10040 (set (match_operand:DI 1 "nonimmediate_operand" "")
10041 (not:DI (match_dup 3)))]
10042 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10043 [(parallel [(set (match_dup 0)
10045 [(xor:DI (match_dup 3) (const_int -1))
10048 (xor:DI (match_dup 3) (const_int -1)))])]
10051 (define_expand "one_cmplsi2"
10052 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10053 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10055 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10057 (define_insn "*one_cmplsi2_1"
10058 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10059 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10060 "ix86_unary_operator_ok (NOT, SImode, operands)"
10062 [(set_attr "type" "negnot")
10063 (set_attr "mode" "SI")])
10065 ;; ??? Currently never generated - xor is used instead.
10066 (define_insn "*one_cmplsi2_1_zext"
10067 [(set (match_operand:DI 0 "register_operand" "=r")
10068 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10069 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10071 [(set_attr "type" "negnot")
10072 (set_attr "mode" "SI")])
10074 (define_insn "*one_cmplsi2_2"
10075 [(set (reg FLAGS_REG)
10076 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10078 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10079 (not:SI (match_dup 1)))]
10080 "ix86_match_ccmode (insn, CCNOmode)
10081 && ix86_unary_operator_ok (NOT, SImode, operands)"
10083 [(set_attr "type" "alu1")
10084 (set_attr "mode" "SI")])
10087 [(set (match_operand 0 "flags_reg_operand" "")
10088 (match_operator 2 "compare_operator"
10089 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10091 (set (match_operand:SI 1 "nonimmediate_operand" "")
10092 (not:SI (match_dup 3)))]
10093 "ix86_match_ccmode (insn, CCNOmode)"
10094 [(parallel [(set (match_dup 0)
10095 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10098 (xor:SI (match_dup 3) (const_int -1)))])]
10101 ;; ??? Currently never generated - xor is used instead.
10102 (define_insn "*one_cmplsi2_2_zext"
10103 [(set (reg FLAGS_REG)
10104 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10106 (set (match_operand:DI 0 "register_operand" "=r")
10107 (zero_extend:DI (not:SI (match_dup 1))))]
10108 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10109 && ix86_unary_operator_ok (NOT, SImode, operands)"
10111 [(set_attr "type" "alu1")
10112 (set_attr "mode" "SI")])
10115 [(set (match_operand 0 "flags_reg_operand" "")
10116 (match_operator 2 "compare_operator"
10117 [(not:SI (match_operand:SI 3 "register_operand" ""))
10119 (set (match_operand:DI 1 "register_operand" "")
10120 (zero_extend:DI (not:SI (match_dup 3))))]
10121 "ix86_match_ccmode (insn, CCNOmode)"
10122 [(parallel [(set (match_dup 0)
10123 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10126 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10129 (define_expand "one_cmplhi2"
10130 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10131 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10132 "TARGET_HIMODE_MATH"
10133 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10135 (define_insn "*one_cmplhi2_1"
10136 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10137 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10138 "ix86_unary_operator_ok (NOT, HImode, operands)"
10140 [(set_attr "type" "negnot")
10141 (set_attr "mode" "HI")])
10143 (define_insn "*one_cmplhi2_2"
10144 [(set (reg FLAGS_REG)
10145 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10147 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10148 (not:HI (match_dup 1)))]
10149 "ix86_match_ccmode (insn, CCNOmode)
10150 && ix86_unary_operator_ok (NEG, HImode, operands)"
10152 [(set_attr "type" "alu1")
10153 (set_attr "mode" "HI")])
10156 [(set (match_operand 0 "flags_reg_operand" "")
10157 (match_operator 2 "compare_operator"
10158 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10160 (set (match_operand:HI 1 "nonimmediate_operand" "")
10161 (not:HI (match_dup 3)))]
10162 "ix86_match_ccmode (insn, CCNOmode)"
10163 [(parallel [(set (match_dup 0)
10164 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10167 (xor:HI (match_dup 3) (const_int -1)))])]
10170 ;; %%% Potential partial reg stall on alternative 1. What to do?
10171 (define_expand "one_cmplqi2"
10172 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10173 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10174 "TARGET_QIMODE_MATH"
10175 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10177 (define_insn "*one_cmplqi2_1"
10178 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10179 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10180 "ix86_unary_operator_ok (NOT, QImode, operands)"
10184 [(set_attr "type" "negnot")
10185 (set_attr "mode" "QI,SI")])
10187 (define_insn "*one_cmplqi2_2"
10188 [(set (reg FLAGS_REG)
10189 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10191 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10192 (not:QI (match_dup 1)))]
10193 "ix86_match_ccmode (insn, CCNOmode)
10194 && ix86_unary_operator_ok (NOT, QImode, operands)"
10196 [(set_attr "type" "alu1")
10197 (set_attr "mode" "QI")])
10200 [(set (match_operand 0 "flags_reg_operand" "")
10201 (match_operator 2 "compare_operator"
10202 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10204 (set (match_operand:QI 1 "nonimmediate_operand" "")
10205 (not:QI (match_dup 3)))]
10206 "ix86_match_ccmode (insn, CCNOmode)"
10207 [(parallel [(set (match_dup 0)
10208 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10211 (xor:QI (match_dup 3) (const_int -1)))])]
10214 ;; Arithmetic shift instructions
10216 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10217 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10218 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10219 ;; from the assembler input.
10221 ;; This instruction shifts the target reg/mem as usual, but instead of
10222 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10223 ;; is a left shift double, bits are taken from the high order bits of
10224 ;; reg, else if the insn is a shift right double, bits are taken from the
10225 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10226 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10228 ;; Since sh[lr]d does not change the `reg' operand, that is done
10229 ;; separately, making all shifts emit pairs of shift double and normal
10230 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10231 ;; support a 63 bit shift, each shift where the count is in a reg expands
10232 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10234 ;; If the shift count is a constant, we need never emit more than one
10235 ;; shift pair, instead using moves and sign extension for counts greater
10238 (define_expand "ashlti3"
10239 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10240 (ashift:TI (match_operand:TI 1 "register_operand" "")
10241 (match_operand:QI 2 "nonmemory_operand" "")))
10242 (clobber (reg:CC FLAGS_REG))])]
10245 if (! immediate_operand (operands[2], QImode))
10247 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10250 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10254 (define_insn "ashlti3_1"
10255 [(set (match_operand:TI 0 "register_operand" "=r")
10256 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10257 (match_operand:QI 2 "register_operand" "c")))
10258 (clobber (match_scratch:DI 3 "=&r"))
10259 (clobber (reg:CC FLAGS_REG))]
10262 [(set_attr "type" "multi")])
10264 (define_insn "*ashlti3_2"
10265 [(set (match_operand:TI 0 "register_operand" "=r")
10266 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10267 (match_operand:QI 2 "immediate_operand" "O")))
10268 (clobber (reg:CC FLAGS_REG))]
10271 [(set_attr "type" "multi")])
10274 [(set (match_operand:TI 0 "register_operand" "")
10275 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10276 (match_operand:QI 2 "register_operand" "")))
10277 (clobber (match_scratch:DI 3 ""))
10278 (clobber (reg:CC FLAGS_REG))]
10279 "TARGET_64BIT && reload_completed"
10281 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10284 [(set (match_operand:TI 0 "register_operand" "")
10285 (ashift:TI (match_operand:TI 1 "register_operand" "")
10286 (match_operand:QI 2 "immediate_operand" "")))
10287 (clobber (reg:CC FLAGS_REG))]
10288 "TARGET_64BIT && reload_completed"
10290 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10292 (define_insn "x86_64_shld"
10293 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10294 (ior:DI (ashift:DI (match_dup 0)
10295 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10296 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10297 (minus:QI (const_int 64) (match_dup 2)))))
10298 (clobber (reg:CC FLAGS_REG))]
10301 shld{q}\t{%2, %1, %0|%0, %1, %2}
10302 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10303 [(set_attr "type" "ishift")
10304 (set_attr "prefix_0f" "1")
10305 (set_attr "mode" "DI")
10306 (set_attr "athlon_decode" "vector")])
10308 (define_expand "x86_64_shift_adj"
10309 [(set (reg:CCZ FLAGS_REG)
10310 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10313 (set (match_operand:DI 0 "register_operand" "")
10314 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10315 (match_operand:DI 1 "register_operand" "")
10318 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10319 (match_operand:DI 3 "register_operand" "r")
10324 (define_expand "ashldi3"
10325 [(set (match_operand:DI 0 "shiftdi_operand" "")
10326 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10327 (match_operand:QI 2 "nonmemory_operand" "")))]
10329 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10331 (define_insn "*ashldi3_1_rex64"
10332 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10333 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10334 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10335 (clobber (reg:CC FLAGS_REG))]
10336 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10338 switch (get_attr_type (insn))
10341 gcc_assert (operands[2] == const1_rtx);
10342 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10343 return "add{q}\t{%0, %0|%0, %0}";
10346 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10347 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10348 operands[1] = gen_rtx_MULT (DImode, operands[1],
10349 GEN_INT (1 << INTVAL (operands[2])));
10350 return "lea{q}\t{%a1, %0|%0, %a1}";
10353 if (REG_P (operands[2]))
10354 return "sal{q}\t{%b2, %0|%0, %b2}";
10355 else if (operands[2] == const1_rtx
10356 && (TARGET_SHIFT1 || optimize_size))
10357 return "sal{q}\t%0";
10359 return "sal{q}\t{%2, %0|%0, %2}";
10362 [(set (attr "type")
10363 (cond [(eq_attr "alternative" "1")
10364 (const_string "lea")
10365 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10367 (match_operand 0 "register_operand" ""))
10368 (match_operand 2 "const1_operand" ""))
10369 (const_string "alu")
10371 (const_string "ishift")))
10372 (set_attr "mode" "DI")])
10374 ;; Convert lea to the lea pattern to avoid flags dependency.
10376 [(set (match_operand:DI 0 "register_operand" "")
10377 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10378 (match_operand:QI 2 "immediate_operand" "")))
10379 (clobber (reg:CC FLAGS_REG))]
10380 "TARGET_64BIT && reload_completed
10381 && true_regnum (operands[0]) != true_regnum (operands[1])"
10382 [(set (match_dup 0)
10383 (mult:DI (match_dup 1)
10385 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10387 ;; This pattern can't accept a variable shift count, since shifts by
10388 ;; zero don't affect the flags. We assume that shifts by constant
10389 ;; zero are optimized away.
10390 (define_insn "*ashldi3_cmp_rex64"
10391 [(set (reg FLAGS_REG)
10393 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10394 (match_operand:QI 2 "immediate_operand" "e"))
10396 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10397 (ashift:DI (match_dup 1) (match_dup 2)))]
10398 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10399 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10401 switch (get_attr_type (insn))
10404 gcc_assert (operands[2] == const1_rtx);
10405 return "add{q}\t{%0, %0|%0, %0}";
10408 if (REG_P (operands[2]))
10409 return "sal{q}\t{%b2, %0|%0, %b2}";
10410 else if (operands[2] == const1_rtx
10411 && (TARGET_SHIFT1 || optimize_size))
10412 return "sal{q}\t%0";
10414 return "sal{q}\t{%2, %0|%0, %2}";
10417 [(set (attr "type")
10418 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10420 (match_operand 0 "register_operand" ""))
10421 (match_operand 2 "const1_operand" ""))
10422 (const_string "alu")
10424 (const_string "ishift")))
10425 (set_attr "mode" "DI")])
10427 (define_insn "*ashldi3_1"
10428 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10429 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10430 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10431 (clobber (reg:CC FLAGS_REG))]
10434 [(set_attr "type" "multi")])
10436 ;; By default we don't ask for a scratch register, because when DImode
10437 ;; values are manipulated, registers are already at a premium. But if
10438 ;; we have one handy, we won't turn it away.
10440 [(match_scratch:SI 3 "r")
10441 (parallel [(set (match_operand:DI 0 "register_operand" "")
10442 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10443 (match_operand:QI 2 "nonmemory_operand" "")))
10444 (clobber (reg:CC FLAGS_REG))])
10446 "!TARGET_64BIT && TARGET_CMOVE"
10448 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10451 [(set (match_operand:DI 0 "register_operand" "")
10452 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10453 (match_operand:QI 2 "nonmemory_operand" "")))
10454 (clobber (reg:CC FLAGS_REG))]
10455 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10456 ? flow2_completed : reload_completed)"
10458 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10460 (define_insn "x86_shld_1"
10461 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10462 (ior:SI (ashift:SI (match_dup 0)
10463 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10464 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10465 (minus:QI (const_int 32) (match_dup 2)))))
10466 (clobber (reg:CC FLAGS_REG))]
10469 shld{l}\t{%2, %1, %0|%0, %1, %2}
10470 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10471 [(set_attr "type" "ishift")
10472 (set_attr "prefix_0f" "1")
10473 (set_attr "mode" "SI")
10474 (set_attr "pent_pair" "np")
10475 (set_attr "athlon_decode" "vector")])
10477 (define_expand "x86_shift_adj_1"
10478 [(set (reg:CCZ FLAGS_REG)
10479 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10482 (set (match_operand:SI 0 "register_operand" "")
10483 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10484 (match_operand:SI 1 "register_operand" "")
10487 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10488 (match_operand:SI 3 "register_operand" "r")
10493 (define_expand "x86_shift_adj_2"
10494 [(use (match_operand:SI 0 "register_operand" ""))
10495 (use (match_operand:SI 1 "register_operand" ""))
10496 (use (match_operand:QI 2 "register_operand" ""))]
10499 rtx label = gen_label_rtx ();
10502 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10504 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10505 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10506 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10507 gen_rtx_LABEL_REF (VOIDmode, label),
10509 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10510 JUMP_LABEL (tmp) = label;
10512 emit_move_insn (operands[0], operands[1]);
10513 ix86_expand_clear (operands[1]);
10515 emit_label (label);
10516 LABEL_NUSES (label) = 1;
10521 (define_expand "ashlsi3"
10522 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10523 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10524 (match_operand:QI 2 "nonmemory_operand" "")))
10525 (clobber (reg:CC FLAGS_REG))]
10527 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10529 (define_insn "*ashlsi3_1"
10530 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10531 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10532 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10533 (clobber (reg:CC FLAGS_REG))]
10534 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10536 switch (get_attr_type (insn))
10539 gcc_assert (operands[2] == const1_rtx);
10540 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10541 return "add{l}\t{%0, %0|%0, %0}";
10547 if (REG_P (operands[2]))
10548 return "sal{l}\t{%b2, %0|%0, %b2}";
10549 else if (operands[2] == const1_rtx
10550 && (TARGET_SHIFT1 || optimize_size))
10551 return "sal{l}\t%0";
10553 return "sal{l}\t{%2, %0|%0, %2}";
10556 [(set (attr "type")
10557 (cond [(eq_attr "alternative" "1")
10558 (const_string "lea")
10559 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10561 (match_operand 0 "register_operand" ""))
10562 (match_operand 2 "const1_operand" ""))
10563 (const_string "alu")
10565 (const_string "ishift")))
10566 (set_attr "mode" "SI")])
10568 ;; Convert lea to the lea pattern to avoid flags dependency.
10570 [(set (match_operand 0 "register_operand" "")
10571 (ashift (match_operand 1 "index_register_operand" "")
10572 (match_operand:QI 2 "const_int_operand" "")))
10573 (clobber (reg:CC FLAGS_REG))]
10575 && true_regnum (operands[0]) != true_regnum (operands[1])
10576 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10580 enum machine_mode mode = GET_MODE (operands[0]);
10582 if (GET_MODE_SIZE (mode) < 4)
10583 operands[0] = gen_lowpart (SImode, operands[0]);
10585 operands[1] = gen_lowpart (Pmode, operands[1]);
10586 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10588 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10589 if (Pmode != SImode)
10590 pat = gen_rtx_SUBREG (SImode, pat, 0);
10591 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10595 ;; Rare case of shifting RSP is handled by generating move and shift
10597 [(set (match_operand 0 "register_operand" "")
10598 (ashift (match_operand 1 "register_operand" "")
10599 (match_operand:QI 2 "const_int_operand" "")))
10600 (clobber (reg:CC FLAGS_REG))]
10602 && true_regnum (operands[0]) != true_regnum (operands[1])"
10606 emit_move_insn (operands[0], operands[1]);
10607 pat = gen_rtx_SET (VOIDmode, operands[0],
10608 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10609 operands[0], operands[2]));
10610 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10611 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10615 (define_insn "*ashlsi3_1_zext"
10616 [(set (match_operand:DI 0 "register_operand" "=r,r")
10617 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10618 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10619 (clobber (reg:CC FLAGS_REG))]
10620 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10622 switch (get_attr_type (insn))
10625 gcc_assert (operands[2] == const1_rtx);
10626 return "add{l}\t{%k0, %k0|%k0, %k0}";
10632 if (REG_P (operands[2]))
10633 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10634 else if (operands[2] == const1_rtx
10635 && (TARGET_SHIFT1 || optimize_size))
10636 return "sal{l}\t%k0";
10638 return "sal{l}\t{%2, %k0|%k0, %2}";
10641 [(set (attr "type")
10642 (cond [(eq_attr "alternative" "1")
10643 (const_string "lea")
10644 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10646 (match_operand 2 "const1_operand" ""))
10647 (const_string "alu")
10649 (const_string "ishift")))
10650 (set_attr "mode" "SI")])
10652 ;; Convert lea to the lea pattern to avoid flags dependency.
10654 [(set (match_operand:DI 0 "register_operand" "")
10655 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10656 (match_operand:QI 2 "const_int_operand" ""))))
10657 (clobber (reg:CC FLAGS_REG))]
10658 "TARGET_64BIT && reload_completed
10659 && true_regnum (operands[0]) != true_regnum (operands[1])"
10660 [(set (match_dup 0) (zero_extend:DI
10661 (subreg:SI (mult:SI (match_dup 1)
10662 (match_dup 2)) 0)))]
10664 operands[1] = gen_lowpart (Pmode, operands[1]);
10665 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10668 ;; This pattern can't accept a variable shift count, since shifts by
10669 ;; zero don't affect the flags. We assume that shifts by constant
10670 ;; zero are optimized away.
10671 (define_insn "*ashlsi3_cmp"
10672 [(set (reg FLAGS_REG)
10674 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10675 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10677 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10678 (ashift:SI (match_dup 1) (match_dup 2)))]
10679 "ix86_match_ccmode (insn, CCGOCmode)
10680 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10682 switch (get_attr_type (insn))
10685 gcc_assert (operands[2] == const1_rtx);
10686 return "add{l}\t{%0, %0|%0, %0}";
10689 if (REG_P (operands[2]))
10690 return "sal{l}\t{%b2, %0|%0, %b2}";
10691 else if (operands[2] == const1_rtx
10692 && (TARGET_SHIFT1 || optimize_size))
10693 return "sal{l}\t%0";
10695 return "sal{l}\t{%2, %0|%0, %2}";
10698 [(set (attr "type")
10699 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10701 (match_operand 0 "register_operand" ""))
10702 (match_operand 2 "const1_operand" ""))
10703 (const_string "alu")
10705 (const_string "ishift")))
10706 (set_attr "mode" "SI")])
10708 (define_insn "*ashlsi3_cmp_zext"
10709 [(set (reg FLAGS_REG)
10711 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10712 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10714 (set (match_operand:DI 0 "register_operand" "=r")
10715 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10716 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10717 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10719 switch (get_attr_type (insn))
10722 gcc_assert (operands[2] == const1_rtx);
10723 return "add{l}\t{%k0, %k0|%k0, %k0}";
10726 if (REG_P (operands[2]))
10727 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10728 else if (operands[2] == const1_rtx
10729 && (TARGET_SHIFT1 || optimize_size))
10730 return "sal{l}\t%k0";
10732 return "sal{l}\t{%2, %k0|%k0, %2}";
10735 [(set (attr "type")
10736 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10738 (match_operand 2 "const1_operand" ""))
10739 (const_string "alu")
10741 (const_string "ishift")))
10742 (set_attr "mode" "SI")])
10744 (define_expand "ashlhi3"
10745 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10746 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10747 (match_operand:QI 2 "nonmemory_operand" "")))
10748 (clobber (reg:CC FLAGS_REG))]
10749 "TARGET_HIMODE_MATH"
10750 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10752 (define_insn "*ashlhi3_1_lea"
10753 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10754 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10755 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10756 (clobber (reg:CC FLAGS_REG))]
10757 "!TARGET_PARTIAL_REG_STALL
10758 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10760 switch (get_attr_type (insn))
10765 gcc_assert (operands[2] == const1_rtx);
10766 return "add{w}\t{%0, %0|%0, %0}";
10769 if (REG_P (operands[2]))
10770 return "sal{w}\t{%b2, %0|%0, %b2}";
10771 else if (operands[2] == const1_rtx
10772 && (TARGET_SHIFT1 || optimize_size))
10773 return "sal{w}\t%0";
10775 return "sal{w}\t{%2, %0|%0, %2}";
10778 [(set (attr "type")
10779 (cond [(eq_attr "alternative" "1")
10780 (const_string "lea")
10781 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10783 (match_operand 0 "register_operand" ""))
10784 (match_operand 2 "const1_operand" ""))
10785 (const_string "alu")
10787 (const_string "ishift")))
10788 (set_attr "mode" "HI,SI")])
10790 (define_insn "*ashlhi3_1"
10791 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10792 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10793 (match_operand:QI 2 "nonmemory_operand" "cI")))
10794 (clobber (reg:CC FLAGS_REG))]
10795 "TARGET_PARTIAL_REG_STALL
10796 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10798 switch (get_attr_type (insn))
10801 gcc_assert (operands[2] == const1_rtx);
10802 return "add{w}\t{%0, %0|%0, %0}";
10805 if (REG_P (operands[2]))
10806 return "sal{w}\t{%b2, %0|%0, %b2}";
10807 else if (operands[2] == const1_rtx
10808 && (TARGET_SHIFT1 || optimize_size))
10809 return "sal{w}\t%0";
10811 return "sal{w}\t{%2, %0|%0, %2}";
10814 [(set (attr "type")
10815 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10817 (match_operand 0 "register_operand" ""))
10818 (match_operand 2 "const1_operand" ""))
10819 (const_string "alu")
10821 (const_string "ishift")))
10822 (set_attr "mode" "HI")])
10824 ;; This pattern can't accept a variable shift count, since shifts by
10825 ;; zero don't affect the flags. We assume that shifts by constant
10826 ;; zero are optimized away.
10827 (define_insn "*ashlhi3_cmp"
10828 [(set (reg FLAGS_REG)
10830 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10831 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10833 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10834 (ashift:HI (match_dup 1) (match_dup 2)))]
10835 "ix86_match_ccmode (insn, CCGOCmode)
10836 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10838 switch (get_attr_type (insn))
10841 gcc_assert (operands[2] == const1_rtx);
10842 return "add{w}\t{%0, %0|%0, %0}";
10845 if (REG_P (operands[2]))
10846 return "sal{w}\t{%b2, %0|%0, %b2}";
10847 else if (operands[2] == const1_rtx
10848 && (TARGET_SHIFT1 || optimize_size))
10849 return "sal{w}\t%0";
10851 return "sal{w}\t{%2, %0|%0, %2}";
10854 [(set (attr "type")
10855 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10857 (match_operand 0 "register_operand" ""))
10858 (match_operand 2 "const1_operand" ""))
10859 (const_string "alu")
10861 (const_string "ishift")))
10862 (set_attr "mode" "HI")])
10864 (define_expand "ashlqi3"
10865 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10866 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10867 (match_operand:QI 2 "nonmemory_operand" "")))
10868 (clobber (reg:CC FLAGS_REG))]
10869 "TARGET_QIMODE_MATH"
10870 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10872 ;; %%% Potential partial reg stall on alternative 2. What to do?
10874 (define_insn "*ashlqi3_1_lea"
10875 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10876 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10877 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10878 (clobber (reg:CC FLAGS_REG))]
10879 "!TARGET_PARTIAL_REG_STALL
10880 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10882 switch (get_attr_type (insn))
10887 gcc_assert (operands[2] == const1_rtx);
10888 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10889 return "add{l}\t{%k0, %k0|%k0, %k0}";
10891 return "add{b}\t{%0, %0|%0, %0}";
10894 if (REG_P (operands[2]))
10896 if (get_attr_mode (insn) == MODE_SI)
10897 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10899 return "sal{b}\t{%b2, %0|%0, %b2}";
10901 else if (operands[2] == const1_rtx
10902 && (TARGET_SHIFT1 || optimize_size))
10904 if (get_attr_mode (insn) == MODE_SI)
10905 return "sal{l}\t%0";
10907 return "sal{b}\t%0";
10911 if (get_attr_mode (insn) == MODE_SI)
10912 return "sal{l}\t{%2, %k0|%k0, %2}";
10914 return "sal{b}\t{%2, %0|%0, %2}";
10918 [(set (attr "type")
10919 (cond [(eq_attr "alternative" "2")
10920 (const_string "lea")
10921 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10923 (match_operand 0 "register_operand" ""))
10924 (match_operand 2 "const1_operand" ""))
10925 (const_string "alu")
10927 (const_string "ishift")))
10928 (set_attr "mode" "QI,SI,SI")])
10930 (define_insn "*ashlqi3_1"
10931 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10932 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10933 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10934 (clobber (reg:CC FLAGS_REG))]
10935 "TARGET_PARTIAL_REG_STALL
10936 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10938 switch (get_attr_type (insn))
10941 gcc_assert (operands[2] == const1_rtx);
10942 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10943 return "add{l}\t{%k0, %k0|%k0, %k0}";
10945 return "add{b}\t{%0, %0|%0, %0}";
10948 if (REG_P (operands[2]))
10950 if (get_attr_mode (insn) == MODE_SI)
10951 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10953 return "sal{b}\t{%b2, %0|%0, %b2}";
10955 else if (operands[2] == const1_rtx
10956 && (TARGET_SHIFT1 || optimize_size))
10958 if (get_attr_mode (insn) == MODE_SI)
10959 return "sal{l}\t%0";
10961 return "sal{b}\t%0";
10965 if (get_attr_mode (insn) == MODE_SI)
10966 return "sal{l}\t{%2, %k0|%k0, %2}";
10968 return "sal{b}\t{%2, %0|%0, %2}";
10972 [(set (attr "type")
10973 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10975 (match_operand 0 "register_operand" ""))
10976 (match_operand 2 "const1_operand" ""))
10977 (const_string "alu")
10979 (const_string "ishift")))
10980 (set_attr "mode" "QI,SI")])
10982 ;; This pattern can't accept a variable shift count, since shifts by
10983 ;; zero don't affect the flags. We assume that shifts by constant
10984 ;; zero are optimized away.
10985 (define_insn "*ashlqi3_cmp"
10986 [(set (reg FLAGS_REG)
10988 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10989 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10991 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10992 (ashift:QI (match_dup 1) (match_dup 2)))]
10993 "ix86_match_ccmode (insn, CCGOCmode)
10994 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10996 switch (get_attr_type (insn))
10999 gcc_assert (operands[2] == const1_rtx);
11000 return "add{b}\t{%0, %0|%0, %0}";
11003 if (REG_P (operands[2]))
11004 return "sal{b}\t{%b2, %0|%0, %b2}";
11005 else if (operands[2] == const1_rtx
11006 && (TARGET_SHIFT1 || optimize_size))
11007 return "sal{b}\t%0";
11009 return "sal{b}\t{%2, %0|%0, %2}";
11012 [(set (attr "type")
11013 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11015 (match_operand 0 "register_operand" ""))
11016 (match_operand 2 "const1_operand" ""))
11017 (const_string "alu")
11019 (const_string "ishift")))
11020 (set_attr "mode" "QI")])
11022 ;; See comment above `ashldi3' about how this works.
11024 (define_expand "ashrti3"
11025 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11026 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11027 (match_operand:QI 2 "nonmemory_operand" "")))
11028 (clobber (reg:CC FLAGS_REG))])]
11031 if (! immediate_operand (operands[2], QImode))
11033 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11036 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11040 (define_insn "ashrti3_1"
11041 [(set (match_operand:TI 0 "register_operand" "=r")
11042 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11043 (match_operand:QI 2 "register_operand" "c")))
11044 (clobber (match_scratch:DI 3 "=&r"))
11045 (clobber (reg:CC FLAGS_REG))]
11048 [(set_attr "type" "multi")])
11050 (define_insn "*ashrti3_2"
11051 [(set (match_operand:TI 0 "register_operand" "=r")
11052 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11053 (match_operand:QI 2 "immediate_operand" "O")))
11054 (clobber (reg:CC FLAGS_REG))]
11057 [(set_attr "type" "multi")])
11060 [(set (match_operand:TI 0 "register_operand" "")
11061 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11062 (match_operand:QI 2 "register_operand" "")))
11063 (clobber (match_scratch:DI 3 ""))
11064 (clobber (reg:CC FLAGS_REG))]
11065 "TARGET_64BIT && reload_completed"
11067 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11070 [(set (match_operand:TI 0 "register_operand" "")
11071 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11072 (match_operand:QI 2 "immediate_operand" "")))
11073 (clobber (reg:CC FLAGS_REG))]
11074 "TARGET_64BIT && reload_completed"
11076 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11078 (define_insn "x86_64_shrd"
11079 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11080 (ior:DI (ashiftrt:DI (match_dup 0)
11081 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11082 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11083 (minus:QI (const_int 64) (match_dup 2)))))
11084 (clobber (reg:CC FLAGS_REG))]
11087 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11088 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11089 [(set_attr "type" "ishift")
11090 (set_attr "prefix_0f" "1")
11091 (set_attr "mode" "DI")
11092 (set_attr "athlon_decode" "vector")])
11094 (define_expand "ashrdi3"
11095 [(set (match_operand:DI 0 "shiftdi_operand" "")
11096 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11097 (match_operand:QI 2 "nonmemory_operand" "")))]
11099 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11101 (define_insn "*ashrdi3_63_rex64"
11102 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11103 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11104 (match_operand:DI 2 "const_int_operand" "i,i")))
11105 (clobber (reg:CC FLAGS_REG))]
11106 "TARGET_64BIT && INTVAL (operands[2]) == 63
11107 && (TARGET_USE_CLTD || optimize_size)
11108 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11111 sar{q}\t{%2, %0|%0, %2}"
11112 [(set_attr "type" "imovx,ishift")
11113 (set_attr "prefix_0f" "0,*")
11114 (set_attr "length_immediate" "0,*")
11115 (set_attr "modrm" "0,1")
11116 (set_attr "mode" "DI")])
11118 (define_insn "*ashrdi3_1_one_bit_rex64"
11119 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11120 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11121 (match_operand:QI 2 "const1_operand" "")))
11122 (clobber (reg:CC FLAGS_REG))]
11123 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11124 && (TARGET_SHIFT1 || optimize_size)"
11126 [(set_attr "type" "ishift")
11127 (set (attr "length")
11128 (if_then_else (match_operand:DI 0 "register_operand" "")
11130 (const_string "*")))])
11132 (define_insn "*ashrdi3_1_rex64"
11133 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11134 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11135 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11136 (clobber (reg:CC FLAGS_REG))]
11137 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11139 sar{q}\t{%2, %0|%0, %2}
11140 sar{q}\t{%b2, %0|%0, %b2}"
11141 [(set_attr "type" "ishift")
11142 (set_attr "mode" "DI")])
11144 ;; This pattern can't accept a variable shift count, since shifts by
11145 ;; zero don't affect the flags. We assume that shifts by constant
11146 ;; zero are optimized away.
11147 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11148 [(set (reg FLAGS_REG)
11150 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11151 (match_operand:QI 2 "const1_operand" ""))
11153 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11154 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11155 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11156 && (TARGET_SHIFT1 || optimize_size)
11157 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11159 [(set_attr "type" "ishift")
11160 (set (attr "length")
11161 (if_then_else (match_operand:DI 0 "register_operand" "")
11163 (const_string "*")))])
11165 ;; This pattern can't accept a variable shift count, since shifts by
11166 ;; zero don't affect the flags. We assume that shifts by constant
11167 ;; zero are optimized away.
11168 (define_insn "*ashrdi3_cmp_rex64"
11169 [(set (reg FLAGS_REG)
11171 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11172 (match_operand:QI 2 "const_int_operand" "n"))
11174 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11175 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11176 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11177 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11178 "sar{q}\t{%2, %0|%0, %2}"
11179 [(set_attr "type" "ishift")
11180 (set_attr "mode" "DI")])
11182 (define_insn "*ashrdi3_1"
11183 [(set (match_operand:DI 0 "register_operand" "=r")
11184 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11185 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11186 (clobber (reg:CC FLAGS_REG))]
11189 [(set_attr "type" "multi")])
11191 ;; By default we don't ask for a scratch register, because when DImode
11192 ;; values are manipulated, registers are already at a premium. But if
11193 ;; we have one handy, we won't turn it away.
11195 [(match_scratch:SI 3 "r")
11196 (parallel [(set (match_operand:DI 0 "register_operand" "")
11197 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11198 (match_operand:QI 2 "nonmemory_operand" "")))
11199 (clobber (reg:CC FLAGS_REG))])
11201 "!TARGET_64BIT && TARGET_CMOVE"
11203 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11206 [(set (match_operand:DI 0 "register_operand" "")
11207 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11208 (match_operand:QI 2 "nonmemory_operand" "")))
11209 (clobber (reg:CC FLAGS_REG))]
11210 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11211 ? flow2_completed : reload_completed)"
11213 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11215 (define_insn "x86_shrd_1"
11216 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11217 (ior:SI (ashiftrt:SI (match_dup 0)
11218 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11219 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11220 (minus:QI (const_int 32) (match_dup 2)))))
11221 (clobber (reg:CC FLAGS_REG))]
11224 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11225 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11226 [(set_attr "type" "ishift")
11227 (set_attr "prefix_0f" "1")
11228 (set_attr "pent_pair" "np")
11229 (set_attr "mode" "SI")])
11231 (define_expand "x86_shift_adj_3"
11232 [(use (match_operand:SI 0 "register_operand" ""))
11233 (use (match_operand:SI 1 "register_operand" ""))
11234 (use (match_operand:QI 2 "register_operand" ""))]
11237 rtx label = gen_label_rtx ();
11240 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11242 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11243 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11244 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11245 gen_rtx_LABEL_REF (VOIDmode, label),
11247 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11248 JUMP_LABEL (tmp) = label;
11250 emit_move_insn (operands[0], operands[1]);
11251 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11253 emit_label (label);
11254 LABEL_NUSES (label) = 1;
11259 (define_insn "ashrsi3_31"
11260 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11261 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11262 (match_operand:SI 2 "const_int_operand" "i,i")))
11263 (clobber (reg:CC FLAGS_REG))]
11264 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11265 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11268 sar{l}\t{%2, %0|%0, %2}"
11269 [(set_attr "type" "imovx,ishift")
11270 (set_attr "prefix_0f" "0,*")
11271 (set_attr "length_immediate" "0,*")
11272 (set_attr "modrm" "0,1")
11273 (set_attr "mode" "SI")])
11275 (define_insn "*ashrsi3_31_zext"
11276 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11277 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11278 (match_operand:SI 2 "const_int_operand" "i,i"))))
11279 (clobber (reg:CC FLAGS_REG))]
11280 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11281 && INTVAL (operands[2]) == 31
11282 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11285 sar{l}\t{%2, %k0|%k0, %2}"
11286 [(set_attr "type" "imovx,ishift")
11287 (set_attr "prefix_0f" "0,*")
11288 (set_attr "length_immediate" "0,*")
11289 (set_attr "modrm" "0,1")
11290 (set_attr "mode" "SI")])
11292 (define_expand "ashrsi3"
11293 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11294 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11295 (match_operand:QI 2 "nonmemory_operand" "")))
11296 (clobber (reg:CC FLAGS_REG))]
11298 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11300 (define_insn "*ashrsi3_1_one_bit"
11301 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11302 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11303 (match_operand:QI 2 "const1_operand" "")))
11304 (clobber (reg:CC FLAGS_REG))]
11305 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11306 && (TARGET_SHIFT1 || optimize_size)"
11308 [(set_attr "type" "ishift")
11309 (set (attr "length")
11310 (if_then_else (match_operand:SI 0 "register_operand" "")
11312 (const_string "*")))])
11314 (define_insn "*ashrsi3_1_one_bit_zext"
11315 [(set (match_operand:DI 0 "register_operand" "=r")
11316 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11317 (match_operand:QI 2 "const1_operand" ""))))
11318 (clobber (reg:CC FLAGS_REG))]
11319 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11320 && (TARGET_SHIFT1 || optimize_size)"
11322 [(set_attr "type" "ishift")
11323 (set_attr "length" "2")])
11325 (define_insn "*ashrsi3_1"
11326 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11327 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11328 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11329 (clobber (reg:CC FLAGS_REG))]
11330 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11332 sar{l}\t{%2, %0|%0, %2}
11333 sar{l}\t{%b2, %0|%0, %b2}"
11334 [(set_attr "type" "ishift")
11335 (set_attr "mode" "SI")])
11337 (define_insn "*ashrsi3_1_zext"
11338 [(set (match_operand:DI 0 "register_operand" "=r,r")
11339 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11340 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11341 (clobber (reg:CC FLAGS_REG))]
11342 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11344 sar{l}\t{%2, %k0|%k0, %2}
11345 sar{l}\t{%b2, %k0|%k0, %b2}"
11346 [(set_attr "type" "ishift")
11347 (set_attr "mode" "SI")])
11349 ;; This pattern can't accept a variable shift count, since shifts by
11350 ;; zero don't affect the flags. We assume that shifts by constant
11351 ;; zero are optimized away.
11352 (define_insn "*ashrsi3_one_bit_cmp"
11353 [(set (reg FLAGS_REG)
11355 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11356 (match_operand:QI 2 "const1_operand" ""))
11358 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11359 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11360 "ix86_match_ccmode (insn, CCGOCmode)
11361 && (TARGET_SHIFT1 || optimize_size)
11362 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11364 [(set_attr "type" "ishift")
11365 (set (attr "length")
11366 (if_then_else (match_operand:SI 0 "register_operand" "")
11368 (const_string "*")))])
11370 (define_insn "*ashrsi3_one_bit_cmp_zext"
11371 [(set (reg FLAGS_REG)
11373 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11374 (match_operand:QI 2 "const1_operand" ""))
11376 (set (match_operand:DI 0 "register_operand" "=r")
11377 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11378 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11379 && (TARGET_SHIFT1 || optimize_size)
11380 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11382 [(set_attr "type" "ishift")
11383 (set_attr "length" "2")])
11385 ;; This pattern can't accept a variable shift count, since shifts by
11386 ;; zero don't affect the flags. We assume that shifts by constant
11387 ;; zero are optimized away.
11388 (define_insn "*ashrsi3_cmp"
11389 [(set (reg FLAGS_REG)
11391 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11392 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11394 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11395 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11396 "ix86_match_ccmode (insn, CCGOCmode)
11397 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11398 "sar{l}\t{%2, %0|%0, %2}"
11399 [(set_attr "type" "ishift")
11400 (set_attr "mode" "SI")])
11402 (define_insn "*ashrsi3_cmp_zext"
11403 [(set (reg FLAGS_REG)
11405 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11406 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11408 (set (match_operand:DI 0 "register_operand" "=r")
11409 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11410 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11411 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11412 "sar{l}\t{%2, %k0|%k0, %2}"
11413 [(set_attr "type" "ishift")
11414 (set_attr "mode" "SI")])
11416 (define_expand "ashrhi3"
11417 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11418 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11419 (match_operand:QI 2 "nonmemory_operand" "")))
11420 (clobber (reg:CC FLAGS_REG))]
11421 "TARGET_HIMODE_MATH"
11422 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11424 (define_insn "*ashrhi3_1_one_bit"
11425 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11426 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11427 (match_operand:QI 2 "const1_operand" "")))
11428 (clobber (reg:CC FLAGS_REG))]
11429 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11430 && (TARGET_SHIFT1 || optimize_size)"
11432 [(set_attr "type" "ishift")
11433 (set (attr "length")
11434 (if_then_else (match_operand 0 "register_operand" "")
11436 (const_string "*")))])
11438 (define_insn "*ashrhi3_1"
11439 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11440 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11441 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11442 (clobber (reg:CC FLAGS_REG))]
11443 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11445 sar{w}\t{%2, %0|%0, %2}
11446 sar{w}\t{%b2, %0|%0, %b2}"
11447 [(set_attr "type" "ishift")
11448 (set_attr "mode" "HI")])
11450 ;; This pattern can't accept a variable shift count, since shifts by
11451 ;; zero don't affect the flags. We assume that shifts by constant
11452 ;; zero are optimized away.
11453 (define_insn "*ashrhi3_one_bit_cmp"
11454 [(set (reg FLAGS_REG)
11456 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11457 (match_operand:QI 2 "const1_operand" ""))
11459 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11460 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11461 "ix86_match_ccmode (insn, CCGOCmode)
11462 && (TARGET_SHIFT1 || optimize_size)
11463 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11465 [(set_attr "type" "ishift")
11466 (set (attr "length")
11467 (if_then_else (match_operand 0 "register_operand" "")
11469 (const_string "*")))])
11471 ;; This pattern can't accept a variable shift count, since shifts by
11472 ;; zero don't affect the flags. We assume that shifts by constant
11473 ;; zero are optimized away.
11474 (define_insn "*ashrhi3_cmp"
11475 [(set (reg FLAGS_REG)
11477 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11478 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11480 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11481 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11482 "ix86_match_ccmode (insn, CCGOCmode)
11483 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11484 "sar{w}\t{%2, %0|%0, %2}"
11485 [(set_attr "type" "ishift")
11486 (set_attr "mode" "HI")])
11488 (define_expand "ashrqi3"
11489 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11490 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11491 (match_operand:QI 2 "nonmemory_operand" "")))
11492 (clobber (reg:CC FLAGS_REG))]
11493 "TARGET_QIMODE_MATH"
11494 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11496 (define_insn "*ashrqi3_1_one_bit"
11497 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11498 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11499 (match_operand:QI 2 "const1_operand" "")))
11500 (clobber (reg:CC FLAGS_REG))]
11501 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11502 && (TARGET_SHIFT1 || optimize_size)"
11504 [(set_attr "type" "ishift")
11505 (set (attr "length")
11506 (if_then_else (match_operand 0 "register_operand" "")
11508 (const_string "*")))])
11510 (define_insn "*ashrqi3_1_one_bit_slp"
11511 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11512 (ashiftrt:QI (match_dup 0)
11513 (match_operand:QI 1 "const1_operand" "")))
11514 (clobber (reg:CC FLAGS_REG))]
11515 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11516 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11517 && (TARGET_SHIFT1 || optimize_size)"
11519 [(set_attr "type" "ishift1")
11520 (set (attr "length")
11521 (if_then_else (match_operand 0 "register_operand" "")
11523 (const_string "*")))])
11525 (define_insn "*ashrqi3_1"
11526 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11527 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11528 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11529 (clobber (reg:CC FLAGS_REG))]
11530 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11532 sar{b}\t{%2, %0|%0, %2}
11533 sar{b}\t{%b2, %0|%0, %b2}"
11534 [(set_attr "type" "ishift")
11535 (set_attr "mode" "QI")])
11537 (define_insn "*ashrqi3_1_slp"
11538 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11539 (ashiftrt:QI (match_dup 0)
11540 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11541 (clobber (reg:CC FLAGS_REG))]
11542 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11543 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11545 sar{b}\t{%1, %0|%0, %1}
11546 sar{b}\t{%b1, %0|%0, %b1}"
11547 [(set_attr "type" "ishift1")
11548 (set_attr "mode" "QI")])
11550 ;; This pattern can't accept a variable shift count, since shifts by
11551 ;; zero don't affect the flags. We assume that shifts by constant
11552 ;; zero are optimized away.
11553 (define_insn "*ashrqi3_one_bit_cmp"
11554 [(set (reg FLAGS_REG)
11556 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11557 (match_operand:QI 2 "const1_operand" "I"))
11559 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11560 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11561 "ix86_match_ccmode (insn, CCGOCmode)
11562 && (TARGET_SHIFT1 || optimize_size)
11563 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11565 [(set_attr "type" "ishift")
11566 (set (attr "length")
11567 (if_then_else (match_operand 0 "register_operand" "")
11569 (const_string "*")))])
11571 ;; This pattern can't accept a variable shift count, since shifts by
11572 ;; zero don't affect the flags. We assume that shifts by constant
11573 ;; zero are optimized away.
11574 (define_insn "*ashrqi3_cmp"
11575 [(set (reg FLAGS_REG)
11577 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11578 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11580 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11581 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11582 "ix86_match_ccmode (insn, CCGOCmode)
11583 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11584 "sar{b}\t{%2, %0|%0, %2}"
11585 [(set_attr "type" "ishift")
11586 (set_attr "mode" "QI")])
11588 ;; Logical shift instructions
11590 ;; See comment above `ashldi3' about how this works.
11592 (define_expand "lshrti3"
11593 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11594 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11595 (match_operand:QI 2 "nonmemory_operand" "")))
11596 (clobber (reg:CC FLAGS_REG))])]
11599 if (! immediate_operand (operands[2], QImode))
11601 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11604 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11608 (define_insn "lshrti3_1"
11609 [(set (match_operand:TI 0 "register_operand" "=r")
11610 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11611 (match_operand:QI 2 "register_operand" "c")))
11612 (clobber (match_scratch:DI 3 "=&r"))
11613 (clobber (reg:CC FLAGS_REG))]
11616 [(set_attr "type" "multi")])
11618 (define_insn "*lshrti3_2"
11619 [(set (match_operand:TI 0 "register_operand" "=r")
11620 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11621 (match_operand:QI 2 "immediate_operand" "O")))
11622 (clobber (reg:CC FLAGS_REG))]
11625 [(set_attr "type" "multi")])
11628 [(set (match_operand:TI 0 "register_operand" "")
11629 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11630 (match_operand:QI 2 "register_operand" "")))
11631 (clobber (match_scratch:DI 3 ""))
11632 (clobber (reg:CC FLAGS_REG))]
11633 "TARGET_64BIT && reload_completed"
11635 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11638 [(set (match_operand:TI 0 "register_operand" "")
11639 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11640 (match_operand:QI 2 "immediate_operand" "")))
11641 (clobber (reg:CC FLAGS_REG))]
11642 "TARGET_64BIT && reload_completed"
11644 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11646 (define_expand "lshrdi3"
11647 [(set (match_operand:DI 0 "shiftdi_operand" "")
11648 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11649 (match_operand:QI 2 "nonmemory_operand" "")))]
11651 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11653 (define_insn "*lshrdi3_1_one_bit_rex64"
11654 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11655 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11656 (match_operand:QI 2 "const1_operand" "")))
11657 (clobber (reg:CC FLAGS_REG))]
11658 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11659 && (TARGET_SHIFT1 || optimize_size)"
11661 [(set_attr "type" "ishift")
11662 (set (attr "length")
11663 (if_then_else (match_operand:DI 0 "register_operand" "")
11665 (const_string "*")))])
11667 (define_insn "*lshrdi3_1_rex64"
11668 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11669 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11670 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11671 (clobber (reg:CC FLAGS_REG))]
11672 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11674 shr{q}\t{%2, %0|%0, %2}
11675 shr{q}\t{%b2, %0|%0, %b2}"
11676 [(set_attr "type" "ishift")
11677 (set_attr "mode" "DI")])
11679 ;; This pattern can't accept a variable shift count, since shifts by
11680 ;; zero don't affect the flags. We assume that shifts by constant
11681 ;; zero are optimized away.
11682 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11683 [(set (reg FLAGS_REG)
11685 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11686 (match_operand:QI 2 "const1_operand" ""))
11688 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11689 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11690 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11691 && (TARGET_SHIFT1 || optimize_size)
11692 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11694 [(set_attr "type" "ishift")
11695 (set (attr "length")
11696 (if_then_else (match_operand:DI 0 "register_operand" "")
11698 (const_string "*")))])
11700 ;; This pattern can't accept a variable shift count, since shifts by
11701 ;; zero don't affect the flags. We assume that shifts by constant
11702 ;; zero are optimized away.
11703 (define_insn "*lshrdi3_cmp_rex64"
11704 [(set (reg FLAGS_REG)
11706 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11707 (match_operand:QI 2 "const_int_operand" "e"))
11709 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11710 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11711 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11712 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11713 "shr{q}\t{%2, %0|%0, %2}"
11714 [(set_attr "type" "ishift")
11715 (set_attr "mode" "DI")])
11717 (define_insn "*lshrdi3_1"
11718 [(set (match_operand:DI 0 "register_operand" "=r")
11719 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11720 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11721 (clobber (reg:CC FLAGS_REG))]
11724 [(set_attr "type" "multi")])
11726 ;; By default we don't ask for a scratch register, because when DImode
11727 ;; values are manipulated, registers are already at a premium. But if
11728 ;; we have one handy, we won't turn it away.
11730 [(match_scratch:SI 3 "r")
11731 (parallel [(set (match_operand:DI 0 "register_operand" "")
11732 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11733 (match_operand:QI 2 "nonmemory_operand" "")))
11734 (clobber (reg:CC FLAGS_REG))])
11736 "!TARGET_64BIT && TARGET_CMOVE"
11738 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11741 [(set (match_operand:DI 0 "register_operand" "")
11742 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11743 (match_operand:QI 2 "nonmemory_operand" "")))
11744 (clobber (reg:CC FLAGS_REG))]
11745 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11746 ? flow2_completed : reload_completed)"
11748 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11750 (define_expand "lshrsi3"
11751 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11752 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11753 (match_operand:QI 2 "nonmemory_operand" "")))
11754 (clobber (reg:CC FLAGS_REG))]
11756 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11758 (define_insn "*lshrsi3_1_one_bit"
11759 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11760 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11761 (match_operand:QI 2 "const1_operand" "")))
11762 (clobber (reg:CC FLAGS_REG))]
11763 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11764 && (TARGET_SHIFT1 || optimize_size)"
11766 [(set_attr "type" "ishift")
11767 (set (attr "length")
11768 (if_then_else (match_operand:SI 0 "register_operand" "")
11770 (const_string "*")))])
11772 (define_insn "*lshrsi3_1_one_bit_zext"
11773 [(set (match_operand:DI 0 "register_operand" "=r")
11774 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11775 (match_operand:QI 2 "const1_operand" "")))
11776 (clobber (reg:CC FLAGS_REG))]
11777 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11778 && (TARGET_SHIFT1 || optimize_size)"
11780 [(set_attr "type" "ishift")
11781 (set_attr "length" "2")])
11783 (define_insn "*lshrsi3_1"
11784 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11785 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11786 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11787 (clobber (reg:CC FLAGS_REG))]
11788 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11790 shr{l}\t{%2, %0|%0, %2}
11791 shr{l}\t{%b2, %0|%0, %b2}"
11792 [(set_attr "type" "ishift")
11793 (set_attr "mode" "SI")])
11795 (define_insn "*lshrsi3_1_zext"
11796 [(set (match_operand:DI 0 "register_operand" "=r,r")
11798 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11799 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11800 (clobber (reg:CC FLAGS_REG))]
11801 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11803 shr{l}\t{%2, %k0|%k0, %2}
11804 shr{l}\t{%b2, %k0|%k0, %b2}"
11805 [(set_attr "type" "ishift")
11806 (set_attr "mode" "SI")])
11808 ;; This pattern can't accept a variable shift count, since shifts by
11809 ;; zero don't affect the flags. We assume that shifts by constant
11810 ;; zero are optimized away.
11811 (define_insn "*lshrsi3_one_bit_cmp"
11812 [(set (reg FLAGS_REG)
11814 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11815 (match_operand:QI 2 "const1_operand" ""))
11817 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11818 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11819 "ix86_match_ccmode (insn, CCGOCmode)
11820 && (TARGET_SHIFT1 || optimize_size)
11821 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11823 [(set_attr "type" "ishift")
11824 (set (attr "length")
11825 (if_then_else (match_operand:SI 0 "register_operand" "")
11827 (const_string "*")))])
11829 (define_insn "*lshrsi3_cmp_one_bit_zext"
11830 [(set (reg FLAGS_REG)
11832 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11833 (match_operand:QI 2 "const1_operand" ""))
11835 (set (match_operand:DI 0 "register_operand" "=r")
11836 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11837 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11838 && (TARGET_SHIFT1 || optimize_size)
11839 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11841 [(set_attr "type" "ishift")
11842 (set_attr "length" "2")])
11844 ;; This pattern can't accept a variable shift count, since shifts by
11845 ;; zero don't affect the flags. We assume that shifts by constant
11846 ;; zero are optimized away.
11847 (define_insn "*lshrsi3_cmp"
11848 [(set (reg FLAGS_REG)
11850 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11851 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11853 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11854 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11855 "ix86_match_ccmode (insn, CCGOCmode)
11856 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11857 "shr{l}\t{%2, %0|%0, %2}"
11858 [(set_attr "type" "ishift")
11859 (set_attr "mode" "SI")])
11861 (define_insn "*lshrsi3_cmp_zext"
11862 [(set (reg FLAGS_REG)
11864 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11865 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11867 (set (match_operand:DI 0 "register_operand" "=r")
11868 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11869 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11870 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11871 "shr{l}\t{%2, %k0|%k0, %2}"
11872 [(set_attr "type" "ishift")
11873 (set_attr "mode" "SI")])
11875 (define_expand "lshrhi3"
11876 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11877 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11878 (match_operand:QI 2 "nonmemory_operand" "")))
11879 (clobber (reg:CC FLAGS_REG))]
11880 "TARGET_HIMODE_MATH"
11881 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11883 (define_insn "*lshrhi3_1_one_bit"
11884 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11885 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11886 (match_operand:QI 2 "const1_operand" "")))
11887 (clobber (reg:CC FLAGS_REG))]
11888 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11889 && (TARGET_SHIFT1 || optimize_size)"
11891 [(set_attr "type" "ishift")
11892 (set (attr "length")
11893 (if_then_else (match_operand 0 "register_operand" "")
11895 (const_string "*")))])
11897 (define_insn "*lshrhi3_1"
11898 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11899 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11900 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11901 (clobber (reg:CC FLAGS_REG))]
11902 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11904 shr{w}\t{%2, %0|%0, %2}
11905 shr{w}\t{%b2, %0|%0, %b2}"
11906 [(set_attr "type" "ishift")
11907 (set_attr "mode" "HI")])
11909 ;; This pattern can't accept a variable shift count, since shifts by
11910 ;; zero don't affect the flags. We assume that shifts by constant
11911 ;; zero are optimized away.
11912 (define_insn "*lshrhi3_one_bit_cmp"
11913 [(set (reg FLAGS_REG)
11915 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11916 (match_operand:QI 2 "const1_operand" ""))
11918 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11919 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11920 "ix86_match_ccmode (insn, CCGOCmode)
11921 && (TARGET_SHIFT1 || optimize_size)
11922 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11924 [(set_attr "type" "ishift")
11925 (set (attr "length")
11926 (if_then_else (match_operand:SI 0 "register_operand" "")
11928 (const_string "*")))])
11930 ;; This pattern can't accept a variable shift count, since shifts by
11931 ;; zero don't affect the flags. We assume that shifts by constant
11932 ;; zero are optimized away.
11933 (define_insn "*lshrhi3_cmp"
11934 [(set (reg FLAGS_REG)
11936 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11937 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11939 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11940 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11941 "ix86_match_ccmode (insn, CCGOCmode)
11942 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11943 "shr{w}\t{%2, %0|%0, %2}"
11944 [(set_attr "type" "ishift")
11945 (set_attr "mode" "HI")])
11947 (define_expand "lshrqi3"
11948 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11949 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11950 (match_operand:QI 2 "nonmemory_operand" "")))
11951 (clobber (reg:CC FLAGS_REG))]
11952 "TARGET_QIMODE_MATH"
11953 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11955 (define_insn "*lshrqi3_1_one_bit"
11956 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11957 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11958 (match_operand:QI 2 "const1_operand" "")))
11959 (clobber (reg:CC FLAGS_REG))]
11960 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11961 && (TARGET_SHIFT1 || optimize_size)"
11963 [(set_attr "type" "ishift")
11964 (set (attr "length")
11965 (if_then_else (match_operand 0 "register_operand" "")
11967 (const_string "*")))])
11969 (define_insn "*lshrqi3_1_one_bit_slp"
11970 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11971 (lshiftrt:QI (match_dup 0)
11972 (match_operand:QI 1 "const1_operand" "")))
11973 (clobber (reg:CC FLAGS_REG))]
11974 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11975 && (TARGET_SHIFT1 || optimize_size)"
11977 [(set_attr "type" "ishift1")
11978 (set (attr "length")
11979 (if_then_else (match_operand 0 "register_operand" "")
11981 (const_string "*")))])
11983 (define_insn "*lshrqi3_1"
11984 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11985 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11986 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11987 (clobber (reg:CC FLAGS_REG))]
11988 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11990 shr{b}\t{%2, %0|%0, %2}
11991 shr{b}\t{%b2, %0|%0, %b2}"
11992 [(set_attr "type" "ishift")
11993 (set_attr "mode" "QI")])
11995 (define_insn "*lshrqi3_1_slp"
11996 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11997 (lshiftrt:QI (match_dup 0)
11998 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11999 (clobber (reg:CC FLAGS_REG))]
12000 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12001 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12003 shr{b}\t{%1, %0|%0, %1}
12004 shr{b}\t{%b1, %0|%0, %b1}"
12005 [(set_attr "type" "ishift1")
12006 (set_attr "mode" "QI")])
12008 ;; This pattern can't accept a variable shift count, since shifts by
12009 ;; zero don't affect the flags. We assume that shifts by constant
12010 ;; zero are optimized away.
12011 (define_insn "*lshrqi2_one_bit_cmp"
12012 [(set (reg FLAGS_REG)
12014 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12015 (match_operand:QI 2 "const1_operand" ""))
12017 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12018 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12019 "ix86_match_ccmode (insn, CCGOCmode)
12020 && (TARGET_SHIFT1 || optimize_size)
12021 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12023 [(set_attr "type" "ishift")
12024 (set (attr "length")
12025 (if_then_else (match_operand:SI 0 "register_operand" "")
12027 (const_string "*")))])
12029 ;; This pattern can't accept a variable shift count, since shifts by
12030 ;; zero don't affect the flags. We assume that shifts by constant
12031 ;; zero are optimized away.
12032 (define_insn "*lshrqi2_cmp"
12033 [(set (reg FLAGS_REG)
12035 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12036 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12038 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12039 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12040 "ix86_match_ccmode (insn, CCGOCmode)
12041 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12042 "shr{b}\t{%2, %0|%0, %2}"
12043 [(set_attr "type" "ishift")
12044 (set_attr "mode" "QI")])
12046 ;; Rotate instructions
12048 (define_expand "rotldi3"
12049 [(set (match_operand:DI 0 "shiftdi_operand" "")
12050 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12051 (match_operand:QI 2 "nonmemory_operand" "")))
12052 (clobber (reg:CC FLAGS_REG))]
12057 ix86_expand_binary_operator (ROTATE, DImode, operands);
12060 if (!const_1_to_31_operand (operands[2], VOIDmode))
12062 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12066 ;; Implement rotation using two double-precision shift instructions
12067 ;; and a scratch register.
12068 (define_insn_and_split "ix86_rotldi3"
12069 [(set (match_operand:DI 0 "register_operand" "=r")
12070 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12071 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12072 (clobber (reg:CC FLAGS_REG))
12073 (clobber (match_scratch:SI 3 "=&r"))]
12076 "&& reload_completed"
12077 [(set (match_dup 3) (match_dup 4))
12079 [(set (match_dup 4)
12080 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12081 (lshiftrt:SI (match_dup 5)
12082 (minus:QI (const_int 32) (match_dup 2)))))
12083 (clobber (reg:CC FLAGS_REG))])
12085 [(set (match_dup 5)
12086 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12087 (lshiftrt:SI (match_dup 3)
12088 (minus:QI (const_int 32) (match_dup 2)))))
12089 (clobber (reg:CC FLAGS_REG))])]
12090 "split_di (operands, 1, operands + 4, operands + 5);")
12092 (define_insn "*rotlsi3_1_one_bit_rex64"
12093 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12094 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12095 (match_operand:QI 2 "const1_operand" "")))
12096 (clobber (reg:CC FLAGS_REG))]
12097 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12098 && (TARGET_SHIFT1 || optimize_size)"
12100 [(set_attr "type" "rotate")
12101 (set (attr "length")
12102 (if_then_else (match_operand:DI 0 "register_operand" "")
12104 (const_string "*")))])
12106 (define_insn "*rotldi3_1_rex64"
12107 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12108 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12109 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12110 (clobber (reg:CC FLAGS_REG))]
12111 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12113 rol{q}\t{%2, %0|%0, %2}
12114 rol{q}\t{%b2, %0|%0, %b2}"
12115 [(set_attr "type" "rotate")
12116 (set_attr "mode" "DI")])
12118 (define_expand "rotlsi3"
12119 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12120 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12121 (match_operand:QI 2 "nonmemory_operand" "")))
12122 (clobber (reg:CC FLAGS_REG))]
12124 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12126 (define_insn "*rotlsi3_1_one_bit"
12127 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12128 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12129 (match_operand:QI 2 "const1_operand" "")))
12130 (clobber (reg:CC FLAGS_REG))]
12131 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12132 && (TARGET_SHIFT1 || optimize_size)"
12134 [(set_attr "type" "rotate")
12135 (set (attr "length")
12136 (if_then_else (match_operand:SI 0 "register_operand" "")
12138 (const_string "*")))])
12140 (define_insn "*rotlsi3_1_one_bit_zext"
12141 [(set (match_operand:DI 0 "register_operand" "=r")
12143 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12144 (match_operand:QI 2 "const1_operand" ""))))
12145 (clobber (reg:CC FLAGS_REG))]
12146 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12147 && (TARGET_SHIFT1 || optimize_size)"
12149 [(set_attr "type" "rotate")
12150 (set_attr "length" "2")])
12152 (define_insn "*rotlsi3_1"
12153 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12154 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12155 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12156 (clobber (reg:CC FLAGS_REG))]
12157 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12159 rol{l}\t{%2, %0|%0, %2}
12160 rol{l}\t{%b2, %0|%0, %b2}"
12161 [(set_attr "type" "rotate")
12162 (set_attr "mode" "SI")])
12164 (define_insn "*rotlsi3_1_zext"
12165 [(set (match_operand:DI 0 "register_operand" "=r,r")
12167 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12168 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12169 (clobber (reg:CC FLAGS_REG))]
12170 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12172 rol{l}\t{%2, %k0|%k0, %2}
12173 rol{l}\t{%b2, %k0|%k0, %b2}"
12174 [(set_attr "type" "rotate")
12175 (set_attr "mode" "SI")])
12177 (define_expand "rotlhi3"
12178 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12179 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12180 (match_operand:QI 2 "nonmemory_operand" "")))
12181 (clobber (reg:CC FLAGS_REG))]
12182 "TARGET_HIMODE_MATH"
12183 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12185 (define_insn "*rotlhi3_1_one_bit"
12186 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12187 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12188 (match_operand:QI 2 "const1_operand" "")))
12189 (clobber (reg:CC FLAGS_REG))]
12190 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12191 && (TARGET_SHIFT1 || optimize_size)"
12193 [(set_attr "type" "rotate")
12194 (set (attr "length")
12195 (if_then_else (match_operand 0 "register_operand" "")
12197 (const_string "*")))])
12199 (define_insn "*rotlhi3_1"
12200 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12201 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12202 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12203 (clobber (reg:CC FLAGS_REG))]
12204 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12206 rol{w}\t{%2, %0|%0, %2}
12207 rol{w}\t{%b2, %0|%0, %b2}"
12208 [(set_attr "type" "rotate")
12209 (set_attr "mode" "HI")])
12211 (define_expand "rotlqi3"
12212 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12213 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12214 (match_operand:QI 2 "nonmemory_operand" "")))
12215 (clobber (reg:CC FLAGS_REG))]
12216 "TARGET_QIMODE_MATH"
12217 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12219 (define_insn "*rotlqi3_1_one_bit_slp"
12220 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12221 (rotate:QI (match_dup 0)
12222 (match_operand:QI 1 "const1_operand" "")))
12223 (clobber (reg:CC FLAGS_REG))]
12224 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12225 && (TARGET_SHIFT1 || optimize_size)"
12227 [(set_attr "type" "rotate1")
12228 (set (attr "length")
12229 (if_then_else (match_operand 0 "register_operand" "")
12231 (const_string "*")))])
12233 (define_insn "*rotlqi3_1_one_bit"
12234 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12235 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12236 (match_operand:QI 2 "const1_operand" "")))
12237 (clobber (reg:CC FLAGS_REG))]
12238 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12239 && (TARGET_SHIFT1 || optimize_size)"
12241 [(set_attr "type" "rotate")
12242 (set (attr "length")
12243 (if_then_else (match_operand 0 "register_operand" "")
12245 (const_string "*")))])
12247 (define_insn "*rotlqi3_1_slp"
12248 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12249 (rotate:QI (match_dup 0)
12250 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12251 (clobber (reg:CC FLAGS_REG))]
12252 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12253 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12255 rol{b}\t{%1, %0|%0, %1}
12256 rol{b}\t{%b1, %0|%0, %b1}"
12257 [(set_attr "type" "rotate1")
12258 (set_attr "mode" "QI")])
12260 (define_insn "*rotlqi3_1"
12261 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12262 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12263 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12264 (clobber (reg:CC FLAGS_REG))]
12265 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12267 rol{b}\t{%2, %0|%0, %2}
12268 rol{b}\t{%b2, %0|%0, %b2}"
12269 [(set_attr "type" "rotate")
12270 (set_attr "mode" "QI")])
12272 (define_expand "rotrdi3"
12273 [(set (match_operand:DI 0 "shiftdi_operand" "")
12274 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12275 (match_operand:QI 2 "nonmemory_operand" "")))
12276 (clobber (reg:CC FLAGS_REG))]
12281 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12284 if (!const_1_to_31_operand (operands[2], VOIDmode))
12286 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12290 ;; Implement rotation using two double-precision shift instructions
12291 ;; and a scratch register.
12292 (define_insn_and_split "ix86_rotrdi3"
12293 [(set (match_operand:DI 0 "register_operand" "=r")
12294 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12295 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12296 (clobber (reg:CC FLAGS_REG))
12297 (clobber (match_scratch:SI 3 "=&r"))]
12300 "&& reload_completed"
12301 [(set (match_dup 3) (match_dup 4))
12303 [(set (match_dup 4)
12304 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12305 (ashift:SI (match_dup 5)
12306 (minus:QI (const_int 32) (match_dup 2)))))
12307 (clobber (reg:CC FLAGS_REG))])
12309 [(set (match_dup 5)
12310 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12311 (ashift:SI (match_dup 3)
12312 (minus:QI (const_int 32) (match_dup 2)))))
12313 (clobber (reg:CC FLAGS_REG))])]
12314 "split_di (operands, 1, operands + 4, operands + 5);")
12316 (define_insn "*rotrdi3_1_one_bit_rex64"
12317 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12318 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12319 (match_operand:QI 2 "const1_operand" "")))
12320 (clobber (reg:CC FLAGS_REG))]
12321 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12322 && (TARGET_SHIFT1 || optimize_size)"
12324 [(set_attr "type" "rotate")
12325 (set (attr "length")
12326 (if_then_else (match_operand:DI 0 "register_operand" "")
12328 (const_string "*")))])
12330 (define_insn "*rotrdi3_1_rex64"
12331 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12332 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12333 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12334 (clobber (reg:CC FLAGS_REG))]
12335 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12337 ror{q}\t{%2, %0|%0, %2}
12338 ror{q}\t{%b2, %0|%0, %b2}"
12339 [(set_attr "type" "rotate")
12340 (set_attr "mode" "DI")])
12342 (define_expand "rotrsi3"
12343 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12344 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12345 (match_operand:QI 2 "nonmemory_operand" "")))
12346 (clobber (reg:CC FLAGS_REG))]
12348 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12350 (define_insn "*rotrsi3_1_one_bit"
12351 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12352 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12353 (match_operand:QI 2 "const1_operand" "")))
12354 (clobber (reg:CC FLAGS_REG))]
12355 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12356 && (TARGET_SHIFT1 || optimize_size)"
12358 [(set_attr "type" "rotate")
12359 (set (attr "length")
12360 (if_then_else (match_operand:SI 0 "register_operand" "")
12362 (const_string "*")))])
12364 (define_insn "*rotrsi3_1_one_bit_zext"
12365 [(set (match_operand:DI 0 "register_operand" "=r")
12367 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12368 (match_operand:QI 2 "const1_operand" ""))))
12369 (clobber (reg:CC FLAGS_REG))]
12370 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12371 && (TARGET_SHIFT1 || optimize_size)"
12373 [(set_attr "type" "rotate")
12374 (set (attr "length")
12375 (if_then_else (match_operand:SI 0 "register_operand" "")
12377 (const_string "*")))])
12379 (define_insn "*rotrsi3_1"
12380 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12381 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12382 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12383 (clobber (reg:CC FLAGS_REG))]
12384 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12386 ror{l}\t{%2, %0|%0, %2}
12387 ror{l}\t{%b2, %0|%0, %b2}"
12388 [(set_attr "type" "rotate")
12389 (set_attr "mode" "SI")])
12391 (define_insn "*rotrsi3_1_zext"
12392 [(set (match_operand:DI 0 "register_operand" "=r,r")
12394 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12395 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12396 (clobber (reg:CC FLAGS_REG))]
12397 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12399 ror{l}\t{%2, %k0|%k0, %2}
12400 ror{l}\t{%b2, %k0|%k0, %b2}"
12401 [(set_attr "type" "rotate")
12402 (set_attr "mode" "SI")])
12404 (define_expand "rotrhi3"
12405 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12406 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12407 (match_operand:QI 2 "nonmemory_operand" "")))
12408 (clobber (reg:CC FLAGS_REG))]
12409 "TARGET_HIMODE_MATH"
12410 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12412 (define_insn "*rotrhi3_one_bit"
12413 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12414 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12415 (match_operand:QI 2 "const1_operand" "")))
12416 (clobber (reg:CC FLAGS_REG))]
12417 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12418 && (TARGET_SHIFT1 || optimize_size)"
12420 [(set_attr "type" "rotate")
12421 (set (attr "length")
12422 (if_then_else (match_operand 0 "register_operand" "")
12424 (const_string "*")))])
12426 (define_insn "*rotrhi3"
12427 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12428 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12429 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12430 (clobber (reg:CC FLAGS_REG))]
12431 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12433 ror{w}\t{%2, %0|%0, %2}
12434 ror{w}\t{%b2, %0|%0, %b2}"
12435 [(set_attr "type" "rotate")
12436 (set_attr "mode" "HI")])
12438 (define_expand "rotrqi3"
12439 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12440 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12441 (match_operand:QI 2 "nonmemory_operand" "")))
12442 (clobber (reg:CC FLAGS_REG))]
12443 "TARGET_QIMODE_MATH"
12444 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12446 (define_insn "*rotrqi3_1_one_bit"
12447 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12448 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12449 (match_operand:QI 2 "const1_operand" "")))
12450 (clobber (reg:CC FLAGS_REG))]
12451 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12452 && (TARGET_SHIFT1 || optimize_size)"
12454 [(set_attr "type" "rotate")
12455 (set (attr "length")
12456 (if_then_else (match_operand 0 "register_operand" "")
12458 (const_string "*")))])
12460 (define_insn "*rotrqi3_1_one_bit_slp"
12461 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12462 (rotatert:QI (match_dup 0)
12463 (match_operand:QI 1 "const1_operand" "")))
12464 (clobber (reg:CC FLAGS_REG))]
12465 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12466 && (TARGET_SHIFT1 || optimize_size)"
12468 [(set_attr "type" "rotate1")
12469 (set (attr "length")
12470 (if_then_else (match_operand 0 "register_operand" "")
12472 (const_string "*")))])
12474 (define_insn "*rotrqi3_1"
12475 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12476 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12477 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12478 (clobber (reg:CC FLAGS_REG))]
12479 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12481 ror{b}\t{%2, %0|%0, %2}
12482 ror{b}\t{%b2, %0|%0, %b2}"
12483 [(set_attr "type" "rotate")
12484 (set_attr "mode" "QI")])
12486 (define_insn "*rotrqi3_1_slp"
12487 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12488 (rotatert:QI (match_dup 0)
12489 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12490 (clobber (reg:CC FLAGS_REG))]
12491 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12492 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12494 ror{b}\t{%1, %0|%0, %1}
12495 ror{b}\t{%b1, %0|%0, %b1}"
12496 [(set_attr "type" "rotate1")
12497 (set_attr "mode" "QI")])
12499 ;; Bit set / bit test instructions
12501 (define_expand "extv"
12502 [(set (match_operand:SI 0 "register_operand" "")
12503 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12504 (match_operand:SI 2 "immediate_operand" "")
12505 (match_operand:SI 3 "immediate_operand" "")))]
12508 /* Handle extractions from %ah et al. */
12509 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12512 /* From mips.md: extract_bit_field doesn't verify that our source
12513 matches the predicate, so check it again here. */
12514 if (! ext_register_operand (operands[1], VOIDmode))
12518 (define_expand "extzv"
12519 [(set (match_operand:SI 0 "register_operand" "")
12520 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12521 (match_operand:SI 2 "immediate_operand" "")
12522 (match_operand:SI 3 "immediate_operand" "")))]
12525 /* Handle extractions from %ah et al. */
12526 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12529 /* From mips.md: extract_bit_field doesn't verify that our source
12530 matches the predicate, so check it again here. */
12531 if (! ext_register_operand (operands[1], VOIDmode))
12535 (define_expand "insv"
12536 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12537 (match_operand 1 "immediate_operand" "")
12538 (match_operand 2 "immediate_operand" ""))
12539 (match_operand 3 "register_operand" ""))]
12542 /* Handle extractions from %ah et al. */
12543 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12546 /* From mips.md: insert_bit_field doesn't verify that our source
12547 matches the predicate, so check it again here. */
12548 if (! ext_register_operand (operands[0], VOIDmode))
12552 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12554 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12559 ;; %%% bts, btr, btc, bt.
12560 ;; In general these instructions are *slow* when applied to memory,
12561 ;; since they enforce atomic operation. When applied to registers,
12562 ;; it depends on the cpu implementation. They're never faster than
12563 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12564 ;; no point. But in 64-bit, we can't hold the relevant immediates
12565 ;; within the instruction itself, so operating on bits in the high
12566 ;; 32-bits of a register becomes easier.
12568 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12569 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12570 ;; negdf respectively, so they can never be disabled entirely.
12572 (define_insn "*btsq"
12573 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12575 (match_operand:DI 1 "const_0_to_63_operand" ""))
12577 (clobber (reg:CC FLAGS_REG))]
12578 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12580 [(set_attr "type" "alu1")])
12582 (define_insn "*btrq"
12583 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12585 (match_operand:DI 1 "const_0_to_63_operand" ""))
12587 (clobber (reg:CC FLAGS_REG))]
12588 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12590 [(set_attr "type" "alu1")])
12592 (define_insn "*btcq"
12593 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12595 (match_operand:DI 1 "const_0_to_63_operand" ""))
12596 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12597 (clobber (reg:CC FLAGS_REG))]
12598 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12600 [(set_attr "type" "alu1")])
12602 ;; Allow Nocona to avoid these instructions if a register is available.
12605 [(match_scratch:DI 2 "r")
12606 (parallel [(set (zero_extract:DI
12607 (match_operand:DI 0 "register_operand" "")
12609 (match_operand:DI 1 "const_0_to_63_operand" ""))
12611 (clobber (reg:CC FLAGS_REG))])]
12612 "TARGET_64BIT && !TARGET_USE_BT"
12615 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12618 if (HOST_BITS_PER_WIDE_INT >= 64)
12619 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12620 else if (i < HOST_BITS_PER_WIDE_INT)
12621 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12623 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12625 op1 = immed_double_const (lo, hi, DImode);
12628 emit_move_insn (operands[2], op1);
12632 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12637 [(match_scratch:DI 2 "r")
12638 (parallel [(set (zero_extract:DI
12639 (match_operand:DI 0 "register_operand" "")
12641 (match_operand:DI 1 "const_0_to_63_operand" ""))
12643 (clobber (reg:CC FLAGS_REG))])]
12644 "TARGET_64BIT && !TARGET_USE_BT"
12647 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12650 if (HOST_BITS_PER_WIDE_INT >= 64)
12651 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12652 else if (i < HOST_BITS_PER_WIDE_INT)
12653 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12655 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12657 op1 = immed_double_const (~lo, ~hi, DImode);
12660 emit_move_insn (operands[2], op1);
12664 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12669 [(match_scratch:DI 2 "r")
12670 (parallel [(set (zero_extract:DI
12671 (match_operand:DI 0 "register_operand" "")
12673 (match_operand:DI 1 "const_0_to_63_operand" ""))
12674 (not:DI (zero_extract:DI
12675 (match_dup 0) (const_int 1) (match_dup 1))))
12676 (clobber (reg:CC FLAGS_REG))])]
12677 "TARGET_64BIT && !TARGET_USE_BT"
12680 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12683 if (HOST_BITS_PER_WIDE_INT >= 64)
12684 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12685 else if (i < HOST_BITS_PER_WIDE_INT)
12686 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12688 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12690 op1 = immed_double_const (lo, hi, DImode);
12693 emit_move_insn (operands[2], op1);
12697 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12701 ;; Store-flag instructions.
12703 ;; For all sCOND expanders, also expand the compare or test insn that
12704 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12706 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12707 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12708 ;; way, which can later delete the movzx if only QImode is needed.
12710 (define_expand "seq"
12711 [(set (match_operand:QI 0 "register_operand" "")
12712 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12714 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12716 (define_expand "sne"
12717 [(set (match_operand:QI 0 "register_operand" "")
12718 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12720 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12722 (define_expand "sgt"
12723 [(set (match_operand:QI 0 "register_operand" "")
12724 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12726 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12728 (define_expand "sgtu"
12729 [(set (match_operand:QI 0 "register_operand" "")
12730 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12732 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12734 (define_expand "slt"
12735 [(set (match_operand:QI 0 "register_operand" "")
12736 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12738 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12740 (define_expand "sltu"
12741 [(set (match_operand:QI 0 "register_operand" "")
12742 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12744 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12746 (define_expand "sge"
12747 [(set (match_operand:QI 0 "register_operand" "")
12748 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12750 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12752 (define_expand "sgeu"
12753 [(set (match_operand:QI 0 "register_operand" "")
12754 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12756 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12758 (define_expand "sle"
12759 [(set (match_operand:QI 0 "register_operand" "")
12760 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12762 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12764 (define_expand "sleu"
12765 [(set (match_operand:QI 0 "register_operand" "")
12766 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12768 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12770 (define_expand "sunordered"
12771 [(set (match_operand:QI 0 "register_operand" "")
12772 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12773 "TARGET_80387 || TARGET_SSE"
12774 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12776 (define_expand "sordered"
12777 [(set (match_operand:QI 0 "register_operand" "")
12778 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12780 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12782 (define_expand "suneq"
12783 [(set (match_operand:QI 0 "register_operand" "")
12784 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12785 "TARGET_80387 || TARGET_SSE"
12786 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12788 (define_expand "sunge"
12789 [(set (match_operand:QI 0 "register_operand" "")
12790 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12791 "TARGET_80387 || TARGET_SSE"
12792 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12794 (define_expand "sungt"
12795 [(set (match_operand:QI 0 "register_operand" "")
12796 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12797 "TARGET_80387 || TARGET_SSE"
12798 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12800 (define_expand "sunle"
12801 [(set (match_operand:QI 0 "register_operand" "")
12802 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12803 "TARGET_80387 || TARGET_SSE"
12804 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12806 (define_expand "sunlt"
12807 [(set (match_operand:QI 0 "register_operand" "")
12808 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12809 "TARGET_80387 || TARGET_SSE"
12810 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12812 (define_expand "sltgt"
12813 [(set (match_operand:QI 0 "register_operand" "")
12814 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12815 "TARGET_80387 || TARGET_SSE"
12816 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12818 (define_insn "*setcc_1"
12819 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12820 (match_operator:QI 1 "ix86_comparison_operator"
12821 [(reg FLAGS_REG) (const_int 0)]))]
12824 [(set_attr "type" "setcc")
12825 (set_attr "mode" "QI")])
12827 (define_insn "*setcc_2"
12828 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12829 (match_operator:QI 1 "ix86_comparison_operator"
12830 [(reg FLAGS_REG) (const_int 0)]))]
12833 [(set_attr "type" "setcc")
12834 (set_attr "mode" "QI")])
12836 ;; In general it is not safe to assume too much about CCmode registers,
12837 ;; so simplify-rtx stops when it sees a second one. Under certain
12838 ;; conditions this is safe on x86, so help combine not create
12845 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12846 (ne:QI (match_operator 1 "ix86_comparison_operator"
12847 [(reg FLAGS_REG) (const_int 0)])
12850 [(set (match_dup 0) (match_dup 1))]
12852 PUT_MODE (operands[1], QImode);
12856 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12857 (ne:QI (match_operator 1 "ix86_comparison_operator"
12858 [(reg FLAGS_REG) (const_int 0)])
12861 [(set (match_dup 0) (match_dup 1))]
12863 PUT_MODE (operands[1], QImode);
12867 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12868 (eq:QI (match_operator 1 "ix86_comparison_operator"
12869 [(reg FLAGS_REG) (const_int 0)])
12872 [(set (match_dup 0) (match_dup 1))]
12874 rtx new_op1 = copy_rtx (operands[1]);
12875 operands[1] = new_op1;
12876 PUT_MODE (new_op1, QImode);
12877 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12878 GET_MODE (XEXP (new_op1, 0))));
12880 /* Make sure that (a) the CCmode we have for the flags is strong
12881 enough for the reversed compare or (b) we have a valid FP compare. */
12882 if (! ix86_comparison_operator (new_op1, VOIDmode))
12887 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12888 (eq:QI (match_operator 1 "ix86_comparison_operator"
12889 [(reg FLAGS_REG) (const_int 0)])
12892 [(set (match_dup 0) (match_dup 1))]
12894 rtx new_op1 = copy_rtx (operands[1]);
12895 operands[1] = new_op1;
12896 PUT_MODE (new_op1, QImode);
12897 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12898 GET_MODE (XEXP (new_op1, 0))));
12900 /* Make sure that (a) the CCmode we have for the flags is strong
12901 enough for the reversed compare or (b) we have a valid FP compare. */
12902 if (! ix86_comparison_operator (new_op1, VOIDmode))
12906 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12907 ;; subsequent logical operations are used to imitate conditional moves.
12908 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12911 (define_insn "*sse_setccsf"
12912 [(set (match_operand:SF 0 "register_operand" "=x")
12913 (match_operator:SF 1 "sse_comparison_operator"
12914 [(match_operand:SF 2 "register_operand" "0")
12915 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12917 "cmp%D1ss\t{%3, %0|%0, %3}"
12918 [(set_attr "type" "ssecmp")
12919 (set_attr "mode" "SF")])
12921 (define_insn "*sse_setccdf"
12922 [(set (match_operand:DF 0 "register_operand" "=Y")
12923 (match_operator:DF 1 "sse_comparison_operator"
12924 [(match_operand:DF 2 "register_operand" "0")
12925 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12927 "cmp%D1sd\t{%3, %0|%0, %3}"
12928 [(set_attr "type" "ssecmp")
12929 (set_attr "mode" "DF")])
12931 ;; Basic conditional jump instructions.
12932 ;; We ignore the overflow flag for signed branch instructions.
12934 ;; For all bCOND expanders, also expand the compare or test insn that
12935 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12937 (define_expand "beq"
12939 (if_then_else (match_dup 1)
12940 (label_ref (match_operand 0 "" ""))
12943 "ix86_expand_branch (EQ, operands[0]); DONE;")
12945 (define_expand "bne"
12947 (if_then_else (match_dup 1)
12948 (label_ref (match_operand 0 "" ""))
12951 "ix86_expand_branch (NE, operands[0]); DONE;")
12953 (define_expand "bgt"
12955 (if_then_else (match_dup 1)
12956 (label_ref (match_operand 0 "" ""))
12959 "ix86_expand_branch (GT, operands[0]); DONE;")
12961 (define_expand "bgtu"
12963 (if_then_else (match_dup 1)
12964 (label_ref (match_operand 0 "" ""))
12967 "ix86_expand_branch (GTU, operands[0]); DONE;")
12969 (define_expand "blt"
12971 (if_then_else (match_dup 1)
12972 (label_ref (match_operand 0 "" ""))
12975 "ix86_expand_branch (LT, operands[0]); DONE;")
12977 (define_expand "bltu"
12979 (if_then_else (match_dup 1)
12980 (label_ref (match_operand 0 "" ""))
12983 "ix86_expand_branch (LTU, operands[0]); DONE;")
12985 (define_expand "bge"
12987 (if_then_else (match_dup 1)
12988 (label_ref (match_operand 0 "" ""))
12991 "ix86_expand_branch (GE, operands[0]); DONE;")
12993 (define_expand "bgeu"
12995 (if_then_else (match_dup 1)
12996 (label_ref (match_operand 0 "" ""))
12999 "ix86_expand_branch (GEU, operands[0]); DONE;")
13001 (define_expand "ble"
13003 (if_then_else (match_dup 1)
13004 (label_ref (match_operand 0 "" ""))
13007 "ix86_expand_branch (LE, operands[0]); DONE;")
13009 (define_expand "bleu"
13011 (if_then_else (match_dup 1)
13012 (label_ref (match_operand 0 "" ""))
13015 "ix86_expand_branch (LEU, operands[0]); DONE;")
13017 (define_expand "bunordered"
13019 (if_then_else (match_dup 1)
13020 (label_ref (match_operand 0 "" ""))
13022 "TARGET_80387 || TARGET_SSE_MATH"
13023 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13025 (define_expand "bordered"
13027 (if_then_else (match_dup 1)
13028 (label_ref (match_operand 0 "" ""))
13030 "TARGET_80387 || TARGET_SSE_MATH"
13031 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13033 (define_expand "buneq"
13035 (if_then_else (match_dup 1)
13036 (label_ref (match_operand 0 "" ""))
13038 "TARGET_80387 || TARGET_SSE_MATH"
13039 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13041 (define_expand "bunge"
13043 (if_then_else (match_dup 1)
13044 (label_ref (match_operand 0 "" ""))
13046 "TARGET_80387 || TARGET_SSE_MATH"
13047 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13049 (define_expand "bungt"
13051 (if_then_else (match_dup 1)
13052 (label_ref (match_operand 0 "" ""))
13054 "TARGET_80387 || TARGET_SSE_MATH"
13055 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13057 (define_expand "bunle"
13059 (if_then_else (match_dup 1)
13060 (label_ref (match_operand 0 "" ""))
13062 "TARGET_80387 || TARGET_SSE_MATH"
13063 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13065 (define_expand "bunlt"
13067 (if_then_else (match_dup 1)
13068 (label_ref (match_operand 0 "" ""))
13070 "TARGET_80387 || TARGET_SSE_MATH"
13071 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13073 (define_expand "bltgt"
13075 (if_then_else (match_dup 1)
13076 (label_ref (match_operand 0 "" ""))
13078 "TARGET_80387 || TARGET_SSE_MATH"
13079 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13081 (define_insn "*jcc_1"
13083 (if_then_else (match_operator 1 "ix86_comparison_operator"
13084 [(reg FLAGS_REG) (const_int 0)])
13085 (label_ref (match_operand 0 "" ""))
13089 [(set_attr "type" "ibr")
13090 (set_attr "modrm" "0")
13091 (set (attr "length")
13092 (if_then_else (and (ge (minus (match_dup 0) (pc))
13094 (lt (minus (match_dup 0) (pc))
13099 (define_insn "*jcc_2"
13101 (if_then_else (match_operator 1 "ix86_comparison_operator"
13102 [(reg FLAGS_REG) (const_int 0)])
13104 (label_ref (match_operand 0 "" ""))))]
13107 [(set_attr "type" "ibr")
13108 (set_attr "modrm" "0")
13109 (set (attr "length")
13110 (if_then_else (and (ge (minus (match_dup 0) (pc))
13112 (lt (minus (match_dup 0) (pc))
13117 ;; In general it is not safe to assume too much about CCmode registers,
13118 ;; so simplify-rtx stops when it sees a second one. Under certain
13119 ;; conditions this is safe on x86, so help combine not create
13127 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13128 [(reg FLAGS_REG) (const_int 0)])
13130 (label_ref (match_operand 1 "" ""))
13134 (if_then_else (match_dup 0)
13135 (label_ref (match_dup 1))
13138 PUT_MODE (operands[0], VOIDmode);
13143 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13144 [(reg FLAGS_REG) (const_int 0)])
13146 (label_ref (match_operand 1 "" ""))
13150 (if_then_else (match_dup 0)
13151 (label_ref (match_dup 1))
13154 rtx new_op0 = copy_rtx (operands[0]);
13155 operands[0] = new_op0;
13156 PUT_MODE (new_op0, VOIDmode);
13157 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13158 GET_MODE (XEXP (new_op0, 0))));
13160 /* Make sure that (a) the CCmode we have for the flags is strong
13161 enough for the reversed compare or (b) we have a valid FP compare. */
13162 if (! ix86_comparison_operator (new_op0, VOIDmode))
13166 ;; Define combination compare-and-branch fp compare instructions to use
13167 ;; during early optimization. Splitting the operation apart early makes
13168 ;; for bad code when we want to reverse the operation.
13170 (define_insn "*fp_jcc_1_mixed"
13172 (if_then_else (match_operator 0 "comparison_operator"
13173 [(match_operand 1 "register_operand" "f,x")
13174 (match_operand 2 "nonimmediate_operand" "f,xm")])
13175 (label_ref (match_operand 3 "" ""))
13177 (clobber (reg:CCFP FPSR_REG))
13178 (clobber (reg:CCFP FLAGS_REG))]
13179 "TARGET_MIX_SSE_I387
13180 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13181 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13182 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13185 (define_insn "*fp_jcc_1_sse"
13187 (if_then_else (match_operator 0 "comparison_operator"
13188 [(match_operand 1 "register_operand" "x")
13189 (match_operand 2 "nonimmediate_operand" "xm")])
13190 (label_ref (match_operand 3 "" ""))
13192 (clobber (reg:CCFP FPSR_REG))
13193 (clobber (reg:CCFP FLAGS_REG))]
13195 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13196 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13197 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13200 (define_insn "*fp_jcc_1_387"
13202 (if_then_else (match_operator 0 "comparison_operator"
13203 [(match_operand 1 "register_operand" "f")
13204 (match_operand 2 "register_operand" "f")])
13205 (label_ref (match_operand 3 "" ""))
13207 (clobber (reg:CCFP FPSR_REG))
13208 (clobber (reg:CCFP FLAGS_REG))]
13209 "TARGET_CMOVE && TARGET_80387
13210 && FLOAT_MODE_P (GET_MODE (operands[1]))
13211 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13212 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13215 (define_insn "*fp_jcc_2_mixed"
13217 (if_then_else (match_operator 0 "comparison_operator"
13218 [(match_operand 1 "register_operand" "f,x")
13219 (match_operand 2 "nonimmediate_operand" "f,xm")])
13221 (label_ref (match_operand 3 "" ""))))
13222 (clobber (reg:CCFP FPSR_REG))
13223 (clobber (reg:CCFP FLAGS_REG))]
13224 "TARGET_MIX_SSE_I387
13225 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13226 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13227 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13230 (define_insn "*fp_jcc_2_sse"
13232 (if_then_else (match_operator 0 "comparison_operator"
13233 [(match_operand 1 "register_operand" "x")
13234 (match_operand 2 "nonimmediate_operand" "xm")])
13236 (label_ref (match_operand 3 "" ""))))
13237 (clobber (reg:CCFP FPSR_REG))
13238 (clobber (reg:CCFP FLAGS_REG))]
13240 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13241 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13242 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13245 (define_insn "*fp_jcc_2_387"
13247 (if_then_else (match_operator 0 "comparison_operator"
13248 [(match_operand 1 "register_operand" "f")
13249 (match_operand 2 "register_operand" "f")])
13251 (label_ref (match_operand 3 "" ""))))
13252 (clobber (reg:CCFP FPSR_REG))
13253 (clobber (reg:CCFP FLAGS_REG))]
13254 "TARGET_CMOVE && TARGET_80387
13255 && FLOAT_MODE_P (GET_MODE (operands[1]))
13256 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13257 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13260 (define_insn "*fp_jcc_3_387"
13262 (if_then_else (match_operator 0 "comparison_operator"
13263 [(match_operand 1 "register_operand" "f")
13264 (match_operand 2 "nonimmediate_operand" "fm")])
13265 (label_ref (match_operand 3 "" ""))
13267 (clobber (reg:CCFP FPSR_REG))
13268 (clobber (reg:CCFP FLAGS_REG))
13269 (clobber (match_scratch:HI 4 "=a"))]
13271 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13272 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13273 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13274 && SELECT_CC_MODE (GET_CODE (operands[0]),
13275 operands[1], operands[2]) == CCFPmode
13276 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13279 (define_insn "*fp_jcc_4_387"
13281 (if_then_else (match_operator 0 "comparison_operator"
13282 [(match_operand 1 "register_operand" "f")
13283 (match_operand 2 "nonimmediate_operand" "fm")])
13285 (label_ref (match_operand 3 "" ""))))
13286 (clobber (reg:CCFP FPSR_REG))
13287 (clobber (reg:CCFP FLAGS_REG))
13288 (clobber (match_scratch:HI 4 "=a"))]
13290 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13291 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13292 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13293 && SELECT_CC_MODE (GET_CODE (operands[0]),
13294 operands[1], operands[2]) == CCFPmode
13295 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13298 (define_insn "*fp_jcc_5_387"
13300 (if_then_else (match_operator 0 "comparison_operator"
13301 [(match_operand 1 "register_operand" "f")
13302 (match_operand 2 "register_operand" "f")])
13303 (label_ref (match_operand 3 "" ""))
13305 (clobber (reg:CCFP FPSR_REG))
13306 (clobber (reg:CCFP FLAGS_REG))
13307 (clobber (match_scratch:HI 4 "=a"))]
13309 && FLOAT_MODE_P (GET_MODE (operands[1]))
13310 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13311 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13314 (define_insn "*fp_jcc_6_387"
13316 (if_then_else (match_operator 0 "comparison_operator"
13317 [(match_operand 1 "register_operand" "f")
13318 (match_operand 2 "register_operand" "f")])
13320 (label_ref (match_operand 3 "" ""))))
13321 (clobber (reg:CCFP FPSR_REG))
13322 (clobber (reg:CCFP FLAGS_REG))
13323 (clobber (match_scratch:HI 4 "=a"))]
13325 && FLOAT_MODE_P (GET_MODE (operands[1]))
13326 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13327 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13330 (define_insn "*fp_jcc_7_387"
13332 (if_then_else (match_operator 0 "comparison_operator"
13333 [(match_operand 1 "register_operand" "f")
13334 (match_operand 2 "const0_operand" "X")])
13335 (label_ref (match_operand 3 "" ""))
13337 (clobber (reg:CCFP FPSR_REG))
13338 (clobber (reg:CCFP FLAGS_REG))
13339 (clobber (match_scratch:HI 4 "=a"))]
13341 && FLOAT_MODE_P (GET_MODE (operands[1]))
13342 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13343 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13344 && SELECT_CC_MODE (GET_CODE (operands[0]),
13345 operands[1], operands[2]) == CCFPmode
13346 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13349 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13350 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13351 ;; with a precedence over other operators and is always put in the first
13352 ;; place. Swap condition and operands to match ficom instruction.
13354 (define_insn "*fp_jcc_8<mode>_387"
13356 (if_then_else (match_operator 0 "comparison_operator"
13357 [(match_operator 1 "float_operator"
13358 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13359 (match_operand 3 "register_operand" "f,f")])
13360 (label_ref (match_operand 4 "" ""))
13362 (clobber (reg:CCFP FPSR_REG))
13363 (clobber (reg:CCFP FLAGS_REG))
13364 (clobber (match_scratch:HI 5 "=a,a"))]
13365 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13366 && FLOAT_MODE_P (GET_MODE (operands[3]))
13367 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13368 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13369 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13370 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13375 (if_then_else (match_operator 0 "comparison_operator"
13376 [(match_operand 1 "register_operand" "")
13377 (match_operand 2 "nonimmediate_operand" "")])
13378 (match_operand 3 "" "")
13379 (match_operand 4 "" "")))
13380 (clobber (reg:CCFP FPSR_REG))
13381 (clobber (reg:CCFP FLAGS_REG))]
13385 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13386 operands[3], operands[4], NULL_RTX, NULL_RTX);
13392 (if_then_else (match_operator 0 "comparison_operator"
13393 [(match_operand 1 "register_operand" "")
13394 (match_operand 2 "general_operand" "")])
13395 (match_operand 3 "" "")
13396 (match_operand 4 "" "")))
13397 (clobber (reg:CCFP FPSR_REG))
13398 (clobber (reg:CCFP FLAGS_REG))
13399 (clobber (match_scratch:HI 5 "=a"))]
13403 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13404 operands[3], operands[4], operands[5], NULL_RTX);
13410 (if_then_else (match_operator 0 "comparison_operator"
13411 [(match_operator 1 "float_operator"
13412 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13413 (match_operand 3 "register_operand" "")])
13414 (match_operand 4 "" "")
13415 (match_operand 5 "" "")))
13416 (clobber (reg:CCFP FPSR_REG))
13417 (clobber (reg:CCFP FLAGS_REG))
13418 (clobber (match_scratch:HI 6 "=a"))]
13422 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13423 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13424 operands[3], operands[7],
13425 operands[4], operands[5], operands[6], NULL_RTX);
13429 ;; %%% Kill this when reload knows how to do it.
13432 (if_then_else (match_operator 0 "comparison_operator"
13433 [(match_operator 1 "float_operator"
13434 [(match_operand:X87MODEI12 2 "register_operand" "")])
13435 (match_operand 3 "register_operand" "")])
13436 (match_operand 4 "" "")
13437 (match_operand 5 "" "")))
13438 (clobber (reg:CCFP FPSR_REG))
13439 (clobber (reg:CCFP FLAGS_REG))
13440 (clobber (match_scratch:HI 6 "=a"))]
13444 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13445 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13446 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13447 operands[3], operands[7],
13448 operands[4], operands[5], operands[6], operands[2]);
13452 ;; Unconditional and other jump instructions
13454 (define_insn "jump"
13456 (label_ref (match_operand 0 "" "")))]
13459 [(set_attr "type" "ibr")
13460 (set (attr "length")
13461 (if_then_else (and (ge (minus (match_dup 0) (pc))
13463 (lt (minus (match_dup 0) (pc))
13467 (set_attr "modrm" "0")])
13469 (define_expand "indirect_jump"
13470 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13474 (define_insn "*indirect_jump"
13475 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13478 [(set_attr "type" "ibr")
13479 (set_attr "length_immediate" "0")])
13481 (define_insn "*indirect_jump_rtx64"
13482 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13485 [(set_attr "type" "ibr")
13486 (set_attr "length_immediate" "0")])
13488 (define_expand "tablejump"
13489 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13490 (use (label_ref (match_operand 1 "" "")))])]
13493 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13494 relative. Convert the relative address to an absolute address. */
13498 enum rtx_code code;
13504 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13506 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13510 op1 = pic_offset_table_rtx;
13515 op0 = pic_offset_table_rtx;
13519 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13524 (define_insn "*tablejump_1"
13525 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13526 (use (label_ref (match_operand 1 "" "")))]
13529 [(set_attr "type" "ibr")
13530 (set_attr "length_immediate" "0")])
13532 (define_insn "*tablejump_1_rtx64"
13533 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13534 (use (label_ref (match_operand 1 "" "")))]
13537 [(set_attr "type" "ibr")
13538 (set_attr "length_immediate" "0")])
13540 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13543 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13544 (set (match_operand:QI 1 "register_operand" "")
13545 (match_operator:QI 2 "ix86_comparison_operator"
13546 [(reg FLAGS_REG) (const_int 0)]))
13547 (set (match_operand 3 "q_regs_operand" "")
13548 (zero_extend (match_dup 1)))]
13549 "(peep2_reg_dead_p (3, operands[1])
13550 || operands_match_p (operands[1], operands[3]))
13551 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13552 [(set (match_dup 4) (match_dup 0))
13553 (set (strict_low_part (match_dup 5))
13556 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13557 operands[5] = gen_lowpart (QImode, operands[3]);
13558 ix86_expand_clear (operands[3]);
13561 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13564 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13565 (set (match_operand:QI 1 "register_operand" "")
13566 (match_operator:QI 2 "ix86_comparison_operator"
13567 [(reg FLAGS_REG) (const_int 0)]))
13568 (parallel [(set (match_operand 3 "q_regs_operand" "")
13569 (zero_extend (match_dup 1)))
13570 (clobber (reg:CC FLAGS_REG))])]
13571 "(peep2_reg_dead_p (3, operands[1])
13572 || operands_match_p (operands[1], operands[3]))
13573 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13574 [(set (match_dup 4) (match_dup 0))
13575 (set (strict_low_part (match_dup 5))
13578 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13579 operands[5] = gen_lowpart (QImode, operands[3]);
13580 ix86_expand_clear (operands[3]);
13583 ;; Call instructions.
13585 ;; The predicates normally associated with named expanders are not properly
13586 ;; checked for calls. This is a bug in the generic code, but it isn't that
13587 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13589 ;; Call subroutine returning no value.
13591 (define_expand "call_pop"
13592 [(parallel [(call (match_operand:QI 0 "" "")
13593 (match_operand:SI 1 "" ""))
13594 (set (reg:SI SP_REG)
13595 (plus:SI (reg:SI SP_REG)
13596 (match_operand:SI 3 "" "")))])]
13599 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13603 (define_insn "*call_pop_0"
13604 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13605 (match_operand:SI 1 "" ""))
13606 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13607 (match_operand:SI 2 "immediate_operand" "")))]
13610 if (SIBLING_CALL_P (insn))
13613 return "call\t%P0";
13615 [(set_attr "type" "call")])
13617 (define_insn "*call_pop_1"
13618 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13619 (match_operand:SI 1 "" ""))
13620 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13621 (match_operand:SI 2 "immediate_operand" "i")))]
13624 if (constant_call_address_operand (operands[0], Pmode))
13626 if (SIBLING_CALL_P (insn))
13629 return "call\t%P0";
13631 if (SIBLING_CALL_P (insn))
13634 return "call\t%A0";
13636 [(set_attr "type" "call")])
13638 (define_expand "call"
13639 [(call (match_operand:QI 0 "" "")
13640 (match_operand 1 "" ""))
13641 (use (match_operand 2 "" ""))]
13644 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13648 (define_expand "sibcall"
13649 [(call (match_operand:QI 0 "" "")
13650 (match_operand 1 "" ""))
13651 (use (match_operand 2 "" ""))]
13654 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13658 (define_insn "*call_0"
13659 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13660 (match_operand 1 "" ""))]
13663 if (SIBLING_CALL_P (insn))
13666 return "call\t%P0";
13668 [(set_attr "type" "call")])
13670 (define_insn "*call_1"
13671 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13672 (match_operand 1 "" ""))]
13673 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13675 if (constant_call_address_operand (operands[0], Pmode))
13676 return "call\t%P0";
13677 return "call\t%A0";
13679 [(set_attr "type" "call")])
13681 (define_insn "*sibcall_1"
13682 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13683 (match_operand 1 "" ""))]
13684 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13686 if (constant_call_address_operand (operands[0], Pmode))
13690 [(set_attr "type" "call")])
13692 (define_insn "*call_1_rex64"
13693 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13694 (match_operand 1 "" ""))]
13695 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13697 if (constant_call_address_operand (operands[0], Pmode))
13698 return "call\t%P0";
13699 return "call\t%A0";
13701 [(set_attr "type" "call")])
13703 (define_insn "*sibcall_1_rex64"
13704 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13705 (match_operand 1 "" ""))]
13706 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13708 [(set_attr "type" "call")])
13710 (define_insn "*sibcall_1_rex64_v"
13711 [(call (mem:QI (reg:DI 40))
13712 (match_operand 0 "" ""))]
13713 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13715 [(set_attr "type" "call")])
13718 ;; Call subroutine, returning value in operand 0
13720 (define_expand "call_value_pop"
13721 [(parallel [(set (match_operand 0 "" "")
13722 (call (match_operand:QI 1 "" "")
13723 (match_operand:SI 2 "" "")))
13724 (set (reg:SI SP_REG)
13725 (plus:SI (reg:SI SP_REG)
13726 (match_operand:SI 4 "" "")))])]
13729 ix86_expand_call (operands[0], operands[1], operands[2],
13730 operands[3], operands[4], 0);
13734 (define_expand "call_value"
13735 [(set (match_operand 0 "" "")
13736 (call (match_operand:QI 1 "" "")
13737 (match_operand:SI 2 "" "")))
13738 (use (match_operand:SI 3 "" ""))]
13739 ;; Operand 2 not used on the i386.
13742 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13746 (define_expand "sibcall_value"
13747 [(set (match_operand 0 "" "")
13748 (call (match_operand:QI 1 "" "")
13749 (match_operand:SI 2 "" "")))
13750 (use (match_operand:SI 3 "" ""))]
13751 ;; Operand 2 not used on the i386.
13754 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13758 ;; Call subroutine returning any type.
13760 (define_expand "untyped_call"
13761 [(parallel [(call (match_operand 0 "" "")
13763 (match_operand 1 "" "")
13764 (match_operand 2 "" "")])]
13769 /* In order to give reg-stack an easier job in validating two
13770 coprocessor registers as containing a possible return value,
13771 simply pretend the untyped call returns a complex long double
13774 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13775 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13776 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13779 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13781 rtx set = XVECEXP (operands[2], 0, i);
13782 emit_move_insn (SET_DEST (set), SET_SRC (set));
13785 /* The optimizer does not know that the call sets the function value
13786 registers we stored in the result block. We avoid problems by
13787 claiming that all hard registers are used and clobbered at this
13789 emit_insn (gen_blockage (const0_rtx));
13794 ;; Prologue and epilogue instructions
13796 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13797 ;; all of memory. This blocks insns from being moved across this point.
13799 (define_insn "blockage"
13800 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13803 [(set_attr "length" "0")])
13805 ;; Insn emitted into the body of a function to return from a function.
13806 ;; This is only done if the function's epilogue is known to be simple.
13807 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13809 (define_expand "return"
13811 "ix86_can_use_return_insn_p ()"
13813 if (current_function_pops_args)
13815 rtx popc = GEN_INT (current_function_pops_args);
13816 emit_jump_insn (gen_return_pop_internal (popc));
13821 (define_insn "return_internal"
13825 [(set_attr "length" "1")
13826 (set_attr "length_immediate" "0")
13827 (set_attr "modrm" "0")])
13829 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13830 ;; instruction Athlon and K8 have.
13832 (define_insn "return_internal_long"
13834 (unspec [(const_int 0)] UNSPEC_REP)]
13837 [(set_attr "length" "1")
13838 (set_attr "length_immediate" "0")
13839 (set_attr "prefix_rep" "1")
13840 (set_attr "modrm" "0")])
13842 (define_insn "return_pop_internal"
13844 (use (match_operand:SI 0 "const_int_operand" ""))]
13847 [(set_attr "length" "3")
13848 (set_attr "length_immediate" "2")
13849 (set_attr "modrm" "0")])
13851 (define_insn "return_indirect_internal"
13853 (use (match_operand:SI 0 "register_operand" "r"))]
13856 [(set_attr "type" "ibr")
13857 (set_attr "length_immediate" "0")])
13863 [(set_attr "length" "1")
13864 (set_attr "length_immediate" "0")
13865 (set_attr "modrm" "0")])
13867 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13868 ;; branch prediction penalty for the third jump in a 16-byte
13871 (define_insn "align"
13872 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13875 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13876 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13878 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13879 The align insn is used to avoid 3 jump instructions in the row to improve
13880 branch prediction and the benefits hardly outweight the cost of extra 8
13881 nops on the average inserted by full alignment pseudo operation. */
13885 [(set_attr "length" "16")])
13887 (define_expand "prologue"
13890 "ix86_expand_prologue (); DONE;")
13892 (define_insn "set_got"
13893 [(set (match_operand:SI 0 "register_operand" "=r")
13894 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13895 (clobber (reg:CC FLAGS_REG))]
13897 { return output_set_got (operands[0], NULL_RTX); }
13898 [(set_attr "type" "multi")
13899 (set_attr "length" "12")])
13901 (define_insn "set_got_labelled"
13902 [(set (match_operand:SI 0 "register_operand" "=r")
13903 (unspec:SI [(label_ref (match_operand 1 "" ""))]
13905 (clobber (reg:CC FLAGS_REG))]
13907 { return output_set_got (operands[0], operands[1]); }
13908 [(set_attr "type" "multi")
13909 (set_attr "length" "12")])
13911 (define_insn "set_got_rex64"
13912 [(set (match_operand:DI 0 "register_operand" "=r")
13913 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13915 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13916 [(set_attr "type" "lea")
13917 (set_attr "length" "6")])
13919 (define_expand "epilogue"
13922 "ix86_expand_epilogue (1); DONE;")
13924 (define_expand "sibcall_epilogue"
13927 "ix86_expand_epilogue (0); DONE;")
13929 (define_expand "eh_return"
13930 [(use (match_operand 0 "register_operand" ""))]
13933 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13935 /* Tricky bit: we write the address of the handler to which we will
13936 be returning into someone else's stack frame, one word below the
13937 stack address we wish to restore. */
13938 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13939 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13940 tmp = gen_rtx_MEM (Pmode, tmp);
13941 emit_move_insn (tmp, ra);
13943 if (Pmode == SImode)
13944 emit_jump_insn (gen_eh_return_si (sa));
13946 emit_jump_insn (gen_eh_return_di (sa));
13951 (define_insn_and_split "eh_return_si"
13953 (unspec [(match_operand:SI 0 "register_operand" "c")]
13954 UNSPEC_EH_RETURN))]
13959 "ix86_expand_epilogue (2); DONE;")
13961 (define_insn_and_split "eh_return_di"
13963 (unspec [(match_operand:DI 0 "register_operand" "c")]
13964 UNSPEC_EH_RETURN))]
13969 "ix86_expand_epilogue (2); DONE;")
13971 (define_insn "leave"
13972 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13973 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13974 (clobber (mem:BLK (scratch)))]
13977 [(set_attr "type" "leave")])
13979 (define_insn "leave_rex64"
13980 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13981 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13982 (clobber (mem:BLK (scratch)))]
13985 [(set_attr "type" "leave")])
13987 (define_expand "ffssi2"
13989 [(set (match_operand:SI 0 "register_operand" "")
13990 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13991 (clobber (match_scratch:SI 2 ""))
13992 (clobber (reg:CC FLAGS_REG))])]
13996 (define_insn_and_split "*ffs_cmove"
13997 [(set (match_operand:SI 0 "register_operand" "=r")
13998 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13999 (clobber (match_scratch:SI 2 "=&r"))
14000 (clobber (reg:CC FLAGS_REG))]
14003 "&& reload_completed"
14004 [(set (match_dup 2) (const_int -1))
14005 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14006 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14007 (set (match_dup 0) (if_then_else:SI
14008 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14011 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14012 (clobber (reg:CC FLAGS_REG))])]
14015 (define_insn_and_split "*ffs_no_cmove"
14016 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14017 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14018 (clobber (match_scratch:SI 2 "=&q"))
14019 (clobber (reg:CC FLAGS_REG))]
14023 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14024 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14025 (set (strict_low_part (match_dup 3))
14026 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14027 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14028 (clobber (reg:CC FLAGS_REG))])
14029 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14030 (clobber (reg:CC FLAGS_REG))])
14031 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14032 (clobber (reg:CC FLAGS_REG))])]
14034 operands[3] = gen_lowpart (QImode, operands[2]);
14035 ix86_expand_clear (operands[2]);
14038 (define_insn "*ffssi_1"
14039 [(set (reg:CCZ FLAGS_REG)
14040 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14042 (set (match_operand:SI 0 "register_operand" "=r")
14043 (ctz:SI (match_dup 1)))]
14045 "bsf{l}\t{%1, %0|%0, %1}"
14046 [(set_attr "prefix_0f" "1")])
14048 (define_expand "ffsdi2"
14050 [(set (match_operand:DI 0 "register_operand" "")
14051 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14052 (clobber (match_scratch:DI 2 ""))
14053 (clobber (reg:CC FLAGS_REG))])]
14054 "TARGET_64BIT && TARGET_CMOVE"
14057 (define_insn_and_split "*ffs_rex64"
14058 [(set (match_operand:DI 0 "register_operand" "=r")
14059 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14060 (clobber (match_scratch:DI 2 "=&r"))
14061 (clobber (reg:CC FLAGS_REG))]
14062 "TARGET_64BIT && TARGET_CMOVE"
14064 "&& reload_completed"
14065 [(set (match_dup 2) (const_int -1))
14066 (parallel [(set (reg:CCZ FLAGS_REG)
14067 (compare:CCZ (match_dup 1) (const_int 0)))
14068 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14069 (set (match_dup 0) (if_then_else:DI
14070 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14073 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14074 (clobber (reg:CC FLAGS_REG))])]
14077 (define_insn "*ffsdi_1"
14078 [(set (reg:CCZ FLAGS_REG)
14079 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14081 (set (match_operand:DI 0 "register_operand" "=r")
14082 (ctz:DI (match_dup 1)))]
14084 "bsf{q}\t{%1, %0|%0, %1}"
14085 [(set_attr "prefix_0f" "1")])
14087 (define_insn "ctzsi2"
14088 [(set (match_operand:SI 0 "register_operand" "=r")
14089 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14090 (clobber (reg:CC FLAGS_REG))]
14092 "bsf{l}\t{%1, %0|%0, %1}"
14093 [(set_attr "prefix_0f" "1")])
14095 (define_insn "ctzdi2"
14096 [(set (match_operand:DI 0 "register_operand" "=r")
14097 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14098 (clobber (reg:CC FLAGS_REG))]
14100 "bsf{q}\t{%1, %0|%0, %1}"
14101 [(set_attr "prefix_0f" "1")])
14103 (define_expand "clzsi2"
14105 [(set (match_operand:SI 0 "register_operand" "")
14106 (minus:SI (const_int 31)
14107 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14108 (clobber (reg:CC FLAGS_REG))])
14110 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14111 (clobber (reg:CC FLAGS_REG))])]
14115 (define_insn "*bsr"
14116 [(set (match_operand:SI 0 "register_operand" "=r")
14117 (minus:SI (const_int 31)
14118 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14119 (clobber (reg:CC FLAGS_REG))]
14121 "bsr{l}\t{%1, %0|%0, %1}"
14122 [(set_attr "prefix_0f" "1")])
14124 (define_expand "clzdi2"
14126 [(set (match_operand:DI 0 "register_operand" "")
14127 (minus:DI (const_int 63)
14128 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14129 (clobber (reg:CC FLAGS_REG))])
14131 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14132 (clobber (reg:CC FLAGS_REG))])]
14136 (define_insn "*bsr_rex64"
14137 [(set (match_operand:DI 0 "register_operand" "=r")
14138 (minus:DI (const_int 63)
14139 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14140 (clobber (reg:CC FLAGS_REG))]
14142 "bsr{q}\t{%1, %0|%0, %1}"
14143 [(set_attr "prefix_0f" "1")])
14145 ;; Thread-local storage patterns for ELF.
14147 ;; Note that these code sequences must appear exactly as shown
14148 ;; in order to allow linker relaxation.
14150 (define_insn "*tls_global_dynamic_32_gnu"
14151 [(set (match_operand:SI 0 "register_operand" "=a")
14152 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14153 (match_operand:SI 2 "tls_symbolic_operand" "")
14154 (match_operand:SI 3 "call_insn_operand" "")]
14156 (clobber (match_scratch:SI 4 "=d"))
14157 (clobber (match_scratch:SI 5 "=c"))
14158 (clobber (reg:CC FLAGS_REG))]
14159 "!TARGET_64BIT && TARGET_GNU_TLS"
14160 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14161 [(set_attr "type" "multi")
14162 (set_attr "length" "12")])
14164 (define_insn "*tls_global_dynamic_32_sun"
14165 [(set (match_operand:SI 0 "register_operand" "=a")
14166 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14167 (match_operand:SI 2 "tls_symbolic_operand" "")
14168 (match_operand:SI 3 "call_insn_operand" "")]
14170 (clobber (match_scratch:SI 4 "=d"))
14171 (clobber (match_scratch:SI 5 "=c"))
14172 (clobber (reg:CC FLAGS_REG))]
14173 "!TARGET_64BIT && TARGET_SUN_TLS"
14174 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14175 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14176 [(set_attr "type" "multi")
14177 (set_attr "length" "14")])
14179 (define_expand "tls_global_dynamic_32"
14180 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14183 (match_operand:SI 1 "tls_symbolic_operand" "")
14186 (clobber (match_scratch:SI 4 ""))
14187 (clobber (match_scratch:SI 5 ""))
14188 (clobber (reg:CC FLAGS_REG))])]
14192 operands[2] = pic_offset_table_rtx;
14195 operands[2] = gen_reg_rtx (Pmode);
14196 emit_insn (gen_set_got (operands[2]));
14198 if (TARGET_GNU2_TLS)
14200 emit_insn (gen_tls_dynamic_gnu2_32
14201 (operands[0], operands[1], operands[2]));
14204 operands[3] = ix86_tls_get_addr ();
14207 (define_insn "*tls_global_dynamic_64"
14208 [(set (match_operand:DI 0 "register_operand" "=a")
14209 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14210 (match_operand:DI 3 "" "")))
14211 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14214 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14215 [(set_attr "type" "multi")
14216 (set_attr "length" "16")])
14218 (define_expand "tls_global_dynamic_64"
14219 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14220 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14221 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14225 if (TARGET_GNU2_TLS)
14227 emit_insn (gen_tls_dynamic_gnu2_64
14228 (operands[0], operands[1]));
14231 operands[2] = ix86_tls_get_addr ();
14234 (define_insn "*tls_local_dynamic_base_32_gnu"
14235 [(set (match_operand:SI 0 "register_operand" "=a")
14236 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14237 (match_operand:SI 2 "call_insn_operand" "")]
14238 UNSPEC_TLS_LD_BASE))
14239 (clobber (match_scratch:SI 3 "=d"))
14240 (clobber (match_scratch:SI 4 "=c"))
14241 (clobber (reg:CC FLAGS_REG))]
14242 "!TARGET_64BIT && TARGET_GNU_TLS"
14243 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14244 [(set_attr "type" "multi")
14245 (set_attr "length" "11")])
14247 (define_insn "*tls_local_dynamic_base_32_sun"
14248 [(set (match_operand:SI 0 "register_operand" "=a")
14249 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14250 (match_operand:SI 2 "call_insn_operand" "")]
14251 UNSPEC_TLS_LD_BASE))
14252 (clobber (match_scratch:SI 3 "=d"))
14253 (clobber (match_scratch:SI 4 "=c"))
14254 (clobber (reg:CC FLAGS_REG))]
14255 "!TARGET_64BIT && TARGET_SUN_TLS"
14256 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14257 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14258 [(set_attr "type" "multi")
14259 (set_attr "length" "13")])
14261 (define_expand "tls_local_dynamic_base_32"
14262 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14263 (unspec:SI [(match_dup 1) (match_dup 2)]
14264 UNSPEC_TLS_LD_BASE))
14265 (clobber (match_scratch:SI 3 ""))
14266 (clobber (match_scratch:SI 4 ""))
14267 (clobber (reg:CC FLAGS_REG))])]
14271 operands[1] = pic_offset_table_rtx;
14274 operands[1] = gen_reg_rtx (Pmode);
14275 emit_insn (gen_set_got (operands[1]));
14277 if (TARGET_GNU2_TLS)
14279 emit_insn (gen_tls_dynamic_gnu2_32
14280 (operands[0], ix86_tls_module_base (), operands[1]));
14283 operands[2] = ix86_tls_get_addr ();
14286 (define_insn "*tls_local_dynamic_base_64"
14287 [(set (match_operand:DI 0 "register_operand" "=a")
14288 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14289 (match_operand:DI 2 "" "")))
14290 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14292 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14293 [(set_attr "type" "multi")
14294 (set_attr "length" "12")])
14296 (define_expand "tls_local_dynamic_base_64"
14297 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14298 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14299 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14302 if (TARGET_GNU2_TLS)
14304 emit_insn (gen_tls_dynamic_gnu2_64
14305 (operands[0], ix86_tls_module_base ()));
14308 operands[1] = ix86_tls_get_addr ();
14311 ;; Local dynamic of a single variable is a lose. Show combine how
14312 ;; to convert that back to global dynamic.
14314 (define_insn_and_split "*tls_local_dynamic_32_once"
14315 [(set (match_operand:SI 0 "register_operand" "=a")
14316 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14317 (match_operand:SI 2 "call_insn_operand" "")]
14318 UNSPEC_TLS_LD_BASE)
14319 (const:SI (unspec:SI
14320 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14322 (clobber (match_scratch:SI 4 "=d"))
14323 (clobber (match_scratch:SI 5 "=c"))
14324 (clobber (reg:CC FLAGS_REG))]
14328 [(parallel [(set (match_dup 0)
14329 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14331 (clobber (match_dup 4))
14332 (clobber (match_dup 5))
14333 (clobber (reg:CC FLAGS_REG))])]
14336 ;; Load and add the thread base pointer from %gs:0.
14338 (define_insn "*load_tp_si"
14339 [(set (match_operand:SI 0 "register_operand" "=r")
14340 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14342 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14343 [(set_attr "type" "imov")
14344 (set_attr "modrm" "0")
14345 (set_attr "length" "7")
14346 (set_attr "memory" "load")
14347 (set_attr "imm_disp" "false")])
14349 (define_insn "*add_tp_si"
14350 [(set (match_operand:SI 0 "register_operand" "=r")
14351 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14352 (match_operand:SI 1 "register_operand" "0")))
14353 (clobber (reg:CC FLAGS_REG))]
14355 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14356 [(set_attr "type" "alu")
14357 (set_attr "modrm" "0")
14358 (set_attr "length" "7")
14359 (set_attr "memory" "load")
14360 (set_attr "imm_disp" "false")])
14362 (define_insn "*load_tp_di"
14363 [(set (match_operand:DI 0 "register_operand" "=r")
14364 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14366 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14367 [(set_attr "type" "imov")
14368 (set_attr "modrm" "0")
14369 (set_attr "length" "7")
14370 (set_attr "memory" "load")
14371 (set_attr "imm_disp" "false")])
14373 (define_insn "*add_tp_di"
14374 [(set (match_operand:DI 0 "register_operand" "=r")
14375 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14376 (match_operand:DI 1 "register_operand" "0")))
14377 (clobber (reg:CC FLAGS_REG))]
14379 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14380 [(set_attr "type" "alu")
14381 (set_attr "modrm" "0")
14382 (set_attr "length" "7")
14383 (set_attr "memory" "load")
14384 (set_attr "imm_disp" "false")])
14386 ;; GNU2 TLS patterns can be split.
14388 (define_expand "tls_dynamic_gnu2_32"
14389 [(set (match_dup 3)
14390 (plus:SI (match_operand:SI 2 "register_operand" "")
14392 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14395 [(set (match_operand:SI 0 "register_operand" "")
14396 (unspec:SI [(match_dup 1) (match_dup 3)
14397 (match_dup 2) (reg:SI SP_REG)]
14399 (clobber (reg:CC FLAGS_REG))])]
14400 "!TARGET_64BIT && TARGET_GNU2_TLS"
14402 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14403 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14406 (define_insn "*tls_dynamic_lea_32"
14407 [(set (match_operand:SI 0 "register_operand" "=r")
14408 (plus:SI (match_operand:SI 1 "register_operand" "b")
14410 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14411 UNSPEC_TLSDESC))))]
14412 "!TARGET_64BIT && TARGET_GNU2_TLS"
14413 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14414 [(set_attr "type" "lea")
14415 (set_attr "mode" "SI")
14416 (set_attr "length" "6")
14417 (set_attr "length_address" "4")])
14419 (define_insn "*tls_dynamic_call_32"
14420 [(set (match_operand:SI 0 "register_operand" "=a")
14421 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14422 (match_operand:SI 2 "register_operand" "0")
14423 ;; we have to make sure %ebx still points to the GOT
14424 (match_operand:SI 3 "register_operand" "b")
14427 (clobber (reg:CC FLAGS_REG))]
14428 "!TARGET_64BIT && TARGET_GNU2_TLS"
14429 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14430 [(set_attr "type" "call")
14431 (set_attr "length" "2")
14432 (set_attr "length_address" "0")])
14434 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14435 [(set (match_operand:SI 0 "register_operand" "=&a")
14437 (plus:SI (match_operand:SI 3 "tp_or_register_operand" "ir")
14438 (unspec:SI [(match_operand:SI 4 "tls_modbase_operand" "")
14439 (match_operand:SI 5 "" "")
14440 (match_operand:SI 2 "register_operand" "b")
14443 (const:SI (unspec:SI
14444 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14446 (clobber (reg:CC FLAGS_REG))]
14447 "!TARGET_64BIT && TARGET_GNU2_TLS"
14451 [(set (match_dup 0)
14452 (plus:SI (match_dup 3)
14454 (clobber (reg:CC FLAGS_REG))])]
14456 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14457 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14460 (define_expand "tls_dynamic_gnu2_64"
14461 [(set (match_dup 2)
14462 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14465 [(set (match_operand:DI 0 "register_operand" "")
14466 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14468 (clobber (reg:CC FLAGS_REG))])]
14469 "TARGET_64BIT && TARGET_GNU2_TLS"
14471 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14472 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14475 (define_insn "*tls_dynamic_lea_64"
14476 [(set (match_operand:DI 0 "register_operand" "=r")
14477 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14479 "TARGET_64BIT && TARGET_GNU2_TLS"
14480 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14481 [(set_attr "type" "lea")
14482 (set_attr "mode" "DI")
14483 (set_attr "length" "7")
14484 (set_attr "length_address" "4")])
14486 (define_insn "*tls_dynamic_call_64"
14487 [(set (match_operand:DI 0 "register_operand" "=a")
14488 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14489 (match_operand:DI 2 "register_operand" "0")
14492 (clobber (reg:CC FLAGS_REG))]
14493 "TARGET_64BIT && TARGET_GNU2_TLS"
14494 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14495 [(set_attr "type" "call")
14496 (set_attr "length" "2")
14497 (set_attr "length_address" "0")])
14499 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14500 [(set (match_operand:DI 0 "register_operand" "=&a")
14502 (plus:DI (match_operand:DI 2 "tp_or_register_operand" "ir")
14503 (unspec:DI [(match_operand:DI 3 "tls_modbase_operand" "")
14504 (match_operand:DI 4 "" "")
14507 (const:DI (unspec:DI
14508 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14510 (clobber (reg:CC FLAGS_REG))]
14511 "TARGET_64BIT && TARGET_GNU2_TLS"
14515 [(set (match_dup 0)
14516 (plus:DI (match_dup 2)
14518 (clobber (reg:CC FLAGS_REG))])]
14520 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14521 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14526 ;; These patterns match the binary 387 instructions for addM3, subM3,
14527 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14528 ;; SFmode. The first is the normal insn, the second the same insn but
14529 ;; with one operand a conversion, and the third the same insn but with
14530 ;; the other operand a conversion. The conversion may be SFmode or
14531 ;; SImode if the target mode DFmode, but only SImode if the target mode
14534 ;; Gcc is slightly more smart about handling normal two address instructions
14535 ;; so use special patterns for add and mull.
14537 (define_insn "*fop_sf_comm_mixed"
14538 [(set (match_operand:SF 0 "register_operand" "=f,x")
14539 (match_operator:SF 3 "binary_fp_operator"
14540 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14541 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14542 "TARGET_MIX_SSE_I387
14543 && COMMUTATIVE_ARITH_P (operands[3])
14544 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14545 "* return output_387_binary_op (insn, operands);"
14546 [(set (attr "type")
14547 (if_then_else (eq_attr "alternative" "1")
14548 (if_then_else (match_operand:SF 3 "mult_operator" "")
14549 (const_string "ssemul")
14550 (const_string "sseadd"))
14551 (if_then_else (match_operand:SF 3 "mult_operator" "")
14552 (const_string "fmul")
14553 (const_string "fop"))))
14554 (set_attr "mode" "SF")])
14556 (define_insn "*fop_sf_comm_sse"
14557 [(set (match_operand:SF 0 "register_operand" "=x")
14558 (match_operator:SF 3 "binary_fp_operator"
14559 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14560 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14562 && COMMUTATIVE_ARITH_P (operands[3])
14563 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14564 "* return output_387_binary_op (insn, operands);"
14565 [(set (attr "type")
14566 (if_then_else (match_operand:SF 3 "mult_operator" "")
14567 (const_string "ssemul")
14568 (const_string "sseadd")))
14569 (set_attr "mode" "SF")])
14571 (define_insn "*fop_sf_comm_i387"
14572 [(set (match_operand:SF 0 "register_operand" "=f")
14573 (match_operator:SF 3 "binary_fp_operator"
14574 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14575 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14577 && COMMUTATIVE_ARITH_P (operands[3])
14578 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14579 "* return output_387_binary_op (insn, operands);"
14580 [(set (attr "type")
14581 (if_then_else (match_operand:SF 3 "mult_operator" "")
14582 (const_string "fmul")
14583 (const_string "fop")))
14584 (set_attr "mode" "SF")])
14586 (define_insn "*fop_sf_1_mixed"
14587 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14588 (match_operator:SF 3 "binary_fp_operator"
14589 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14590 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
14591 "TARGET_MIX_SSE_I387
14592 && !COMMUTATIVE_ARITH_P (operands[3])
14593 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14594 "* return output_387_binary_op (insn, operands);"
14595 [(set (attr "type")
14596 (cond [(and (eq_attr "alternative" "2")
14597 (match_operand:SF 3 "mult_operator" ""))
14598 (const_string "ssemul")
14599 (and (eq_attr "alternative" "2")
14600 (match_operand:SF 3 "div_operator" ""))
14601 (const_string "ssediv")
14602 (eq_attr "alternative" "2")
14603 (const_string "sseadd")
14604 (match_operand:SF 3 "mult_operator" "")
14605 (const_string "fmul")
14606 (match_operand:SF 3 "div_operator" "")
14607 (const_string "fdiv")
14609 (const_string "fop")))
14610 (set_attr "mode" "SF")])
14612 (define_insn "*fop_sf_1_sse"
14613 [(set (match_operand:SF 0 "register_operand" "=x")
14614 (match_operator:SF 3 "binary_fp_operator"
14615 [(match_operand:SF 1 "register_operand" "0")
14616 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14618 && !COMMUTATIVE_ARITH_P (operands[3])"
14619 "* return output_387_binary_op (insn, operands);"
14620 [(set (attr "type")
14621 (cond [(match_operand:SF 3 "mult_operator" "")
14622 (const_string "ssemul")
14623 (match_operand:SF 3 "div_operator" "")
14624 (const_string "ssediv")
14626 (const_string "sseadd")))
14627 (set_attr "mode" "SF")])
14629 ;; This pattern is not fully shadowed by the pattern above.
14630 (define_insn "*fop_sf_1_i387"
14631 [(set (match_operand:SF 0 "register_operand" "=f,f")
14632 (match_operator:SF 3 "binary_fp_operator"
14633 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14634 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14635 "TARGET_80387 && !TARGET_SSE_MATH
14636 && !COMMUTATIVE_ARITH_P (operands[3])
14637 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14638 "* return output_387_binary_op (insn, operands);"
14639 [(set (attr "type")
14640 (cond [(match_operand:SF 3 "mult_operator" "")
14641 (const_string "fmul")
14642 (match_operand:SF 3 "div_operator" "")
14643 (const_string "fdiv")
14645 (const_string "fop")))
14646 (set_attr "mode" "SF")])
14648 ;; ??? Add SSE splitters for these!
14649 (define_insn "*fop_sf_2<mode>_i387"
14650 [(set (match_operand:SF 0 "register_operand" "=f,f")
14651 (match_operator:SF 3 "binary_fp_operator"
14652 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14653 (match_operand:SF 2 "register_operand" "0,0")]))]
14654 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14655 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14656 [(set (attr "type")
14657 (cond [(match_operand:SF 3 "mult_operator" "")
14658 (const_string "fmul")
14659 (match_operand:SF 3 "div_operator" "")
14660 (const_string "fdiv")
14662 (const_string "fop")))
14663 (set_attr "fp_int_src" "true")
14664 (set_attr "mode" "<MODE>")])
14666 (define_insn "*fop_sf_3<mode>_i387"
14667 [(set (match_operand:SF 0 "register_operand" "=f,f")
14668 (match_operator:SF 3 "binary_fp_operator"
14669 [(match_operand:SF 1 "register_operand" "0,0")
14670 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14671 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14672 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14673 [(set (attr "type")
14674 (cond [(match_operand:SF 3 "mult_operator" "")
14675 (const_string "fmul")
14676 (match_operand:SF 3 "div_operator" "")
14677 (const_string "fdiv")
14679 (const_string "fop")))
14680 (set_attr "fp_int_src" "true")
14681 (set_attr "mode" "<MODE>")])
14683 (define_insn "*fop_df_comm_mixed"
14684 [(set (match_operand:DF 0 "register_operand" "=f,Y")
14685 (match_operator:DF 3 "binary_fp_operator"
14686 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14687 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
14688 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14689 && COMMUTATIVE_ARITH_P (operands[3])
14690 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14691 "* return output_387_binary_op (insn, operands);"
14692 [(set (attr "type")
14693 (if_then_else (eq_attr "alternative" "1")
14694 (if_then_else (match_operand:SF 3 "mult_operator" "")
14695 (const_string "ssemul")
14696 (const_string "sseadd"))
14697 (if_then_else (match_operand:SF 3 "mult_operator" "")
14698 (const_string "fmul")
14699 (const_string "fop"))))
14700 (set_attr "mode" "DF")])
14702 (define_insn "*fop_df_comm_sse"
14703 [(set (match_operand:DF 0 "register_operand" "=Y")
14704 (match_operator:DF 3 "binary_fp_operator"
14705 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14706 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14707 "TARGET_SSE2 && TARGET_SSE_MATH
14708 && COMMUTATIVE_ARITH_P (operands[3])
14709 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14710 "* return output_387_binary_op (insn, operands);"
14711 [(set (attr "type")
14712 (if_then_else (match_operand:SF 3 "mult_operator" "")
14713 (const_string "ssemul")
14714 (const_string "sseadd")))
14715 (set_attr "mode" "DF")])
14717 (define_insn "*fop_df_comm_i387"
14718 [(set (match_operand:DF 0 "register_operand" "=f")
14719 (match_operator:DF 3 "binary_fp_operator"
14720 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14721 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14723 && COMMUTATIVE_ARITH_P (operands[3])
14724 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14725 "* return output_387_binary_op (insn, operands);"
14726 [(set (attr "type")
14727 (if_then_else (match_operand:SF 3 "mult_operator" "")
14728 (const_string "fmul")
14729 (const_string "fop")))
14730 (set_attr "mode" "DF")])
14732 (define_insn "*fop_df_1_mixed"
14733 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
14734 (match_operator:DF 3 "binary_fp_operator"
14735 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14736 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
14737 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14738 && !COMMUTATIVE_ARITH_P (operands[3])
14739 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14740 "* return output_387_binary_op (insn, operands);"
14741 [(set (attr "type")
14742 (cond [(and (eq_attr "alternative" "2")
14743 (match_operand:SF 3 "mult_operator" ""))
14744 (const_string "ssemul")
14745 (and (eq_attr "alternative" "2")
14746 (match_operand:SF 3 "div_operator" ""))
14747 (const_string "ssediv")
14748 (eq_attr "alternative" "2")
14749 (const_string "sseadd")
14750 (match_operand:DF 3 "mult_operator" "")
14751 (const_string "fmul")
14752 (match_operand:DF 3 "div_operator" "")
14753 (const_string "fdiv")
14755 (const_string "fop")))
14756 (set_attr "mode" "DF")])
14758 (define_insn "*fop_df_1_sse"
14759 [(set (match_operand:DF 0 "register_operand" "=Y")
14760 (match_operator:DF 3 "binary_fp_operator"
14761 [(match_operand:DF 1 "register_operand" "0")
14762 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14763 "TARGET_SSE2 && TARGET_SSE_MATH
14764 && !COMMUTATIVE_ARITH_P (operands[3])"
14765 "* return output_387_binary_op (insn, operands);"
14766 [(set_attr "mode" "DF")
14768 (cond [(match_operand:SF 3 "mult_operator" "")
14769 (const_string "ssemul")
14770 (match_operand:SF 3 "div_operator" "")
14771 (const_string "ssediv")
14773 (const_string "sseadd")))])
14775 ;; This pattern is not fully shadowed by the pattern above.
14776 (define_insn "*fop_df_1_i387"
14777 [(set (match_operand:DF 0 "register_operand" "=f,f")
14778 (match_operator:DF 3 "binary_fp_operator"
14779 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14780 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14781 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14782 && !COMMUTATIVE_ARITH_P (operands[3])
14783 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14784 "* return output_387_binary_op (insn, operands);"
14785 [(set (attr "type")
14786 (cond [(match_operand:DF 3 "mult_operator" "")
14787 (const_string "fmul")
14788 (match_operand:DF 3 "div_operator" "")
14789 (const_string "fdiv")
14791 (const_string "fop")))
14792 (set_attr "mode" "DF")])
14794 ;; ??? Add SSE splitters for these!
14795 (define_insn "*fop_df_2<mode>_i387"
14796 [(set (match_operand:DF 0 "register_operand" "=f,f")
14797 (match_operator:DF 3 "binary_fp_operator"
14798 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14799 (match_operand:DF 2 "register_operand" "0,0")]))]
14800 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14801 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14802 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14803 [(set (attr "type")
14804 (cond [(match_operand:DF 3 "mult_operator" "")
14805 (const_string "fmul")
14806 (match_operand:DF 3 "div_operator" "")
14807 (const_string "fdiv")
14809 (const_string "fop")))
14810 (set_attr "fp_int_src" "true")
14811 (set_attr "mode" "<MODE>")])
14813 (define_insn "*fop_df_3<mode>_i387"
14814 [(set (match_operand:DF 0 "register_operand" "=f,f")
14815 (match_operator:DF 3 "binary_fp_operator"
14816 [(match_operand:DF 1 "register_operand" "0,0")
14817 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14818 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14819 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14820 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14821 [(set (attr "type")
14822 (cond [(match_operand:DF 3 "mult_operator" "")
14823 (const_string "fmul")
14824 (match_operand:DF 3 "div_operator" "")
14825 (const_string "fdiv")
14827 (const_string "fop")))
14828 (set_attr "fp_int_src" "true")
14829 (set_attr "mode" "<MODE>")])
14831 (define_insn "*fop_df_4_i387"
14832 [(set (match_operand:DF 0 "register_operand" "=f,f")
14833 (match_operator:DF 3 "binary_fp_operator"
14834 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14835 (match_operand:DF 2 "register_operand" "0,f")]))]
14836 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14837 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14838 "* return output_387_binary_op (insn, operands);"
14839 [(set (attr "type")
14840 (cond [(match_operand:DF 3 "mult_operator" "")
14841 (const_string "fmul")
14842 (match_operand:DF 3 "div_operator" "")
14843 (const_string "fdiv")
14845 (const_string "fop")))
14846 (set_attr "mode" "SF")])
14848 (define_insn "*fop_df_5_i387"
14849 [(set (match_operand:DF 0 "register_operand" "=f,f")
14850 (match_operator:DF 3 "binary_fp_operator"
14851 [(match_operand:DF 1 "register_operand" "0,f")
14853 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14854 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14855 "* return output_387_binary_op (insn, operands);"
14856 [(set (attr "type")
14857 (cond [(match_operand:DF 3 "mult_operator" "")
14858 (const_string "fmul")
14859 (match_operand:DF 3 "div_operator" "")
14860 (const_string "fdiv")
14862 (const_string "fop")))
14863 (set_attr "mode" "SF")])
14865 (define_insn "*fop_df_6_i387"
14866 [(set (match_operand:DF 0 "register_operand" "=f,f")
14867 (match_operator:DF 3 "binary_fp_operator"
14869 (match_operand:SF 1 "register_operand" "0,f"))
14871 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14872 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14873 "* return output_387_binary_op (insn, operands);"
14874 [(set (attr "type")
14875 (cond [(match_operand:DF 3 "mult_operator" "")
14876 (const_string "fmul")
14877 (match_operand:DF 3 "div_operator" "")
14878 (const_string "fdiv")
14880 (const_string "fop")))
14881 (set_attr "mode" "SF")])
14883 (define_insn "*fop_xf_comm_i387"
14884 [(set (match_operand:XF 0 "register_operand" "=f")
14885 (match_operator:XF 3 "binary_fp_operator"
14886 [(match_operand:XF 1 "register_operand" "%0")
14887 (match_operand:XF 2 "register_operand" "f")]))]
14889 && COMMUTATIVE_ARITH_P (operands[3])"
14890 "* return output_387_binary_op (insn, operands);"
14891 [(set (attr "type")
14892 (if_then_else (match_operand:XF 3 "mult_operator" "")
14893 (const_string "fmul")
14894 (const_string "fop")))
14895 (set_attr "mode" "XF")])
14897 (define_insn "*fop_xf_1_i387"
14898 [(set (match_operand:XF 0 "register_operand" "=f,f")
14899 (match_operator:XF 3 "binary_fp_operator"
14900 [(match_operand:XF 1 "register_operand" "0,f")
14901 (match_operand:XF 2 "register_operand" "f,0")]))]
14903 && !COMMUTATIVE_ARITH_P (operands[3])"
14904 "* return output_387_binary_op (insn, operands);"
14905 [(set (attr "type")
14906 (cond [(match_operand:XF 3 "mult_operator" "")
14907 (const_string "fmul")
14908 (match_operand:XF 3 "div_operator" "")
14909 (const_string "fdiv")
14911 (const_string "fop")))
14912 (set_attr "mode" "XF")])
14914 (define_insn "*fop_xf_2<mode>_i387"
14915 [(set (match_operand:XF 0 "register_operand" "=f,f")
14916 (match_operator:XF 3 "binary_fp_operator"
14917 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14918 (match_operand:XF 2 "register_operand" "0,0")]))]
14919 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14920 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14921 [(set (attr "type")
14922 (cond [(match_operand:XF 3 "mult_operator" "")
14923 (const_string "fmul")
14924 (match_operand:XF 3 "div_operator" "")
14925 (const_string "fdiv")
14927 (const_string "fop")))
14928 (set_attr "fp_int_src" "true")
14929 (set_attr "mode" "<MODE>")])
14931 (define_insn "*fop_xf_3<mode>_i387"
14932 [(set (match_operand:XF 0 "register_operand" "=f,f")
14933 (match_operator:XF 3 "binary_fp_operator"
14934 [(match_operand:XF 1 "register_operand" "0,0")
14935 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14936 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14937 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14938 [(set (attr "type")
14939 (cond [(match_operand:XF 3 "mult_operator" "")
14940 (const_string "fmul")
14941 (match_operand:XF 3 "div_operator" "")
14942 (const_string "fdiv")
14944 (const_string "fop")))
14945 (set_attr "fp_int_src" "true")
14946 (set_attr "mode" "<MODE>")])
14948 (define_insn "*fop_xf_4_i387"
14949 [(set (match_operand:XF 0 "register_operand" "=f,f")
14950 (match_operator:XF 3 "binary_fp_operator"
14951 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14952 (match_operand:XF 2 "register_operand" "0,f")]))]
14954 "* return output_387_binary_op (insn, operands);"
14955 [(set (attr "type")
14956 (cond [(match_operand:XF 3 "mult_operator" "")
14957 (const_string "fmul")
14958 (match_operand:XF 3 "div_operator" "")
14959 (const_string "fdiv")
14961 (const_string "fop")))
14962 (set_attr "mode" "SF")])
14964 (define_insn "*fop_xf_5_i387"
14965 [(set (match_operand:XF 0 "register_operand" "=f,f")
14966 (match_operator:XF 3 "binary_fp_operator"
14967 [(match_operand:XF 1 "register_operand" "0,f")
14969 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14971 "* return output_387_binary_op (insn, operands);"
14972 [(set (attr "type")
14973 (cond [(match_operand:XF 3 "mult_operator" "")
14974 (const_string "fmul")
14975 (match_operand:XF 3 "div_operator" "")
14976 (const_string "fdiv")
14978 (const_string "fop")))
14979 (set_attr "mode" "SF")])
14981 (define_insn "*fop_xf_6_i387"
14982 [(set (match_operand:XF 0 "register_operand" "=f,f")
14983 (match_operator:XF 3 "binary_fp_operator"
14985 (match_operand 1 "register_operand" "0,f"))
14987 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14989 "* return output_387_binary_op (insn, operands);"
14990 [(set (attr "type")
14991 (cond [(match_operand:XF 3 "mult_operator" "")
14992 (const_string "fmul")
14993 (match_operand:XF 3 "div_operator" "")
14994 (const_string "fdiv")
14996 (const_string "fop")))
14997 (set_attr "mode" "SF")])
15000 [(set (match_operand 0 "register_operand" "")
15001 (match_operator 3 "binary_fp_operator"
15002 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15003 (match_operand 2 "register_operand" "")]))]
15004 "TARGET_80387 && reload_completed
15005 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15008 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15009 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15010 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15011 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15012 GET_MODE (operands[3]),
15015 ix86_free_from_memory (GET_MODE (operands[1]));
15020 [(set (match_operand 0 "register_operand" "")
15021 (match_operator 3 "binary_fp_operator"
15022 [(match_operand 1 "register_operand" "")
15023 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15024 "TARGET_80387 && reload_completed
15025 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15028 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15029 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15030 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15031 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15032 GET_MODE (operands[3]),
15035 ix86_free_from_memory (GET_MODE (operands[2]));
15039 ;; FPU special functions.
15041 (define_expand "sqrtsf2"
15042 [(set (match_operand:SF 0 "register_operand" "")
15043 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15044 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15046 if (!TARGET_SSE_MATH)
15047 operands[1] = force_reg (SFmode, operands[1]);
15050 (define_insn "*sqrtsf2_mixed"
15051 [(set (match_operand:SF 0 "register_operand" "=f,x")
15052 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15053 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15056 sqrtss\t{%1, %0|%0, %1}"
15057 [(set_attr "type" "fpspc,sse")
15058 (set_attr "mode" "SF,SF")
15059 (set_attr "athlon_decode" "direct,*")])
15061 (define_insn "*sqrtsf2_sse"
15062 [(set (match_operand:SF 0 "register_operand" "=x")
15063 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15065 "sqrtss\t{%1, %0|%0, %1}"
15066 [(set_attr "type" "sse")
15067 (set_attr "mode" "SF")
15068 (set_attr "athlon_decode" "*")])
15070 (define_insn "*sqrtsf2_i387"
15071 [(set (match_operand:SF 0 "register_operand" "=f")
15072 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15073 "TARGET_USE_FANCY_MATH_387"
15075 [(set_attr "type" "fpspc")
15076 (set_attr "mode" "SF")
15077 (set_attr "athlon_decode" "direct")])
15079 (define_expand "sqrtdf2"
15080 [(set (match_operand:DF 0 "register_operand" "")
15081 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15082 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15084 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15085 operands[1] = force_reg (DFmode, operands[1]);
15088 (define_insn "*sqrtdf2_mixed"
15089 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15090 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15091 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15094 sqrtsd\t{%1, %0|%0, %1}"
15095 [(set_attr "type" "fpspc,sse")
15096 (set_attr "mode" "DF,DF")
15097 (set_attr "athlon_decode" "direct,*")])
15099 (define_insn "*sqrtdf2_sse"
15100 [(set (match_operand:DF 0 "register_operand" "=Y")
15101 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15102 "TARGET_SSE2 && TARGET_SSE_MATH"
15103 "sqrtsd\t{%1, %0|%0, %1}"
15104 [(set_attr "type" "sse")
15105 (set_attr "mode" "DF")
15106 (set_attr "athlon_decode" "*")])
15108 (define_insn "*sqrtdf2_i387"
15109 [(set (match_operand:DF 0 "register_operand" "=f")
15110 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15111 "TARGET_USE_FANCY_MATH_387"
15113 [(set_attr "type" "fpspc")
15114 (set_attr "mode" "DF")
15115 (set_attr "athlon_decode" "direct")])
15117 (define_insn "*sqrtextendsfdf2_i387"
15118 [(set (match_operand:DF 0 "register_operand" "=f")
15119 (sqrt:DF (float_extend:DF
15120 (match_operand:SF 1 "register_operand" "0"))))]
15121 "TARGET_USE_FANCY_MATH_387
15122 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15124 [(set_attr "type" "fpspc")
15125 (set_attr "mode" "DF")
15126 (set_attr "athlon_decode" "direct")])
15128 (define_insn "sqrtxf2"
15129 [(set (match_operand:XF 0 "register_operand" "=f")
15130 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15131 "TARGET_USE_FANCY_MATH_387
15132 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15134 [(set_attr "type" "fpspc")
15135 (set_attr "mode" "XF")
15136 (set_attr "athlon_decode" "direct")])
15138 (define_insn "*sqrtextendsfxf2_i387"
15139 [(set (match_operand:XF 0 "register_operand" "=f")
15140 (sqrt:XF (float_extend:XF
15141 (match_operand:SF 1 "register_operand" "0"))))]
15142 "TARGET_USE_FANCY_MATH_387"
15144 [(set_attr "type" "fpspc")
15145 (set_attr "mode" "XF")
15146 (set_attr "athlon_decode" "direct")])
15148 (define_insn "*sqrtextenddfxf2_i387"
15149 [(set (match_operand:XF 0 "register_operand" "=f")
15150 (sqrt:XF (float_extend:XF
15151 (match_operand:DF 1 "register_operand" "0"))))]
15152 "TARGET_USE_FANCY_MATH_387"
15154 [(set_attr "type" "fpspc")
15155 (set_attr "mode" "XF")
15156 (set_attr "athlon_decode" "direct")])
15158 (define_insn "fpremxf4"
15159 [(set (match_operand:XF 0 "register_operand" "=f")
15160 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15161 (match_operand:XF 3 "register_operand" "1")]
15163 (set (match_operand:XF 1 "register_operand" "=u")
15164 (unspec:XF [(match_dup 2) (match_dup 3)]
15166 (set (reg:CCFP FPSR_REG)
15167 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15168 "TARGET_USE_FANCY_MATH_387
15169 && flag_unsafe_math_optimizations"
15171 [(set_attr "type" "fpspc")
15172 (set_attr "mode" "XF")])
15174 (define_expand "fmodsf3"
15175 [(use (match_operand:SF 0 "register_operand" ""))
15176 (use (match_operand:SF 1 "register_operand" ""))
15177 (use (match_operand:SF 2 "register_operand" ""))]
15178 "TARGET_USE_FANCY_MATH_387
15179 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15180 && flag_unsafe_math_optimizations"
15182 rtx label = gen_label_rtx ();
15184 rtx op1 = gen_reg_rtx (XFmode);
15185 rtx op2 = gen_reg_rtx (XFmode);
15187 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15188 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15190 emit_label (label);
15192 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15193 ix86_emit_fp_unordered_jump (label);
15195 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15199 (define_expand "fmoddf3"
15200 [(use (match_operand:DF 0 "register_operand" ""))
15201 (use (match_operand:DF 1 "register_operand" ""))
15202 (use (match_operand:DF 2 "register_operand" ""))]
15203 "TARGET_USE_FANCY_MATH_387
15204 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15205 && flag_unsafe_math_optimizations"
15207 rtx label = gen_label_rtx ();
15209 rtx op1 = gen_reg_rtx (XFmode);
15210 rtx op2 = gen_reg_rtx (XFmode);
15212 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15213 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15215 emit_label (label);
15217 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15218 ix86_emit_fp_unordered_jump (label);
15220 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15224 (define_expand "fmodxf3"
15225 [(use (match_operand:XF 0 "register_operand" ""))
15226 (use (match_operand:XF 1 "register_operand" ""))
15227 (use (match_operand:XF 2 "register_operand" ""))]
15228 "TARGET_USE_FANCY_MATH_387
15229 && flag_unsafe_math_optimizations"
15231 rtx label = gen_label_rtx ();
15233 emit_label (label);
15235 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15236 operands[1], operands[2]));
15237 ix86_emit_fp_unordered_jump (label);
15239 emit_move_insn (operands[0], operands[1]);
15243 (define_insn "fprem1xf4"
15244 [(set (match_operand:XF 0 "register_operand" "=f")
15245 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15246 (match_operand:XF 3 "register_operand" "1")]
15248 (set (match_operand:XF 1 "register_operand" "=u")
15249 (unspec:XF [(match_dup 2) (match_dup 3)]
15251 (set (reg:CCFP FPSR_REG)
15252 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15253 "TARGET_USE_FANCY_MATH_387
15254 && flag_unsafe_math_optimizations"
15256 [(set_attr "type" "fpspc")
15257 (set_attr "mode" "XF")])
15259 (define_expand "dremsf3"
15260 [(use (match_operand:SF 0 "register_operand" ""))
15261 (use (match_operand:SF 1 "register_operand" ""))
15262 (use (match_operand:SF 2 "register_operand" ""))]
15263 "TARGET_USE_FANCY_MATH_387
15264 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15265 && flag_unsafe_math_optimizations"
15267 rtx label = gen_label_rtx ();
15269 rtx op1 = gen_reg_rtx (XFmode);
15270 rtx op2 = gen_reg_rtx (XFmode);
15272 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15273 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15275 emit_label (label);
15277 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15278 ix86_emit_fp_unordered_jump (label);
15280 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15284 (define_expand "dremdf3"
15285 [(use (match_operand:DF 0 "register_operand" ""))
15286 (use (match_operand:DF 1 "register_operand" ""))
15287 (use (match_operand:DF 2 "register_operand" ""))]
15288 "TARGET_USE_FANCY_MATH_387
15289 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15290 && flag_unsafe_math_optimizations"
15292 rtx label = gen_label_rtx ();
15294 rtx op1 = gen_reg_rtx (XFmode);
15295 rtx op2 = gen_reg_rtx (XFmode);
15297 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15298 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15300 emit_label (label);
15302 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15303 ix86_emit_fp_unordered_jump (label);
15305 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15309 (define_expand "dremxf3"
15310 [(use (match_operand:XF 0 "register_operand" ""))
15311 (use (match_operand:XF 1 "register_operand" ""))
15312 (use (match_operand:XF 2 "register_operand" ""))]
15313 "TARGET_USE_FANCY_MATH_387
15314 && flag_unsafe_math_optimizations"
15316 rtx label = gen_label_rtx ();
15318 emit_label (label);
15320 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15321 operands[1], operands[2]));
15322 ix86_emit_fp_unordered_jump (label);
15324 emit_move_insn (operands[0], operands[1]);
15328 (define_insn "*sindf2"
15329 [(set (match_operand:DF 0 "register_operand" "=f")
15330 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15331 "TARGET_USE_FANCY_MATH_387
15332 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15333 && flag_unsafe_math_optimizations"
15335 [(set_attr "type" "fpspc")
15336 (set_attr "mode" "DF")])
15338 (define_insn "*sinsf2"
15339 [(set (match_operand:SF 0 "register_operand" "=f")
15340 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15341 "TARGET_USE_FANCY_MATH_387
15342 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15343 && flag_unsafe_math_optimizations"
15345 [(set_attr "type" "fpspc")
15346 (set_attr "mode" "SF")])
15348 (define_insn "*sinextendsfdf2"
15349 [(set (match_operand:DF 0 "register_operand" "=f")
15350 (unspec:DF [(float_extend:DF
15351 (match_operand:SF 1 "register_operand" "0"))]
15353 "TARGET_USE_FANCY_MATH_387
15354 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15355 && flag_unsafe_math_optimizations"
15357 [(set_attr "type" "fpspc")
15358 (set_attr "mode" "DF")])
15360 (define_insn "*sinxf2"
15361 [(set (match_operand:XF 0 "register_operand" "=f")
15362 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15363 "TARGET_USE_FANCY_MATH_387
15364 && flag_unsafe_math_optimizations"
15366 [(set_attr "type" "fpspc")
15367 (set_attr "mode" "XF")])
15369 (define_insn "*cosdf2"
15370 [(set (match_operand:DF 0 "register_operand" "=f")
15371 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15372 "TARGET_USE_FANCY_MATH_387
15373 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15374 && flag_unsafe_math_optimizations"
15376 [(set_attr "type" "fpspc")
15377 (set_attr "mode" "DF")])
15379 (define_insn "*cossf2"
15380 [(set (match_operand:SF 0 "register_operand" "=f")
15381 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15382 "TARGET_USE_FANCY_MATH_387
15383 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15384 && flag_unsafe_math_optimizations"
15386 [(set_attr "type" "fpspc")
15387 (set_attr "mode" "SF")])
15389 (define_insn "*cosextendsfdf2"
15390 [(set (match_operand:DF 0 "register_operand" "=f")
15391 (unspec:DF [(float_extend:DF
15392 (match_operand:SF 1 "register_operand" "0"))]
15394 "TARGET_USE_FANCY_MATH_387
15395 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15396 && flag_unsafe_math_optimizations"
15398 [(set_attr "type" "fpspc")
15399 (set_attr "mode" "DF")])
15401 (define_insn "*cosxf2"
15402 [(set (match_operand:XF 0 "register_operand" "=f")
15403 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15404 "TARGET_USE_FANCY_MATH_387
15405 && flag_unsafe_math_optimizations"
15407 [(set_attr "type" "fpspc")
15408 (set_attr "mode" "XF")])
15410 ;; With sincos pattern defined, sin and cos builtin function will be
15411 ;; expanded to sincos pattern with one of its outputs left unused.
15412 ;; Cse pass will detected, if two sincos patterns can be combined,
15413 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15414 ;; depending on the unused output.
15416 (define_insn "sincosdf3"
15417 [(set (match_operand:DF 0 "register_operand" "=f")
15418 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15419 UNSPEC_SINCOS_COS))
15420 (set (match_operand:DF 1 "register_operand" "=u")
15421 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15422 "TARGET_USE_FANCY_MATH_387
15423 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15424 && flag_unsafe_math_optimizations"
15426 [(set_attr "type" "fpspc")
15427 (set_attr "mode" "DF")])
15430 [(set (match_operand:DF 0 "register_operand" "")
15431 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15432 UNSPEC_SINCOS_COS))
15433 (set (match_operand:DF 1 "register_operand" "")
15434 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15435 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15436 && !reload_completed && !reload_in_progress"
15437 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15441 [(set (match_operand:DF 0 "register_operand" "")
15442 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15443 UNSPEC_SINCOS_COS))
15444 (set (match_operand:DF 1 "register_operand" "")
15445 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15446 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15447 && !reload_completed && !reload_in_progress"
15448 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15451 (define_insn "sincossf3"
15452 [(set (match_operand:SF 0 "register_operand" "=f")
15453 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15454 UNSPEC_SINCOS_COS))
15455 (set (match_operand:SF 1 "register_operand" "=u")
15456 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15457 "TARGET_USE_FANCY_MATH_387
15458 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15459 && flag_unsafe_math_optimizations"
15461 [(set_attr "type" "fpspc")
15462 (set_attr "mode" "SF")])
15465 [(set (match_operand:SF 0 "register_operand" "")
15466 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15467 UNSPEC_SINCOS_COS))
15468 (set (match_operand:SF 1 "register_operand" "")
15469 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15470 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15471 && !reload_completed && !reload_in_progress"
15472 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15476 [(set (match_operand:SF 0 "register_operand" "")
15477 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15478 UNSPEC_SINCOS_COS))
15479 (set (match_operand:SF 1 "register_operand" "")
15480 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15481 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15482 && !reload_completed && !reload_in_progress"
15483 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15486 (define_insn "*sincosextendsfdf3"
15487 [(set (match_operand:DF 0 "register_operand" "=f")
15488 (unspec:DF [(float_extend:DF
15489 (match_operand:SF 2 "register_operand" "0"))]
15490 UNSPEC_SINCOS_COS))
15491 (set (match_operand:DF 1 "register_operand" "=u")
15492 (unspec:DF [(float_extend:DF
15493 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15494 "TARGET_USE_FANCY_MATH_387
15495 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15496 && flag_unsafe_math_optimizations"
15498 [(set_attr "type" "fpspc")
15499 (set_attr "mode" "DF")])
15502 [(set (match_operand:DF 0 "register_operand" "")
15503 (unspec:DF [(float_extend:DF
15504 (match_operand:SF 2 "register_operand" ""))]
15505 UNSPEC_SINCOS_COS))
15506 (set (match_operand:DF 1 "register_operand" "")
15507 (unspec:DF [(float_extend:DF
15508 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15509 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15510 && !reload_completed && !reload_in_progress"
15511 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15512 (match_dup 2))] UNSPEC_SIN))]
15516 [(set (match_operand:DF 0 "register_operand" "")
15517 (unspec:DF [(float_extend:DF
15518 (match_operand:SF 2 "register_operand" ""))]
15519 UNSPEC_SINCOS_COS))
15520 (set (match_operand:DF 1 "register_operand" "")
15521 (unspec:DF [(float_extend:DF
15522 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15523 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15524 && !reload_completed && !reload_in_progress"
15525 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15526 (match_dup 2))] UNSPEC_COS))]
15529 (define_insn "sincosxf3"
15530 [(set (match_operand:XF 0 "register_operand" "=f")
15531 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15532 UNSPEC_SINCOS_COS))
15533 (set (match_operand:XF 1 "register_operand" "=u")
15534 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15535 "TARGET_USE_FANCY_MATH_387
15536 && flag_unsafe_math_optimizations"
15538 [(set_attr "type" "fpspc")
15539 (set_attr "mode" "XF")])
15542 [(set (match_operand:XF 0 "register_operand" "")
15543 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15544 UNSPEC_SINCOS_COS))
15545 (set (match_operand:XF 1 "register_operand" "")
15546 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15547 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15548 && !reload_completed && !reload_in_progress"
15549 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15553 [(set (match_operand:XF 0 "register_operand" "")
15554 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15555 UNSPEC_SINCOS_COS))
15556 (set (match_operand:XF 1 "register_operand" "")
15557 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15558 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15559 && !reload_completed && !reload_in_progress"
15560 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15563 (define_insn "*tandf3_1"
15564 [(set (match_operand:DF 0 "register_operand" "=f")
15565 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15567 (set (match_operand:DF 1 "register_operand" "=u")
15568 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15569 "TARGET_USE_FANCY_MATH_387
15570 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15571 && flag_unsafe_math_optimizations"
15573 [(set_attr "type" "fpspc")
15574 (set_attr "mode" "DF")])
15576 ;; optimize sequence: fptan
15579 ;; into fptan insn.
15582 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15583 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15585 (set (match_operand:DF 1 "register_operand" "")
15586 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15588 (match_operand:DF 3 "immediate_operand" ""))]
15589 "standard_80387_constant_p (operands[3]) == 2"
15590 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15591 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15594 (define_expand "tandf2"
15595 [(parallel [(set (match_dup 2)
15596 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15598 (set (match_operand:DF 0 "register_operand" "")
15599 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15600 "TARGET_USE_FANCY_MATH_387
15601 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15602 && flag_unsafe_math_optimizations"
15604 operands[2] = gen_reg_rtx (DFmode);
15607 (define_insn "*tansf3_1"
15608 [(set (match_operand:SF 0 "register_operand" "=f")
15609 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15611 (set (match_operand:SF 1 "register_operand" "=u")
15612 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15613 "TARGET_USE_FANCY_MATH_387
15614 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15615 && flag_unsafe_math_optimizations"
15617 [(set_attr "type" "fpspc")
15618 (set_attr "mode" "SF")])
15620 ;; optimize sequence: fptan
15623 ;; into fptan insn.
15626 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15627 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15629 (set (match_operand:SF 1 "register_operand" "")
15630 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15632 (match_operand:SF 3 "immediate_operand" ""))]
15633 "standard_80387_constant_p (operands[3]) == 2"
15634 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15635 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15638 (define_expand "tansf2"
15639 [(parallel [(set (match_dup 2)
15640 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15642 (set (match_operand:SF 0 "register_operand" "")
15643 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15644 "TARGET_USE_FANCY_MATH_387
15645 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15646 && flag_unsafe_math_optimizations"
15648 operands[2] = gen_reg_rtx (SFmode);
15651 (define_insn "*tanxf3_1"
15652 [(set (match_operand:XF 0 "register_operand" "=f")
15653 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15655 (set (match_operand:XF 1 "register_operand" "=u")
15656 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15657 "TARGET_USE_FANCY_MATH_387
15658 && flag_unsafe_math_optimizations"
15660 [(set_attr "type" "fpspc")
15661 (set_attr "mode" "XF")])
15663 ;; optimize sequence: fptan
15666 ;; into fptan insn.
15669 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15670 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15672 (set (match_operand:XF 1 "register_operand" "")
15673 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15675 (match_operand:XF 3 "immediate_operand" ""))]
15676 "standard_80387_constant_p (operands[3]) == 2"
15677 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15678 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15681 (define_expand "tanxf2"
15682 [(parallel [(set (match_dup 2)
15683 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15685 (set (match_operand:XF 0 "register_operand" "")
15686 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15687 "TARGET_USE_FANCY_MATH_387
15688 && flag_unsafe_math_optimizations"
15690 operands[2] = gen_reg_rtx (XFmode);
15693 (define_insn "atan2df3_1"
15694 [(set (match_operand:DF 0 "register_operand" "=f")
15695 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15696 (match_operand:DF 1 "register_operand" "u")]
15698 (clobber (match_scratch:DF 3 "=1"))]
15699 "TARGET_USE_FANCY_MATH_387
15700 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15701 && flag_unsafe_math_optimizations"
15703 [(set_attr "type" "fpspc")
15704 (set_attr "mode" "DF")])
15706 (define_expand "atan2df3"
15707 [(use (match_operand:DF 0 "register_operand" ""))
15708 (use (match_operand:DF 2 "register_operand" ""))
15709 (use (match_operand:DF 1 "register_operand" ""))]
15710 "TARGET_USE_FANCY_MATH_387
15711 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15712 && flag_unsafe_math_optimizations"
15714 rtx copy = gen_reg_rtx (DFmode);
15715 emit_move_insn (copy, operands[1]);
15716 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15720 (define_expand "atandf2"
15721 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15722 (unspec:DF [(match_dup 2)
15723 (match_operand:DF 1 "register_operand" "")]
15725 (clobber (match_scratch:DF 3 ""))])]
15726 "TARGET_USE_FANCY_MATH_387
15727 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15728 && flag_unsafe_math_optimizations"
15730 operands[2] = gen_reg_rtx (DFmode);
15731 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15734 (define_insn "atan2sf3_1"
15735 [(set (match_operand:SF 0 "register_operand" "=f")
15736 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15737 (match_operand:SF 1 "register_operand" "u")]
15739 (clobber (match_scratch:SF 3 "=1"))]
15740 "TARGET_USE_FANCY_MATH_387
15741 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15742 && flag_unsafe_math_optimizations"
15744 [(set_attr "type" "fpspc")
15745 (set_attr "mode" "SF")])
15747 (define_expand "atan2sf3"
15748 [(use (match_operand:SF 0 "register_operand" ""))
15749 (use (match_operand:SF 2 "register_operand" ""))
15750 (use (match_operand:SF 1 "register_operand" ""))]
15751 "TARGET_USE_FANCY_MATH_387
15752 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15753 && flag_unsafe_math_optimizations"
15755 rtx copy = gen_reg_rtx (SFmode);
15756 emit_move_insn (copy, operands[1]);
15757 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15761 (define_expand "atansf2"
15762 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15763 (unspec:SF [(match_dup 2)
15764 (match_operand:SF 1 "register_operand" "")]
15766 (clobber (match_scratch:SF 3 ""))])]
15767 "TARGET_USE_FANCY_MATH_387
15768 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15769 && flag_unsafe_math_optimizations"
15771 operands[2] = gen_reg_rtx (SFmode);
15772 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15775 (define_insn "atan2xf3_1"
15776 [(set (match_operand:XF 0 "register_operand" "=f")
15777 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15778 (match_operand:XF 1 "register_operand" "u")]
15780 (clobber (match_scratch:XF 3 "=1"))]
15781 "TARGET_USE_FANCY_MATH_387
15782 && flag_unsafe_math_optimizations"
15784 [(set_attr "type" "fpspc")
15785 (set_attr "mode" "XF")])
15787 (define_expand "atan2xf3"
15788 [(use (match_operand:XF 0 "register_operand" ""))
15789 (use (match_operand:XF 2 "register_operand" ""))
15790 (use (match_operand:XF 1 "register_operand" ""))]
15791 "TARGET_USE_FANCY_MATH_387
15792 && flag_unsafe_math_optimizations"
15794 rtx copy = gen_reg_rtx (XFmode);
15795 emit_move_insn (copy, operands[1]);
15796 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15800 (define_expand "atanxf2"
15801 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15802 (unspec:XF [(match_dup 2)
15803 (match_operand:XF 1 "register_operand" "")]
15805 (clobber (match_scratch:XF 3 ""))])]
15806 "TARGET_USE_FANCY_MATH_387
15807 && flag_unsafe_math_optimizations"
15809 operands[2] = gen_reg_rtx (XFmode);
15810 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15813 (define_expand "asindf2"
15814 [(set (match_dup 2)
15815 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15816 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15817 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15818 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15819 (parallel [(set (match_dup 7)
15820 (unspec:XF [(match_dup 6) (match_dup 2)]
15822 (clobber (match_scratch:XF 8 ""))])
15823 (set (match_operand:DF 0 "register_operand" "")
15824 (float_truncate:DF (match_dup 7)))]
15825 "TARGET_USE_FANCY_MATH_387
15826 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15827 && flag_unsafe_math_optimizations"
15831 for (i=2; i<8; i++)
15832 operands[i] = gen_reg_rtx (XFmode);
15834 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15837 (define_expand "asinsf2"
15838 [(set (match_dup 2)
15839 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15840 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15841 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15842 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15843 (parallel [(set (match_dup 7)
15844 (unspec:XF [(match_dup 6) (match_dup 2)]
15846 (clobber (match_scratch:XF 8 ""))])
15847 (set (match_operand:SF 0 "register_operand" "")
15848 (float_truncate:SF (match_dup 7)))]
15849 "TARGET_USE_FANCY_MATH_387
15850 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15851 && flag_unsafe_math_optimizations"
15855 for (i=2; i<8; i++)
15856 operands[i] = gen_reg_rtx (XFmode);
15858 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15861 (define_expand "asinxf2"
15862 [(set (match_dup 2)
15863 (mult:XF (match_operand:XF 1 "register_operand" "")
15865 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15866 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15867 (parallel [(set (match_operand:XF 0 "register_operand" "")
15868 (unspec:XF [(match_dup 5) (match_dup 1)]
15870 (clobber (match_scratch:XF 6 ""))])]
15871 "TARGET_USE_FANCY_MATH_387
15872 && flag_unsafe_math_optimizations"
15876 for (i=2; i<6; i++)
15877 operands[i] = gen_reg_rtx (XFmode);
15879 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15882 (define_expand "acosdf2"
15883 [(set (match_dup 2)
15884 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15885 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15886 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15887 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15888 (parallel [(set (match_dup 7)
15889 (unspec:XF [(match_dup 2) (match_dup 6)]
15891 (clobber (match_scratch:XF 8 ""))])
15892 (set (match_operand:DF 0 "register_operand" "")
15893 (float_truncate:DF (match_dup 7)))]
15894 "TARGET_USE_FANCY_MATH_387
15895 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15896 && flag_unsafe_math_optimizations"
15900 for (i=2; i<8; i++)
15901 operands[i] = gen_reg_rtx (XFmode);
15903 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15906 (define_expand "acossf2"
15907 [(set (match_dup 2)
15908 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15909 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15910 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15911 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15912 (parallel [(set (match_dup 7)
15913 (unspec:XF [(match_dup 2) (match_dup 6)]
15915 (clobber (match_scratch:XF 8 ""))])
15916 (set (match_operand:SF 0 "register_operand" "")
15917 (float_truncate:SF (match_dup 7)))]
15918 "TARGET_USE_FANCY_MATH_387
15919 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15920 && flag_unsafe_math_optimizations"
15924 for (i=2; i<8; i++)
15925 operands[i] = gen_reg_rtx (XFmode);
15927 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15930 (define_expand "acosxf2"
15931 [(set (match_dup 2)
15932 (mult:XF (match_operand:XF 1 "register_operand" "")
15934 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15935 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15936 (parallel [(set (match_operand:XF 0 "register_operand" "")
15937 (unspec:XF [(match_dup 1) (match_dup 5)]
15939 (clobber (match_scratch:XF 6 ""))])]
15940 "TARGET_USE_FANCY_MATH_387
15941 && flag_unsafe_math_optimizations"
15945 for (i=2; i<6; i++)
15946 operands[i] = gen_reg_rtx (XFmode);
15948 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15951 (define_insn "fyl2x_xf3"
15952 [(set (match_operand:XF 0 "register_operand" "=f")
15953 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15954 (match_operand:XF 1 "register_operand" "u")]
15956 (clobber (match_scratch:XF 3 "=1"))]
15957 "TARGET_USE_FANCY_MATH_387
15958 && flag_unsafe_math_optimizations"
15960 [(set_attr "type" "fpspc")
15961 (set_attr "mode" "XF")])
15963 (define_expand "logsf2"
15964 [(set (match_dup 2)
15965 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15966 (parallel [(set (match_dup 4)
15967 (unspec:XF [(match_dup 2)
15968 (match_dup 3)] UNSPEC_FYL2X))
15969 (clobber (match_scratch:XF 5 ""))])
15970 (set (match_operand:SF 0 "register_operand" "")
15971 (float_truncate:SF (match_dup 4)))]
15972 "TARGET_USE_FANCY_MATH_387
15973 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15974 && flag_unsafe_math_optimizations"
15978 operands[2] = gen_reg_rtx (XFmode);
15979 operands[3] = gen_reg_rtx (XFmode);
15980 operands[4] = gen_reg_rtx (XFmode);
15982 temp = standard_80387_constant_rtx (4); /* fldln2 */
15983 emit_move_insn (operands[3], temp);
15986 (define_expand "logdf2"
15987 [(set (match_dup 2)
15988 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15989 (parallel [(set (match_dup 4)
15990 (unspec:XF [(match_dup 2)
15991 (match_dup 3)] UNSPEC_FYL2X))
15992 (clobber (match_scratch:XF 5 ""))])
15993 (set (match_operand:DF 0 "register_operand" "")
15994 (float_truncate:DF (match_dup 4)))]
15995 "TARGET_USE_FANCY_MATH_387
15996 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15997 && flag_unsafe_math_optimizations"
16001 operands[2] = gen_reg_rtx (XFmode);
16002 operands[3] = gen_reg_rtx (XFmode);
16003 operands[4] = gen_reg_rtx (XFmode);
16005 temp = standard_80387_constant_rtx (4); /* fldln2 */
16006 emit_move_insn (operands[3], temp);
16009 (define_expand "logxf2"
16010 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16011 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16012 (match_dup 2)] UNSPEC_FYL2X))
16013 (clobber (match_scratch:XF 3 ""))])]
16014 "TARGET_USE_FANCY_MATH_387
16015 && flag_unsafe_math_optimizations"
16019 operands[2] = gen_reg_rtx (XFmode);
16020 temp = standard_80387_constant_rtx (4); /* fldln2 */
16021 emit_move_insn (operands[2], temp);
16024 (define_expand "log10sf2"
16025 [(set (match_dup 2)
16026 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16027 (parallel [(set (match_dup 4)
16028 (unspec:XF [(match_dup 2)
16029 (match_dup 3)] UNSPEC_FYL2X))
16030 (clobber (match_scratch:XF 5 ""))])
16031 (set (match_operand:SF 0 "register_operand" "")
16032 (float_truncate:SF (match_dup 4)))]
16033 "TARGET_USE_FANCY_MATH_387
16034 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16035 && flag_unsafe_math_optimizations"
16039 operands[2] = gen_reg_rtx (XFmode);
16040 operands[3] = gen_reg_rtx (XFmode);
16041 operands[4] = gen_reg_rtx (XFmode);
16043 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16044 emit_move_insn (operands[3], temp);
16047 (define_expand "log10df2"
16048 [(set (match_dup 2)
16049 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16050 (parallel [(set (match_dup 4)
16051 (unspec:XF [(match_dup 2)
16052 (match_dup 3)] UNSPEC_FYL2X))
16053 (clobber (match_scratch:XF 5 ""))])
16054 (set (match_operand:DF 0 "register_operand" "")
16055 (float_truncate:DF (match_dup 4)))]
16056 "TARGET_USE_FANCY_MATH_387
16057 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16058 && flag_unsafe_math_optimizations"
16062 operands[2] = gen_reg_rtx (XFmode);
16063 operands[3] = gen_reg_rtx (XFmode);
16064 operands[4] = gen_reg_rtx (XFmode);
16066 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16067 emit_move_insn (operands[3], temp);
16070 (define_expand "log10xf2"
16071 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16072 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16073 (match_dup 2)] UNSPEC_FYL2X))
16074 (clobber (match_scratch:XF 3 ""))])]
16075 "TARGET_USE_FANCY_MATH_387
16076 && flag_unsafe_math_optimizations"
16080 operands[2] = gen_reg_rtx (XFmode);
16081 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16082 emit_move_insn (operands[2], temp);
16085 (define_expand "log2sf2"
16086 [(set (match_dup 2)
16087 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16088 (parallel [(set (match_dup 4)
16089 (unspec:XF [(match_dup 2)
16090 (match_dup 3)] UNSPEC_FYL2X))
16091 (clobber (match_scratch:XF 5 ""))])
16092 (set (match_operand:SF 0 "register_operand" "")
16093 (float_truncate:SF (match_dup 4)))]
16094 "TARGET_USE_FANCY_MATH_387
16095 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16096 && flag_unsafe_math_optimizations"
16098 operands[2] = gen_reg_rtx (XFmode);
16099 operands[3] = gen_reg_rtx (XFmode);
16100 operands[4] = gen_reg_rtx (XFmode);
16102 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16105 (define_expand "log2df2"
16106 [(set (match_dup 2)
16107 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16108 (parallel [(set (match_dup 4)
16109 (unspec:XF [(match_dup 2)
16110 (match_dup 3)] UNSPEC_FYL2X))
16111 (clobber (match_scratch:XF 5 ""))])
16112 (set (match_operand:DF 0 "register_operand" "")
16113 (float_truncate:DF (match_dup 4)))]
16114 "TARGET_USE_FANCY_MATH_387
16115 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16116 && flag_unsafe_math_optimizations"
16118 operands[2] = gen_reg_rtx (XFmode);
16119 operands[3] = gen_reg_rtx (XFmode);
16120 operands[4] = gen_reg_rtx (XFmode);
16122 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16125 (define_expand "log2xf2"
16126 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16127 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16128 (match_dup 2)] UNSPEC_FYL2X))
16129 (clobber (match_scratch:XF 3 ""))])]
16130 "TARGET_USE_FANCY_MATH_387
16131 && flag_unsafe_math_optimizations"
16133 operands[2] = gen_reg_rtx (XFmode);
16134 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16137 (define_insn "fyl2xp1_xf3"
16138 [(set (match_operand:XF 0 "register_operand" "=f")
16139 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16140 (match_operand:XF 1 "register_operand" "u")]
16142 (clobber (match_scratch:XF 3 "=1"))]
16143 "TARGET_USE_FANCY_MATH_387
16144 && flag_unsafe_math_optimizations"
16146 [(set_attr "type" "fpspc")
16147 (set_attr "mode" "XF")])
16149 (define_expand "log1psf2"
16150 [(use (match_operand:SF 0 "register_operand" ""))
16151 (use (match_operand:SF 1 "register_operand" ""))]
16152 "TARGET_USE_FANCY_MATH_387
16153 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16154 && flag_unsafe_math_optimizations"
16156 rtx op0 = gen_reg_rtx (XFmode);
16157 rtx op1 = gen_reg_rtx (XFmode);
16159 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16160 ix86_emit_i387_log1p (op0, op1);
16161 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16165 (define_expand "log1pdf2"
16166 [(use (match_operand:DF 0 "register_operand" ""))
16167 (use (match_operand:DF 1 "register_operand" ""))]
16168 "TARGET_USE_FANCY_MATH_387
16169 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16170 && flag_unsafe_math_optimizations"
16172 rtx op0 = gen_reg_rtx (XFmode);
16173 rtx op1 = gen_reg_rtx (XFmode);
16175 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16176 ix86_emit_i387_log1p (op0, op1);
16177 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16181 (define_expand "log1pxf2"
16182 [(use (match_operand:XF 0 "register_operand" ""))
16183 (use (match_operand:XF 1 "register_operand" ""))]
16184 "TARGET_USE_FANCY_MATH_387
16185 && flag_unsafe_math_optimizations"
16187 ix86_emit_i387_log1p (operands[0], operands[1]);
16191 (define_insn "*fxtractxf3"
16192 [(set (match_operand:XF 0 "register_operand" "=f")
16193 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16194 UNSPEC_XTRACT_FRACT))
16195 (set (match_operand:XF 1 "register_operand" "=u")
16196 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16197 "TARGET_USE_FANCY_MATH_387
16198 && flag_unsafe_math_optimizations"
16200 [(set_attr "type" "fpspc")
16201 (set_attr "mode" "XF")])
16203 (define_expand "logbsf2"
16204 [(set (match_dup 2)
16205 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16206 (parallel [(set (match_dup 3)
16207 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16209 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16210 (set (match_operand:SF 0 "register_operand" "")
16211 (float_truncate:SF (match_dup 4)))]
16212 "TARGET_USE_FANCY_MATH_387
16213 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16214 && flag_unsafe_math_optimizations"
16216 operands[2] = gen_reg_rtx (XFmode);
16217 operands[3] = gen_reg_rtx (XFmode);
16218 operands[4] = gen_reg_rtx (XFmode);
16221 (define_expand "logbdf2"
16222 [(set (match_dup 2)
16223 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16224 (parallel [(set (match_dup 3)
16225 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16227 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16228 (set (match_operand:DF 0 "register_operand" "")
16229 (float_truncate:DF (match_dup 4)))]
16230 "TARGET_USE_FANCY_MATH_387
16231 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16232 && flag_unsafe_math_optimizations"
16234 operands[2] = gen_reg_rtx (XFmode);
16235 operands[3] = gen_reg_rtx (XFmode);
16236 operands[4] = gen_reg_rtx (XFmode);
16239 (define_expand "logbxf2"
16240 [(parallel [(set (match_dup 2)
16241 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16242 UNSPEC_XTRACT_FRACT))
16243 (set (match_operand:XF 0 "register_operand" "")
16244 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16245 "TARGET_USE_FANCY_MATH_387
16246 && flag_unsafe_math_optimizations"
16248 operands[2] = gen_reg_rtx (XFmode);
16251 (define_expand "ilogbsi2"
16252 [(parallel [(set (match_dup 2)
16253 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16254 UNSPEC_XTRACT_FRACT))
16255 (set (match_operand:XF 3 "register_operand" "")
16256 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16257 (parallel [(set (match_operand:SI 0 "register_operand" "")
16258 (fix:SI (match_dup 3)))
16259 (clobber (reg:CC FLAGS_REG))])]
16260 "TARGET_USE_FANCY_MATH_387
16261 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16262 && flag_unsafe_math_optimizations"
16264 operands[2] = gen_reg_rtx (XFmode);
16265 operands[3] = gen_reg_rtx (XFmode);
16268 (define_insn "*f2xm1xf2"
16269 [(set (match_operand:XF 0 "register_operand" "=f")
16270 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16272 "TARGET_USE_FANCY_MATH_387
16273 && flag_unsafe_math_optimizations"
16275 [(set_attr "type" "fpspc")
16276 (set_attr "mode" "XF")])
16278 (define_insn "*fscalexf4"
16279 [(set (match_operand:XF 0 "register_operand" "=f")
16280 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16281 (match_operand:XF 3 "register_operand" "1")]
16282 UNSPEC_FSCALE_FRACT))
16283 (set (match_operand:XF 1 "register_operand" "=u")
16284 (unspec:XF [(match_dup 2) (match_dup 3)]
16285 UNSPEC_FSCALE_EXP))]
16286 "TARGET_USE_FANCY_MATH_387
16287 && flag_unsafe_math_optimizations"
16289 [(set_attr "type" "fpspc")
16290 (set_attr "mode" "XF")])
16292 (define_expand "expsf2"
16293 [(set (match_dup 2)
16294 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16295 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16296 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16297 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16298 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16299 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16300 (parallel [(set (match_dup 10)
16301 (unspec:XF [(match_dup 9) (match_dup 5)]
16302 UNSPEC_FSCALE_FRACT))
16303 (set (match_dup 11)
16304 (unspec:XF [(match_dup 9) (match_dup 5)]
16305 UNSPEC_FSCALE_EXP))])
16306 (set (match_operand:SF 0 "register_operand" "")
16307 (float_truncate:SF (match_dup 10)))]
16308 "TARGET_USE_FANCY_MATH_387
16309 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16310 && flag_unsafe_math_optimizations"
16315 for (i=2; i<12; i++)
16316 operands[i] = gen_reg_rtx (XFmode);
16317 temp = standard_80387_constant_rtx (5); /* fldl2e */
16318 emit_move_insn (operands[3], temp);
16319 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16322 (define_expand "expdf2"
16323 [(set (match_dup 2)
16324 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16325 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16326 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16327 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16328 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16329 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16330 (parallel [(set (match_dup 10)
16331 (unspec:XF [(match_dup 9) (match_dup 5)]
16332 UNSPEC_FSCALE_FRACT))
16333 (set (match_dup 11)
16334 (unspec:XF [(match_dup 9) (match_dup 5)]
16335 UNSPEC_FSCALE_EXP))])
16336 (set (match_operand:DF 0 "register_operand" "")
16337 (float_truncate:DF (match_dup 10)))]
16338 "TARGET_USE_FANCY_MATH_387
16339 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16340 && flag_unsafe_math_optimizations"
16345 for (i=2; i<12; i++)
16346 operands[i] = gen_reg_rtx (XFmode);
16347 temp = standard_80387_constant_rtx (5); /* fldl2e */
16348 emit_move_insn (operands[3], temp);
16349 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16352 (define_expand "expxf2"
16353 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16355 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16356 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16357 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16358 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16359 (parallel [(set (match_operand:XF 0 "register_operand" "")
16360 (unspec:XF [(match_dup 8) (match_dup 4)]
16361 UNSPEC_FSCALE_FRACT))
16363 (unspec:XF [(match_dup 8) (match_dup 4)]
16364 UNSPEC_FSCALE_EXP))])]
16365 "TARGET_USE_FANCY_MATH_387
16366 && flag_unsafe_math_optimizations"
16371 for (i=2; i<10; i++)
16372 operands[i] = gen_reg_rtx (XFmode);
16373 temp = standard_80387_constant_rtx (5); /* fldl2e */
16374 emit_move_insn (operands[2], temp);
16375 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16378 (define_expand "exp10sf2"
16379 [(set (match_dup 2)
16380 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16381 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16382 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16383 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16384 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16385 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16386 (parallel [(set (match_dup 10)
16387 (unspec:XF [(match_dup 9) (match_dup 5)]
16388 UNSPEC_FSCALE_FRACT))
16389 (set (match_dup 11)
16390 (unspec:XF [(match_dup 9) (match_dup 5)]
16391 UNSPEC_FSCALE_EXP))])
16392 (set (match_operand:SF 0 "register_operand" "")
16393 (float_truncate:SF (match_dup 10)))]
16394 "TARGET_USE_FANCY_MATH_387
16395 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16396 && flag_unsafe_math_optimizations"
16401 for (i=2; i<12; i++)
16402 operands[i] = gen_reg_rtx (XFmode);
16403 temp = standard_80387_constant_rtx (6); /* fldl2t */
16404 emit_move_insn (operands[3], temp);
16405 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16408 (define_expand "exp10df2"
16409 [(set (match_dup 2)
16410 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16411 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16412 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16413 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16414 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16415 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16416 (parallel [(set (match_dup 10)
16417 (unspec:XF [(match_dup 9) (match_dup 5)]
16418 UNSPEC_FSCALE_FRACT))
16419 (set (match_dup 11)
16420 (unspec:XF [(match_dup 9) (match_dup 5)]
16421 UNSPEC_FSCALE_EXP))])
16422 (set (match_operand:DF 0 "register_operand" "")
16423 (float_truncate:DF (match_dup 10)))]
16424 "TARGET_USE_FANCY_MATH_387
16425 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16426 && flag_unsafe_math_optimizations"
16431 for (i=2; i<12; i++)
16432 operands[i] = gen_reg_rtx (XFmode);
16433 temp = standard_80387_constant_rtx (6); /* fldl2t */
16434 emit_move_insn (operands[3], temp);
16435 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16438 (define_expand "exp10xf2"
16439 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16441 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16442 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16443 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16444 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16445 (parallel [(set (match_operand:XF 0 "register_operand" "")
16446 (unspec:XF [(match_dup 8) (match_dup 4)]
16447 UNSPEC_FSCALE_FRACT))
16449 (unspec:XF [(match_dup 8) (match_dup 4)]
16450 UNSPEC_FSCALE_EXP))])]
16451 "TARGET_USE_FANCY_MATH_387
16452 && flag_unsafe_math_optimizations"
16457 for (i=2; i<10; i++)
16458 operands[i] = gen_reg_rtx (XFmode);
16459 temp = standard_80387_constant_rtx (6); /* fldl2t */
16460 emit_move_insn (operands[2], temp);
16461 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16464 (define_expand "exp2sf2"
16465 [(set (match_dup 2)
16466 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16467 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16468 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16469 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16470 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16471 (parallel [(set (match_dup 8)
16472 (unspec:XF [(match_dup 7) (match_dup 3)]
16473 UNSPEC_FSCALE_FRACT))
16475 (unspec:XF [(match_dup 7) (match_dup 3)]
16476 UNSPEC_FSCALE_EXP))])
16477 (set (match_operand:SF 0 "register_operand" "")
16478 (float_truncate:SF (match_dup 8)))]
16479 "TARGET_USE_FANCY_MATH_387
16480 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16481 && flag_unsafe_math_optimizations"
16485 for (i=2; i<10; i++)
16486 operands[i] = gen_reg_rtx (XFmode);
16487 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16490 (define_expand "exp2df2"
16491 [(set (match_dup 2)
16492 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16493 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16494 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16495 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16496 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16497 (parallel [(set (match_dup 8)
16498 (unspec:XF [(match_dup 7) (match_dup 3)]
16499 UNSPEC_FSCALE_FRACT))
16501 (unspec:XF [(match_dup 7) (match_dup 3)]
16502 UNSPEC_FSCALE_EXP))])
16503 (set (match_operand:DF 0 "register_operand" "")
16504 (float_truncate:DF (match_dup 8)))]
16505 "TARGET_USE_FANCY_MATH_387
16506 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16507 && flag_unsafe_math_optimizations"
16511 for (i=2; i<10; i++)
16512 operands[i] = gen_reg_rtx (XFmode);
16513 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16516 (define_expand "exp2xf2"
16517 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16518 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16519 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16520 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16521 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16522 (parallel [(set (match_operand:XF 0 "register_operand" "")
16523 (unspec:XF [(match_dup 7) (match_dup 3)]
16524 UNSPEC_FSCALE_FRACT))
16526 (unspec:XF [(match_dup 7) (match_dup 3)]
16527 UNSPEC_FSCALE_EXP))])]
16528 "TARGET_USE_FANCY_MATH_387
16529 && flag_unsafe_math_optimizations"
16533 for (i=2; i<9; i++)
16534 operands[i] = gen_reg_rtx (XFmode);
16535 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16538 (define_expand "expm1df2"
16539 [(set (match_dup 2)
16540 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16541 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16542 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16543 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16544 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16545 (parallel [(set (match_dup 8)
16546 (unspec:XF [(match_dup 7) (match_dup 5)]
16547 UNSPEC_FSCALE_FRACT))
16549 (unspec:XF [(match_dup 7) (match_dup 5)]
16550 UNSPEC_FSCALE_EXP))])
16551 (parallel [(set (match_dup 11)
16552 (unspec:XF [(match_dup 10) (match_dup 9)]
16553 UNSPEC_FSCALE_FRACT))
16554 (set (match_dup 12)
16555 (unspec:XF [(match_dup 10) (match_dup 9)]
16556 UNSPEC_FSCALE_EXP))])
16557 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16558 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16559 (set (match_operand:DF 0 "register_operand" "")
16560 (float_truncate:DF (match_dup 14)))]
16561 "TARGET_USE_FANCY_MATH_387
16562 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16563 && flag_unsafe_math_optimizations"
16568 for (i=2; i<15; i++)
16569 operands[i] = gen_reg_rtx (XFmode);
16570 temp = standard_80387_constant_rtx (5); /* fldl2e */
16571 emit_move_insn (operands[3], temp);
16572 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16575 (define_expand "expm1sf2"
16576 [(set (match_dup 2)
16577 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16578 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16579 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16580 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16581 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16582 (parallel [(set (match_dup 8)
16583 (unspec:XF [(match_dup 7) (match_dup 5)]
16584 UNSPEC_FSCALE_FRACT))
16586 (unspec:XF [(match_dup 7) (match_dup 5)]
16587 UNSPEC_FSCALE_EXP))])
16588 (parallel [(set (match_dup 11)
16589 (unspec:XF [(match_dup 10) (match_dup 9)]
16590 UNSPEC_FSCALE_FRACT))
16591 (set (match_dup 12)
16592 (unspec:XF [(match_dup 10) (match_dup 9)]
16593 UNSPEC_FSCALE_EXP))])
16594 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16595 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16596 (set (match_operand:SF 0 "register_operand" "")
16597 (float_truncate:SF (match_dup 14)))]
16598 "TARGET_USE_FANCY_MATH_387
16599 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16600 && flag_unsafe_math_optimizations"
16605 for (i=2; i<15; i++)
16606 operands[i] = gen_reg_rtx (XFmode);
16607 temp = standard_80387_constant_rtx (5); /* fldl2e */
16608 emit_move_insn (operands[3], temp);
16609 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16612 (define_expand "expm1xf2"
16613 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16615 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16616 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16617 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16618 (parallel [(set (match_dup 7)
16619 (unspec:XF [(match_dup 6) (match_dup 4)]
16620 UNSPEC_FSCALE_FRACT))
16622 (unspec:XF [(match_dup 6) (match_dup 4)]
16623 UNSPEC_FSCALE_EXP))])
16624 (parallel [(set (match_dup 10)
16625 (unspec:XF [(match_dup 9) (match_dup 8)]
16626 UNSPEC_FSCALE_FRACT))
16627 (set (match_dup 11)
16628 (unspec:XF [(match_dup 9) (match_dup 8)]
16629 UNSPEC_FSCALE_EXP))])
16630 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16631 (set (match_operand:XF 0 "register_operand" "")
16632 (plus:XF (match_dup 12) (match_dup 7)))]
16633 "TARGET_USE_FANCY_MATH_387
16634 && flag_unsafe_math_optimizations"
16639 for (i=2; i<13; i++)
16640 operands[i] = gen_reg_rtx (XFmode);
16641 temp = standard_80387_constant_rtx (5); /* fldl2e */
16642 emit_move_insn (operands[2], temp);
16643 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16646 (define_expand "ldexpdf3"
16647 [(set (match_dup 3)
16648 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16650 (float:XF (match_operand:SI 2 "register_operand" "")))
16651 (parallel [(set (match_dup 5)
16652 (unspec:XF [(match_dup 3) (match_dup 4)]
16653 UNSPEC_FSCALE_FRACT))
16655 (unspec:XF [(match_dup 3) (match_dup 4)]
16656 UNSPEC_FSCALE_EXP))])
16657 (set (match_operand:DF 0 "register_operand" "")
16658 (float_truncate:DF (match_dup 5)))]
16659 "TARGET_USE_FANCY_MATH_387
16660 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16661 && flag_unsafe_math_optimizations"
16665 for (i=3; i<7; i++)
16666 operands[i] = gen_reg_rtx (XFmode);
16669 (define_expand "ldexpsf3"
16670 [(set (match_dup 3)
16671 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16673 (float:XF (match_operand:SI 2 "register_operand" "")))
16674 (parallel [(set (match_dup 5)
16675 (unspec:XF [(match_dup 3) (match_dup 4)]
16676 UNSPEC_FSCALE_FRACT))
16678 (unspec:XF [(match_dup 3) (match_dup 4)]
16679 UNSPEC_FSCALE_EXP))])
16680 (set (match_operand:SF 0 "register_operand" "")
16681 (float_truncate:SF (match_dup 5)))]
16682 "TARGET_USE_FANCY_MATH_387
16683 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16684 && flag_unsafe_math_optimizations"
16688 for (i=3; i<7; i++)
16689 operands[i] = gen_reg_rtx (XFmode);
16692 (define_expand "ldexpxf3"
16693 [(set (match_dup 3)
16694 (float:XF (match_operand:SI 2 "register_operand" "")))
16695 (parallel [(set (match_operand:XF 0 " register_operand" "")
16696 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16698 UNSPEC_FSCALE_FRACT))
16700 (unspec:XF [(match_dup 1) (match_dup 3)]
16701 UNSPEC_FSCALE_EXP))])]
16702 "TARGET_USE_FANCY_MATH_387
16703 && flag_unsafe_math_optimizations"
16707 for (i=3; i<5; i++)
16708 operands[i] = gen_reg_rtx (XFmode);
16712 (define_insn "frndintxf2"
16713 [(set (match_operand:XF 0 "register_operand" "=f")
16714 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16716 "TARGET_USE_FANCY_MATH_387
16717 && flag_unsafe_math_optimizations"
16719 [(set_attr "type" "fpspc")
16720 (set_attr "mode" "XF")])
16722 (define_expand "rintdf2"
16723 [(use (match_operand:DF 0 "register_operand" ""))
16724 (use (match_operand:DF 1 "register_operand" ""))]
16725 "TARGET_USE_FANCY_MATH_387
16726 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16727 && flag_unsafe_math_optimizations"
16729 rtx op0 = gen_reg_rtx (XFmode);
16730 rtx op1 = gen_reg_rtx (XFmode);
16732 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16733 emit_insn (gen_frndintxf2 (op0, op1));
16735 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16739 (define_expand "rintsf2"
16740 [(use (match_operand:SF 0 "register_operand" ""))
16741 (use (match_operand:SF 1 "register_operand" ""))]
16742 "TARGET_USE_FANCY_MATH_387
16743 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16744 && flag_unsafe_math_optimizations"
16746 rtx op0 = gen_reg_rtx (XFmode);
16747 rtx op1 = gen_reg_rtx (XFmode);
16749 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16750 emit_insn (gen_frndintxf2 (op0, op1));
16752 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16756 (define_expand "rintxf2"
16757 [(use (match_operand:XF 0 "register_operand" ""))
16758 (use (match_operand:XF 1 "register_operand" ""))]
16759 "TARGET_USE_FANCY_MATH_387
16760 && flag_unsafe_math_optimizations"
16762 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16766 (define_insn_and_split "*fistdi2_1"
16767 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16768 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16770 "TARGET_USE_FANCY_MATH_387
16771 && flag_unsafe_math_optimizations
16772 && !(reload_completed || reload_in_progress)"
16777 if (memory_operand (operands[0], VOIDmode))
16778 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16781 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16782 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16787 [(set_attr "type" "fpspc")
16788 (set_attr "mode" "DI")])
16790 (define_insn "fistdi2"
16791 [(set (match_operand:DI 0 "memory_operand" "=m")
16792 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16794 (clobber (match_scratch:XF 2 "=&1f"))]
16795 "TARGET_USE_FANCY_MATH_387
16796 && flag_unsafe_math_optimizations"
16797 "* return output_fix_trunc (insn, operands, 0);"
16798 [(set_attr "type" "fpspc")
16799 (set_attr "mode" "DI")])
16801 (define_insn "fistdi2_with_temp"
16802 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16803 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16805 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16806 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16807 "TARGET_USE_FANCY_MATH_387
16808 && flag_unsafe_math_optimizations"
16810 [(set_attr "type" "fpspc")
16811 (set_attr "mode" "DI")])
16814 [(set (match_operand:DI 0 "register_operand" "")
16815 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16817 (clobber (match_operand:DI 2 "memory_operand" ""))
16818 (clobber (match_scratch 3 ""))]
16820 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16821 (clobber (match_dup 3))])
16822 (set (match_dup 0) (match_dup 2))]
16826 [(set (match_operand:DI 0 "memory_operand" "")
16827 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16829 (clobber (match_operand:DI 2 "memory_operand" ""))
16830 (clobber (match_scratch 3 ""))]
16832 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16833 (clobber (match_dup 3))])]
16836 (define_insn_and_split "*fist<mode>2_1"
16837 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16838 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16840 "TARGET_USE_FANCY_MATH_387
16841 && flag_unsafe_math_optimizations
16842 && !(reload_completed || reload_in_progress)"
16847 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16848 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16852 [(set_attr "type" "fpspc")
16853 (set_attr "mode" "<MODE>")])
16855 (define_insn "fist<mode>2"
16856 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16857 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16859 "TARGET_USE_FANCY_MATH_387
16860 && flag_unsafe_math_optimizations"
16861 "* return output_fix_trunc (insn, operands, 0);"
16862 [(set_attr "type" "fpspc")
16863 (set_attr "mode" "<MODE>")])
16865 (define_insn "fist<mode>2_with_temp"
16866 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16867 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16869 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16870 "TARGET_USE_FANCY_MATH_387
16871 && flag_unsafe_math_optimizations"
16873 [(set_attr "type" "fpspc")
16874 (set_attr "mode" "<MODE>")])
16877 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16878 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16880 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16882 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16884 (set (match_dup 0) (match_dup 2))]
16888 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16889 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16891 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16893 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16897 (define_expand "lrint<mode>2"
16898 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16899 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16901 "TARGET_USE_FANCY_MATH_387
16902 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16903 && flag_unsafe_math_optimizations"
16906 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16907 (define_insn_and_split "frndintxf2_floor"
16908 [(set (match_operand:XF 0 "register_operand" "=f")
16909 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16910 UNSPEC_FRNDINT_FLOOR))
16911 (clobber (reg:CC FLAGS_REG))]
16912 "TARGET_USE_FANCY_MATH_387
16913 && flag_unsafe_math_optimizations
16914 && !(reload_completed || reload_in_progress)"
16919 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16921 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16922 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16924 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16925 operands[2], operands[3]));
16928 [(set_attr "type" "frndint")
16929 (set_attr "i387_cw" "floor")
16930 (set_attr "mode" "XF")])
16932 (define_insn "frndintxf2_floor_i387"
16933 [(set (match_operand:XF 0 "register_operand" "=f")
16934 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16935 UNSPEC_FRNDINT_FLOOR))
16936 (use (match_operand:HI 2 "memory_operand" "m"))
16937 (use (match_operand:HI 3 "memory_operand" "m"))]
16938 "TARGET_USE_FANCY_MATH_387
16939 && flag_unsafe_math_optimizations"
16940 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16941 [(set_attr "type" "frndint")
16942 (set_attr "i387_cw" "floor")
16943 (set_attr "mode" "XF")])
16945 (define_expand "floorxf2"
16946 [(use (match_operand:XF 0 "register_operand" ""))
16947 (use (match_operand:XF 1 "register_operand" ""))]
16948 "TARGET_USE_FANCY_MATH_387
16949 && flag_unsafe_math_optimizations"
16951 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16955 (define_expand "floordf2"
16956 [(use (match_operand:DF 0 "register_operand" ""))
16957 (use (match_operand:DF 1 "register_operand" ""))]
16958 "TARGET_USE_FANCY_MATH_387
16959 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16960 && flag_unsafe_math_optimizations"
16962 rtx op0 = gen_reg_rtx (XFmode);
16963 rtx op1 = gen_reg_rtx (XFmode);
16965 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16966 emit_insn (gen_frndintxf2_floor (op0, op1));
16968 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16972 (define_expand "floorsf2"
16973 [(use (match_operand:SF 0 "register_operand" ""))
16974 (use (match_operand:SF 1 "register_operand" ""))]
16975 "TARGET_USE_FANCY_MATH_387
16976 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16977 && flag_unsafe_math_optimizations"
16979 rtx op0 = gen_reg_rtx (XFmode);
16980 rtx op1 = gen_reg_rtx (XFmode);
16982 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16983 emit_insn (gen_frndintxf2_floor (op0, op1));
16985 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16989 (define_insn_and_split "*fist<mode>2_floor_1"
16990 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16991 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16992 UNSPEC_FIST_FLOOR))
16993 (clobber (reg:CC FLAGS_REG))]
16994 "TARGET_USE_FANCY_MATH_387
16995 && flag_unsafe_math_optimizations
16996 && !(reload_completed || reload_in_progress)"
17001 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17003 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17004 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17005 if (memory_operand (operands[0], VOIDmode))
17006 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17007 operands[2], operands[3]));
17010 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17011 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17012 operands[2], operands[3],
17017 [(set_attr "type" "fistp")
17018 (set_attr "i387_cw" "floor")
17019 (set_attr "mode" "<MODE>")])
17021 (define_insn "fistdi2_floor"
17022 [(set (match_operand:DI 0 "memory_operand" "=m")
17023 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17024 UNSPEC_FIST_FLOOR))
17025 (use (match_operand:HI 2 "memory_operand" "m"))
17026 (use (match_operand:HI 3 "memory_operand" "m"))
17027 (clobber (match_scratch:XF 4 "=&1f"))]
17028 "TARGET_USE_FANCY_MATH_387
17029 && flag_unsafe_math_optimizations"
17030 "* return output_fix_trunc (insn, operands, 0);"
17031 [(set_attr "type" "fistp")
17032 (set_attr "i387_cw" "floor")
17033 (set_attr "mode" "DI")])
17035 (define_insn "fistdi2_floor_with_temp"
17036 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17037 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17038 UNSPEC_FIST_FLOOR))
17039 (use (match_operand:HI 2 "memory_operand" "m,m"))
17040 (use (match_operand:HI 3 "memory_operand" "m,m"))
17041 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17042 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17043 "TARGET_USE_FANCY_MATH_387
17044 && flag_unsafe_math_optimizations"
17046 [(set_attr "type" "fistp")
17047 (set_attr "i387_cw" "floor")
17048 (set_attr "mode" "DI")])
17051 [(set (match_operand:DI 0 "register_operand" "")
17052 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17053 UNSPEC_FIST_FLOOR))
17054 (use (match_operand:HI 2 "memory_operand" ""))
17055 (use (match_operand:HI 3 "memory_operand" ""))
17056 (clobber (match_operand:DI 4 "memory_operand" ""))
17057 (clobber (match_scratch 5 ""))]
17059 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17060 (use (match_dup 2))
17061 (use (match_dup 3))
17062 (clobber (match_dup 5))])
17063 (set (match_dup 0) (match_dup 4))]
17067 [(set (match_operand:DI 0 "memory_operand" "")
17068 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17069 UNSPEC_FIST_FLOOR))
17070 (use (match_operand:HI 2 "memory_operand" ""))
17071 (use (match_operand:HI 3 "memory_operand" ""))
17072 (clobber (match_operand:DI 4 "memory_operand" ""))
17073 (clobber (match_scratch 5 ""))]
17075 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17076 (use (match_dup 2))
17077 (use (match_dup 3))
17078 (clobber (match_dup 5))])]
17081 (define_insn "fist<mode>2_floor"
17082 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17083 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17084 UNSPEC_FIST_FLOOR))
17085 (use (match_operand:HI 2 "memory_operand" "m"))
17086 (use (match_operand:HI 3 "memory_operand" "m"))]
17087 "TARGET_USE_FANCY_MATH_387
17088 && flag_unsafe_math_optimizations"
17089 "* return output_fix_trunc (insn, operands, 0);"
17090 [(set_attr "type" "fistp")
17091 (set_attr "i387_cw" "floor")
17092 (set_attr "mode" "<MODE>")])
17094 (define_insn "fist<mode>2_floor_with_temp"
17095 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17096 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17097 UNSPEC_FIST_FLOOR))
17098 (use (match_operand:HI 2 "memory_operand" "m,m"))
17099 (use (match_operand:HI 3 "memory_operand" "m,m"))
17100 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17101 "TARGET_USE_FANCY_MATH_387
17102 && flag_unsafe_math_optimizations"
17104 [(set_attr "type" "fistp")
17105 (set_attr "i387_cw" "floor")
17106 (set_attr "mode" "<MODE>")])
17109 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17110 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17111 UNSPEC_FIST_FLOOR))
17112 (use (match_operand:HI 2 "memory_operand" ""))
17113 (use (match_operand:HI 3 "memory_operand" ""))
17114 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17116 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17117 UNSPEC_FIST_FLOOR))
17118 (use (match_dup 2))
17119 (use (match_dup 3))])
17120 (set (match_dup 0) (match_dup 4))]
17124 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17125 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17126 UNSPEC_FIST_FLOOR))
17127 (use (match_operand:HI 2 "memory_operand" ""))
17128 (use (match_operand:HI 3 "memory_operand" ""))
17129 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17131 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17132 UNSPEC_FIST_FLOOR))
17133 (use (match_dup 2))
17134 (use (match_dup 3))])]
17137 (define_expand "lfloor<mode>2"
17138 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17139 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17140 UNSPEC_FIST_FLOOR))
17141 (clobber (reg:CC FLAGS_REG))])]
17142 "TARGET_USE_FANCY_MATH_387
17143 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17144 && flag_unsafe_math_optimizations"
17147 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17148 (define_insn_and_split "frndintxf2_ceil"
17149 [(set (match_operand:XF 0 "register_operand" "=f")
17150 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17151 UNSPEC_FRNDINT_CEIL))
17152 (clobber (reg:CC FLAGS_REG))]
17153 "TARGET_USE_FANCY_MATH_387
17154 && flag_unsafe_math_optimizations
17155 && !(reload_completed || reload_in_progress)"
17160 ix86_optimize_mode_switching[I387_CEIL] = 1;
17162 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17163 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17165 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17166 operands[2], operands[3]));
17169 [(set_attr "type" "frndint")
17170 (set_attr "i387_cw" "ceil")
17171 (set_attr "mode" "XF")])
17173 (define_insn "frndintxf2_ceil_i387"
17174 [(set (match_operand:XF 0 "register_operand" "=f")
17175 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17176 UNSPEC_FRNDINT_CEIL))
17177 (use (match_operand:HI 2 "memory_operand" "m"))
17178 (use (match_operand:HI 3 "memory_operand" "m"))]
17179 "TARGET_USE_FANCY_MATH_387
17180 && flag_unsafe_math_optimizations"
17181 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17182 [(set_attr "type" "frndint")
17183 (set_attr "i387_cw" "ceil")
17184 (set_attr "mode" "XF")])
17186 (define_expand "ceilxf2"
17187 [(use (match_operand:XF 0 "register_operand" ""))
17188 (use (match_operand:XF 1 "register_operand" ""))]
17189 "TARGET_USE_FANCY_MATH_387
17190 && flag_unsafe_math_optimizations"
17192 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17196 (define_expand "ceildf2"
17197 [(use (match_operand:DF 0 "register_operand" ""))
17198 (use (match_operand:DF 1 "register_operand" ""))]
17199 "TARGET_USE_FANCY_MATH_387
17200 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17201 && flag_unsafe_math_optimizations"
17203 rtx op0 = gen_reg_rtx (XFmode);
17204 rtx op1 = gen_reg_rtx (XFmode);
17206 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17207 emit_insn (gen_frndintxf2_ceil (op0, op1));
17209 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17213 (define_expand "ceilsf2"
17214 [(use (match_operand:SF 0 "register_operand" ""))
17215 (use (match_operand:SF 1 "register_operand" ""))]
17216 "TARGET_USE_FANCY_MATH_387
17217 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17218 && flag_unsafe_math_optimizations"
17220 rtx op0 = gen_reg_rtx (XFmode);
17221 rtx op1 = gen_reg_rtx (XFmode);
17223 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17224 emit_insn (gen_frndintxf2_ceil (op0, op1));
17226 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17230 (define_insn_and_split "*fist<mode>2_ceil_1"
17231 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17232 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17234 (clobber (reg:CC FLAGS_REG))]
17235 "TARGET_USE_FANCY_MATH_387
17236 && flag_unsafe_math_optimizations
17237 && !(reload_completed || reload_in_progress)"
17242 ix86_optimize_mode_switching[I387_CEIL] = 1;
17244 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17245 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17246 if (memory_operand (operands[0], VOIDmode))
17247 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17248 operands[2], operands[3]));
17251 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17252 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17253 operands[2], operands[3],
17258 [(set_attr "type" "fistp")
17259 (set_attr "i387_cw" "ceil")
17260 (set_attr "mode" "<MODE>")])
17262 (define_insn "fistdi2_ceil"
17263 [(set (match_operand:DI 0 "memory_operand" "=m")
17264 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17266 (use (match_operand:HI 2 "memory_operand" "m"))
17267 (use (match_operand:HI 3 "memory_operand" "m"))
17268 (clobber (match_scratch:XF 4 "=&1f"))]
17269 "TARGET_USE_FANCY_MATH_387
17270 && flag_unsafe_math_optimizations"
17271 "* return output_fix_trunc (insn, operands, 0);"
17272 [(set_attr "type" "fistp")
17273 (set_attr "i387_cw" "ceil")
17274 (set_attr "mode" "DI")])
17276 (define_insn "fistdi2_ceil_with_temp"
17277 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17278 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17280 (use (match_operand:HI 2 "memory_operand" "m,m"))
17281 (use (match_operand:HI 3 "memory_operand" "m,m"))
17282 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17283 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17284 "TARGET_USE_FANCY_MATH_387
17285 && flag_unsafe_math_optimizations"
17287 [(set_attr "type" "fistp")
17288 (set_attr "i387_cw" "ceil")
17289 (set_attr "mode" "DI")])
17292 [(set (match_operand:DI 0 "register_operand" "")
17293 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17295 (use (match_operand:HI 2 "memory_operand" ""))
17296 (use (match_operand:HI 3 "memory_operand" ""))
17297 (clobber (match_operand:DI 4 "memory_operand" ""))
17298 (clobber (match_scratch 5 ""))]
17300 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17301 (use (match_dup 2))
17302 (use (match_dup 3))
17303 (clobber (match_dup 5))])
17304 (set (match_dup 0) (match_dup 4))]
17308 [(set (match_operand:DI 0 "memory_operand" "")
17309 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17311 (use (match_operand:HI 2 "memory_operand" ""))
17312 (use (match_operand:HI 3 "memory_operand" ""))
17313 (clobber (match_operand:DI 4 "memory_operand" ""))
17314 (clobber (match_scratch 5 ""))]
17316 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17317 (use (match_dup 2))
17318 (use (match_dup 3))
17319 (clobber (match_dup 5))])]
17322 (define_insn "fist<mode>2_ceil"
17323 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17324 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17326 (use (match_operand:HI 2 "memory_operand" "m"))
17327 (use (match_operand:HI 3 "memory_operand" "m"))]
17328 "TARGET_USE_FANCY_MATH_387
17329 && flag_unsafe_math_optimizations"
17330 "* return output_fix_trunc (insn, operands, 0);"
17331 [(set_attr "type" "fistp")
17332 (set_attr "i387_cw" "ceil")
17333 (set_attr "mode" "<MODE>")])
17335 (define_insn "fist<mode>2_ceil_with_temp"
17336 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17337 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17339 (use (match_operand:HI 2 "memory_operand" "m,m"))
17340 (use (match_operand:HI 3 "memory_operand" "m,m"))
17341 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17342 "TARGET_USE_FANCY_MATH_387
17343 && flag_unsafe_math_optimizations"
17345 [(set_attr "type" "fistp")
17346 (set_attr "i387_cw" "ceil")
17347 (set_attr "mode" "<MODE>")])
17350 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17351 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17353 (use (match_operand:HI 2 "memory_operand" ""))
17354 (use (match_operand:HI 3 "memory_operand" ""))
17355 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17357 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17359 (use (match_dup 2))
17360 (use (match_dup 3))])
17361 (set (match_dup 0) (match_dup 4))]
17365 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17366 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17368 (use (match_operand:HI 2 "memory_operand" ""))
17369 (use (match_operand:HI 3 "memory_operand" ""))
17370 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17372 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17374 (use (match_dup 2))
17375 (use (match_dup 3))])]
17378 (define_expand "lceil<mode>2"
17379 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17380 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17382 (clobber (reg:CC FLAGS_REG))])]
17383 "TARGET_USE_FANCY_MATH_387
17384 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17385 && flag_unsafe_math_optimizations"
17388 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17389 (define_insn_and_split "frndintxf2_trunc"
17390 [(set (match_operand:XF 0 "register_operand" "=f")
17391 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17392 UNSPEC_FRNDINT_TRUNC))
17393 (clobber (reg:CC FLAGS_REG))]
17394 "TARGET_USE_FANCY_MATH_387
17395 && flag_unsafe_math_optimizations
17396 && !(reload_completed || reload_in_progress)"
17401 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17403 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17404 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17406 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17407 operands[2], operands[3]));
17410 [(set_attr "type" "frndint")
17411 (set_attr "i387_cw" "trunc")
17412 (set_attr "mode" "XF")])
17414 (define_insn "frndintxf2_trunc_i387"
17415 [(set (match_operand:XF 0 "register_operand" "=f")
17416 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17417 UNSPEC_FRNDINT_TRUNC))
17418 (use (match_operand:HI 2 "memory_operand" "m"))
17419 (use (match_operand:HI 3 "memory_operand" "m"))]
17420 "TARGET_USE_FANCY_MATH_387
17421 && flag_unsafe_math_optimizations"
17422 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17423 [(set_attr "type" "frndint")
17424 (set_attr "i387_cw" "trunc")
17425 (set_attr "mode" "XF")])
17427 (define_expand "btruncxf2"
17428 [(use (match_operand:XF 0 "register_operand" ""))
17429 (use (match_operand:XF 1 "register_operand" ""))]
17430 "TARGET_USE_FANCY_MATH_387
17431 && flag_unsafe_math_optimizations"
17433 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17437 (define_expand "btruncdf2"
17438 [(use (match_operand:DF 0 "register_operand" ""))
17439 (use (match_operand:DF 1 "register_operand" ""))]
17440 "TARGET_USE_FANCY_MATH_387
17441 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17442 && flag_unsafe_math_optimizations"
17444 rtx op0 = gen_reg_rtx (XFmode);
17445 rtx op1 = gen_reg_rtx (XFmode);
17447 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17448 emit_insn (gen_frndintxf2_trunc (op0, op1));
17450 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17454 (define_expand "btruncsf2"
17455 [(use (match_operand:SF 0 "register_operand" ""))
17456 (use (match_operand:SF 1 "register_operand" ""))]
17457 "TARGET_USE_FANCY_MATH_387
17458 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17459 && flag_unsafe_math_optimizations"
17461 rtx op0 = gen_reg_rtx (XFmode);
17462 rtx op1 = gen_reg_rtx (XFmode);
17464 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17465 emit_insn (gen_frndintxf2_trunc (op0, op1));
17467 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17471 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17472 (define_insn_and_split "frndintxf2_mask_pm"
17473 [(set (match_operand:XF 0 "register_operand" "=f")
17474 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17475 UNSPEC_FRNDINT_MASK_PM))
17476 (clobber (reg:CC FLAGS_REG))]
17477 "TARGET_USE_FANCY_MATH_387
17478 && flag_unsafe_math_optimizations
17479 && !(reload_completed || reload_in_progress)"
17484 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17486 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17487 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17489 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17490 operands[2], operands[3]));
17493 [(set_attr "type" "frndint")
17494 (set_attr "i387_cw" "mask_pm")
17495 (set_attr "mode" "XF")])
17497 (define_insn "frndintxf2_mask_pm_i387"
17498 [(set (match_operand:XF 0 "register_operand" "=f")
17499 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17500 UNSPEC_FRNDINT_MASK_PM))
17501 (use (match_operand:HI 2 "memory_operand" "m"))
17502 (use (match_operand:HI 3 "memory_operand" "m"))]
17503 "TARGET_USE_FANCY_MATH_387
17504 && flag_unsafe_math_optimizations"
17505 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17506 [(set_attr "type" "frndint")
17507 (set_attr "i387_cw" "mask_pm")
17508 (set_attr "mode" "XF")])
17510 (define_expand "nearbyintxf2"
17511 [(use (match_operand:XF 0 "register_operand" ""))
17512 (use (match_operand:XF 1 "register_operand" ""))]
17513 "TARGET_USE_FANCY_MATH_387
17514 && flag_unsafe_math_optimizations"
17516 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17521 (define_expand "nearbyintdf2"
17522 [(use (match_operand:DF 0 "register_operand" ""))
17523 (use (match_operand:DF 1 "register_operand" ""))]
17524 "TARGET_USE_FANCY_MATH_387
17525 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17526 && flag_unsafe_math_optimizations"
17528 rtx op0 = gen_reg_rtx (XFmode);
17529 rtx op1 = gen_reg_rtx (XFmode);
17531 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17532 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17534 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17538 (define_expand "nearbyintsf2"
17539 [(use (match_operand:SF 0 "register_operand" ""))
17540 (use (match_operand:SF 1 "register_operand" ""))]
17541 "TARGET_USE_FANCY_MATH_387
17542 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17543 && flag_unsafe_math_optimizations"
17545 rtx op0 = gen_reg_rtx (XFmode);
17546 rtx op1 = gen_reg_rtx (XFmode);
17548 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17549 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17551 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17556 ;; Block operation instructions
17559 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17562 [(set_attr "type" "cld")])
17564 (define_expand "movmemsi"
17565 [(use (match_operand:BLK 0 "memory_operand" ""))
17566 (use (match_operand:BLK 1 "memory_operand" ""))
17567 (use (match_operand:SI 2 "nonmemory_operand" ""))
17568 (use (match_operand:SI 3 "const_int_operand" ""))]
17569 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17571 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17577 (define_expand "movmemdi"
17578 [(use (match_operand:BLK 0 "memory_operand" ""))
17579 (use (match_operand:BLK 1 "memory_operand" ""))
17580 (use (match_operand:DI 2 "nonmemory_operand" ""))
17581 (use (match_operand:DI 3 "const_int_operand" ""))]
17584 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17590 ;; Most CPUs don't like single string operations
17591 ;; Handle this case here to simplify previous expander.
17593 (define_expand "strmov"
17594 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17595 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17596 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17597 (clobber (reg:CC FLAGS_REG))])
17598 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17599 (clobber (reg:CC FLAGS_REG))])]
17602 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17604 /* If .md ever supports :P for Pmode, these can be directly
17605 in the pattern above. */
17606 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17607 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17609 if (TARGET_SINGLE_STRINGOP || optimize_size)
17611 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17612 operands[2], operands[3],
17613 operands[5], operands[6]));
17617 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17620 (define_expand "strmov_singleop"
17621 [(parallel [(set (match_operand 1 "memory_operand" "")
17622 (match_operand 3 "memory_operand" ""))
17623 (set (match_operand 0 "register_operand" "")
17624 (match_operand 4 "" ""))
17625 (set (match_operand 2 "register_operand" "")
17626 (match_operand 5 "" ""))
17627 (use (reg:SI DIRFLAG_REG))])]
17628 "TARGET_SINGLE_STRINGOP || optimize_size"
17631 (define_insn "*strmovdi_rex_1"
17632 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17633 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17634 (set (match_operand:DI 0 "register_operand" "=D")
17635 (plus:DI (match_dup 2)
17637 (set (match_operand:DI 1 "register_operand" "=S")
17638 (plus:DI (match_dup 3)
17640 (use (reg:SI DIRFLAG_REG))]
17641 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17643 [(set_attr "type" "str")
17644 (set_attr "mode" "DI")
17645 (set_attr "memory" "both")])
17647 (define_insn "*strmovsi_1"
17648 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17649 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17650 (set (match_operand:SI 0 "register_operand" "=D")
17651 (plus:SI (match_dup 2)
17653 (set (match_operand:SI 1 "register_operand" "=S")
17654 (plus:SI (match_dup 3)
17656 (use (reg:SI DIRFLAG_REG))]
17657 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17659 [(set_attr "type" "str")
17660 (set_attr "mode" "SI")
17661 (set_attr "memory" "both")])
17663 (define_insn "*strmovsi_rex_1"
17664 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17665 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17666 (set (match_operand:DI 0 "register_operand" "=D")
17667 (plus:DI (match_dup 2)
17669 (set (match_operand:DI 1 "register_operand" "=S")
17670 (plus:DI (match_dup 3)
17672 (use (reg:SI DIRFLAG_REG))]
17673 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17675 [(set_attr "type" "str")
17676 (set_attr "mode" "SI")
17677 (set_attr "memory" "both")])
17679 (define_insn "*strmovhi_1"
17680 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17681 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17682 (set (match_operand:SI 0 "register_operand" "=D")
17683 (plus:SI (match_dup 2)
17685 (set (match_operand:SI 1 "register_operand" "=S")
17686 (plus:SI (match_dup 3)
17688 (use (reg:SI DIRFLAG_REG))]
17689 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17691 [(set_attr "type" "str")
17692 (set_attr "memory" "both")
17693 (set_attr "mode" "HI")])
17695 (define_insn "*strmovhi_rex_1"
17696 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17697 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17698 (set (match_operand:DI 0 "register_operand" "=D")
17699 (plus:DI (match_dup 2)
17701 (set (match_operand:DI 1 "register_operand" "=S")
17702 (plus:DI (match_dup 3)
17704 (use (reg:SI DIRFLAG_REG))]
17705 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17707 [(set_attr "type" "str")
17708 (set_attr "memory" "both")
17709 (set_attr "mode" "HI")])
17711 (define_insn "*strmovqi_1"
17712 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17713 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17714 (set (match_operand:SI 0 "register_operand" "=D")
17715 (plus:SI (match_dup 2)
17717 (set (match_operand:SI 1 "register_operand" "=S")
17718 (plus:SI (match_dup 3)
17720 (use (reg:SI DIRFLAG_REG))]
17721 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17723 [(set_attr "type" "str")
17724 (set_attr "memory" "both")
17725 (set_attr "mode" "QI")])
17727 (define_insn "*strmovqi_rex_1"
17728 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17729 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17730 (set (match_operand:DI 0 "register_operand" "=D")
17731 (plus:DI (match_dup 2)
17733 (set (match_operand:DI 1 "register_operand" "=S")
17734 (plus:DI (match_dup 3)
17736 (use (reg:SI DIRFLAG_REG))]
17737 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17739 [(set_attr "type" "str")
17740 (set_attr "memory" "both")
17741 (set_attr "mode" "QI")])
17743 (define_expand "rep_mov"
17744 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17745 (set (match_operand 0 "register_operand" "")
17746 (match_operand 5 "" ""))
17747 (set (match_operand 2 "register_operand" "")
17748 (match_operand 6 "" ""))
17749 (set (match_operand 1 "memory_operand" "")
17750 (match_operand 3 "memory_operand" ""))
17751 (use (match_dup 4))
17752 (use (reg:SI DIRFLAG_REG))])]
17756 (define_insn "*rep_movdi_rex64"
17757 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17758 (set (match_operand:DI 0 "register_operand" "=D")
17759 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17761 (match_operand:DI 3 "register_operand" "0")))
17762 (set (match_operand:DI 1 "register_operand" "=S")
17763 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17764 (match_operand:DI 4 "register_operand" "1")))
17765 (set (mem:BLK (match_dup 3))
17766 (mem:BLK (match_dup 4)))
17767 (use (match_dup 5))
17768 (use (reg:SI DIRFLAG_REG))]
17770 "{rep\;movsq|rep movsq}"
17771 [(set_attr "type" "str")
17772 (set_attr "prefix_rep" "1")
17773 (set_attr "memory" "both")
17774 (set_attr "mode" "DI")])
17776 (define_insn "*rep_movsi"
17777 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17778 (set (match_operand:SI 0 "register_operand" "=D")
17779 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17781 (match_operand:SI 3 "register_operand" "0")))
17782 (set (match_operand:SI 1 "register_operand" "=S")
17783 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17784 (match_operand:SI 4 "register_operand" "1")))
17785 (set (mem:BLK (match_dup 3))
17786 (mem:BLK (match_dup 4)))
17787 (use (match_dup 5))
17788 (use (reg:SI DIRFLAG_REG))]
17790 "{rep\;movsl|rep movsd}"
17791 [(set_attr "type" "str")
17792 (set_attr "prefix_rep" "1")
17793 (set_attr "memory" "both")
17794 (set_attr "mode" "SI")])
17796 (define_insn "*rep_movsi_rex64"
17797 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17798 (set (match_operand:DI 0 "register_operand" "=D")
17799 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17801 (match_operand:DI 3 "register_operand" "0")))
17802 (set (match_operand:DI 1 "register_operand" "=S")
17803 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17804 (match_operand:DI 4 "register_operand" "1")))
17805 (set (mem:BLK (match_dup 3))
17806 (mem:BLK (match_dup 4)))
17807 (use (match_dup 5))
17808 (use (reg:SI DIRFLAG_REG))]
17810 "{rep\;movsl|rep movsd}"
17811 [(set_attr "type" "str")
17812 (set_attr "prefix_rep" "1")
17813 (set_attr "memory" "both")
17814 (set_attr "mode" "SI")])
17816 (define_insn "*rep_movqi"
17817 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17818 (set (match_operand:SI 0 "register_operand" "=D")
17819 (plus:SI (match_operand:SI 3 "register_operand" "0")
17820 (match_operand:SI 5 "register_operand" "2")))
17821 (set (match_operand:SI 1 "register_operand" "=S")
17822 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17823 (set (mem:BLK (match_dup 3))
17824 (mem:BLK (match_dup 4)))
17825 (use (match_dup 5))
17826 (use (reg:SI DIRFLAG_REG))]
17828 "{rep\;movsb|rep movsb}"
17829 [(set_attr "type" "str")
17830 (set_attr "prefix_rep" "1")
17831 (set_attr "memory" "both")
17832 (set_attr "mode" "SI")])
17834 (define_insn "*rep_movqi_rex64"
17835 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17836 (set (match_operand:DI 0 "register_operand" "=D")
17837 (plus:DI (match_operand:DI 3 "register_operand" "0")
17838 (match_operand:DI 5 "register_operand" "2")))
17839 (set (match_operand:DI 1 "register_operand" "=S")
17840 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17841 (set (mem:BLK (match_dup 3))
17842 (mem:BLK (match_dup 4)))
17843 (use (match_dup 5))
17844 (use (reg:SI DIRFLAG_REG))]
17846 "{rep\;movsb|rep movsb}"
17847 [(set_attr "type" "str")
17848 (set_attr "prefix_rep" "1")
17849 (set_attr "memory" "both")
17850 (set_attr "mode" "SI")])
17852 (define_expand "setmemsi"
17853 [(use (match_operand:BLK 0 "memory_operand" ""))
17854 (use (match_operand:SI 1 "nonmemory_operand" ""))
17855 (use (match_operand 2 "const_int_operand" ""))
17856 (use (match_operand 3 "const_int_operand" ""))]
17859 /* If value to set is not zero, use the library routine. */
17860 if (operands[2] != const0_rtx)
17863 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17869 (define_expand "setmemdi"
17870 [(use (match_operand:BLK 0 "memory_operand" ""))
17871 (use (match_operand:DI 1 "nonmemory_operand" ""))
17872 (use (match_operand 2 "const_int_operand" ""))
17873 (use (match_operand 3 "const_int_operand" ""))]
17876 /* If value to set is not zero, use the library routine. */
17877 if (operands[2] != const0_rtx)
17880 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17886 ;; Most CPUs don't like single string operations
17887 ;; Handle this case here to simplify previous expander.
17889 (define_expand "strset"
17890 [(set (match_operand 1 "memory_operand" "")
17891 (match_operand 2 "register_operand" ""))
17892 (parallel [(set (match_operand 0 "register_operand" "")
17894 (clobber (reg:CC FLAGS_REG))])]
17897 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17898 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17900 /* If .md ever supports :P for Pmode, this can be directly
17901 in the pattern above. */
17902 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17903 GEN_INT (GET_MODE_SIZE (GET_MODE
17905 if (TARGET_SINGLE_STRINGOP || optimize_size)
17907 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17913 (define_expand "strset_singleop"
17914 [(parallel [(set (match_operand 1 "memory_operand" "")
17915 (match_operand 2 "register_operand" ""))
17916 (set (match_operand 0 "register_operand" "")
17917 (match_operand 3 "" ""))
17918 (use (reg:SI DIRFLAG_REG))])]
17919 "TARGET_SINGLE_STRINGOP || optimize_size"
17922 (define_insn "*strsetdi_rex_1"
17923 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17924 (match_operand:DI 2 "register_operand" "a"))
17925 (set (match_operand:DI 0 "register_operand" "=D")
17926 (plus:DI (match_dup 1)
17928 (use (reg:SI DIRFLAG_REG))]
17929 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17931 [(set_attr "type" "str")
17932 (set_attr "memory" "store")
17933 (set_attr "mode" "DI")])
17935 (define_insn "*strsetsi_1"
17936 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17937 (match_operand:SI 2 "register_operand" "a"))
17938 (set (match_operand:SI 0 "register_operand" "=D")
17939 (plus:SI (match_dup 1)
17941 (use (reg:SI DIRFLAG_REG))]
17942 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17944 [(set_attr "type" "str")
17945 (set_attr "memory" "store")
17946 (set_attr "mode" "SI")])
17948 (define_insn "*strsetsi_rex_1"
17949 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17950 (match_operand:SI 2 "register_operand" "a"))
17951 (set (match_operand:DI 0 "register_operand" "=D")
17952 (plus:DI (match_dup 1)
17954 (use (reg:SI DIRFLAG_REG))]
17955 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17957 [(set_attr "type" "str")
17958 (set_attr "memory" "store")
17959 (set_attr "mode" "SI")])
17961 (define_insn "*strsethi_1"
17962 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17963 (match_operand:HI 2 "register_operand" "a"))
17964 (set (match_operand:SI 0 "register_operand" "=D")
17965 (plus:SI (match_dup 1)
17967 (use (reg:SI DIRFLAG_REG))]
17968 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17970 [(set_attr "type" "str")
17971 (set_attr "memory" "store")
17972 (set_attr "mode" "HI")])
17974 (define_insn "*strsethi_rex_1"
17975 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17976 (match_operand:HI 2 "register_operand" "a"))
17977 (set (match_operand:DI 0 "register_operand" "=D")
17978 (plus:DI (match_dup 1)
17980 (use (reg:SI DIRFLAG_REG))]
17981 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17983 [(set_attr "type" "str")
17984 (set_attr "memory" "store")
17985 (set_attr "mode" "HI")])
17987 (define_insn "*strsetqi_1"
17988 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17989 (match_operand:QI 2 "register_operand" "a"))
17990 (set (match_operand:SI 0 "register_operand" "=D")
17991 (plus:SI (match_dup 1)
17993 (use (reg:SI DIRFLAG_REG))]
17994 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17996 [(set_attr "type" "str")
17997 (set_attr "memory" "store")
17998 (set_attr "mode" "QI")])
18000 (define_insn "*strsetqi_rex_1"
18001 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18002 (match_operand:QI 2 "register_operand" "a"))
18003 (set (match_operand:DI 0 "register_operand" "=D")
18004 (plus:DI (match_dup 1)
18006 (use (reg:SI DIRFLAG_REG))]
18007 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18009 [(set_attr "type" "str")
18010 (set_attr "memory" "store")
18011 (set_attr "mode" "QI")])
18013 (define_expand "rep_stos"
18014 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18015 (set (match_operand 0 "register_operand" "")
18016 (match_operand 4 "" ""))
18017 (set (match_operand 2 "memory_operand" "") (const_int 0))
18018 (use (match_operand 3 "register_operand" ""))
18019 (use (match_dup 1))
18020 (use (reg:SI DIRFLAG_REG))])]
18024 (define_insn "*rep_stosdi_rex64"
18025 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18026 (set (match_operand:DI 0 "register_operand" "=D")
18027 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18029 (match_operand:DI 3 "register_operand" "0")))
18030 (set (mem:BLK (match_dup 3))
18032 (use (match_operand:DI 2 "register_operand" "a"))
18033 (use (match_dup 4))
18034 (use (reg:SI DIRFLAG_REG))]
18036 "{rep\;stosq|rep stosq}"
18037 [(set_attr "type" "str")
18038 (set_attr "prefix_rep" "1")
18039 (set_attr "memory" "store")
18040 (set_attr "mode" "DI")])
18042 (define_insn "*rep_stossi"
18043 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18044 (set (match_operand:SI 0 "register_operand" "=D")
18045 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18047 (match_operand:SI 3 "register_operand" "0")))
18048 (set (mem:BLK (match_dup 3))
18050 (use (match_operand:SI 2 "register_operand" "a"))
18051 (use (match_dup 4))
18052 (use (reg:SI DIRFLAG_REG))]
18054 "{rep\;stosl|rep stosd}"
18055 [(set_attr "type" "str")
18056 (set_attr "prefix_rep" "1")
18057 (set_attr "memory" "store")
18058 (set_attr "mode" "SI")])
18060 (define_insn "*rep_stossi_rex64"
18061 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18062 (set (match_operand:DI 0 "register_operand" "=D")
18063 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18065 (match_operand:DI 3 "register_operand" "0")))
18066 (set (mem:BLK (match_dup 3))
18068 (use (match_operand:SI 2 "register_operand" "a"))
18069 (use (match_dup 4))
18070 (use (reg:SI DIRFLAG_REG))]
18072 "{rep\;stosl|rep stosd}"
18073 [(set_attr "type" "str")
18074 (set_attr "prefix_rep" "1")
18075 (set_attr "memory" "store")
18076 (set_attr "mode" "SI")])
18078 (define_insn "*rep_stosqi"
18079 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18080 (set (match_operand:SI 0 "register_operand" "=D")
18081 (plus:SI (match_operand:SI 3 "register_operand" "0")
18082 (match_operand:SI 4 "register_operand" "1")))
18083 (set (mem:BLK (match_dup 3))
18085 (use (match_operand:QI 2 "register_operand" "a"))
18086 (use (match_dup 4))
18087 (use (reg:SI DIRFLAG_REG))]
18089 "{rep\;stosb|rep stosb}"
18090 [(set_attr "type" "str")
18091 (set_attr "prefix_rep" "1")
18092 (set_attr "memory" "store")
18093 (set_attr "mode" "QI")])
18095 (define_insn "*rep_stosqi_rex64"
18096 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18097 (set (match_operand:DI 0 "register_operand" "=D")
18098 (plus:DI (match_operand:DI 3 "register_operand" "0")
18099 (match_operand:DI 4 "register_operand" "1")))
18100 (set (mem:BLK (match_dup 3))
18102 (use (match_operand:QI 2 "register_operand" "a"))
18103 (use (match_dup 4))
18104 (use (reg:SI DIRFLAG_REG))]
18106 "{rep\;stosb|rep stosb}"
18107 [(set_attr "type" "str")
18108 (set_attr "prefix_rep" "1")
18109 (set_attr "memory" "store")
18110 (set_attr "mode" "QI")])
18112 (define_expand "cmpstrnsi"
18113 [(set (match_operand:SI 0 "register_operand" "")
18114 (compare:SI (match_operand:BLK 1 "general_operand" "")
18115 (match_operand:BLK 2 "general_operand" "")))
18116 (use (match_operand 3 "general_operand" ""))
18117 (use (match_operand 4 "immediate_operand" ""))]
18118 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18120 rtx addr1, addr2, out, outlow, count, countreg, align;
18122 /* Can't use this if the user has appropriated esi or edi. */
18123 if (global_regs[4] || global_regs[5])
18127 if (GET_CODE (out) != REG)
18128 out = gen_reg_rtx (SImode);
18130 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18131 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18132 if (addr1 != XEXP (operands[1], 0))
18133 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18134 if (addr2 != XEXP (operands[2], 0))
18135 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18137 count = operands[3];
18138 countreg = ix86_zero_extend_to_Pmode (count);
18140 /* %%% Iff we are testing strict equality, we can use known alignment
18141 to good advantage. This may be possible with combine, particularly
18142 once cc0 is dead. */
18143 align = operands[4];
18145 emit_insn (gen_cld ());
18146 if (GET_CODE (count) == CONST_INT)
18148 if (INTVAL (count) == 0)
18150 emit_move_insn (operands[0], const0_rtx);
18153 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18154 operands[1], operands[2]));
18159 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18161 emit_insn (gen_cmpsi_1 (countreg, countreg));
18162 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18163 operands[1], operands[2]));
18166 outlow = gen_lowpart (QImode, out);
18167 emit_insn (gen_cmpintqi (outlow));
18168 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18170 if (operands[0] != out)
18171 emit_move_insn (operands[0], out);
18176 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18178 (define_expand "cmpintqi"
18179 [(set (match_dup 1)
18180 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18182 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18183 (parallel [(set (match_operand:QI 0 "register_operand" "")
18184 (minus:QI (match_dup 1)
18186 (clobber (reg:CC FLAGS_REG))])]
18188 "operands[1] = gen_reg_rtx (QImode);
18189 operands[2] = gen_reg_rtx (QImode);")
18191 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18192 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18194 (define_expand "cmpstrnqi_nz_1"
18195 [(parallel [(set (reg:CC FLAGS_REG)
18196 (compare:CC (match_operand 4 "memory_operand" "")
18197 (match_operand 5 "memory_operand" "")))
18198 (use (match_operand 2 "register_operand" ""))
18199 (use (match_operand:SI 3 "immediate_operand" ""))
18200 (use (reg:SI DIRFLAG_REG))
18201 (clobber (match_operand 0 "register_operand" ""))
18202 (clobber (match_operand 1 "register_operand" ""))
18203 (clobber (match_dup 2))])]
18207 (define_insn "*cmpstrnqi_nz_1"
18208 [(set (reg:CC FLAGS_REG)
18209 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18210 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18211 (use (match_operand:SI 6 "register_operand" "2"))
18212 (use (match_operand:SI 3 "immediate_operand" "i"))
18213 (use (reg:SI DIRFLAG_REG))
18214 (clobber (match_operand:SI 0 "register_operand" "=S"))
18215 (clobber (match_operand:SI 1 "register_operand" "=D"))
18216 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18219 [(set_attr "type" "str")
18220 (set_attr "mode" "QI")
18221 (set_attr "prefix_rep" "1")])
18223 (define_insn "*cmpstrnqi_nz_rex_1"
18224 [(set (reg:CC FLAGS_REG)
18225 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18226 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18227 (use (match_operand:DI 6 "register_operand" "2"))
18228 (use (match_operand:SI 3 "immediate_operand" "i"))
18229 (use (reg:SI DIRFLAG_REG))
18230 (clobber (match_operand:DI 0 "register_operand" "=S"))
18231 (clobber (match_operand:DI 1 "register_operand" "=D"))
18232 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18235 [(set_attr "type" "str")
18236 (set_attr "mode" "QI")
18237 (set_attr "prefix_rep" "1")])
18239 ;; The same, but the count is not known to not be zero.
18241 (define_expand "cmpstrnqi_1"
18242 [(parallel [(set (reg:CC FLAGS_REG)
18243 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18245 (compare:CC (match_operand 4 "memory_operand" "")
18246 (match_operand 5 "memory_operand" ""))
18248 (use (match_operand:SI 3 "immediate_operand" ""))
18249 (use (reg:CC FLAGS_REG))
18250 (use (reg:SI DIRFLAG_REG))
18251 (clobber (match_operand 0 "register_operand" ""))
18252 (clobber (match_operand 1 "register_operand" ""))
18253 (clobber (match_dup 2))])]
18257 (define_insn "*cmpstrnqi_1"
18258 [(set (reg:CC FLAGS_REG)
18259 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18261 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18262 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18264 (use (match_operand:SI 3 "immediate_operand" "i"))
18265 (use (reg:CC FLAGS_REG))
18266 (use (reg:SI DIRFLAG_REG))
18267 (clobber (match_operand:SI 0 "register_operand" "=S"))
18268 (clobber (match_operand:SI 1 "register_operand" "=D"))
18269 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18272 [(set_attr "type" "str")
18273 (set_attr "mode" "QI")
18274 (set_attr "prefix_rep" "1")])
18276 (define_insn "*cmpstrnqi_rex_1"
18277 [(set (reg:CC FLAGS_REG)
18278 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18280 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18281 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18283 (use (match_operand:SI 3 "immediate_operand" "i"))
18284 (use (reg:CC FLAGS_REG))
18285 (use (reg:SI DIRFLAG_REG))
18286 (clobber (match_operand:DI 0 "register_operand" "=S"))
18287 (clobber (match_operand:DI 1 "register_operand" "=D"))
18288 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18291 [(set_attr "type" "str")
18292 (set_attr "mode" "QI")
18293 (set_attr "prefix_rep" "1")])
18295 (define_expand "strlensi"
18296 [(set (match_operand:SI 0 "register_operand" "")
18297 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18298 (match_operand:QI 2 "immediate_operand" "")
18299 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18302 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18308 (define_expand "strlendi"
18309 [(set (match_operand:DI 0 "register_operand" "")
18310 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18311 (match_operand:QI 2 "immediate_operand" "")
18312 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18315 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18321 (define_expand "strlenqi_1"
18322 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18323 (use (reg:SI DIRFLAG_REG))
18324 (clobber (match_operand 1 "register_operand" ""))
18325 (clobber (reg:CC FLAGS_REG))])]
18329 (define_insn "*strlenqi_1"
18330 [(set (match_operand:SI 0 "register_operand" "=&c")
18331 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18332 (match_operand:QI 2 "register_operand" "a")
18333 (match_operand:SI 3 "immediate_operand" "i")
18334 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18335 (use (reg:SI DIRFLAG_REG))
18336 (clobber (match_operand:SI 1 "register_operand" "=D"))
18337 (clobber (reg:CC FLAGS_REG))]
18340 [(set_attr "type" "str")
18341 (set_attr "mode" "QI")
18342 (set_attr "prefix_rep" "1")])
18344 (define_insn "*strlenqi_rex_1"
18345 [(set (match_operand:DI 0 "register_operand" "=&c")
18346 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18347 (match_operand:QI 2 "register_operand" "a")
18348 (match_operand:DI 3 "immediate_operand" "i")
18349 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18350 (use (reg:SI DIRFLAG_REG))
18351 (clobber (match_operand:DI 1 "register_operand" "=D"))
18352 (clobber (reg:CC FLAGS_REG))]
18355 [(set_attr "type" "str")
18356 (set_attr "mode" "QI")
18357 (set_attr "prefix_rep" "1")])
18359 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18360 ;; handled in combine, but it is not currently up to the task.
18361 ;; When used for their truth value, the cmpstrn* expanders generate
18370 ;; The intermediate three instructions are unnecessary.
18372 ;; This one handles cmpstrn*_nz_1...
18375 (set (reg:CC FLAGS_REG)
18376 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18377 (mem:BLK (match_operand 5 "register_operand" ""))))
18378 (use (match_operand 6 "register_operand" ""))
18379 (use (match_operand:SI 3 "immediate_operand" ""))
18380 (use (reg:SI DIRFLAG_REG))
18381 (clobber (match_operand 0 "register_operand" ""))
18382 (clobber (match_operand 1 "register_operand" ""))
18383 (clobber (match_operand 2 "register_operand" ""))])
18384 (set (match_operand:QI 7 "register_operand" "")
18385 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18386 (set (match_operand:QI 8 "register_operand" "")
18387 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18388 (set (reg FLAGS_REG)
18389 (compare (match_dup 7) (match_dup 8)))
18391 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18393 (set (reg:CC FLAGS_REG)
18394 (compare:CC (mem:BLK (match_dup 4))
18395 (mem:BLK (match_dup 5))))
18396 (use (match_dup 6))
18397 (use (match_dup 3))
18398 (use (reg:SI DIRFLAG_REG))
18399 (clobber (match_dup 0))
18400 (clobber (match_dup 1))
18401 (clobber (match_dup 2))])]
18404 ;; ...and this one handles cmpstrn*_1.
18407 (set (reg:CC FLAGS_REG)
18408 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18410 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18411 (mem:BLK (match_operand 5 "register_operand" "")))
18413 (use (match_operand:SI 3 "immediate_operand" ""))
18414 (use (reg:CC FLAGS_REG))
18415 (use (reg:SI DIRFLAG_REG))
18416 (clobber (match_operand 0 "register_operand" ""))
18417 (clobber (match_operand 1 "register_operand" ""))
18418 (clobber (match_operand 2 "register_operand" ""))])
18419 (set (match_operand:QI 7 "register_operand" "")
18420 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18421 (set (match_operand:QI 8 "register_operand" "")
18422 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18423 (set (reg FLAGS_REG)
18424 (compare (match_dup 7) (match_dup 8)))
18426 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18428 (set (reg:CC FLAGS_REG)
18429 (if_then_else:CC (ne (match_dup 6)
18431 (compare:CC (mem:BLK (match_dup 4))
18432 (mem:BLK (match_dup 5)))
18434 (use (match_dup 3))
18435 (use (reg:CC FLAGS_REG))
18436 (use (reg:SI DIRFLAG_REG))
18437 (clobber (match_dup 0))
18438 (clobber (match_dup 1))
18439 (clobber (match_dup 2))])]
18444 ;; Conditional move instructions.
18446 (define_expand "movdicc"
18447 [(set (match_operand:DI 0 "register_operand" "")
18448 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18449 (match_operand:DI 2 "general_operand" "")
18450 (match_operand:DI 3 "general_operand" "")))]
18452 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18454 (define_insn "x86_movdicc_0_m1_rex64"
18455 [(set (match_operand:DI 0 "register_operand" "=r")
18456 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18459 (clobber (reg:CC FLAGS_REG))]
18462 ; Since we don't have the proper number of operands for an alu insn,
18463 ; fill in all the blanks.
18464 [(set_attr "type" "alu")
18465 (set_attr "pent_pair" "pu")
18466 (set_attr "memory" "none")
18467 (set_attr "imm_disp" "false")
18468 (set_attr "mode" "DI")
18469 (set_attr "length_immediate" "0")])
18471 (define_insn "*movdicc_c_rex64"
18472 [(set (match_operand:DI 0 "register_operand" "=r,r")
18473 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18474 [(reg FLAGS_REG) (const_int 0)])
18475 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18476 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18477 "TARGET_64BIT && TARGET_CMOVE
18478 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18480 cmov%O2%C1\t{%2, %0|%0, %2}
18481 cmov%O2%c1\t{%3, %0|%0, %3}"
18482 [(set_attr "type" "icmov")
18483 (set_attr "mode" "DI")])
18485 (define_expand "movsicc"
18486 [(set (match_operand:SI 0 "register_operand" "")
18487 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18488 (match_operand:SI 2 "general_operand" "")
18489 (match_operand:SI 3 "general_operand" "")))]
18491 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18493 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18494 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18495 ;; So just document what we're doing explicitly.
18497 (define_insn "x86_movsicc_0_m1"
18498 [(set (match_operand:SI 0 "register_operand" "=r")
18499 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18502 (clobber (reg:CC FLAGS_REG))]
18505 ; Since we don't have the proper number of operands for an alu insn,
18506 ; fill in all the blanks.
18507 [(set_attr "type" "alu")
18508 (set_attr "pent_pair" "pu")
18509 (set_attr "memory" "none")
18510 (set_attr "imm_disp" "false")
18511 (set_attr "mode" "SI")
18512 (set_attr "length_immediate" "0")])
18514 (define_insn "*movsicc_noc"
18515 [(set (match_operand:SI 0 "register_operand" "=r,r")
18516 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18517 [(reg FLAGS_REG) (const_int 0)])
18518 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18519 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18521 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18523 cmov%O2%C1\t{%2, %0|%0, %2}
18524 cmov%O2%c1\t{%3, %0|%0, %3}"
18525 [(set_attr "type" "icmov")
18526 (set_attr "mode" "SI")])
18528 (define_expand "movhicc"
18529 [(set (match_operand:HI 0 "register_operand" "")
18530 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18531 (match_operand:HI 2 "general_operand" "")
18532 (match_operand:HI 3 "general_operand" "")))]
18533 "TARGET_HIMODE_MATH"
18534 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18536 (define_insn "*movhicc_noc"
18537 [(set (match_operand:HI 0 "register_operand" "=r,r")
18538 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18539 [(reg FLAGS_REG) (const_int 0)])
18540 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18541 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18543 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18545 cmov%O2%C1\t{%2, %0|%0, %2}
18546 cmov%O2%c1\t{%3, %0|%0, %3}"
18547 [(set_attr "type" "icmov")
18548 (set_attr "mode" "HI")])
18550 (define_expand "movqicc"
18551 [(set (match_operand:QI 0 "register_operand" "")
18552 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18553 (match_operand:QI 2 "general_operand" "")
18554 (match_operand:QI 3 "general_operand" "")))]
18555 "TARGET_QIMODE_MATH"
18556 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18558 (define_insn_and_split "*movqicc_noc"
18559 [(set (match_operand:QI 0 "register_operand" "=r,r")
18560 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18561 [(match_operand 4 "flags_reg_operand" "")
18563 (match_operand:QI 2 "register_operand" "r,0")
18564 (match_operand:QI 3 "register_operand" "0,r")))]
18565 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18567 "&& reload_completed"
18568 [(set (match_dup 0)
18569 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18572 "operands[0] = gen_lowpart (SImode, operands[0]);
18573 operands[2] = gen_lowpart (SImode, operands[2]);
18574 operands[3] = gen_lowpart (SImode, operands[3]);"
18575 [(set_attr "type" "icmov")
18576 (set_attr "mode" "SI")])
18578 (define_expand "movsfcc"
18579 [(set (match_operand:SF 0 "register_operand" "")
18580 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18581 (match_operand:SF 2 "register_operand" "")
18582 (match_operand:SF 3 "register_operand" "")))]
18583 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18584 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18586 (define_insn "*movsfcc_1_387"
18587 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18588 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18589 [(reg FLAGS_REG) (const_int 0)])
18590 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18591 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18592 "TARGET_80387 && TARGET_CMOVE
18593 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18595 fcmov%F1\t{%2, %0|%0, %2}
18596 fcmov%f1\t{%3, %0|%0, %3}
18597 cmov%O2%C1\t{%2, %0|%0, %2}
18598 cmov%O2%c1\t{%3, %0|%0, %3}"
18599 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18600 (set_attr "mode" "SF,SF,SI,SI")])
18602 (define_expand "movdfcc"
18603 [(set (match_operand:DF 0 "register_operand" "")
18604 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18605 (match_operand:DF 2 "register_operand" "")
18606 (match_operand:DF 3 "register_operand" "")))]
18607 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18608 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18610 (define_insn "*movdfcc_1"
18611 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18612 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18613 [(reg FLAGS_REG) (const_int 0)])
18614 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18615 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18616 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18617 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18619 fcmov%F1\t{%2, %0|%0, %2}
18620 fcmov%f1\t{%3, %0|%0, %3}
18623 [(set_attr "type" "fcmov,fcmov,multi,multi")
18624 (set_attr "mode" "DF")])
18626 (define_insn "*movdfcc_1_rex64"
18627 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18628 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18629 [(reg FLAGS_REG) (const_int 0)])
18630 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18631 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18632 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18633 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18635 fcmov%F1\t{%2, %0|%0, %2}
18636 fcmov%f1\t{%3, %0|%0, %3}
18637 cmov%O2%C1\t{%2, %0|%0, %2}
18638 cmov%O2%c1\t{%3, %0|%0, %3}"
18639 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18640 (set_attr "mode" "DF")])
18643 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18644 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18645 [(match_operand 4 "flags_reg_operand" "")
18647 (match_operand:DF 2 "nonimmediate_operand" "")
18648 (match_operand:DF 3 "nonimmediate_operand" "")))]
18649 "!TARGET_64BIT && reload_completed"
18650 [(set (match_dup 2)
18651 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18655 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18658 "split_di (operands+2, 1, operands+5, operands+6);
18659 split_di (operands+3, 1, operands+7, operands+8);
18660 split_di (operands, 1, operands+2, operands+3);")
18662 (define_expand "movxfcc"
18663 [(set (match_operand:XF 0 "register_operand" "")
18664 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18665 (match_operand:XF 2 "register_operand" "")
18666 (match_operand:XF 3 "register_operand" "")))]
18667 "TARGET_80387 && TARGET_CMOVE"
18668 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18670 (define_insn "*movxfcc_1"
18671 [(set (match_operand:XF 0 "register_operand" "=f,f")
18672 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18673 [(reg FLAGS_REG) (const_int 0)])
18674 (match_operand:XF 2 "register_operand" "f,0")
18675 (match_operand:XF 3 "register_operand" "0,f")))]
18676 "TARGET_80387 && TARGET_CMOVE"
18678 fcmov%F1\t{%2, %0|%0, %2}
18679 fcmov%f1\t{%3, %0|%0, %3}"
18680 [(set_attr "type" "fcmov")
18681 (set_attr "mode" "XF")])
18683 ;; These versions of the min/max patterns are intentionally ignorant of
18684 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18685 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18686 ;; are undefined in this condition, we're certain this is correct.
18688 (define_insn "sminsf3"
18689 [(set (match_operand:SF 0 "register_operand" "=x")
18690 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18691 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18693 "minss\t{%2, %0|%0, %2}"
18694 [(set_attr "type" "sseadd")
18695 (set_attr "mode" "SF")])
18697 (define_insn "smaxsf3"
18698 [(set (match_operand:SF 0 "register_operand" "=x")
18699 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18700 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18702 "maxss\t{%2, %0|%0, %2}"
18703 [(set_attr "type" "sseadd")
18704 (set_attr "mode" "SF")])
18706 (define_insn "smindf3"
18707 [(set (match_operand:DF 0 "register_operand" "=x")
18708 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18709 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18710 "TARGET_SSE2 && TARGET_SSE_MATH"
18711 "minsd\t{%2, %0|%0, %2}"
18712 [(set_attr "type" "sseadd")
18713 (set_attr "mode" "DF")])
18715 (define_insn "smaxdf3"
18716 [(set (match_operand:DF 0 "register_operand" "=x")
18717 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18718 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18719 "TARGET_SSE2 && TARGET_SSE_MATH"
18720 "maxsd\t{%2, %0|%0, %2}"
18721 [(set_attr "type" "sseadd")
18722 (set_attr "mode" "DF")])
18724 ;; These versions of the min/max patterns implement exactly the operations
18725 ;; min = (op1 < op2 ? op1 : op2)
18726 ;; max = (!(op1 < op2) ? op1 : op2)
18727 ;; Their operands are not commutative, and thus they may be used in the
18728 ;; presence of -0.0 and NaN.
18730 (define_insn "*ieee_sminsf3"
18731 [(set (match_operand:SF 0 "register_operand" "=x")
18732 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18733 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18736 "minss\t{%2, %0|%0, %2}"
18737 [(set_attr "type" "sseadd")
18738 (set_attr "mode" "SF")])
18740 (define_insn "*ieee_smaxsf3"
18741 [(set (match_operand:SF 0 "register_operand" "=x")
18742 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18743 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18746 "maxss\t{%2, %0|%0, %2}"
18747 [(set_attr "type" "sseadd")
18748 (set_attr "mode" "SF")])
18750 (define_insn "*ieee_smindf3"
18751 [(set (match_operand:DF 0 "register_operand" "=x")
18752 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18753 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18755 "TARGET_SSE2 && TARGET_SSE_MATH"
18756 "minsd\t{%2, %0|%0, %2}"
18757 [(set_attr "type" "sseadd")
18758 (set_attr "mode" "DF")])
18760 (define_insn "*ieee_smaxdf3"
18761 [(set (match_operand:DF 0 "register_operand" "=x")
18762 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18763 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18765 "TARGET_SSE2 && TARGET_SSE_MATH"
18766 "maxsd\t{%2, %0|%0, %2}"
18767 [(set_attr "type" "sseadd")
18768 (set_attr "mode" "DF")])
18770 ;; Conditional addition patterns
18771 (define_expand "addqicc"
18772 [(match_operand:QI 0 "register_operand" "")
18773 (match_operand 1 "comparison_operator" "")
18774 (match_operand:QI 2 "register_operand" "")
18775 (match_operand:QI 3 "const_int_operand" "")]
18777 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18779 (define_expand "addhicc"
18780 [(match_operand:HI 0 "register_operand" "")
18781 (match_operand 1 "comparison_operator" "")
18782 (match_operand:HI 2 "register_operand" "")
18783 (match_operand:HI 3 "const_int_operand" "")]
18785 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18787 (define_expand "addsicc"
18788 [(match_operand:SI 0 "register_operand" "")
18789 (match_operand 1 "comparison_operator" "")
18790 (match_operand:SI 2 "register_operand" "")
18791 (match_operand:SI 3 "const_int_operand" "")]
18793 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18795 (define_expand "adddicc"
18796 [(match_operand:DI 0 "register_operand" "")
18797 (match_operand 1 "comparison_operator" "")
18798 (match_operand:DI 2 "register_operand" "")
18799 (match_operand:DI 3 "const_int_operand" "")]
18801 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18804 ;; Misc patterns (?)
18806 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18807 ;; Otherwise there will be nothing to keep
18809 ;; [(set (reg ebp) (reg esp))]
18810 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18811 ;; (clobber (eflags)]
18812 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18814 ;; in proper program order.
18815 (define_insn "pro_epilogue_adjust_stack_1"
18816 [(set (match_operand:SI 0 "register_operand" "=r,r")
18817 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18818 (match_operand:SI 2 "immediate_operand" "i,i")))
18819 (clobber (reg:CC FLAGS_REG))
18820 (clobber (mem:BLK (scratch)))]
18823 switch (get_attr_type (insn))
18826 return "mov{l}\t{%1, %0|%0, %1}";
18829 if (GET_CODE (operands[2]) == CONST_INT
18830 && (INTVAL (operands[2]) == 128
18831 || (INTVAL (operands[2]) < 0
18832 && INTVAL (operands[2]) != -128)))
18834 operands[2] = GEN_INT (-INTVAL (operands[2]));
18835 return "sub{l}\t{%2, %0|%0, %2}";
18837 return "add{l}\t{%2, %0|%0, %2}";
18840 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18841 return "lea{l}\t{%a2, %0|%0, %a2}";
18844 gcc_unreachable ();
18847 [(set (attr "type")
18848 (cond [(eq_attr "alternative" "0")
18849 (const_string "alu")
18850 (match_operand:SI 2 "const0_operand" "")
18851 (const_string "imov")
18853 (const_string "lea")))
18854 (set_attr "mode" "SI")])
18856 (define_insn "pro_epilogue_adjust_stack_rex64"
18857 [(set (match_operand:DI 0 "register_operand" "=r,r")
18858 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18859 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18860 (clobber (reg:CC FLAGS_REG))
18861 (clobber (mem:BLK (scratch)))]
18864 switch (get_attr_type (insn))
18867 return "mov{q}\t{%1, %0|%0, %1}";
18870 if (GET_CODE (operands[2]) == CONST_INT
18871 /* Avoid overflows. */
18872 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18873 && (INTVAL (operands[2]) == 128
18874 || (INTVAL (operands[2]) < 0
18875 && INTVAL (operands[2]) != -128)))
18877 operands[2] = GEN_INT (-INTVAL (operands[2]));
18878 return "sub{q}\t{%2, %0|%0, %2}";
18880 return "add{q}\t{%2, %0|%0, %2}";
18883 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18884 return "lea{q}\t{%a2, %0|%0, %a2}";
18887 gcc_unreachable ();
18890 [(set (attr "type")
18891 (cond [(eq_attr "alternative" "0")
18892 (const_string "alu")
18893 (match_operand:DI 2 "const0_operand" "")
18894 (const_string "imov")
18896 (const_string "lea")))
18897 (set_attr "mode" "DI")])
18899 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18900 [(set (match_operand:DI 0 "register_operand" "=r,r")
18901 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18902 (match_operand:DI 3 "immediate_operand" "i,i")))
18903 (use (match_operand:DI 2 "register_operand" "r,r"))
18904 (clobber (reg:CC FLAGS_REG))
18905 (clobber (mem:BLK (scratch)))]
18908 switch (get_attr_type (insn))
18911 return "add{q}\t{%2, %0|%0, %2}";
18914 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18915 return "lea{q}\t{%a2, %0|%0, %a2}";
18918 gcc_unreachable ();
18921 [(set_attr "type" "alu,lea")
18922 (set_attr "mode" "DI")])
18924 (define_expand "allocate_stack_worker"
18925 [(match_operand:SI 0 "register_operand" "")]
18926 "TARGET_STACK_PROBE"
18928 if (reload_completed)
18931 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18933 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18938 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18940 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18945 (define_insn "allocate_stack_worker_1"
18946 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18947 UNSPECV_STACK_PROBE)
18948 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18949 (clobber (match_scratch:SI 1 "=0"))
18950 (clobber (reg:CC FLAGS_REG))]
18951 "!TARGET_64BIT && TARGET_STACK_PROBE"
18953 [(set_attr "type" "multi")
18954 (set_attr "length" "5")])
18956 (define_expand "allocate_stack_worker_postreload"
18957 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18958 UNSPECV_STACK_PROBE)
18959 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18960 (clobber (match_dup 0))
18961 (clobber (reg:CC FLAGS_REG))])]
18965 (define_insn "allocate_stack_worker_rex64"
18966 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18967 UNSPECV_STACK_PROBE)
18968 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18969 (clobber (match_scratch:DI 1 "=0"))
18970 (clobber (reg:CC FLAGS_REG))]
18971 "TARGET_64BIT && TARGET_STACK_PROBE"
18973 [(set_attr "type" "multi")
18974 (set_attr "length" "5")])
18976 (define_expand "allocate_stack_worker_rex64_postreload"
18977 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18978 UNSPECV_STACK_PROBE)
18979 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18980 (clobber (match_dup 0))
18981 (clobber (reg:CC FLAGS_REG))])]
18985 (define_expand "allocate_stack"
18986 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18987 (minus:SI (reg:SI SP_REG)
18988 (match_operand:SI 1 "general_operand" "")))
18989 (clobber (reg:CC FLAGS_REG))])
18990 (parallel [(set (reg:SI SP_REG)
18991 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18992 (clobber (reg:CC FLAGS_REG))])]
18993 "TARGET_STACK_PROBE"
18995 #ifdef CHECK_STACK_LIMIT
18996 if (GET_CODE (operands[1]) == CONST_INT
18997 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18998 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19002 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19005 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19009 (define_expand "builtin_setjmp_receiver"
19010 [(label_ref (match_operand 0 "" ""))]
19011 "!TARGET_64BIT && flag_pic"
19016 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19017 rtx label_rtx = gen_label_rtx ();
19018 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19019 xops[0] = xops[1] = picreg;
19020 xops[2] = gen_rtx_CONST (SImode,
19021 gen_rtx_MINUS (SImode,
19022 gen_rtx_LABEL_REF (SImode, label_rtx),
19023 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19024 ix86_expand_binary_operator (MINUS, SImode, xops);
19027 emit_insn (gen_set_got (pic_offset_table_rtx));
19031 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19034 [(set (match_operand 0 "register_operand" "")
19035 (match_operator 3 "promotable_binary_operator"
19036 [(match_operand 1 "register_operand" "")
19037 (match_operand 2 "aligned_operand" "")]))
19038 (clobber (reg:CC FLAGS_REG))]
19039 "! TARGET_PARTIAL_REG_STALL && reload_completed
19040 && ((GET_MODE (operands[0]) == HImode
19041 && ((!optimize_size && !TARGET_FAST_PREFIX)
19042 /* ??? next two lines just !satisfies_constraint_K (...) */
19043 || GET_CODE (operands[2]) != CONST_INT
19044 || satisfies_constraint_K (operands[2])))
19045 || (GET_MODE (operands[0]) == QImode
19046 && (TARGET_PROMOTE_QImode || optimize_size)))"
19047 [(parallel [(set (match_dup 0)
19048 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19049 (clobber (reg:CC FLAGS_REG))])]
19050 "operands[0] = gen_lowpart (SImode, operands[0]);
19051 operands[1] = gen_lowpart (SImode, operands[1]);
19052 if (GET_CODE (operands[3]) != ASHIFT)
19053 operands[2] = gen_lowpart (SImode, operands[2]);
19054 PUT_MODE (operands[3], SImode);")
19056 ; Promote the QImode tests, as i386 has encoding of the AND
19057 ; instruction with 32-bit sign-extended immediate and thus the
19058 ; instruction size is unchanged, except in the %eax case for
19059 ; which it is increased by one byte, hence the ! optimize_size.
19061 [(set (match_operand 0 "flags_reg_operand" "")
19062 (match_operator 2 "compare_operator"
19063 [(and (match_operand 3 "aligned_operand" "")
19064 (match_operand 4 "const_int_operand" ""))
19066 (set (match_operand 1 "register_operand" "")
19067 (and (match_dup 3) (match_dup 4)))]
19068 "! TARGET_PARTIAL_REG_STALL && reload_completed
19069 /* Ensure that the operand will remain sign-extended immediate. */
19070 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19072 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19073 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19074 [(parallel [(set (match_dup 0)
19075 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19078 (and:SI (match_dup 3) (match_dup 4)))])]
19081 = gen_int_mode (INTVAL (operands[4])
19082 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19083 operands[1] = gen_lowpart (SImode, operands[1]);
19084 operands[3] = gen_lowpart (SImode, operands[3]);
19087 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19088 ; the TEST instruction with 32-bit sign-extended immediate and thus
19089 ; the instruction size would at least double, which is not what we
19090 ; want even with ! optimize_size.
19092 [(set (match_operand 0 "flags_reg_operand" "")
19093 (match_operator 1 "compare_operator"
19094 [(and (match_operand:HI 2 "aligned_operand" "")
19095 (match_operand:HI 3 "const_int_operand" ""))
19097 "! TARGET_PARTIAL_REG_STALL && reload_completed
19098 /* Ensure that the operand will remain sign-extended immediate. */
19099 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19100 && ! TARGET_FAST_PREFIX
19101 && ! optimize_size"
19102 [(set (match_dup 0)
19103 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19107 = gen_int_mode (INTVAL (operands[3])
19108 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19109 operands[2] = gen_lowpart (SImode, operands[2]);
19113 [(set (match_operand 0 "register_operand" "")
19114 (neg (match_operand 1 "register_operand" "")))
19115 (clobber (reg:CC FLAGS_REG))]
19116 "! TARGET_PARTIAL_REG_STALL && reload_completed
19117 && (GET_MODE (operands[0]) == HImode
19118 || (GET_MODE (operands[0]) == QImode
19119 && (TARGET_PROMOTE_QImode || optimize_size)))"
19120 [(parallel [(set (match_dup 0)
19121 (neg:SI (match_dup 1)))
19122 (clobber (reg:CC FLAGS_REG))])]
19123 "operands[0] = gen_lowpart (SImode, operands[0]);
19124 operands[1] = gen_lowpart (SImode, operands[1]);")
19127 [(set (match_operand 0 "register_operand" "")
19128 (not (match_operand 1 "register_operand" "")))]
19129 "! TARGET_PARTIAL_REG_STALL && reload_completed
19130 && (GET_MODE (operands[0]) == HImode
19131 || (GET_MODE (operands[0]) == QImode
19132 && (TARGET_PROMOTE_QImode || optimize_size)))"
19133 [(set (match_dup 0)
19134 (not:SI (match_dup 1)))]
19135 "operands[0] = gen_lowpart (SImode, operands[0]);
19136 operands[1] = gen_lowpart (SImode, operands[1]);")
19139 [(set (match_operand 0 "register_operand" "")
19140 (if_then_else (match_operator 1 "comparison_operator"
19141 [(reg FLAGS_REG) (const_int 0)])
19142 (match_operand 2 "register_operand" "")
19143 (match_operand 3 "register_operand" "")))]
19144 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19145 && (GET_MODE (operands[0]) == HImode
19146 || (GET_MODE (operands[0]) == QImode
19147 && (TARGET_PROMOTE_QImode || optimize_size)))"
19148 [(set (match_dup 0)
19149 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19150 "operands[0] = gen_lowpart (SImode, operands[0]);
19151 operands[2] = gen_lowpart (SImode, operands[2]);
19152 operands[3] = gen_lowpart (SImode, operands[3]);")
19155 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19156 ;; transform a complex memory operation into two memory to register operations.
19158 ;; Don't push memory operands
19160 [(set (match_operand:SI 0 "push_operand" "")
19161 (match_operand:SI 1 "memory_operand" ""))
19162 (match_scratch:SI 2 "r")]
19163 "!optimize_size && !TARGET_PUSH_MEMORY
19164 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19165 [(set (match_dup 2) (match_dup 1))
19166 (set (match_dup 0) (match_dup 2))]
19170 [(set (match_operand:DI 0 "push_operand" "")
19171 (match_operand:DI 1 "memory_operand" ""))
19172 (match_scratch:DI 2 "r")]
19173 "!optimize_size && !TARGET_PUSH_MEMORY
19174 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19175 [(set (match_dup 2) (match_dup 1))
19176 (set (match_dup 0) (match_dup 2))]
19179 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19182 [(set (match_operand:SF 0 "push_operand" "")
19183 (match_operand:SF 1 "memory_operand" ""))
19184 (match_scratch:SF 2 "r")]
19185 "!optimize_size && !TARGET_PUSH_MEMORY
19186 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19187 [(set (match_dup 2) (match_dup 1))
19188 (set (match_dup 0) (match_dup 2))]
19192 [(set (match_operand:HI 0 "push_operand" "")
19193 (match_operand:HI 1 "memory_operand" ""))
19194 (match_scratch:HI 2 "r")]
19195 "!optimize_size && !TARGET_PUSH_MEMORY
19196 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19197 [(set (match_dup 2) (match_dup 1))
19198 (set (match_dup 0) (match_dup 2))]
19202 [(set (match_operand:QI 0 "push_operand" "")
19203 (match_operand:QI 1 "memory_operand" ""))
19204 (match_scratch:QI 2 "q")]
19205 "!optimize_size && !TARGET_PUSH_MEMORY
19206 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19207 [(set (match_dup 2) (match_dup 1))
19208 (set (match_dup 0) (match_dup 2))]
19211 ;; Don't move an immediate directly to memory when the instruction
19214 [(match_scratch:SI 1 "r")
19215 (set (match_operand:SI 0 "memory_operand" "")
19218 && ! TARGET_USE_MOV0
19219 && TARGET_SPLIT_LONG_MOVES
19220 && get_attr_length (insn) >= ix86_cost->large_insn
19221 && peep2_regno_dead_p (0, FLAGS_REG)"
19222 [(parallel [(set (match_dup 1) (const_int 0))
19223 (clobber (reg:CC FLAGS_REG))])
19224 (set (match_dup 0) (match_dup 1))]
19228 [(match_scratch:HI 1 "r")
19229 (set (match_operand:HI 0 "memory_operand" "")
19232 && ! TARGET_USE_MOV0
19233 && TARGET_SPLIT_LONG_MOVES
19234 && get_attr_length (insn) >= ix86_cost->large_insn
19235 && peep2_regno_dead_p (0, FLAGS_REG)"
19236 [(parallel [(set (match_dup 2) (const_int 0))
19237 (clobber (reg:CC FLAGS_REG))])
19238 (set (match_dup 0) (match_dup 1))]
19239 "operands[2] = gen_lowpart (SImode, operands[1]);")
19242 [(match_scratch:QI 1 "q")
19243 (set (match_operand:QI 0 "memory_operand" "")
19246 && ! TARGET_USE_MOV0
19247 && TARGET_SPLIT_LONG_MOVES
19248 && get_attr_length (insn) >= ix86_cost->large_insn
19249 && peep2_regno_dead_p (0, FLAGS_REG)"
19250 [(parallel [(set (match_dup 2) (const_int 0))
19251 (clobber (reg:CC FLAGS_REG))])
19252 (set (match_dup 0) (match_dup 1))]
19253 "operands[2] = gen_lowpart (SImode, operands[1]);")
19256 [(match_scratch:SI 2 "r")
19257 (set (match_operand:SI 0 "memory_operand" "")
19258 (match_operand:SI 1 "immediate_operand" ""))]
19260 && get_attr_length (insn) >= ix86_cost->large_insn
19261 && TARGET_SPLIT_LONG_MOVES"
19262 [(set (match_dup 2) (match_dup 1))
19263 (set (match_dup 0) (match_dup 2))]
19267 [(match_scratch:HI 2 "r")
19268 (set (match_operand:HI 0 "memory_operand" "")
19269 (match_operand:HI 1 "immediate_operand" ""))]
19270 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19271 && TARGET_SPLIT_LONG_MOVES"
19272 [(set (match_dup 2) (match_dup 1))
19273 (set (match_dup 0) (match_dup 2))]
19277 [(match_scratch:QI 2 "q")
19278 (set (match_operand:QI 0 "memory_operand" "")
19279 (match_operand:QI 1 "immediate_operand" ""))]
19280 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19281 && TARGET_SPLIT_LONG_MOVES"
19282 [(set (match_dup 2) (match_dup 1))
19283 (set (match_dup 0) (match_dup 2))]
19286 ;; Don't compare memory with zero, load and use a test instead.
19288 [(set (match_operand 0 "flags_reg_operand" "")
19289 (match_operator 1 "compare_operator"
19290 [(match_operand:SI 2 "memory_operand" "")
19292 (match_scratch:SI 3 "r")]
19293 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19294 [(set (match_dup 3) (match_dup 2))
19295 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19298 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19299 ;; Don't split NOTs with a displacement operand, because resulting XOR
19300 ;; will not be pairable anyway.
19302 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19303 ;; represented using a modRM byte. The XOR replacement is long decoded,
19304 ;; so this split helps here as well.
19306 ;; Note: Can't do this as a regular split because we can't get proper
19307 ;; lifetime information then.
19310 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19311 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19313 && peep2_regno_dead_p (0, FLAGS_REG)
19314 && ((TARGET_PENTIUM
19315 && (GET_CODE (operands[0]) != MEM
19316 || !memory_displacement_operand (operands[0], SImode)))
19317 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19318 [(parallel [(set (match_dup 0)
19319 (xor:SI (match_dup 1) (const_int -1)))
19320 (clobber (reg:CC FLAGS_REG))])]
19324 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19325 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19327 && peep2_regno_dead_p (0, FLAGS_REG)
19328 && ((TARGET_PENTIUM
19329 && (GET_CODE (operands[0]) != MEM
19330 || !memory_displacement_operand (operands[0], HImode)))
19331 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19332 [(parallel [(set (match_dup 0)
19333 (xor:HI (match_dup 1) (const_int -1)))
19334 (clobber (reg:CC FLAGS_REG))])]
19338 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19339 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19341 && peep2_regno_dead_p (0, FLAGS_REG)
19342 && ((TARGET_PENTIUM
19343 && (GET_CODE (operands[0]) != MEM
19344 || !memory_displacement_operand (operands[0], QImode)))
19345 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19346 [(parallel [(set (match_dup 0)
19347 (xor:QI (match_dup 1) (const_int -1)))
19348 (clobber (reg:CC FLAGS_REG))])]
19351 ;; Non pairable "test imm, reg" instructions can be translated to
19352 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19353 ;; byte opcode instead of two, have a short form for byte operands),
19354 ;; so do it for other CPUs as well. Given that the value was dead,
19355 ;; this should not create any new dependencies. Pass on the sub-word
19356 ;; versions if we're concerned about partial register stalls.
19359 [(set (match_operand 0 "flags_reg_operand" "")
19360 (match_operator 1 "compare_operator"
19361 [(and:SI (match_operand:SI 2 "register_operand" "")
19362 (match_operand:SI 3 "immediate_operand" ""))
19364 "ix86_match_ccmode (insn, CCNOmode)
19365 && (true_regnum (operands[2]) != 0
19366 || satisfies_constraint_K (operands[3]))
19367 && peep2_reg_dead_p (1, operands[2])"
19369 [(set (match_dup 0)
19370 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19373 (and:SI (match_dup 2) (match_dup 3)))])]
19376 ;; We don't need to handle HImode case, because it will be promoted to SImode
19377 ;; on ! TARGET_PARTIAL_REG_STALL
19380 [(set (match_operand 0 "flags_reg_operand" "")
19381 (match_operator 1 "compare_operator"
19382 [(and:QI (match_operand:QI 2 "register_operand" "")
19383 (match_operand:QI 3 "immediate_operand" ""))
19385 "! TARGET_PARTIAL_REG_STALL
19386 && ix86_match_ccmode (insn, CCNOmode)
19387 && true_regnum (operands[2]) != 0
19388 && peep2_reg_dead_p (1, operands[2])"
19390 [(set (match_dup 0)
19391 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19394 (and:QI (match_dup 2) (match_dup 3)))])]
19398 [(set (match_operand 0 "flags_reg_operand" "")
19399 (match_operator 1 "compare_operator"
19402 (match_operand 2 "ext_register_operand" "")
19405 (match_operand 3 "const_int_operand" ""))
19407 "! TARGET_PARTIAL_REG_STALL
19408 && ix86_match_ccmode (insn, CCNOmode)
19409 && true_regnum (operands[2]) != 0
19410 && peep2_reg_dead_p (1, operands[2])"
19411 [(parallel [(set (match_dup 0)
19420 (set (zero_extract:SI (match_dup 2)
19431 ;; Don't do logical operations with memory inputs.
19433 [(match_scratch:SI 2 "r")
19434 (parallel [(set (match_operand:SI 0 "register_operand" "")
19435 (match_operator:SI 3 "arith_or_logical_operator"
19437 (match_operand:SI 1 "memory_operand" "")]))
19438 (clobber (reg:CC FLAGS_REG))])]
19439 "! optimize_size && ! TARGET_READ_MODIFY"
19440 [(set (match_dup 2) (match_dup 1))
19441 (parallel [(set (match_dup 0)
19442 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19443 (clobber (reg:CC FLAGS_REG))])]
19447 [(match_scratch:SI 2 "r")
19448 (parallel [(set (match_operand:SI 0 "register_operand" "")
19449 (match_operator:SI 3 "arith_or_logical_operator"
19450 [(match_operand:SI 1 "memory_operand" "")
19452 (clobber (reg:CC FLAGS_REG))])]
19453 "! optimize_size && ! TARGET_READ_MODIFY"
19454 [(set (match_dup 2) (match_dup 1))
19455 (parallel [(set (match_dup 0)
19456 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19457 (clobber (reg:CC FLAGS_REG))])]
19460 ; Don't do logical operations with memory outputs
19462 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19463 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19464 ; the same decoder scheduling characteristics as the original.
19467 [(match_scratch:SI 2 "r")
19468 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19469 (match_operator:SI 3 "arith_or_logical_operator"
19471 (match_operand:SI 1 "nonmemory_operand" "")]))
19472 (clobber (reg:CC FLAGS_REG))])]
19473 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19474 [(set (match_dup 2) (match_dup 0))
19475 (parallel [(set (match_dup 2)
19476 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19477 (clobber (reg:CC FLAGS_REG))])
19478 (set (match_dup 0) (match_dup 2))]
19482 [(match_scratch:SI 2 "r")
19483 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19484 (match_operator:SI 3 "arith_or_logical_operator"
19485 [(match_operand:SI 1 "nonmemory_operand" "")
19487 (clobber (reg:CC FLAGS_REG))])]
19488 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19489 [(set (match_dup 2) (match_dup 0))
19490 (parallel [(set (match_dup 2)
19491 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19492 (clobber (reg:CC FLAGS_REG))])
19493 (set (match_dup 0) (match_dup 2))]
19496 ;; Attempt to always use XOR for zeroing registers.
19498 [(set (match_operand 0 "register_operand" "")
19499 (match_operand 1 "const0_operand" ""))]
19500 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19501 && (! TARGET_USE_MOV0 || optimize_size)
19502 && GENERAL_REG_P (operands[0])
19503 && peep2_regno_dead_p (0, FLAGS_REG)"
19504 [(parallel [(set (match_dup 0) (const_int 0))
19505 (clobber (reg:CC FLAGS_REG))])]
19507 operands[0] = gen_lowpart (word_mode, operands[0]);
19511 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19513 "(GET_MODE (operands[0]) == QImode
19514 || GET_MODE (operands[0]) == HImode)
19515 && (! TARGET_USE_MOV0 || optimize_size)
19516 && peep2_regno_dead_p (0, FLAGS_REG)"
19517 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19518 (clobber (reg:CC FLAGS_REG))])])
19520 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19522 [(set (match_operand 0 "register_operand" "")
19524 "(GET_MODE (operands[0]) == HImode
19525 || GET_MODE (operands[0]) == SImode
19526 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19527 && (optimize_size || TARGET_PENTIUM)
19528 && peep2_regno_dead_p (0, FLAGS_REG)"
19529 [(parallel [(set (match_dup 0) (const_int -1))
19530 (clobber (reg:CC FLAGS_REG))])]
19531 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19534 ;; Attempt to convert simple leas to adds. These can be created by
19537 [(set (match_operand:SI 0 "register_operand" "")
19538 (plus:SI (match_dup 0)
19539 (match_operand:SI 1 "nonmemory_operand" "")))]
19540 "peep2_regno_dead_p (0, FLAGS_REG)"
19541 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19542 (clobber (reg:CC FLAGS_REG))])]
19546 [(set (match_operand:SI 0 "register_operand" "")
19547 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19548 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19549 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19550 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19551 (clobber (reg:CC FLAGS_REG))])]
19552 "operands[2] = gen_lowpart (SImode, operands[2]);")
19555 [(set (match_operand:DI 0 "register_operand" "")
19556 (plus:DI (match_dup 0)
19557 (match_operand:DI 1 "x86_64_general_operand" "")))]
19558 "peep2_regno_dead_p (0, FLAGS_REG)"
19559 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19560 (clobber (reg:CC FLAGS_REG))])]
19564 [(set (match_operand:SI 0 "register_operand" "")
19565 (mult:SI (match_dup 0)
19566 (match_operand:SI 1 "const_int_operand" "")))]
19567 "exact_log2 (INTVAL (operands[1])) >= 0
19568 && peep2_regno_dead_p (0, FLAGS_REG)"
19569 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19570 (clobber (reg:CC FLAGS_REG))])]
19571 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19574 [(set (match_operand:DI 0 "register_operand" "")
19575 (mult:DI (match_dup 0)
19576 (match_operand:DI 1 "const_int_operand" "")))]
19577 "exact_log2 (INTVAL (operands[1])) >= 0
19578 && peep2_regno_dead_p (0, FLAGS_REG)"
19579 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19580 (clobber (reg:CC FLAGS_REG))])]
19581 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19584 [(set (match_operand:SI 0 "register_operand" "")
19585 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19586 (match_operand:DI 2 "const_int_operand" "")) 0))]
19587 "exact_log2 (INTVAL (operands[2])) >= 0
19588 && REGNO (operands[0]) == REGNO (operands[1])
19589 && peep2_regno_dead_p (0, FLAGS_REG)"
19590 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19591 (clobber (reg:CC FLAGS_REG))])]
19592 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19594 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19595 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19596 ;; many CPUs it is also faster, since special hardware to avoid esp
19597 ;; dependencies is present.
19599 ;; While some of these conversions may be done using splitters, we use peepholes
19600 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19602 ;; Convert prologue esp subtractions to push.
19603 ;; We need register to push. In order to keep verify_flow_info happy we have
19605 ;; - use scratch and clobber it in order to avoid dependencies
19606 ;; - use already live register
19607 ;; We can't use the second way right now, since there is no reliable way how to
19608 ;; verify that given register is live. First choice will also most likely in
19609 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19610 ;; call clobbered registers are dead. We may want to use base pointer as an
19611 ;; alternative when no register is available later.
19614 [(match_scratch:SI 0 "r")
19615 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19616 (clobber (reg:CC FLAGS_REG))
19617 (clobber (mem:BLK (scratch)))])]
19618 "optimize_size || !TARGET_SUB_ESP_4"
19619 [(clobber (match_dup 0))
19620 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19621 (clobber (mem:BLK (scratch)))])])
19624 [(match_scratch:SI 0 "r")
19625 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19626 (clobber (reg:CC FLAGS_REG))
19627 (clobber (mem:BLK (scratch)))])]
19628 "optimize_size || !TARGET_SUB_ESP_8"
19629 [(clobber (match_dup 0))
19630 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19631 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19632 (clobber (mem:BLK (scratch)))])])
19634 ;; Convert esp subtractions to push.
19636 [(match_scratch:SI 0 "r")
19637 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19638 (clobber (reg:CC FLAGS_REG))])]
19639 "optimize_size || !TARGET_SUB_ESP_4"
19640 [(clobber (match_dup 0))
19641 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19644 [(match_scratch:SI 0 "r")
19645 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19646 (clobber (reg:CC FLAGS_REG))])]
19647 "optimize_size || !TARGET_SUB_ESP_8"
19648 [(clobber (match_dup 0))
19649 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19650 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19652 ;; Convert epilogue deallocator to pop.
19654 [(match_scratch:SI 0 "r")
19655 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19656 (clobber (reg:CC FLAGS_REG))
19657 (clobber (mem:BLK (scratch)))])]
19658 "optimize_size || !TARGET_ADD_ESP_4"
19659 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19660 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19661 (clobber (mem:BLK (scratch)))])]
19664 ;; Two pops case is tricky, since pop causes dependency on destination register.
19665 ;; We use two registers if available.
19667 [(match_scratch:SI 0 "r")
19668 (match_scratch:SI 1 "r")
19669 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19670 (clobber (reg:CC FLAGS_REG))
19671 (clobber (mem:BLK (scratch)))])]
19672 "optimize_size || !TARGET_ADD_ESP_8"
19673 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19674 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19675 (clobber (mem:BLK (scratch)))])
19676 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19677 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19681 [(match_scratch:SI 0 "r")
19682 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19683 (clobber (reg:CC FLAGS_REG))
19684 (clobber (mem:BLK (scratch)))])]
19686 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19687 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19688 (clobber (mem:BLK (scratch)))])
19689 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19690 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19693 ;; Convert esp additions to pop.
19695 [(match_scratch:SI 0 "r")
19696 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19697 (clobber (reg:CC FLAGS_REG))])]
19699 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19700 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19703 ;; Two pops case is tricky, since pop causes dependency on destination register.
19704 ;; We use two registers if available.
19706 [(match_scratch:SI 0 "r")
19707 (match_scratch:SI 1 "r")
19708 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19709 (clobber (reg:CC FLAGS_REG))])]
19711 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19712 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19713 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19714 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19718 [(match_scratch:SI 0 "r")
19719 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19720 (clobber (reg:CC FLAGS_REG))])]
19722 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19723 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19724 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19725 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19728 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19729 ;; required and register dies. Similarly for 128 to plus -128.
19731 [(set (match_operand 0 "flags_reg_operand" "")
19732 (match_operator 1 "compare_operator"
19733 [(match_operand 2 "register_operand" "")
19734 (match_operand 3 "const_int_operand" "")]))]
19735 "(INTVAL (operands[3]) == -1
19736 || INTVAL (operands[3]) == 1
19737 || INTVAL (operands[3]) == 128)
19738 && ix86_match_ccmode (insn, CCGCmode)
19739 && peep2_reg_dead_p (1, operands[2])"
19740 [(parallel [(set (match_dup 0)
19741 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19742 (clobber (match_dup 2))])]
19746 [(match_scratch:DI 0 "r")
19747 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19748 (clobber (reg:CC FLAGS_REG))
19749 (clobber (mem:BLK (scratch)))])]
19750 "optimize_size || !TARGET_SUB_ESP_4"
19751 [(clobber (match_dup 0))
19752 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19753 (clobber (mem:BLK (scratch)))])])
19756 [(match_scratch:DI 0 "r")
19757 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19758 (clobber (reg:CC FLAGS_REG))
19759 (clobber (mem:BLK (scratch)))])]
19760 "optimize_size || !TARGET_SUB_ESP_8"
19761 [(clobber (match_dup 0))
19762 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19763 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19764 (clobber (mem:BLK (scratch)))])])
19766 ;; Convert esp subtractions to push.
19768 [(match_scratch:DI 0 "r")
19769 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19770 (clobber (reg:CC FLAGS_REG))])]
19771 "optimize_size || !TARGET_SUB_ESP_4"
19772 [(clobber (match_dup 0))
19773 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19776 [(match_scratch:DI 0 "r")
19777 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19778 (clobber (reg:CC FLAGS_REG))])]
19779 "optimize_size || !TARGET_SUB_ESP_8"
19780 [(clobber (match_dup 0))
19781 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19782 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19784 ;; Convert epilogue deallocator to pop.
19786 [(match_scratch:DI 0 "r")
19787 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19788 (clobber (reg:CC FLAGS_REG))
19789 (clobber (mem:BLK (scratch)))])]
19790 "optimize_size || !TARGET_ADD_ESP_4"
19791 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19792 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19793 (clobber (mem:BLK (scratch)))])]
19796 ;; Two pops case is tricky, since pop causes dependency on destination register.
19797 ;; We use two registers if available.
19799 [(match_scratch:DI 0 "r")
19800 (match_scratch:DI 1 "r")
19801 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19802 (clobber (reg:CC FLAGS_REG))
19803 (clobber (mem:BLK (scratch)))])]
19804 "optimize_size || !TARGET_ADD_ESP_8"
19805 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19806 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19807 (clobber (mem:BLK (scratch)))])
19808 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19809 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19813 [(match_scratch:DI 0 "r")
19814 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19815 (clobber (reg:CC FLAGS_REG))
19816 (clobber (mem:BLK (scratch)))])]
19818 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19819 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19820 (clobber (mem:BLK (scratch)))])
19821 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19822 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19825 ;; Convert esp additions to pop.
19827 [(match_scratch:DI 0 "r")
19828 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19829 (clobber (reg:CC FLAGS_REG))])]
19831 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19832 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19835 ;; Two pops case is tricky, since pop causes dependency on destination register.
19836 ;; We use two registers if available.
19838 [(match_scratch:DI 0 "r")
19839 (match_scratch:DI 1 "r")
19840 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19841 (clobber (reg:CC FLAGS_REG))])]
19843 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19844 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19845 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19846 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19850 [(match_scratch:DI 0 "r")
19851 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19852 (clobber (reg:CC FLAGS_REG))])]
19854 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19855 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19856 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19857 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19860 ;; Convert imul by three, five and nine into lea
19863 [(set (match_operand:SI 0 "register_operand" "")
19864 (mult:SI (match_operand:SI 1 "register_operand" "")
19865 (match_operand:SI 2 "const_int_operand" "")))
19866 (clobber (reg:CC FLAGS_REG))])]
19867 "INTVAL (operands[2]) == 3
19868 || INTVAL (operands[2]) == 5
19869 || INTVAL (operands[2]) == 9"
19870 [(set (match_dup 0)
19871 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19873 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19877 [(set (match_operand:SI 0 "register_operand" "")
19878 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19879 (match_operand:SI 2 "const_int_operand" "")))
19880 (clobber (reg:CC FLAGS_REG))])]
19882 && (INTVAL (operands[2]) == 3
19883 || INTVAL (operands[2]) == 5
19884 || INTVAL (operands[2]) == 9)"
19885 [(set (match_dup 0) (match_dup 1))
19887 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19889 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19893 [(set (match_operand:DI 0 "register_operand" "")
19894 (mult:DI (match_operand:DI 1 "register_operand" "")
19895 (match_operand:DI 2 "const_int_operand" "")))
19896 (clobber (reg:CC FLAGS_REG))])]
19898 && (INTVAL (operands[2]) == 3
19899 || INTVAL (operands[2]) == 5
19900 || INTVAL (operands[2]) == 9)"
19901 [(set (match_dup 0)
19902 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19904 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19908 [(set (match_operand:DI 0 "register_operand" "")
19909 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19910 (match_operand:DI 2 "const_int_operand" "")))
19911 (clobber (reg:CC FLAGS_REG))])]
19914 && (INTVAL (operands[2]) == 3
19915 || INTVAL (operands[2]) == 5
19916 || INTVAL (operands[2]) == 9)"
19917 [(set (match_dup 0) (match_dup 1))
19919 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19921 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19923 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19924 ;; imul $32bit_imm, reg, reg is direct decoded.
19926 [(match_scratch:DI 3 "r")
19927 (parallel [(set (match_operand:DI 0 "register_operand" "")
19928 (mult:DI (match_operand:DI 1 "memory_operand" "")
19929 (match_operand:DI 2 "immediate_operand" "")))
19930 (clobber (reg:CC FLAGS_REG))])]
19931 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19932 && !satisfies_constraint_K (operands[2])"
19933 [(set (match_dup 3) (match_dup 1))
19934 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19935 (clobber (reg:CC FLAGS_REG))])]
19939 [(match_scratch:SI 3 "r")
19940 (parallel [(set (match_operand:SI 0 "register_operand" "")
19941 (mult:SI (match_operand:SI 1 "memory_operand" "")
19942 (match_operand:SI 2 "immediate_operand" "")))
19943 (clobber (reg:CC FLAGS_REG))])]
19944 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19945 && !satisfies_constraint_K (operands[2])"
19946 [(set (match_dup 3) (match_dup 1))
19947 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19948 (clobber (reg:CC FLAGS_REG))])]
19952 [(match_scratch:SI 3 "r")
19953 (parallel [(set (match_operand:DI 0 "register_operand" "")
19955 (mult:SI (match_operand:SI 1 "memory_operand" "")
19956 (match_operand:SI 2 "immediate_operand" ""))))
19957 (clobber (reg:CC FLAGS_REG))])]
19958 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19959 && !satisfies_constraint_K (operands[2])"
19960 [(set (match_dup 3) (match_dup 1))
19961 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19962 (clobber (reg:CC FLAGS_REG))])]
19965 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19966 ;; Convert it into imul reg, reg
19967 ;; It would be better to force assembler to encode instruction using long
19968 ;; immediate, but there is apparently no way to do so.
19970 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19971 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19972 (match_operand:DI 2 "const_int_operand" "")))
19973 (clobber (reg:CC FLAGS_REG))])
19974 (match_scratch:DI 3 "r")]
19975 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19976 && satisfies_constraint_K (operands[2])"
19977 [(set (match_dup 3) (match_dup 2))
19978 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19979 (clobber (reg:CC FLAGS_REG))])]
19981 if (!rtx_equal_p (operands[0], operands[1]))
19982 emit_move_insn (operands[0], operands[1]);
19986 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19987 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19988 (match_operand:SI 2 "const_int_operand" "")))
19989 (clobber (reg:CC FLAGS_REG))])
19990 (match_scratch:SI 3 "r")]
19991 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19992 && satisfies_constraint_K (operands[2])"
19993 [(set (match_dup 3) (match_dup 2))
19994 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19995 (clobber (reg:CC FLAGS_REG))])]
19997 if (!rtx_equal_p (operands[0], operands[1]))
19998 emit_move_insn (operands[0], operands[1]);
20002 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20003 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20004 (match_operand:HI 2 "immediate_operand" "")))
20005 (clobber (reg:CC FLAGS_REG))])
20006 (match_scratch:HI 3 "r")]
20007 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20008 [(set (match_dup 3) (match_dup 2))
20009 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20010 (clobber (reg:CC FLAGS_REG))])]
20012 if (!rtx_equal_p (operands[0], operands[1]))
20013 emit_move_insn (operands[0], operands[1]);
20016 ;; After splitting up read-modify operations, array accesses with memory
20017 ;; operands might end up in form:
20019 ;; movl 4(%esp), %edx
20021 ;; instead of pre-splitting:
20023 ;; addl 4(%esp), %eax
20025 ;; movl 4(%esp), %edx
20026 ;; leal (%edx,%eax,4), %eax
20029 [(parallel [(set (match_operand 0 "register_operand" "")
20030 (ashift (match_operand 1 "register_operand" "")
20031 (match_operand 2 "const_int_operand" "")))
20032 (clobber (reg:CC FLAGS_REG))])
20033 (set (match_operand 3 "register_operand")
20034 (match_operand 4 "x86_64_general_operand" ""))
20035 (parallel [(set (match_operand 5 "register_operand" "")
20036 (plus (match_operand 6 "register_operand" "")
20037 (match_operand 7 "register_operand" "")))
20038 (clobber (reg:CC FLAGS_REG))])]
20039 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20040 /* Validate MODE for lea. */
20041 && ((!TARGET_PARTIAL_REG_STALL
20042 && (GET_MODE (operands[0]) == QImode
20043 || GET_MODE (operands[0]) == HImode))
20044 || GET_MODE (operands[0]) == SImode
20045 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20046 /* We reorder load and the shift. */
20047 && !rtx_equal_p (operands[1], operands[3])
20048 && !reg_overlap_mentioned_p (operands[0], operands[4])
20049 /* Last PLUS must consist of operand 0 and 3. */
20050 && !rtx_equal_p (operands[0], operands[3])
20051 && (rtx_equal_p (operands[3], operands[6])
20052 || rtx_equal_p (operands[3], operands[7]))
20053 && (rtx_equal_p (operands[0], operands[6])
20054 || rtx_equal_p (operands[0], operands[7]))
20055 /* The intermediate operand 0 must die or be same as output. */
20056 && (rtx_equal_p (operands[0], operands[5])
20057 || peep2_reg_dead_p (3, operands[0]))"
20058 [(set (match_dup 3) (match_dup 4))
20059 (set (match_dup 0) (match_dup 1))]
20061 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20062 int scale = 1 << INTVAL (operands[2]);
20063 rtx index = gen_lowpart (Pmode, operands[1]);
20064 rtx base = gen_lowpart (Pmode, operands[3]);
20065 rtx dest = gen_lowpart (mode, operands[5]);
20067 operands[1] = gen_rtx_PLUS (Pmode, base,
20068 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20070 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20071 operands[0] = dest;
20074 ;; Call-value patterns last so that the wildcard operand does not
20075 ;; disrupt insn-recog's switch tables.
20077 (define_insn "*call_value_pop_0"
20078 [(set (match_operand 0 "" "")
20079 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20080 (match_operand:SI 2 "" "")))
20081 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20082 (match_operand:SI 3 "immediate_operand" "")))]
20085 if (SIBLING_CALL_P (insn))
20088 return "call\t%P1";
20090 [(set_attr "type" "callv")])
20092 (define_insn "*call_value_pop_1"
20093 [(set (match_operand 0 "" "")
20094 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20095 (match_operand:SI 2 "" "")))
20096 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20097 (match_operand:SI 3 "immediate_operand" "i")))]
20100 if (constant_call_address_operand (operands[1], Pmode))
20102 if (SIBLING_CALL_P (insn))
20105 return "call\t%P1";
20107 if (SIBLING_CALL_P (insn))
20110 return "call\t%A1";
20112 [(set_attr "type" "callv")])
20114 (define_insn "*call_value_0"
20115 [(set (match_operand 0 "" "")
20116 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20117 (match_operand:SI 2 "" "")))]
20120 if (SIBLING_CALL_P (insn))
20123 return "call\t%P1";
20125 [(set_attr "type" "callv")])
20127 (define_insn "*call_value_0_rex64"
20128 [(set (match_operand 0 "" "")
20129 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20130 (match_operand:DI 2 "const_int_operand" "")))]
20133 if (SIBLING_CALL_P (insn))
20136 return "call\t%P1";
20138 [(set_attr "type" "callv")])
20140 (define_insn "*call_value_1"
20141 [(set (match_operand 0 "" "")
20142 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20143 (match_operand:SI 2 "" "")))]
20144 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20146 if (constant_call_address_operand (operands[1], Pmode))
20147 return "call\t%P1";
20148 return "call\t%A1";
20150 [(set_attr "type" "callv")])
20152 (define_insn "*sibcall_value_1"
20153 [(set (match_operand 0 "" "")
20154 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20155 (match_operand:SI 2 "" "")))]
20156 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20158 if (constant_call_address_operand (operands[1], Pmode))
20162 [(set_attr "type" "callv")])
20164 (define_insn "*call_value_1_rex64"
20165 [(set (match_operand 0 "" "")
20166 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20167 (match_operand:DI 2 "" "")))]
20168 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20170 if (constant_call_address_operand (operands[1], Pmode))
20171 return "call\t%P1";
20172 return "call\t%A1";
20174 [(set_attr "type" "callv")])
20176 (define_insn "*sibcall_value_1_rex64"
20177 [(set (match_operand 0 "" "")
20178 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20179 (match_operand:DI 2 "" "")))]
20180 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20182 [(set_attr "type" "callv")])
20184 (define_insn "*sibcall_value_1_rex64_v"
20185 [(set (match_operand 0 "" "")
20186 (call (mem:QI (reg:DI 40))
20187 (match_operand:DI 1 "" "")))]
20188 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20190 [(set_attr "type" "callv")])
20192 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20193 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20194 ;; caught for use by garbage collectors and the like. Using an insn that
20195 ;; maps to SIGILL makes it more likely the program will rightfully die.
20196 ;; Keeping with tradition, "6" is in honor of #UD.
20197 (define_insn "trap"
20198 [(trap_if (const_int 1) (const_int 6))]
20200 { return ASM_SHORT "0x0b0f"; }
20201 [(set_attr "length" "2")])
20203 (define_expand "sse_prologue_save"
20204 [(parallel [(set (match_operand:BLK 0 "" "")
20205 (unspec:BLK [(reg:DI 21)
20212 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20213 (use (match_operand:DI 1 "register_operand" ""))
20214 (use (match_operand:DI 2 "immediate_operand" ""))
20215 (use (label_ref:DI (match_operand 3 "" "")))])]
20219 (define_insn "*sse_prologue_save_insn"
20220 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20221 (match_operand:DI 4 "const_int_operand" "n")))
20222 (unspec:BLK [(reg:DI 21)
20229 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20230 (use (match_operand:DI 1 "register_operand" "r"))
20231 (use (match_operand:DI 2 "const_int_operand" "i"))
20232 (use (label_ref:DI (match_operand 3 "" "X")))]
20234 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20235 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20239 operands[0] = gen_rtx_MEM (Pmode,
20240 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20241 output_asm_insn (\"jmp\\t%A1\", operands);
20242 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20244 operands[4] = adjust_address (operands[0], DImode, i*16);
20245 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20246 PUT_MODE (operands[4], TImode);
20247 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20248 output_asm_insn (\"rex\", operands);
20249 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20251 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20252 CODE_LABEL_NUMBER (operands[3]));
20256 [(set_attr "type" "other")
20257 (set_attr "length_immediate" "0")
20258 (set_attr "length_address" "0")
20259 (set_attr "length" "135")
20260 (set_attr "memory" "store")
20261 (set_attr "modrm" "0")
20262 (set_attr "mode" "DI")])
20264 (define_expand "prefetch"
20265 [(prefetch (match_operand 0 "address_operand" "")
20266 (match_operand:SI 1 "const_int_operand" "")
20267 (match_operand:SI 2 "const_int_operand" ""))]
20268 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20270 int rw = INTVAL (operands[1]);
20271 int locality = INTVAL (operands[2]);
20273 gcc_assert (rw == 0 || rw == 1);
20274 gcc_assert (locality >= 0 && locality <= 3);
20275 gcc_assert (GET_MODE (operands[0]) == Pmode
20276 || GET_MODE (operands[0]) == VOIDmode);
20278 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20279 supported by SSE counterpart or the SSE prefetch is not available
20280 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20282 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20283 operands[2] = GEN_INT (3);
20285 operands[1] = const0_rtx;
20288 (define_insn "*prefetch_sse"
20289 [(prefetch (match_operand:SI 0 "address_operand" "p")
20291 (match_operand:SI 1 "const_int_operand" ""))]
20292 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20294 static const char * const patterns[4] = {
20295 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20298 int locality = INTVAL (operands[1]);
20299 gcc_assert (locality >= 0 && locality <= 3);
20301 return patterns[locality];
20303 [(set_attr "type" "sse")
20304 (set_attr "memory" "none")])
20306 (define_insn "*prefetch_sse_rex"
20307 [(prefetch (match_operand:DI 0 "address_operand" "p")
20309 (match_operand:SI 1 "const_int_operand" ""))]
20310 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20312 static const char * const patterns[4] = {
20313 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20316 int locality = INTVAL (operands[1]);
20317 gcc_assert (locality >= 0 && locality <= 3);
20319 return patterns[locality];
20321 [(set_attr "type" "sse")
20322 (set_attr "memory" "none")])
20324 (define_insn "*prefetch_3dnow"
20325 [(prefetch (match_operand:SI 0 "address_operand" "p")
20326 (match_operand:SI 1 "const_int_operand" "n")
20328 "TARGET_3DNOW && !TARGET_64BIT"
20330 if (INTVAL (operands[1]) == 0)
20331 return "prefetch\t%a0";
20333 return "prefetchw\t%a0";
20335 [(set_attr "type" "mmx")
20336 (set_attr "memory" "none")])
20338 (define_insn "*prefetch_3dnow_rex"
20339 [(prefetch (match_operand:DI 0 "address_operand" "p")
20340 (match_operand:SI 1 "const_int_operand" "n")
20342 "TARGET_3DNOW && TARGET_64BIT"
20344 if (INTVAL (operands[1]) == 0)
20345 return "prefetch\t%a0";
20347 return "prefetchw\t%a0";
20349 [(set_attr "type" "mmx")
20350 (set_attr "memory" "none")])
20352 (define_expand "stack_protect_set"
20353 [(match_operand 0 "memory_operand" "")
20354 (match_operand 1 "memory_operand" "")]
20357 #ifdef TARGET_THREAD_SSP_OFFSET
20359 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20360 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20362 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20363 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20366 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20368 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20373 (define_insn "stack_protect_set_si"
20374 [(set (match_operand:SI 0 "memory_operand" "=m")
20375 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20376 (set (match_scratch:SI 2 "=&r") (const_int 0))
20377 (clobber (reg:CC FLAGS_REG))]
20379 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20380 [(set_attr "type" "multi")])
20382 (define_insn "stack_protect_set_di"
20383 [(set (match_operand:DI 0 "memory_operand" "=m")
20384 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20385 (set (match_scratch:DI 2 "=&r") (const_int 0))
20386 (clobber (reg:CC FLAGS_REG))]
20388 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20389 [(set_attr "type" "multi")])
20391 (define_insn "stack_tls_protect_set_si"
20392 [(set (match_operand:SI 0 "memory_operand" "=m")
20393 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20394 (set (match_scratch:SI 2 "=&r") (const_int 0))
20395 (clobber (reg:CC FLAGS_REG))]
20397 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20398 [(set_attr "type" "multi")])
20400 (define_insn "stack_tls_protect_set_di"
20401 [(set (match_operand:DI 0 "memory_operand" "=m")
20402 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20403 (set (match_scratch:DI 2 "=&r") (const_int 0))
20404 (clobber (reg:CC FLAGS_REG))]
20406 "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20407 [(set_attr "type" "multi")])
20409 (define_expand "stack_protect_test"
20410 [(match_operand 0 "memory_operand" "")
20411 (match_operand 1 "memory_operand" "")
20412 (match_operand 2 "" "")]
20415 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20416 ix86_compare_op0 = operands[0];
20417 ix86_compare_op1 = operands[1];
20418 ix86_compare_emitted = flags;
20420 #ifdef TARGET_THREAD_SSP_OFFSET
20422 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20423 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20425 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20426 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20429 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20431 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20433 emit_jump_insn (gen_beq (operands[2]));
20437 (define_insn "stack_protect_test_si"
20438 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20439 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20440 (match_operand:SI 2 "memory_operand" "m")]
20442 (clobber (match_scratch:SI 3 "=&r"))]
20444 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20445 [(set_attr "type" "multi")])
20447 (define_insn "stack_protect_test_di"
20448 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20449 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20450 (match_operand:DI 2 "memory_operand" "m")]
20452 (clobber (match_scratch:DI 3 "=&r"))]
20454 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20455 [(set_attr "type" "multi")])
20457 (define_insn "stack_tls_protect_test_si"
20458 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20459 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20460 (match_operand:SI 2 "const_int_operand" "i")]
20461 UNSPEC_SP_TLS_TEST))
20462 (clobber (match_scratch:SI 3 "=r"))]
20464 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20465 [(set_attr "type" "multi")])
20467 (define_insn "stack_tls_protect_test_di"
20468 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20469 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20470 (match_operand:DI 2 "const_int_operand" "i")]
20471 UNSPEC_SP_TLS_TEST))
20472 (clobber (match_scratch:DI 3 "=r"))]
20474 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20475 [(set_attr "type" "multi")])
20479 (include "sync.md")