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{l}\t{%2, %1|%1, %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 || !TARGET_SSE_MATH)"
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 || !(TARGET_SSE2 && TARGET_SSE_MATH))"
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")))]
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 || !TARGET_SSE_MATH)"
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 || !(TARGET_SSE2 && TARGET_SSE_MATH))"
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")))]
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 "const8_operand" "")
12505 (match_operand:SI 3 "const8_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 "const8_operand" "")
12522 (match_operand:SI 3 "const8_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 "const8_operand" "")
12538 (match_operand 2 "const8_operand" ""))
12539 (match_operand 3 "register_operand" ""))]
12542 /* Handle insertions to %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 outweigh 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 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14438 (match_operand:SI 4 "" "")
14439 (match_operand:SI 2 "register_operand" "b")
14442 (const:SI (unspec:SI
14443 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14445 (clobber (reg:CC FLAGS_REG))]
14446 "!TARGET_64BIT && TARGET_GNU2_TLS"
14449 [(set (match_dup 0) (match_dup 5))]
14451 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14452 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14455 (define_expand "tls_dynamic_gnu2_64"
14456 [(set (match_dup 2)
14457 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14460 [(set (match_operand:DI 0 "register_operand" "")
14461 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14463 (clobber (reg:CC FLAGS_REG))])]
14464 "TARGET_64BIT && TARGET_GNU2_TLS"
14466 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14467 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14470 (define_insn "*tls_dynamic_lea_64"
14471 [(set (match_operand:DI 0 "register_operand" "=r")
14472 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14474 "TARGET_64BIT && TARGET_GNU2_TLS"
14475 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14476 [(set_attr "type" "lea")
14477 (set_attr "mode" "DI")
14478 (set_attr "length" "7")
14479 (set_attr "length_address" "4")])
14481 (define_insn "*tls_dynamic_call_64"
14482 [(set (match_operand:DI 0 "register_operand" "=a")
14483 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14484 (match_operand:DI 2 "register_operand" "0")
14487 (clobber (reg:CC FLAGS_REG))]
14488 "TARGET_64BIT && TARGET_GNU2_TLS"
14489 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14490 [(set_attr "type" "call")
14491 (set_attr "length" "2")
14492 (set_attr "length_address" "0")])
14494 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14495 [(set (match_operand:DI 0 "register_operand" "=&a")
14497 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14498 (match_operand:DI 3 "" "")
14501 (const:DI (unspec:DI
14502 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14504 (clobber (reg:CC FLAGS_REG))]
14505 "TARGET_64BIT && TARGET_GNU2_TLS"
14508 [(set (match_dup 0) (match_dup 4))]
14510 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14511 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14516 ;; These patterns match the binary 387 instructions for addM3, subM3,
14517 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14518 ;; SFmode. The first is the normal insn, the second the same insn but
14519 ;; with one operand a conversion, and the third the same insn but with
14520 ;; the other operand a conversion. The conversion may be SFmode or
14521 ;; SImode if the target mode DFmode, but only SImode if the target mode
14524 ;; Gcc is slightly more smart about handling normal two address instructions
14525 ;; so use special patterns for add and mull.
14527 (define_insn "*fop_sf_comm_mixed"
14528 [(set (match_operand:SF 0 "register_operand" "=f,x")
14529 (match_operator:SF 3 "binary_fp_operator"
14530 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14531 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14532 "TARGET_MIX_SSE_I387
14533 && COMMUTATIVE_ARITH_P (operands[3])
14534 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14535 "* return output_387_binary_op (insn, operands);"
14536 [(set (attr "type")
14537 (if_then_else (eq_attr "alternative" "1")
14538 (if_then_else (match_operand:SF 3 "mult_operator" "")
14539 (const_string "ssemul")
14540 (const_string "sseadd"))
14541 (if_then_else (match_operand:SF 3 "mult_operator" "")
14542 (const_string "fmul")
14543 (const_string "fop"))))
14544 (set_attr "mode" "SF")])
14546 (define_insn "*fop_sf_comm_sse"
14547 [(set (match_operand:SF 0 "register_operand" "=x")
14548 (match_operator:SF 3 "binary_fp_operator"
14549 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14550 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14552 && COMMUTATIVE_ARITH_P (operands[3])
14553 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14554 "* return output_387_binary_op (insn, operands);"
14555 [(set (attr "type")
14556 (if_then_else (match_operand:SF 3 "mult_operator" "")
14557 (const_string "ssemul")
14558 (const_string "sseadd")))
14559 (set_attr "mode" "SF")])
14561 (define_insn "*fop_sf_comm_i387"
14562 [(set (match_operand:SF 0 "register_operand" "=f")
14563 (match_operator:SF 3 "binary_fp_operator"
14564 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14565 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14567 && COMMUTATIVE_ARITH_P (operands[3])
14568 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14569 "* return output_387_binary_op (insn, operands);"
14570 [(set (attr "type")
14571 (if_then_else (match_operand:SF 3 "mult_operator" "")
14572 (const_string "fmul")
14573 (const_string "fop")))
14574 (set_attr "mode" "SF")])
14576 (define_insn "*fop_sf_1_mixed"
14577 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14578 (match_operator:SF 3 "binary_fp_operator"
14579 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14580 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
14581 "TARGET_MIX_SSE_I387
14582 && !COMMUTATIVE_ARITH_P (operands[3])
14583 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14584 "* return output_387_binary_op (insn, operands);"
14585 [(set (attr "type")
14586 (cond [(and (eq_attr "alternative" "2")
14587 (match_operand:SF 3 "mult_operator" ""))
14588 (const_string "ssemul")
14589 (and (eq_attr "alternative" "2")
14590 (match_operand:SF 3 "div_operator" ""))
14591 (const_string "ssediv")
14592 (eq_attr "alternative" "2")
14593 (const_string "sseadd")
14594 (match_operand:SF 3 "mult_operator" "")
14595 (const_string "fmul")
14596 (match_operand:SF 3 "div_operator" "")
14597 (const_string "fdiv")
14599 (const_string "fop")))
14600 (set_attr "mode" "SF")])
14602 (define_insn "*fop_sf_1_sse"
14603 [(set (match_operand:SF 0 "register_operand" "=x")
14604 (match_operator:SF 3 "binary_fp_operator"
14605 [(match_operand:SF 1 "register_operand" "0")
14606 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14608 && !COMMUTATIVE_ARITH_P (operands[3])"
14609 "* return output_387_binary_op (insn, operands);"
14610 [(set (attr "type")
14611 (cond [(match_operand:SF 3 "mult_operator" "")
14612 (const_string "ssemul")
14613 (match_operand:SF 3 "div_operator" "")
14614 (const_string "ssediv")
14616 (const_string "sseadd")))
14617 (set_attr "mode" "SF")])
14619 ;; This pattern is not fully shadowed by the pattern above.
14620 (define_insn "*fop_sf_1_i387"
14621 [(set (match_operand:SF 0 "register_operand" "=f,f")
14622 (match_operator:SF 3 "binary_fp_operator"
14623 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14624 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14625 "TARGET_80387 && !TARGET_SSE_MATH
14626 && !COMMUTATIVE_ARITH_P (operands[3])
14627 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14628 "* return output_387_binary_op (insn, operands);"
14629 [(set (attr "type")
14630 (cond [(match_operand:SF 3 "mult_operator" "")
14631 (const_string "fmul")
14632 (match_operand:SF 3 "div_operator" "")
14633 (const_string "fdiv")
14635 (const_string "fop")))
14636 (set_attr "mode" "SF")])
14638 ;; ??? Add SSE splitters for these!
14639 (define_insn "*fop_sf_2<mode>_i387"
14640 [(set (match_operand:SF 0 "register_operand" "=f,f")
14641 (match_operator:SF 3 "binary_fp_operator"
14642 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14643 (match_operand:SF 2 "register_operand" "0,0")]))]
14644 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14645 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14646 [(set (attr "type")
14647 (cond [(match_operand:SF 3 "mult_operator" "")
14648 (const_string "fmul")
14649 (match_operand:SF 3 "div_operator" "")
14650 (const_string "fdiv")
14652 (const_string "fop")))
14653 (set_attr "fp_int_src" "true")
14654 (set_attr "mode" "<MODE>")])
14656 (define_insn "*fop_sf_3<mode>_i387"
14657 [(set (match_operand:SF 0 "register_operand" "=f,f")
14658 (match_operator:SF 3 "binary_fp_operator"
14659 [(match_operand:SF 1 "register_operand" "0,0")
14660 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14661 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14662 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14663 [(set (attr "type")
14664 (cond [(match_operand:SF 3 "mult_operator" "")
14665 (const_string "fmul")
14666 (match_operand:SF 3 "div_operator" "")
14667 (const_string "fdiv")
14669 (const_string "fop")))
14670 (set_attr "fp_int_src" "true")
14671 (set_attr "mode" "<MODE>")])
14673 (define_insn "*fop_df_comm_mixed"
14674 [(set (match_operand:DF 0 "register_operand" "=f,Y")
14675 (match_operator:DF 3 "binary_fp_operator"
14676 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14677 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
14678 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14679 && COMMUTATIVE_ARITH_P (operands[3])
14680 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14681 "* return output_387_binary_op (insn, operands);"
14682 [(set (attr "type")
14683 (if_then_else (eq_attr "alternative" "1")
14684 (if_then_else (match_operand:SF 3 "mult_operator" "")
14685 (const_string "ssemul")
14686 (const_string "sseadd"))
14687 (if_then_else (match_operand:SF 3 "mult_operator" "")
14688 (const_string "fmul")
14689 (const_string "fop"))))
14690 (set_attr "mode" "DF")])
14692 (define_insn "*fop_df_comm_sse"
14693 [(set (match_operand:DF 0 "register_operand" "=Y")
14694 (match_operator:DF 3 "binary_fp_operator"
14695 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14696 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14697 "TARGET_SSE2 && TARGET_SSE_MATH
14698 && COMMUTATIVE_ARITH_P (operands[3])
14699 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14700 "* return output_387_binary_op (insn, operands);"
14701 [(set (attr "type")
14702 (if_then_else (match_operand:SF 3 "mult_operator" "")
14703 (const_string "ssemul")
14704 (const_string "sseadd")))
14705 (set_attr "mode" "DF")])
14707 (define_insn "*fop_df_comm_i387"
14708 [(set (match_operand:DF 0 "register_operand" "=f")
14709 (match_operator:DF 3 "binary_fp_operator"
14710 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14711 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14713 && COMMUTATIVE_ARITH_P (operands[3])
14714 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14715 "* return output_387_binary_op (insn, operands);"
14716 [(set (attr "type")
14717 (if_then_else (match_operand:SF 3 "mult_operator" "")
14718 (const_string "fmul")
14719 (const_string "fop")))
14720 (set_attr "mode" "DF")])
14722 (define_insn "*fop_df_1_mixed"
14723 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
14724 (match_operator:DF 3 "binary_fp_operator"
14725 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14726 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
14727 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14728 && !COMMUTATIVE_ARITH_P (operands[3])
14729 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14730 "* return output_387_binary_op (insn, operands);"
14731 [(set (attr "type")
14732 (cond [(and (eq_attr "alternative" "2")
14733 (match_operand:SF 3 "mult_operator" ""))
14734 (const_string "ssemul")
14735 (and (eq_attr "alternative" "2")
14736 (match_operand:SF 3 "div_operator" ""))
14737 (const_string "ssediv")
14738 (eq_attr "alternative" "2")
14739 (const_string "sseadd")
14740 (match_operand:DF 3 "mult_operator" "")
14741 (const_string "fmul")
14742 (match_operand:DF 3 "div_operator" "")
14743 (const_string "fdiv")
14745 (const_string "fop")))
14746 (set_attr "mode" "DF")])
14748 (define_insn "*fop_df_1_sse"
14749 [(set (match_operand:DF 0 "register_operand" "=Y")
14750 (match_operator:DF 3 "binary_fp_operator"
14751 [(match_operand:DF 1 "register_operand" "0")
14752 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14753 "TARGET_SSE2 && TARGET_SSE_MATH
14754 && !COMMUTATIVE_ARITH_P (operands[3])"
14755 "* return output_387_binary_op (insn, operands);"
14756 [(set_attr "mode" "DF")
14758 (cond [(match_operand:SF 3 "mult_operator" "")
14759 (const_string "ssemul")
14760 (match_operand:SF 3 "div_operator" "")
14761 (const_string "ssediv")
14763 (const_string "sseadd")))])
14765 ;; This pattern is not fully shadowed by the pattern above.
14766 (define_insn "*fop_df_1_i387"
14767 [(set (match_operand:DF 0 "register_operand" "=f,f")
14768 (match_operator:DF 3 "binary_fp_operator"
14769 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14770 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14771 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14772 && !COMMUTATIVE_ARITH_P (operands[3])
14773 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14774 "* return output_387_binary_op (insn, operands);"
14775 [(set (attr "type")
14776 (cond [(match_operand:DF 3 "mult_operator" "")
14777 (const_string "fmul")
14778 (match_operand:DF 3 "div_operator" "")
14779 (const_string "fdiv")
14781 (const_string "fop")))
14782 (set_attr "mode" "DF")])
14784 ;; ??? Add SSE splitters for these!
14785 (define_insn "*fop_df_2<mode>_i387"
14786 [(set (match_operand:DF 0 "register_operand" "=f,f")
14787 (match_operator:DF 3 "binary_fp_operator"
14788 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14789 (match_operand:DF 2 "register_operand" "0,0")]))]
14790 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14791 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14792 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14793 [(set (attr "type")
14794 (cond [(match_operand:DF 3 "mult_operator" "")
14795 (const_string "fmul")
14796 (match_operand:DF 3 "div_operator" "")
14797 (const_string "fdiv")
14799 (const_string "fop")))
14800 (set_attr "fp_int_src" "true")
14801 (set_attr "mode" "<MODE>")])
14803 (define_insn "*fop_df_3<mode>_i387"
14804 [(set (match_operand:DF 0 "register_operand" "=f,f")
14805 (match_operator:DF 3 "binary_fp_operator"
14806 [(match_operand:DF 1 "register_operand" "0,0")
14807 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14808 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14809 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14810 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14811 [(set (attr "type")
14812 (cond [(match_operand:DF 3 "mult_operator" "")
14813 (const_string "fmul")
14814 (match_operand:DF 3 "div_operator" "")
14815 (const_string "fdiv")
14817 (const_string "fop")))
14818 (set_attr "fp_int_src" "true")
14819 (set_attr "mode" "<MODE>")])
14821 (define_insn "*fop_df_4_i387"
14822 [(set (match_operand:DF 0 "register_operand" "=f,f")
14823 (match_operator:DF 3 "binary_fp_operator"
14824 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14825 (match_operand:DF 2 "register_operand" "0,f")]))]
14826 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14827 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14828 "* return output_387_binary_op (insn, operands);"
14829 [(set (attr "type")
14830 (cond [(match_operand:DF 3 "mult_operator" "")
14831 (const_string "fmul")
14832 (match_operand:DF 3 "div_operator" "")
14833 (const_string "fdiv")
14835 (const_string "fop")))
14836 (set_attr "mode" "SF")])
14838 (define_insn "*fop_df_5_i387"
14839 [(set (match_operand:DF 0 "register_operand" "=f,f")
14840 (match_operator:DF 3 "binary_fp_operator"
14841 [(match_operand:DF 1 "register_operand" "0,f")
14843 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14844 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14845 "* return output_387_binary_op (insn, operands);"
14846 [(set (attr "type")
14847 (cond [(match_operand:DF 3 "mult_operator" "")
14848 (const_string "fmul")
14849 (match_operand:DF 3 "div_operator" "")
14850 (const_string "fdiv")
14852 (const_string "fop")))
14853 (set_attr "mode" "SF")])
14855 (define_insn "*fop_df_6_i387"
14856 [(set (match_operand:DF 0 "register_operand" "=f,f")
14857 (match_operator:DF 3 "binary_fp_operator"
14859 (match_operand:SF 1 "register_operand" "0,f"))
14861 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14862 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14863 "* return output_387_binary_op (insn, operands);"
14864 [(set (attr "type")
14865 (cond [(match_operand:DF 3 "mult_operator" "")
14866 (const_string "fmul")
14867 (match_operand:DF 3 "div_operator" "")
14868 (const_string "fdiv")
14870 (const_string "fop")))
14871 (set_attr "mode" "SF")])
14873 (define_insn "*fop_xf_comm_i387"
14874 [(set (match_operand:XF 0 "register_operand" "=f")
14875 (match_operator:XF 3 "binary_fp_operator"
14876 [(match_operand:XF 1 "register_operand" "%0")
14877 (match_operand:XF 2 "register_operand" "f")]))]
14879 && COMMUTATIVE_ARITH_P (operands[3])"
14880 "* return output_387_binary_op (insn, operands);"
14881 [(set (attr "type")
14882 (if_then_else (match_operand:XF 3 "mult_operator" "")
14883 (const_string "fmul")
14884 (const_string "fop")))
14885 (set_attr "mode" "XF")])
14887 (define_insn "*fop_xf_1_i387"
14888 [(set (match_operand:XF 0 "register_operand" "=f,f")
14889 (match_operator:XF 3 "binary_fp_operator"
14890 [(match_operand:XF 1 "register_operand" "0,f")
14891 (match_operand:XF 2 "register_operand" "f,0")]))]
14893 && !COMMUTATIVE_ARITH_P (operands[3])"
14894 "* return output_387_binary_op (insn, operands);"
14895 [(set (attr "type")
14896 (cond [(match_operand:XF 3 "mult_operator" "")
14897 (const_string "fmul")
14898 (match_operand:XF 3 "div_operator" "")
14899 (const_string "fdiv")
14901 (const_string "fop")))
14902 (set_attr "mode" "XF")])
14904 (define_insn "*fop_xf_2<mode>_i387"
14905 [(set (match_operand:XF 0 "register_operand" "=f,f")
14906 (match_operator:XF 3 "binary_fp_operator"
14907 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14908 (match_operand:XF 2 "register_operand" "0,0")]))]
14909 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14910 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14911 [(set (attr "type")
14912 (cond [(match_operand:XF 3 "mult_operator" "")
14913 (const_string "fmul")
14914 (match_operand:XF 3 "div_operator" "")
14915 (const_string "fdiv")
14917 (const_string "fop")))
14918 (set_attr "fp_int_src" "true")
14919 (set_attr "mode" "<MODE>")])
14921 (define_insn "*fop_xf_3<mode>_i387"
14922 [(set (match_operand:XF 0 "register_operand" "=f,f")
14923 (match_operator:XF 3 "binary_fp_operator"
14924 [(match_operand:XF 1 "register_operand" "0,0")
14925 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14926 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14927 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14928 [(set (attr "type")
14929 (cond [(match_operand:XF 3 "mult_operator" "")
14930 (const_string "fmul")
14931 (match_operand:XF 3 "div_operator" "")
14932 (const_string "fdiv")
14934 (const_string "fop")))
14935 (set_attr "fp_int_src" "true")
14936 (set_attr "mode" "<MODE>")])
14938 (define_insn "*fop_xf_4_i387"
14939 [(set (match_operand:XF 0 "register_operand" "=f,f")
14940 (match_operator:XF 3 "binary_fp_operator"
14941 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14942 (match_operand:XF 2 "register_operand" "0,f")]))]
14944 "* return output_387_binary_op (insn, operands);"
14945 [(set (attr "type")
14946 (cond [(match_operand:XF 3 "mult_operator" "")
14947 (const_string "fmul")
14948 (match_operand:XF 3 "div_operator" "")
14949 (const_string "fdiv")
14951 (const_string "fop")))
14952 (set_attr "mode" "SF")])
14954 (define_insn "*fop_xf_5_i387"
14955 [(set (match_operand:XF 0 "register_operand" "=f,f")
14956 (match_operator:XF 3 "binary_fp_operator"
14957 [(match_operand:XF 1 "register_operand" "0,f")
14959 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14961 "* return output_387_binary_op (insn, operands);"
14962 [(set (attr "type")
14963 (cond [(match_operand:XF 3 "mult_operator" "")
14964 (const_string "fmul")
14965 (match_operand:XF 3 "div_operator" "")
14966 (const_string "fdiv")
14968 (const_string "fop")))
14969 (set_attr "mode" "SF")])
14971 (define_insn "*fop_xf_6_i387"
14972 [(set (match_operand:XF 0 "register_operand" "=f,f")
14973 (match_operator:XF 3 "binary_fp_operator"
14975 (match_operand 1 "register_operand" "0,f"))
14977 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14979 "* return output_387_binary_op (insn, operands);"
14980 [(set (attr "type")
14981 (cond [(match_operand:XF 3 "mult_operator" "")
14982 (const_string "fmul")
14983 (match_operand:XF 3 "div_operator" "")
14984 (const_string "fdiv")
14986 (const_string "fop")))
14987 (set_attr "mode" "SF")])
14990 [(set (match_operand 0 "register_operand" "")
14991 (match_operator 3 "binary_fp_operator"
14992 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14993 (match_operand 2 "register_operand" "")]))]
14994 "TARGET_80387 && reload_completed
14995 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14998 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14999 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15000 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15001 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15002 GET_MODE (operands[3]),
15005 ix86_free_from_memory (GET_MODE (operands[1]));
15010 [(set (match_operand 0 "register_operand" "")
15011 (match_operator 3 "binary_fp_operator"
15012 [(match_operand 1 "register_operand" "")
15013 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15014 "TARGET_80387 && reload_completed
15015 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15018 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15019 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15020 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15021 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15022 GET_MODE (operands[3]),
15025 ix86_free_from_memory (GET_MODE (operands[2]));
15029 ;; FPU special functions.
15031 (define_expand "sqrtsf2"
15032 [(set (match_operand:SF 0 "register_operand" "")
15033 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15034 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15036 if (!TARGET_SSE_MATH)
15037 operands[1] = force_reg (SFmode, operands[1]);
15040 (define_insn "*sqrtsf2_mixed"
15041 [(set (match_operand:SF 0 "register_operand" "=f,x")
15042 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15043 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15046 sqrtss\t{%1, %0|%0, %1}"
15047 [(set_attr "type" "fpspc,sse")
15048 (set_attr "mode" "SF,SF")
15049 (set_attr "athlon_decode" "direct,*")])
15051 (define_insn "*sqrtsf2_sse"
15052 [(set (match_operand:SF 0 "register_operand" "=x")
15053 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15055 "sqrtss\t{%1, %0|%0, %1}"
15056 [(set_attr "type" "sse")
15057 (set_attr "mode" "SF")
15058 (set_attr "athlon_decode" "*")])
15060 (define_insn "*sqrtsf2_i387"
15061 [(set (match_operand:SF 0 "register_operand" "=f")
15062 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15063 "TARGET_USE_FANCY_MATH_387"
15065 [(set_attr "type" "fpspc")
15066 (set_attr "mode" "SF")
15067 (set_attr "athlon_decode" "direct")])
15069 (define_expand "sqrtdf2"
15070 [(set (match_operand:DF 0 "register_operand" "")
15071 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15072 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15074 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15075 operands[1] = force_reg (DFmode, operands[1]);
15078 (define_insn "*sqrtdf2_mixed"
15079 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15080 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15081 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15084 sqrtsd\t{%1, %0|%0, %1}"
15085 [(set_attr "type" "fpspc,sse")
15086 (set_attr "mode" "DF,DF")
15087 (set_attr "athlon_decode" "direct,*")])
15089 (define_insn "*sqrtdf2_sse"
15090 [(set (match_operand:DF 0 "register_operand" "=Y")
15091 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15092 "TARGET_SSE2 && TARGET_SSE_MATH"
15093 "sqrtsd\t{%1, %0|%0, %1}"
15094 [(set_attr "type" "sse")
15095 (set_attr "mode" "DF")
15096 (set_attr "athlon_decode" "*")])
15098 (define_insn "*sqrtdf2_i387"
15099 [(set (match_operand:DF 0 "register_operand" "=f")
15100 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15101 "TARGET_USE_FANCY_MATH_387"
15103 [(set_attr "type" "fpspc")
15104 (set_attr "mode" "DF")
15105 (set_attr "athlon_decode" "direct")])
15107 (define_insn "*sqrtextendsfdf2_i387"
15108 [(set (match_operand:DF 0 "register_operand" "=f")
15109 (sqrt:DF (float_extend:DF
15110 (match_operand:SF 1 "register_operand" "0"))))]
15111 "TARGET_USE_FANCY_MATH_387
15112 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15114 [(set_attr "type" "fpspc")
15115 (set_attr "mode" "DF")
15116 (set_attr "athlon_decode" "direct")])
15118 (define_insn "sqrtxf2"
15119 [(set (match_operand:XF 0 "register_operand" "=f")
15120 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15121 "TARGET_USE_FANCY_MATH_387
15122 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15124 [(set_attr "type" "fpspc")
15125 (set_attr "mode" "XF")
15126 (set_attr "athlon_decode" "direct")])
15128 (define_insn "*sqrtextendsfxf2_i387"
15129 [(set (match_operand:XF 0 "register_operand" "=f")
15130 (sqrt:XF (float_extend:XF
15131 (match_operand:SF 1 "register_operand" "0"))))]
15132 "TARGET_USE_FANCY_MATH_387"
15134 [(set_attr "type" "fpspc")
15135 (set_attr "mode" "XF")
15136 (set_attr "athlon_decode" "direct")])
15138 (define_insn "*sqrtextenddfxf2_i387"
15139 [(set (match_operand:XF 0 "register_operand" "=f")
15140 (sqrt:XF (float_extend:XF
15141 (match_operand:DF 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 "fpremxf4"
15149 [(set (match_operand:XF 0 "register_operand" "=f")
15150 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15151 (match_operand:XF 3 "register_operand" "1")]
15153 (set (match_operand:XF 1 "register_operand" "=u")
15154 (unspec:XF [(match_dup 2) (match_dup 3)]
15156 (set (reg:CCFP FPSR_REG)
15157 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15158 "TARGET_USE_FANCY_MATH_387
15159 && flag_unsafe_math_optimizations"
15161 [(set_attr "type" "fpspc")
15162 (set_attr "mode" "XF")])
15164 (define_expand "fmodsf3"
15165 [(use (match_operand:SF 0 "register_operand" ""))
15166 (use (match_operand:SF 1 "register_operand" ""))
15167 (use (match_operand:SF 2 "register_operand" ""))]
15168 "TARGET_USE_FANCY_MATH_387
15169 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15170 && flag_unsafe_math_optimizations"
15172 rtx label = gen_label_rtx ();
15174 rtx op1 = gen_reg_rtx (XFmode);
15175 rtx op2 = gen_reg_rtx (XFmode);
15177 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15178 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15180 emit_label (label);
15182 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15183 ix86_emit_fp_unordered_jump (label);
15185 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15189 (define_expand "fmoddf3"
15190 [(use (match_operand:DF 0 "register_operand" ""))
15191 (use (match_operand:DF 1 "register_operand" ""))
15192 (use (match_operand:DF 2 "register_operand" ""))]
15193 "TARGET_USE_FANCY_MATH_387
15194 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15195 && flag_unsafe_math_optimizations"
15197 rtx label = gen_label_rtx ();
15199 rtx op1 = gen_reg_rtx (XFmode);
15200 rtx op2 = gen_reg_rtx (XFmode);
15202 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15203 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15205 emit_label (label);
15207 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15208 ix86_emit_fp_unordered_jump (label);
15210 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15214 (define_expand "fmodxf3"
15215 [(use (match_operand:XF 0 "register_operand" ""))
15216 (use (match_operand:XF 1 "register_operand" ""))
15217 (use (match_operand:XF 2 "register_operand" ""))]
15218 "TARGET_USE_FANCY_MATH_387
15219 && flag_unsafe_math_optimizations"
15221 rtx label = gen_label_rtx ();
15223 emit_label (label);
15225 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15226 operands[1], operands[2]));
15227 ix86_emit_fp_unordered_jump (label);
15229 emit_move_insn (operands[0], operands[1]);
15233 (define_insn "fprem1xf4"
15234 [(set (match_operand:XF 0 "register_operand" "=f")
15235 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15236 (match_operand:XF 3 "register_operand" "1")]
15238 (set (match_operand:XF 1 "register_operand" "=u")
15239 (unspec:XF [(match_dup 2) (match_dup 3)]
15241 (set (reg:CCFP FPSR_REG)
15242 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15243 "TARGET_USE_FANCY_MATH_387
15244 && flag_unsafe_math_optimizations"
15246 [(set_attr "type" "fpspc")
15247 (set_attr "mode" "XF")])
15249 (define_expand "dremsf3"
15250 [(use (match_operand:SF 0 "register_operand" ""))
15251 (use (match_operand:SF 1 "register_operand" ""))
15252 (use (match_operand:SF 2 "register_operand" ""))]
15253 "TARGET_USE_FANCY_MATH_387
15254 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15255 && flag_unsafe_math_optimizations"
15257 rtx label = gen_label_rtx ();
15259 rtx op1 = gen_reg_rtx (XFmode);
15260 rtx op2 = gen_reg_rtx (XFmode);
15262 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15263 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15265 emit_label (label);
15267 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15268 ix86_emit_fp_unordered_jump (label);
15270 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15274 (define_expand "dremdf3"
15275 [(use (match_operand:DF 0 "register_operand" ""))
15276 (use (match_operand:DF 1 "register_operand" ""))
15277 (use (match_operand:DF 2 "register_operand" ""))]
15278 "TARGET_USE_FANCY_MATH_387
15279 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15280 && flag_unsafe_math_optimizations"
15282 rtx label = gen_label_rtx ();
15284 rtx op1 = gen_reg_rtx (XFmode);
15285 rtx op2 = gen_reg_rtx (XFmode);
15287 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15288 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15290 emit_label (label);
15292 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15293 ix86_emit_fp_unordered_jump (label);
15295 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15299 (define_expand "dremxf3"
15300 [(use (match_operand:XF 0 "register_operand" ""))
15301 (use (match_operand:XF 1 "register_operand" ""))
15302 (use (match_operand:XF 2 "register_operand" ""))]
15303 "TARGET_USE_FANCY_MATH_387
15304 && flag_unsafe_math_optimizations"
15306 rtx label = gen_label_rtx ();
15308 emit_label (label);
15310 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15311 operands[1], operands[2]));
15312 ix86_emit_fp_unordered_jump (label);
15314 emit_move_insn (operands[0], operands[1]);
15318 (define_insn "*sindf2"
15319 [(set (match_operand:DF 0 "register_operand" "=f")
15320 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15321 "TARGET_USE_FANCY_MATH_387
15322 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15323 && flag_unsafe_math_optimizations"
15325 [(set_attr "type" "fpspc")
15326 (set_attr "mode" "DF")])
15328 (define_insn "*sinsf2"
15329 [(set (match_operand:SF 0 "register_operand" "=f")
15330 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15331 "TARGET_USE_FANCY_MATH_387
15332 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15333 && flag_unsafe_math_optimizations"
15335 [(set_attr "type" "fpspc")
15336 (set_attr "mode" "SF")])
15338 (define_insn "*sinextendsfdf2"
15339 [(set (match_operand:DF 0 "register_operand" "=f")
15340 (unspec:DF [(float_extend:DF
15341 (match_operand:SF 1 "register_operand" "0"))]
15343 "TARGET_USE_FANCY_MATH_387
15344 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15345 && flag_unsafe_math_optimizations"
15347 [(set_attr "type" "fpspc")
15348 (set_attr "mode" "DF")])
15350 (define_insn "*sinxf2"
15351 [(set (match_operand:XF 0 "register_operand" "=f")
15352 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15353 "TARGET_USE_FANCY_MATH_387
15354 && flag_unsafe_math_optimizations"
15356 [(set_attr "type" "fpspc")
15357 (set_attr "mode" "XF")])
15359 (define_insn "*cosdf2"
15360 [(set (match_operand:DF 0 "register_operand" "=f")
15361 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15362 "TARGET_USE_FANCY_MATH_387
15363 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15364 && flag_unsafe_math_optimizations"
15366 [(set_attr "type" "fpspc")
15367 (set_attr "mode" "DF")])
15369 (define_insn "*cossf2"
15370 [(set (match_operand:SF 0 "register_operand" "=f")
15371 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15372 "TARGET_USE_FANCY_MATH_387
15373 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15374 && flag_unsafe_math_optimizations"
15376 [(set_attr "type" "fpspc")
15377 (set_attr "mode" "SF")])
15379 (define_insn "*cosextendsfdf2"
15380 [(set (match_operand:DF 0 "register_operand" "=f")
15381 (unspec:DF [(float_extend:DF
15382 (match_operand:SF 1 "register_operand" "0"))]
15384 "TARGET_USE_FANCY_MATH_387
15385 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15386 && flag_unsafe_math_optimizations"
15388 [(set_attr "type" "fpspc")
15389 (set_attr "mode" "DF")])
15391 (define_insn "*cosxf2"
15392 [(set (match_operand:XF 0 "register_operand" "=f")
15393 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15394 "TARGET_USE_FANCY_MATH_387
15395 && flag_unsafe_math_optimizations"
15397 [(set_attr "type" "fpspc")
15398 (set_attr "mode" "XF")])
15400 ;; With sincos pattern defined, sin and cos builtin function will be
15401 ;; expanded to sincos pattern with one of its outputs left unused.
15402 ;; Cse pass will detected, if two sincos patterns can be combined,
15403 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15404 ;; depending on the unused output.
15406 (define_insn "sincosdf3"
15407 [(set (match_operand:DF 0 "register_operand" "=f")
15408 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15409 UNSPEC_SINCOS_COS))
15410 (set (match_operand:DF 1 "register_operand" "=u")
15411 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15412 "TARGET_USE_FANCY_MATH_387
15413 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15414 && flag_unsafe_math_optimizations"
15416 [(set_attr "type" "fpspc")
15417 (set_attr "mode" "DF")])
15420 [(set (match_operand:DF 0 "register_operand" "")
15421 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15422 UNSPEC_SINCOS_COS))
15423 (set (match_operand:DF 1 "register_operand" "")
15424 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15425 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15426 && !reload_completed && !reload_in_progress"
15427 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15431 [(set (match_operand:DF 0 "register_operand" "")
15432 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15433 UNSPEC_SINCOS_COS))
15434 (set (match_operand:DF 1 "register_operand" "")
15435 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15436 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15437 && !reload_completed && !reload_in_progress"
15438 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15441 (define_insn "sincossf3"
15442 [(set (match_operand:SF 0 "register_operand" "=f")
15443 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15444 UNSPEC_SINCOS_COS))
15445 (set (match_operand:SF 1 "register_operand" "=u")
15446 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15447 "TARGET_USE_FANCY_MATH_387
15448 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15449 && flag_unsafe_math_optimizations"
15451 [(set_attr "type" "fpspc")
15452 (set_attr "mode" "SF")])
15455 [(set (match_operand:SF 0 "register_operand" "")
15456 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15457 UNSPEC_SINCOS_COS))
15458 (set (match_operand:SF 1 "register_operand" "")
15459 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15460 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15461 && !reload_completed && !reload_in_progress"
15462 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15466 [(set (match_operand:SF 0 "register_operand" "")
15467 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15468 UNSPEC_SINCOS_COS))
15469 (set (match_operand:SF 1 "register_operand" "")
15470 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15471 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15472 && !reload_completed && !reload_in_progress"
15473 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15476 (define_insn "*sincosextendsfdf3"
15477 [(set (match_operand:DF 0 "register_operand" "=f")
15478 (unspec:DF [(float_extend:DF
15479 (match_operand:SF 2 "register_operand" "0"))]
15480 UNSPEC_SINCOS_COS))
15481 (set (match_operand:DF 1 "register_operand" "=u")
15482 (unspec:DF [(float_extend:DF
15483 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15484 "TARGET_USE_FANCY_MATH_387
15485 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15486 && flag_unsafe_math_optimizations"
15488 [(set_attr "type" "fpspc")
15489 (set_attr "mode" "DF")])
15492 [(set (match_operand:DF 0 "register_operand" "")
15493 (unspec:DF [(float_extend:DF
15494 (match_operand:SF 2 "register_operand" ""))]
15495 UNSPEC_SINCOS_COS))
15496 (set (match_operand:DF 1 "register_operand" "")
15497 (unspec:DF [(float_extend:DF
15498 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15499 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15500 && !reload_completed && !reload_in_progress"
15501 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15502 (match_dup 2))] UNSPEC_SIN))]
15506 [(set (match_operand:DF 0 "register_operand" "")
15507 (unspec:DF [(float_extend:DF
15508 (match_operand:SF 2 "register_operand" ""))]
15509 UNSPEC_SINCOS_COS))
15510 (set (match_operand:DF 1 "register_operand" "")
15511 (unspec:DF [(float_extend:DF
15512 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15513 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15514 && !reload_completed && !reload_in_progress"
15515 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15516 (match_dup 2))] UNSPEC_COS))]
15519 (define_insn "sincosxf3"
15520 [(set (match_operand:XF 0 "register_operand" "=f")
15521 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15522 UNSPEC_SINCOS_COS))
15523 (set (match_operand:XF 1 "register_operand" "=u")
15524 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15525 "TARGET_USE_FANCY_MATH_387
15526 && flag_unsafe_math_optimizations"
15528 [(set_attr "type" "fpspc")
15529 (set_attr "mode" "XF")])
15532 [(set (match_operand:XF 0 "register_operand" "")
15533 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15534 UNSPEC_SINCOS_COS))
15535 (set (match_operand:XF 1 "register_operand" "")
15536 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15537 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15538 && !reload_completed && !reload_in_progress"
15539 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15543 [(set (match_operand:XF 0 "register_operand" "")
15544 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15545 UNSPEC_SINCOS_COS))
15546 (set (match_operand:XF 1 "register_operand" "")
15547 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15548 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15549 && !reload_completed && !reload_in_progress"
15550 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15553 (define_insn "*tandf3_1"
15554 [(set (match_operand:DF 0 "register_operand" "=f")
15555 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15557 (set (match_operand:DF 1 "register_operand" "=u")
15558 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15559 "TARGET_USE_FANCY_MATH_387
15560 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15561 && flag_unsafe_math_optimizations"
15563 [(set_attr "type" "fpspc")
15564 (set_attr "mode" "DF")])
15566 ;; optimize sequence: fptan
15569 ;; into fptan insn.
15572 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15573 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15575 (set (match_operand:DF 1 "register_operand" "")
15576 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15578 (match_operand:DF 3 "immediate_operand" ""))]
15579 "standard_80387_constant_p (operands[3]) == 2"
15580 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15581 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15584 (define_expand "tandf2"
15585 [(parallel [(set (match_dup 2)
15586 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15588 (set (match_operand:DF 0 "register_operand" "")
15589 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15590 "TARGET_USE_FANCY_MATH_387
15591 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15592 && flag_unsafe_math_optimizations"
15594 operands[2] = gen_reg_rtx (DFmode);
15597 (define_insn "*tansf3_1"
15598 [(set (match_operand:SF 0 "register_operand" "=f")
15599 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15601 (set (match_operand:SF 1 "register_operand" "=u")
15602 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15603 "TARGET_USE_FANCY_MATH_387
15604 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15605 && flag_unsafe_math_optimizations"
15607 [(set_attr "type" "fpspc")
15608 (set_attr "mode" "SF")])
15610 ;; optimize sequence: fptan
15613 ;; into fptan insn.
15616 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15617 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15619 (set (match_operand:SF 1 "register_operand" "")
15620 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15622 (match_operand:SF 3 "immediate_operand" ""))]
15623 "standard_80387_constant_p (operands[3]) == 2"
15624 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15625 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15628 (define_expand "tansf2"
15629 [(parallel [(set (match_dup 2)
15630 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15632 (set (match_operand:SF 0 "register_operand" "")
15633 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15634 "TARGET_USE_FANCY_MATH_387
15635 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15636 && flag_unsafe_math_optimizations"
15638 operands[2] = gen_reg_rtx (SFmode);
15641 (define_insn "*tanxf3_1"
15642 [(set (match_operand:XF 0 "register_operand" "=f")
15643 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15645 (set (match_operand:XF 1 "register_operand" "=u")
15646 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15647 "TARGET_USE_FANCY_MATH_387
15648 && flag_unsafe_math_optimizations"
15650 [(set_attr "type" "fpspc")
15651 (set_attr "mode" "XF")])
15653 ;; optimize sequence: fptan
15656 ;; into fptan insn.
15659 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15660 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15662 (set (match_operand:XF 1 "register_operand" "")
15663 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15665 (match_operand:XF 3 "immediate_operand" ""))]
15666 "standard_80387_constant_p (operands[3]) == 2"
15667 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15668 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15671 (define_expand "tanxf2"
15672 [(parallel [(set (match_dup 2)
15673 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15675 (set (match_operand:XF 0 "register_operand" "")
15676 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15677 "TARGET_USE_FANCY_MATH_387
15678 && flag_unsafe_math_optimizations"
15680 operands[2] = gen_reg_rtx (XFmode);
15683 (define_insn "atan2df3_1"
15684 [(set (match_operand:DF 0 "register_operand" "=f")
15685 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15686 (match_operand:DF 1 "register_operand" "u")]
15688 (clobber (match_scratch:DF 3 "=1"))]
15689 "TARGET_USE_FANCY_MATH_387
15690 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15691 && flag_unsafe_math_optimizations"
15693 [(set_attr "type" "fpspc")
15694 (set_attr "mode" "DF")])
15696 (define_expand "atan2df3"
15697 [(use (match_operand:DF 0 "register_operand" ""))
15698 (use (match_operand:DF 2 "register_operand" ""))
15699 (use (match_operand:DF 1 "register_operand" ""))]
15700 "TARGET_USE_FANCY_MATH_387
15701 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15702 && flag_unsafe_math_optimizations"
15704 rtx copy = gen_reg_rtx (DFmode);
15705 emit_move_insn (copy, operands[1]);
15706 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15710 (define_expand "atandf2"
15711 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15712 (unspec:DF [(match_dup 2)
15713 (match_operand:DF 1 "register_operand" "")]
15715 (clobber (match_scratch:DF 3 ""))])]
15716 "TARGET_USE_FANCY_MATH_387
15717 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15718 && flag_unsafe_math_optimizations"
15720 operands[2] = gen_reg_rtx (DFmode);
15721 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15724 (define_insn "atan2sf3_1"
15725 [(set (match_operand:SF 0 "register_operand" "=f")
15726 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15727 (match_operand:SF 1 "register_operand" "u")]
15729 (clobber (match_scratch:SF 3 "=1"))]
15730 "TARGET_USE_FANCY_MATH_387
15731 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15732 && flag_unsafe_math_optimizations"
15734 [(set_attr "type" "fpspc")
15735 (set_attr "mode" "SF")])
15737 (define_expand "atan2sf3"
15738 [(use (match_operand:SF 0 "register_operand" ""))
15739 (use (match_operand:SF 2 "register_operand" ""))
15740 (use (match_operand:SF 1 "register_operand" ""))]
15741 "TARGET_USE_FANCY_MATH_387
15742 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15743 && flag_unsafe_math_optimizations"
15745 rtx copy = gen_reg_rtx (SFmode);
15746 emit_move_insn (copy, operands[1]);
15747 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15751 (define_expand "atansf2"
15752 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15753 (unspec:SF [(match_dup 2)
15754 (match_operand:SF 1 "register_operand" "")]
15756 (clobber (match_scratch:SF 3 ""))])]
15757 "TARGET_USE_FANCY_MATH_387
15758 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15759 && flag_unsafe_math_optimizations"
15761 operands[2] = gen_reg_rtx (SFmode);
15762 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15765 (define_insn "atan2xf3_1"
15766 [(set (match_operand:XF 0 "register_operand" "=f")
15767 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15768 (match_operand:XF 1 "register_operand" "u")]
15770 (clobber (match_scratch:XF 3 "=1"))]
15771 "TARGET_USE_FANCY_MATH_387
15772 && flag_unsafe_math_optimizations"
15774 [(set_attr "type" "fpspc")
15775 (set_attr "mode" "XF")])
15777 (define_expand "atan2xf3"
15778 [(use (match_operand:XF 0 "register_operand" ""))
15779 (use (match_operand:XF 2 "register_operand" ""))
15780 (use (match_operand:XF 1 "register_operand" ""))]
15781 "TARGET_USE_FANCY_MATH_387
15782 && flag_unsafe_math_optimizations"
15784 rtx copy = gen_reg_rtx (XFmode);
15785 emit_move_insn (copy, operands[1]);
15786 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15790 (define_expand "atanxf2"
15791 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15792 (unspec:XF [(match_dup 2)
15793 (match_operand:XF 1 "register_operand" "")]
15795 (clobber (match_scratch:XF 3 ""))])]
15796 "TARGET_USE_FANCY_MATH_387
15797 && flag_unsafe_math_optimizations"
15799 operands[2] = gen_reg_rtx (XFmode);
15800 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15803 (define_expand "asindf2"
15804 [(set (match_dup 2)
15805 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15806 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15807 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15808 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15809 (parallel [(set (match_dup 7)
15810 (unspec:XF [(match_dup 6) (match_dup 2)]
15812 (clobber (match_scratch:XF 8 ""))])
15813 (set (match_operand:DF 0 "register_operand" "")
15814 (float_truncate:DF (match_dup 7)))]
15815 "TARGET_USE_FANCY_MATH_387
15816 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15817 && flag_unsafe_math_optimizations"
15821 for (i=2; i<8; i++)
15822 operands[i] = gen_reg_rtx (XFmode);
15824 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15827 (define_expand "asinsf2"
15828 [(set (match_dup 2)
15829 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15830 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15831 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15832 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15833 (parallel [(set (match_dup 7)
15834 (unspec:XF [(match_dup 6) (match_dup 2)]
15836 (clobber (match_scratch:XF 8 ""))])
15837 (set (match_operand:SF 0 "register_operand" "")
15838 (float_truncate:SF (match_dup 7)))]
15839 "TARGET_USE_FANCY_MATH_387
15840 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15841 && flag_unsafe_math_optimizations"
15845 for (i=2; i<8; i++)
15846 operands[i] = gen_reg_rtx (XFmode);
15848 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15851 (define_expand "asinxf2"
15852 [(set (match_dup 2)
15853 (mult:XF (match_operand:XF 1 "register_operand" "")
15855 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15856 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15857 (parallel [(set (match_operand:XF 0 "register_operand" "")
15858 (unspec:XF [(match_dup 5) (match_dup 1)]
15860 (clobber (match_scratch:XF 6 ""))])]
15861 "TARGET_USE_FANCY_MATH_387
15862 && flag_unsafe_math_optimizations"
15866 for (i=2; i<6; i++)
15867 operands[i] = gen_reg_rtx (XFmode);
15869 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15872 (define_expand "acosdf2"
15873 [(set (match_dup 2)
15874 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15875 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15876 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15877 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15878 (parallel [(set (match_dup 7)
15879 (unspec:XF [(match_dup 2) (match_dup 6)]
15881 (clobber (match_scratch:XF 8 ""))])
15882 (set (match_operand:DF 0 "register_operand" "")
15883 (float_truncate:DF (match_dup 7)))]
15884 "TARGET_USE_FANCY_MATH_387
15885 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15886 && flag_unsafe_math_optimizations"
15890 for (i=2; i<8; i++)
15891 operands[i] = gen_reg_rtx (XFmode);
15893 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15896 (define_expand "acossf2"
15897 [(set (match_dup 2)
15898 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15899 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15900 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15901 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15902 (parallel [(set (match_dup 7)
15903 (unspec:XF [(match_dup 2) (match_dup 6)]
15905 (clobber (match_scratch:XF 8 ""))])
15906 (set (match_operand:SF 0 "register_operand" "")
15907 (float_truncate:SF (match_dup 7)))]
15908 "TARGET_USE_FANCY_MATH_387
15909 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15910 && flag_unsafe_math_optimizations"
15914 for (i=2; i<8; i++)
15915 operands[i] = gen_reg_rtx (XFmode);
15917 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15920 (define_expand "acosxf2"
15921 [(set (match_dup 2)
15922 (mult:XF (match_operand:XF 1 "register_operand" "")
15924 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15925 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15926 (parallel [(set (match_operand:XF 0 "register_operand" "")
15927 (unspec:XF [(match_dup 1) (match_dup 5)]
15929 (clobber (match_scratch:XF 6 ""))])]
15930 "TARGET_USE_FANCY_MATH_387
15931 && flag_unsafe_math_optimizations"
15935 for (i=2; i<6; i++)
15936 operands[i] = gen_reg_rtx (XFmode);
15938 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15941 (define_insn "fyl2x_xf3"
15942 [(set (match_operand:XF 0 "register_operand" "=f")
15943 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15944 (match_operand:XF 1 "register_operand" "u")]
15946 (clobber (match_scratch:XF 3 "=1"))]
15947 "TARGET_USE_FANCY_MATH_387
15948 && flag_unsafe_math_optimizations"
15950 [(set_attr "type" "fpspc")
15951 (set_attr "mode" "XF")])
15953 (define_expand "logsf2"
15954 [(set (match_dup 2)
15955 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15956 (parallel [(set (match_dup 4)
15957 (unspec:XF [(match_dup 2)
15958 (match_dup 3)] UNSPEC_FYL2X))
15959 (clobber (match_scratch:XF 5 ""))])
15960 (set (match_operand:SF 0 "register_operand" "")
15961 (float_truncate:SF (match_dup 4)))]
15962 "TARGET_USE_FANCY_MATH_387
15963 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15964 && flag_unsafe_math_optimizations"
15968 operands[2] = gen_reg_rtx (XFmode);
15969 operands[3] = gen_reg_rtx (XFmode);
15970 operands[4] = gen_reg_rtx (XFmode);
15972 temp = standard_80387_constant_rtx (4); /* fldln2 */
15973 emit_move_insn (operands[3], temp);
15976 (define_expand "logdf2"
15977 [(set (match_dup 2)
15978 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15979 (parallel [(set (match_dup 4)
15980 (unspec:XF [(match_dup 2)
15981 (match_dup 3)] UNSPEC_FYL2X))
15982 (clobber (match_scratch:XF 5 ""))])
15983 (set (match_operand:DF 0 "register_operand" "")
15984 (float_truncate:DF (match_dup 4)))]
15985 "TARGET_USE_FANCY_MATH_387
15986 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15987 && flag_unsafe_math_optimizations"
15991 operands[2] = gen_reg_rtx (XFmode);
15992 operands[3] = gen_reg_rtx (XFmode);
15993 operands[4] = gen_reg_rtx (XFmode);
15995 temp = standard_80387_constant_rtx (4); /* fldln2 */
15996 emit_move_insn (operands[3], temp);
15999 (define_expand "logxf2"
16000 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16001 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16002 (match_dup 2)] UNSPEC_FYL2X))
16003 (clobber (match_scratch:XF 3 ""))])]
16004 "TARGET_USE_FANCY_MATH_387
16005 && flag_unsafe_math_optimizations"
16009 operands[2] = gen_reg_rtx (XFmode);
16010 temp = standard_80387_constant_rtx (4); /* fldln2 */
16011 emit_move_insn (operands[2], temp);
16014 (define_expand "log10sf2"
16015 [(set (match_dup 2)
16016 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16017 (parallel [(set (match_dup 4)
16018 (unspec:XF [(match_dup 2)
16019 (match_dup 3)] UNSPEC_FYL2X))
16020 (clobber (match_scratch:XF 5 ""))])
16021 (set (match_operand:SF 0 "register_operand" "")
16022 (float_truncate:SF (match_dup 4)))]
16023 "TARGET_USE_FANCY_MATH_387
16024 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16025 && flag_unsafe_math_optimizations"
16029 operands[2] = gen_reg_rtx (XFmode);
16030 operands[3] = gen_reg_rtx (XFmode);
16031 operands[4] = gen_reg_rtx (XFmode);
16033 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16034 emit_move_insn (operands[3], temp);
16037 (define_expand "log10df2"
16038 [(set (match_dup 2)
16039 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16040 (parallel [(set (match_dup 4)
16041 (unspec:XF [(match_dup 2)
16042 (match_dup 3)] UNSPEC_FYL2X))
16043 (clobber (match_scratch:XF 5 ""))])
16044 (set (match_operand:DF 0 "register_operand" "")
16045 (float_truncate:DF (match_dup 4)))]
16046 "TARGET_USE_FANCY_MATH_387
16047 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16048 && flag_unsafe_math_optimizations"
16052 operands[2] = gen_reg_rtx (XFmode);
16053 operands[3] = gen_reg_rtx (XFmode);
16054 operands[4] = gen_reg_rtx (XFmode);
16056 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16057 emit_move_insn (operands[3], temp);
16060 (define_expand "log10xf2"
16061 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16062 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16063 (match_dup 2)] UNSPEC_FYL2X))
16064 (clobber (match_scratch:XF 3 ""))])]
16065 "TARGET_USE_FANCY_MATH_387
16066 && flag_unsafe_math_optimizations"
16070 operands[2] = gen_reg_rtx (XFmode);
16071 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16072 emit_move_insn (operands[2], temp);
16075 (define_expand "log2sf2"
16076 [(set (match_dup 2)
16077 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16078 (parallel [(set (match_dup 4)
16079 (unspec:XF [(match_dup 2)
16080 (match_dup 3)] UNSPEC_FYL2X))
16081 (clobber (match_scratch:XF 5 ""))])
16082 (set (match_operand:SF 0 "register_operand" "")
16083 (float_truncate:SF (match_dup 4)))]
16084 "TARGET_USE_FANCY_MATH_387
16085 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16086 && flag_unsafe_math_optimizations"
16088 operands[2] = gen_reg_rtx (XFmode);
16089 operands[3] = gen_reg_rtx (XFmode);
16090 operands[4] = gen_reg_rtx (XFmode);
16092 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16095 (define_expand "log2df2"
16096 [(set (match_dup 2)
16097 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16098 (parallel [(set (match_dup 4)
16099 (unspec:XF [(match_dup 2)
16100 (match_dup 3)] UNSPEC_FYL2X))
16101 (clobber (match_scratch:XF 5 ""))])
16102 (set (match_operand:DF 0 "register_operand" "")
16103 (float_truncate:DF (match_dup 4)))]
16104 "TARGET_USE_FANCY_MATH_387
16105 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16106 && flag_unsafe_math_optimizations"
16108 operands[2] = gen_reg_rtx (XFmode);
16109 operands[3] = gen_reg_rtx (XFmode);
16110 operands[4] = gen_reg_rtx (XFmode);
16112 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16115 (define_expand "log2xf2"
16116 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16117 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16118 (match_dup 2)] UNSPEC_FYL2X))
16119 (clobber (match_scratch:XF 3 ""))])]
16120 "TARGET_USE_FANCY_MATH_387
16121 && flag_unsafe_math_optimizations"
16123 operands[2] = gen_reg_rtx (XFmode);
16124 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16127 (define_insn "fyl2xp1_xf3"
16128 [(set (match_operand:XF 0 "register_operand" "=f")
16129 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16130 (match_operand:XF 1 "register_operand" "u")]
16132 (clobber (match_scratch:XF 3 "=1"))]
16133 "TARGET_USE_FANCY_MATH_387
16134 && flag_unsafe_math_optimizations"
16136 [(set_attr "type" "fpspc")
16137 (set_attr "mode" "XF")])
16139 (define_expand "log1psf2"
16140 [(use (match_operand:SF 0 "register_operand" ""))
16141 (use (match_operand:SF 1 "register_operand" ""))]
16142 "TARGET_USE_FANCY_MATH_387
16143 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16144 && flag_unsafe_math_optimizations"
16146 rtx op0 = gen_reg_rtx (XFmode);
16147 rtx op1 = gen_reg_rtx (XFmode);
16149 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16150 ix86_emit_i387_log1p (op0, op1);
16151 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16155 (define_expand "log1pdf2"
16156 [(use (match_operand:DF 0 "register_operand" ""))
16157 (use (match_operand:DF 1 "register_operand" ""))]
16158 "TARGET_USE_FANCY_MATH_387
16159 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16160 && flag_unsafe_math_optimizations"
16162 rtx op0 = gen_reg_rtx (XFmode);
16163 rtx op1 = gen_reg_rtx (XFmode);
16165 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16166 ix86_emit_i387_log1p (op0, op1);
16167 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16171 (define_expand "log1pxf2"
16172 [(use (match_operand:XF 0 "register_operand" ""))
16173 (use (match_operand:XF 1 "register_operand" ""))]
16174 "TARGET_USE_FANCY_MATH_387
16175 && flag_unsafe_math_optimizations"
16177 ix86_emit_i387_log1p (operands[0], operands[1]);
16181 (define_insn "*fxtractxf3"
16182 [(set (match_operand:XF 0 "register_operand" "=f")
16183 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16184 UNSPEC_XTRACT_FRACT))
16185 (set (match_operand:XF 1 "register_operand" "=u")
16186 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16187 "TARGET_USE_FANCY_MATH_387
16188 && flag_unsafe_math_optimizations"
16190 [(set_attr "type" "fpspc")
16191 (set_attr "mode" "XF")])
16193 (define_expand "logbsf2"
16194 [(set (match_dup 2)
16195 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16196 (parallel [(set (match_dup 3)
16197 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16199 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16200 (set (match_operand:SF 0 "register_operand" "")
16201 (float_truncate:SF (match_dup 4)))]
16202 "TARGET_USE_FANCY_MATH_387
16203 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16204 && flag_unsafe_math_optimizations"
16206 operands[2] = gen_reg_rtx (XFmode);
16207 operands[3] = gen_reg_rtx (XFmode);
16208 operands[4] = gen_reg_rtx (XFmode);
16211 (define_expand "logbdf2"
16212 [(set (match_dup 2)
16213 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16214 (parallel [(set (match_dup 3)
16215 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16217 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16218 (set (match_operand:DF 0 "register_operand" "")
16219 (float_truncate:DF (match_dup 4)))]
16220 "TARGET_USE_FANCY_MATH_387
16221 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16222 && flag_unsafe_math_optimizations"
16224 operands[2] = gen_reg_rtx (XFmode);
16225 operands[3] = gen_reg_rtx (XFmode);
16226 operands[4] = gen_reg_rtx (XFmode);
16229 (define_expand "logbxf2"
16230 [(parallel [(set (match_dup 2)
16231 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16232 UNSPEC_XTRACT_FRACT))
16233 (set (match_operand:XF 0 "register_operand" "")
16234 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16235 "TARGET_USE_FANCY_MATH_387
16236 && flag_unsafe_math_optimizations"
16238 operands[2] = gen_reg_rtx (XFmode);
16241 (define_expand "ilogbsi2"
16242 [(parallel [(set (match_dup 2)
16243 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16244 UNSPEC_XTRACT_FRACT))
16245 (set (match_operand:XF 3 "register_operand" "")
16246 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16247 (parallel [(set (match_operand:SI 0 "register_operand" "")
16248 (fix:SI (match_dup 3)))
16249 (clobber (reg:CC FLAGS_REG))])]
16250 "TARGET_USE_FANCY_MATH_387
16251 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16252 && flag_unsafe_math_optimizations"
16254 operands[2] = gen_reg_rtx (XFmode);
16255 operands[3] = gen_reg_rtx (XFmode);
16258 (define_insn "*f2xm1xf2"
16259 [(set (match_operand:XF 0 "register_operand" "=f")
16260 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16262 "TARGET_USE_FANCY_MATH_387
16263 && flag_unsafe_math_optimizations"
16265 [(set_attr "type" "fpspc")
16266 (set_attr "mode" "XF")])
16268 (define_insn "*fscalexf4"
16269 [(set (match_operand:XF 0 "register_operand" "=f")
16270 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16271 (match_operand:XF 3 "register_operand" "1")]
16272 UNSPEC_FSCALE_FRACT))
16273 (set (match_operand:XF 1 "register_operand" "=u")
16274 (unspec:XF [(match_dup 2) (match_dup 3)]
16275 UNSPEC_FSCALE_EXP))]
16276 "TARGET_USE_FANCY_MATH_387
16277 && flag_unsafe_math_optimizations"
16279 [(set_attr "type" "fpspc")
16280 (set_attr "mode" "XF")])
16282 (define_expand "expsf2"
16283 [(set (match_dup 2)
16284 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16285 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16286 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16287 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16288 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16289 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16290 (parallel [(set (match_dup 10)
16291 (unspec:XF [(match_dup 9) (match_dup 5)]
16292 UNSPEC_FSCALE_FRACT))
16293 (set (match_dup 11)
16294 (unspec:XF [(match_dup 9) (match_dup 5)]
16295 UNSPEC_FSCALE_EXP))])
16296 (set (match_operand:SF 0 "register_operand" "")
16297 (float_truncate:SF (match_dup 10)))]
16298 "TARGET_USE_FANCY_MATH_387
16299 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16300 && flag_unsafe_math_optimizations"
16305 for (i=2; i<12; i++)
16306 operands[i] = gen_reg_rtx (XFmode);
16307 temp = standard_80387_constant_rtx (5); /* fldl2e */
16308 emit_move_insn (operands[3], temp);
16309 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16312 (define_expand "expdf2"
16313 [(set (match_dup 2)
16314 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16315 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16316 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16317 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16318 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16319 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16320 (parallel [(set (match_dup 10)
16321 (unspec:XF [(match_dup 9) (match_dup 5)]
16322 UNSPEC_FSCALE_FRACT))
16323 (set (match_dup 11)
16324 (unspec:XF [(match_dup 9) (match_dup 5)]
16325 UNSPEC_FSCALE_EXP))])
16326 (set (match_operand:DF 0 "register_operand" "")
16327 (float_truncate:DF (match_dup 10)))]
16328 "TARGET_USE_FANCY_MATH_387
16329 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16330 && flag_unsafe_math_optimizations"
16335 for (i=2; i<12; i++)
16336 operands[i] = gen_reg_rtx (XFmode);
16337 temp = standard_80387_constant_rtx (5); /* fldl2e */
16338 emit_move_insn (operands[3], temp);
16339 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16342 (define_expand "expxf2"
16343 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16345 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16346 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16347 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16348 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16349 (parallel [(set (match_operand:XF 0 "register_operand" "")
16350 (unspec:XF [(match_dup 8) (match_dup 4)]
16351 UNSPEC_FSCALE_FRACT))
16353 (unspec:XF [(match_dup 8) (match_dup 4)]
16354 UNSPEC_FSCALE_EXP))])]
16355 "TARGET_USE_FANCY_MATH_387
16356 && flag_unsafe_math_optimizations"
16361 for (i=2; i<10; i++)
16362 operands[i] = gen_reg_rtx (XFmode);
16363 temp = standard_80387_constant_rtx (5); /* fldl2e */
16364 emit_move_insn (operands[2], temp);
16365 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16368 (define_expand "exp10sf2"
16369 [(set (match_dup 2)
16370 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16371 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16372 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16373 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16374 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16375 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16376 (parallel [(set (match_dup 10)
16377 (unspec:XF [(match_dup 9) (match_dup 5)]
16378 UNSPEC_FSCALE_FRACT))
16379 (set (match_dup 11)
16380 (unspec:XF [(match_dup 9) (match_dup 5)]
16381 UNSPEC_FSCALE_EXP))])
16382 (set (match_operand:SF 0 "register_operand" "")
16383 (float_truncate:SF (match_dup 10)))]
16384 "TARGET_USE_FANCY_MATH_387
16385 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16386 && flag_unsafe_math_optimizations"
16391 for (i=2; i<12; i++)
16392 operands[i] = gen_reg_rtx (XFmode);
16393 temp = standard_80387_constant_rtx (6); /* fldl2t */
16394 emit_move_insn (operands[3], temp);
16395 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16398 (define_expand "exp10df2"
16399 [(set (match_dup 2)
16400 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16401 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16402 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16403 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16404 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16405 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16406 (parallel [(set (match_dup 10)
16407 (unspec:XF [(match_dup 9) (match_dup 5)]
16408 UNSPEC_FSCALE_FRACT))
16409 (set (match_dup 11)
16410 (unspec:XF [(match_dup 9) (match_dup 5)]
16411 UNSPEC_FSCALE_EXP))])
16412 (set (match_operand:DF 0 "register_operand" "")
16413 (float_truncate:DF (match_dup 10)))]
16414 "TARGET_USE_FANCY_MATH_387
16415 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16416 && flag_unsafe_math_optimizations"
16421 for (i=2; i<12; i++)
16422 operands[i] = gen_reg_rtx (XFmode);
16423 temp = standard_80387_constant_rtx (6); /* fldl2t */
16424 emit_move_insn (operands[3], temp);
16425 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16428 (define_expand "exp10xf2"
16429 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16431 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16432 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16433 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16434 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16435 (parallel [(set (match_operand:XF 0 "register_operand" "")
16436 (unspec:XF [(match_dup 8) (match_dup 4)]
16437 UNSPEC_FSCALE_FRACT))
16439 (unspec:XF [(match_dup 8) (match_dup 4)]
16440 UNSPEC_FSCALE_EXP))])]
16441 "TARGET_USE_FANCY_MATH_387
16442 && flag_unsafe_math_optimizations"
16447 for (i=2; i<10; i++)
16448 operands[i] = gen_reg_rtx (XFmode);
16449 temp = standard_80387_constant_rtx (6); /* fldl2t */
16450 emit_move_insn (operands[2], temp);
16451 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16454 (define_expand "exp2sf2"
16455 [(set (match_dup 2)
16456 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16457 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16458 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16459 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16460 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16461 (parallel [(set (match_dup 8)
16462 (unspec:XF [(match_dup 7) (match_dup 3)]
16463 UNSPEC_FSCALE_FRACT))
16465 (unspec:XF [(match_dup 7) (match_dup 3)]
16466 UNSPEC_FSCALE_EXP))])
16467 (set (match_operand:SF 0 "register_operand" "")
16468 (float_truncate:SF (match_dup 8)))]
16469 "TARGET_USE_FANCY_MATH_387
16470 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16471 && flag_unsafe_math_optimizations"
16475 for (i=2; i<10; i++)
16476 operands[i] = gen_reg_rtx (XFmode);
16477 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16480 (define_expand "exp2df2"
16481 [(set (match_dup 2)
16482 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16483 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16484 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16485 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16486 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16487 (parallel [(set (match_dup 8)
16488 (unspec:XF [(match_dup 7) (match_dup 3)]
16489 UNSPEC_FSCALE_FRACT))
16491 (unspec:XF [(match_dup 7) (match_dup 3)]
16492 UNSPEC_FSCALE_EXP))])
16493 (set (match_operand:DF 0 "register_operand" "")
16494 (float_truncate:DF (match_dup 8)))]
16495 "TARGET_USE_FANCY_MATH_387
16496 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16497 && flag_unsafe_math_optimizations"
16501 for (i=2; i<10; i++)
16502 operands[i] = gen_reg_rtx (XFmode);
16503 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16506 (define_expand "exp2xf2"
16507 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16508 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16509 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16510 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16511 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16512 (parallel [(set (match_operand:XF 0 "register_operand" "")
16513 (unspec:XF [(match_dup 7) (match_dup 3)]
16514 UNSPEC_FSCALE_FRACT))
16516 (unspec:XF [(match_dup 7) (match_dup 3)]
16517 UNSPEC_FSCALE_EXP))])]
16518 "TARGET_USE_FANCY_MATH_387
16519 && flag_unsafe_math_optimizations"
16523 for (i=2; i<9; i++)
16524 operands[i] = gen_reg_rtx (XFmode);
16525 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16528 (define_expand "expm1df2"
16529 [(set (match_dup 2)
16530 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16531 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16532 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16533 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16534 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16535 (parallel [(set (match_dup 8)
16536 (unspec:XF [(match_dup 7) (match_dup 5)]
16537 UNSPEC_FSCALE_FRACT))
16539 (unspec:XF [(match_dup 7) (match_dup 5)]
16540 UNSPEC_FSCALE_EXP))])
16541 (parallel [(set (match_dup 11)
16542 (unspec:XF [(match_dup 10) (match_dup 9)]
16543 UNSPEC_FSCALE_FRACT))
16544 (set (match_dup 12)
16545 (unspec:XF [(match_dup 10) (match_dup 9)]
16546 UNSPEC_FSCALE_EXP))])
16547 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16548 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16549 (set (match_operand:DF 0 "register_operand" "")
16550 (float_truncate:DF (match_dup 14)))]
16551 "TARGET_USE_FANCY_MATH_387
16552 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16553 && flag_unsafe_math_optimizations"
16558 for (i=2; i<15; i++)
16559 operands[i] = gen_reg_rtx (XFmode);
16560 temp = standard_80387_constant_rtx (5); /* fldl2e */
16561 emit_move_insn (operands[3], temp);
16562 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16565 (define_expand "expm1sf2"
16566 [(set (match_dup 2)
16567 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16568 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16569 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16570 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16571 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16572 (parallel [(set (match_dup 8)
16573 (unspec:XF [(match_dup 7) (match_dup 5)]
16574 UNSPEC_FSCALE_FRACT))
16576 (unspec:XF [(match_dup 7) (match_dup 5)]
16577 UNSPEC_FSCALE_EXP))])
16578 (parallel [(set (match_dup 11)
16579 (unspec:XF [(match_dup 10) (match_dup 9)]
16580 UNSPEC_FSCALE_FRACT))
16581 (set (match_dup 12)
16582 (unspec:XF [(match_dup 10) (match_dup 9)]
16583 UNSPEC_FSCALE_EXP))])
16584 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16585 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16586 (set (match_operand:SF 0 "register_operand" "")
16587 (float_truncate:SF (match_dup 14)))]
16588 "TARGET_USE_FANCY_MATH_387
16589 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16590 && flag_unsafe_math_optimizations"
16595 for (i=2; i<15; i++)
16596 operands[i] = gen_reg_rtx (XFmode);
16597 temp = standard_80387_constant_rtx (5); /* fldl2e */
16598 emit_move_insn (operands[3], temp);
16599 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16602 (define_expand "expm1xf2"
16603 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16605 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16606 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16607 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16608 (parallel [(set (match_dup 7)
16609 (unspec:XF [(match_dup 6) (match_dup 4)]
16610 UNSPEC_FSCALE_FRACT))
16612 (unspec:XF [(match_dup 6) (match_dup 4)]
16613 UNSPEC_FSCALE_EXP))])
16614 (parallel [(set (match_dup 10)
16615 (unspec:XF [(match_dup 9) (match_dup 8)]
16616 UNSPEC_FSCALE_FRACT))
16617 (set (match_dup 11)
16618 (unspec:XF [(match_dup 9) (match_dup 8)]
16619 UNSPEC_FSCALE_EXP))])
16620 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16621 (set (match_operand:XF 0 "register_operand" "")
16622 (plus:XF (match_dup 12) (match_dup 7)))]
16623 "TARGET_USE_FANCY_MATH_387
16624 && flag_unsafe_math_optimizations"
16629 for (i=2; i<13; i++)
16630 operands[i] = gen_reg_rtx (XFmode);
16631 temp = standard_80387_constant_rtx (5); /* fldl2e */
16632 emit_move_insn (operands[2], temp);
16633 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16636 (define_expand "ldexpdf3"
16637 [(set (match_dup 3)
16638 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16640 (float:XF (match_operand:SI 2 "register_operand" "")))
16641 (parallel [(set (match_dup 5)
16642 (unspec:XF [(match_dup 3) (match_dup 4)]
16643 UNSPEC_FSCALE_FRACT))
16645 (unspec:XF [(match_dup 3) (match_dup 4)]
16646 UNSPEC_FSCALE_EXP))])
16647 (set (match_operand:DF 0 "register_operand" "")
16648 (float_truncate:DF (match_dup 5)))]
16649 "TARGET_USE_FANCY_MATH_387
16650 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16651 && flag_unsafe_math_optimizations"
16655 for (i=3; i<7; i++)
16656 operands[i] = gen_reg_rtx (XFmode);
16659 (define_expand "ldexpsf3"
16660 [(set (match_dup 3)
16661 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16663 (float:XF (match_operand:SI 2 "register_operand" "")))
16664 (parallel [(set (match_dup 5)
16665 (unspec:XF [(match_dup 3) (match_dup 4)]
16666 UNSPEC_FSCALE_FRACT))
16668 (unspec:XF [(match_dup 3) (match_dup 4)]
16669 UNSPEC_FSCALE_EXP))])
16670 (set (match_operand:SF 0 "register_operand" "")
16671 (float_truncate:SF (match_dup 5)))]
16672 "TARGET_USE_FANCY_MATH_387
16673 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16674 && flag_unsafe_math_optimizations"
16678 for (i=3; i<7; i++)
16679 operands[i] = gen_reg_rtx (XFmode);
16682 (define_expand "ldexpxf3"
16683 [(set (match_dup 3)
16684 (float:XF (match_operand:SI 2 "register_operand" "")))
16685 (parallel [(set (match_operand:XF 0 " register_operand" "")
16686 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16688 UNSPEC_FSCALE_FRACT))
16690 (unspec:XF [(match_dup 1) (match_dup 3)]
16691 UNSPEC_FSCALE_EXP))])]
16692 "TARGET_USE_FANCY_MATH_387
16693 && flag_unsafe_math_optimizations"
16697 for (i=3; i<5; i++)
16698 operands[i] = gen_reg_rtx (XFmode);
16702 (define_insn "frndintxf2"
16703 [(set (match_operand:XF 0 "register_operand" "=f")
16704 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16706 "TARGET_USE_FANCY_MATH_387
16707 && flag_unsafe_math_optimizations"
16709 [(set_attr "type" "fpspc")
16710 (set_attr "mode" "XF")])
16712 (define_expand "rintdf2"
16713 [(use (match_operand:DF 0 "register_operand" ""))
16714 (use (match_operand:DF 1 "register_operand" ""))]
16715 "TARGET_USE_FANCY_MATH_387
16716 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16717 && flag_unsafe_math_optimizations"
16719 rtx op0 = gen_reg_rtx (XFmode);
16720 rtx op1 = gen_reg_rtx (XFmode);
16722 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16723 emit_insn (gen_frndintxf2 (op0, op1));
16725 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16729 (define_expand "rintsf2"
16730 [(use (match_operand:SF 0 "register_operand" ""))
16731 (use (match_operand:SF 1 "register_operand" ""))]
16732 "TARGET_USE_FANCY_MATH_387
16733 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16734 && flag_unsafe_math_optimizations"
16736 rtx op0 = gen_reg_rtx (XFmode);
16737 rtx op1 = gen_reg_rtx (XFmode);
16739 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16740 emit_insn (gen_frndintxf2 (op0, op1));
16742 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16746 (define_expand "rintxf2"
16747 [(use (match_operand:XF 0 "register_operand" ""))
16748 (use (match_operand:XF 1 "register_operand" ""))]
16749 "TARGET_USE_FANCY_MATH_387
16750 && flag_unsafe_math_optimizations"
16752 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16756 (define_insn_and_split "*fistdi2_1"
16757 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16758 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16760 "TARGET_USE_FANCY_MATH_387
16761 && flag_unsafe_math_optimizations
16762 && !(reload_completed || reload_in_progress)"
16767 if (memory_operand (operands[0], VOIDmode))
16768 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16771 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16772 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16777 [(set_attr "type" "fpspc")
16778 (set_attr "mode" "DI")])
16780 (define_insn "fistdi2"
16781 [(set (match_operand:DI 0 "memory_operand" "=m")
16782 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16784 (clobber (match_scratch:XF 2 "=&1f"))]
16785 "TARGET_USE_FANCY_MATH_387
16786 && flag_unsafe_math_optimizations"
16787 "* return output_fix_trunc (insn, operands, 0);"
16788 [(set_attr "type" "fpspc")
16789 (set_attr "mode" "DI")])
16791 (define_insn "fistdi2_with_temp"
16792 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16793 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16795 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16796 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16797 "TARGET_USE_FANCY_MATH_387
16798 && flag_unsafe_math_optimizations"
16800 [(set_attr "type" "fpspc")
16801 (set_attr "mode" "DI")])
16804 [(set (match_operand:DI 0 "register_operand" "")
16805 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16807 (clobber (match_operand:DI 2 "memory_operand" ""))
16808 (clobber (match_scratch 3 ""))]
16810 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16811 (clobber (match_dup 3))])
16812 (set (match_dup 0) (match_dup 2))]
16816 [(set (match_operand:DI 0 "memory_operand" "")
16817 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16819 (clobber (match_operand:DI 2 "memory_operand" ""))
16820 (clobber (match_scratch 3 ""))]
16822 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16823 (clobber (match_dup 3))])]
16826 (define_insn_and_split "*fist<mode>2_1"
16827 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16828 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16830 "TARGET_USE_FANCY_MATH_387
16831 && flag_unsafe_math_optimizations
16832 && !(reload_completed || reload_in_progress)"
16837 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16838 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16842 [(set_attr "type" "fpspc")
16843 (set_attr "mode" "<MODE>")])
16845 (define_insn "fist<mode>2"
16846 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16847 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16849 "TARGET_USE_FANCY_MATH_387
16850 && flag_unsafe_math_optimizations"
16851 "* return output_fix_trunc (insn, operands, 0);"
16852 [(set_attr "type" "fpspc")
16853 (set_attr "mode" "<MODE>")])
16855 (define_insn "fist<mode>2_with_temp"
16856 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16857 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16859 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16860 "TARGET_USE_FANCY_MATH_387
16861 && flag_unsafe_math_optimizations"
16863 [(set_attr "type" "fpspc")
16864 (set_attr "mode" "<MODE>")])
16867 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16868 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16870 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16872 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16874 (set (match_dup 0) (match_dup 2))]
16878 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16879 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16881 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16883 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16887 (define_expand "lrint<mode>2"
16888 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16889 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16891 "TARGET_USE_FANCY_MATH_387
16892 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16893 && flag_unsafe_math_optimizations"
16896 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16897 (define_insn_and_split "frndintxf2_floor"
16898 [(set (match_operand:XF 0 "register_operand" "=f")
16899 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16900 UNSPEC_FRNDINT_FLOOR))
16901 (clobber (reg:CC FLAGS_REG))]
16902 "TARGET_USE_FANCY_MATH_387
16903 && flag_unsafe_math_optimizations
16904 && !(reload_completed || reload_in_progress)"
16909 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16911 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16912 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16914 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16915 operands[2], operands[3]));
16918 [(set_attr "type" "frndint")
16919 (set_attr "i387_cw" "floor")
16920 (set_attr "mode" "XF")])
16922 (define_insn "frndintxf2_floor_i387"
16923 [(set (match_operand:XF 0 "register_operand" "=f")
16924 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16925 UNSPEC_FRNDINT_FLOOR))
16926 (use (match_operand:HI 2 "memory_operand" "m"))
16927 (use (match_operand:HI 3 "memory_operand" "m"))]
16928 "TARGET_USE_FANCY_MATH_387
16929 && flag_unsafe_math_optimizations"
16930 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16931 [(set_attr "type" "frndint")
16932 (set_attr "i387_cw" "floor")
16933 (set_attr "mode" "XF")])
16935 (define_expand "floorxf2"
16936 [(use (match_operand:XF 0 "register_operand" ""))
16937 (use (match_operand:XF 1 "register_operand" ""))]
16938 "TARGET_USE_FANCY_MATH_387
16939 && flag_unsafe_math_optimizations"
16941 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16945 (define_expand "floordf2"
16946 [(use (match_operand:DF 0 "register_operand" ""))
16947 (use (match_operand:DF 1 "register_operand" ""))]
16948 "TARGET_USE_FANCY_MATH_387
16949 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16950 && flag_unsafe_math_optimizations"
16952 rtx op0 = gen_reg_rtx (XFmode);
16953 rtx op1 = gen_reg_rtx (XFmode);
16955 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16956 emit_insn (gen_frndintxf2_floor (op0, op1));
16958 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16962 (define_expand "floorsf2"
16963 [(use (match_operand:SF 0 "register_operand" ""))
16964 (use (match_operand:SF 1 "register_operand" ""))]
16965 "TARGET_USE_FANCY_MATH_387
16966 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16967 && flag_unsafe_math_optimizations"
16969 rtx op0 = gen_reg_rtx (XFmode);
16970 rtx op1 = gen_reg_rtx (XFmode);
16972 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16973 emit_insn (gen_frndintxf2_floor (op0, op1));
16975 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16979 (define_insn_and_split "*fist<mode>2_floor_1"
16980 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16981 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16982 UNSPEC_FIST_FLOOR))
16983 (clobber (reg:CC FLAGS_REG))]
16984 "TARGET_USE_FANCY_MATH_387
16985 && flag_unsafe_math_optimizations
16986 && !(reload_completed || reload_in_progress)"
16991 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16993 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16994 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16995 if (memory_operand (operands[0], VOIDmode))
16996 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16997 operands[2], operands[3]));
17000 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17001 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17002 operands[2], operands[3],
17007 [(set_attr "type" "fistp")
17008 (set_attr "i387_cw" "floor")
17009 (set_attr "mode" "<MODE>")])
17011 (define_insn "fistdi2_floor"
17012 [(set (match_operand:DI 0 "memory_operand" "=m")
17013 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17014 UNSPEC_FIST_FLOOR))
17015 (use (match_operand:HI 2 "memory_operand" "m"))
17016 (use (match_operand:HI 3 "memory_operand" "m"))
17017 (clobber (match_scratch:XF 4 "=&1f"))]
17018 "TARGET_USE_FANCY_MATH_387
17019 && flag_unsafe_math_optimizations"
17020 "* return output_fix_trunc (insn, operands, 0);"
17021 [(set_attr "type" "fistp")
17022 (set_attr "i387_cw" "floor")
17023 (set_attr "mode" "DI")])
17025 (define_insn "fistdi2_floor_with_temp"
17026 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17027 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17028 UNSPEC_FIST_FLOOR))
17029 (use (match_operand:HI 2 "memory_operand" "m,m"))
17030 (use (match_operand:HI 3 "memory_operand" "m,m"))
17031 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17032 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17033 "TARGET_USE_FANCY_MATH_387
17034 && flag_unsafe_math_optimizations"
17036 [(set_attr "type" "fistp")
17037 (set_attr "i387_cw" "floor")
17038 (set_attr "mode" "DI")])
17041 [(set (match_operand:DI 0 "register_operand" "")
17042 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17043 UNSPEC_FIST_FLOOR))
17044 (use (match_operand:HI 2 "memory_operand" ""))
17045 (use (match_operand:HI 3 "memory_operand" ""))
17046 (clobber (match_operand:DI 4 "memory_operand" ""))
17047 (clobber (match_scratch 5 ""))]
17049 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17050 (use (match_dup 2))
17051 (use (match_dup 3))
17052 (clobber (match_dup 5))])
17053 (set (match_dup 0) (match_dup 4))]
17057 [(set (match_operand:DI 0 "memory_operand" "")
17058 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17059 UNSPEC_FIST_FLOOR))
17060 (use (match_operand:HI 2 "memory_operand" ""))
17061 (use (match_operand:HI 3 "memory_operand" ""))
17062 (clobber (match_operand:DI 4 "memory_operand" ""))
17063 (clobber (match_scratch 5 ""))]
17065 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17066 (use (match_dup 2))
17067 (use (match_dup 3))
17068 (clobber (match_dup 5))])]
17071 (define_insn "fist<mode>2_floor"
17072 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17073 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17074 UNSPEC_FIST_FLOOR))
17075 (use (match_operand:HI 2 "memory_operand" "m"))
17076 (use (match_operand:HI 3 "memory_operand" "m"))]
17077 "TARGET_USE_FANCY_MATH_387
17078 && flag_unsafe_math_optimizations"
17079 "* return output_fix_trunc (insn, operands, 0);"
17080 [(set_attr "type" "fistp")
17081 (set_attr "i387_cw" "floor")
17082 (set_attr "mode" "<MODE>")])
17084 (define_insn "fist<mode>2_floor_with_temp"
17085 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17086 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17087 UNSPEC_FIST_FLOOR))
17088 (use (match_operand:HI 2 "memory_operand" "m,m"))
17089 (use (match_operand:HI 3 "memory_operand" "m,m"))
17090 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17091 "TARGET_USE_FANCY_MATH_387
17092 && flag_unsafe_math_optimizations"
17094 [(set_attr "type" "fistp")
17095 (set_attr "i387_cw" "floor")
17096 (set_attr "mode" "<MODE>")])
17099 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17100 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17101 UNSPEC_FIST_FLOOR))
17102 (use (match_operand:HI 2 "memory_operand" ""))
17103 (use (match_operand:HI 3 "memory_operand" ""))
17104 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17106 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17107 UNSPEC_FIST_FLOOR))
17108 (use (match_dup 2))
17109 (use (match_dup 3))])
17110 (set (match_dup 0) (match_dup 4))]
17114 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17115 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17116 UNSPEC_FIST_FLOOR))
17117 (use (match_operand:HI 2 "memory_operand" ""))
17118 (use (match_operand:HI 3 "memory_operand" ""))
17119 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17121 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17122 UNSPEC_FIST_FLOOR))
17123 (use (match_dup 2))
17124 (use (match_dup 3))])]
17127 (define_expand "lfloor<mode>2"
17128 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17129 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17130 UNSPEC_FIST_FLOOR))
17131 (clobber (reg:CC FLAGS_REG))])]
17132 "TARGET_USE_FANCY_MATH_387
17133 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17134 && flag_unsafe_math_optimizations"
17137 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17138 (define_insn_and_split "frndintxf2_ceil"
17139 [(set (match_operand:XF 0 "register_operand" "=f")
17140 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17141 UNSPEC_FRNDINT_CEIL))
17142 (clobber (reg:CC FLAGS_REG))]
17143 "TARGET_USE_FANCY_MATH_387
17144 && flag_unsafe_math_optimizations
17145 && !(reload_completed || reload_in_progress)"
17150 ix86_optimize_mode_switching[I387_CEIL] = 1;
17152 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17153 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17155 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17156 operands[2], operands[3]));
17159 [(set_attr "type" "frndint")
17160 (set_attr "i387_cw" "ceil")
17161 (set_attr "mode" "XF")])
17163 (define_insn "frndintxf2_ceil_i387"
17164 [(set (match_operand:XF 0 "register_operand" "=f")
17165 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17166 UNSPEC_FRNDINT_CEIL))
17167 (use (match_operand:HI 2 "memory_operand" "m"))
17168 (use (match_operand:HI 3 "memory_operand" "m"))]
17169 "TARGET_USE_FANCY_MATH_387
17170 && flag_unsafe_math_optimizations"
17171 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17172 [(set_attr "type" "frndint")
17173 (set_attr "i387_cw" "ceil")
17174 (set_attr "mode" "XF")])
17176 (define_expand "ceilxf2"
17177 [(use (match_operand:XF 0 "register_operand" ""))
17178 (use (match_operand:XF 1 "register_operand" ""))]
17179 "TARGET_USE_FANCY_MATH_387
17180 && flag_unsafe_math_optimizations"
17182 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17186 (define_expand "ceildf2"
17187 [(use (match_operand:DF 0 "register_operand" ""))
17188 (use (match_operand:DF 1 "register_operand" ""))]
17189 "TARGET_USE_FANCY_MATH_387
17190 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17191 && flag_unsafe_math_optimizations"
17193 rtx op0 = gen_reg_rtx (XFmode);
17194 rtx op1 = gen_reg_rtx (XFmode);
17196 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17197 emit_insn (gen_frndintxf2_ceil (op0, op1));
17199 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17203 (define_expand "ceilsf2"
17204 [(use (match_operand:SF 0 "register_operand" ""))
17205 (use (match_operand:SF 1 "register_operand" ""))]
17206 "TARGET_USE_FANCY_MATH_387
17207 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17208 && flag_unsafe_math_optimizations"
17210 rtx op0 = gen_reg_rtx (XFmode);
17211 rtx op1 = gen_reg_rtx (XFmode);
17213 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17214 emit_insn (gen_frndintxf2_ceil (op0, op1));
17216 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17220 (define_insn_and_split "*fist<mode>2_ceil_1"
17221 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17222 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17224 (clobber (reg:CC FLAGS_REG))]
17225 "TARGET_USE_FANCY_MATH_387
17226 && flag_unsafe_math_optimizations
17227 && !(reload_completed || reload_in_progress)"
17232 ix86_optimize_mode_switching[I387_CEIL] = 1;
17234 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17235 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17236 if (memory_operand (operands[0], VOIDmode))
17237 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17238 operands[2], operands[3]));
17241 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17242 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17243 operands[2], operands[3],
17248 [(set_attr "type" "fistp")
17249 (set_attr "i387_cw" "ceil")
17250 (set_attr "mode" "<MODE>")])
17252 (define_insn "fistdi2_ceil"
17253 [(set (match_operand:DI 0 "memory_operand" "=m")
17254 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17256 (use (match_operand:HI 2 "memory_operand" "m"))
17257 (use (match_operand:HI 3 "memory_operand" "m"))
17258 (clobber (match_scratch:XF 4 "=&1f"))]
17259 "TARGET_USE_FANCY_MATH_387
17260 && flag_unsafe_math_optimizations"
17261 "* return output_fix_trunc (insn, operands, 0);"
17262 [(set_attr "type" "fistp")
17263 (set_attr "i387_cw" "ceil")
17264 (set_attr "mode" "DI")])
17266 (define_insn "fistdi2_ceil_with_temp"
17267 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17268 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17270 (use (match_operand:HI 2 "memory_operand" "m,m"))
17271 (use (match_operand:HI 3 "memory_operand" "m,m"))
17272 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17273 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17274 "TARGET_USE_FANCY_MATH_387
17275 && flag_unsafe_math_optimizations"
17277 [(set_attr "type" "fistp")
17278 (set_attr "i387_cw" "ceil")
17279 (set_attr "mode" "DI")])
17282 [(set (match_operand:DI 0 "register_operand" "")
17283 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17285 (use (match_operand:HI 2 "memory_operand" ""))
17286 (use (match_operand:HI 3 "memory_operand" ""))
17287 (clobber (match_operand:DI 4 "memory_operand" ""))
17288 (clobber (match_scratch 5 ""))]
17290 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17291 (use (match_dup 2))
17292 (use (match_dup 3))
17293 (clobber (match_dup 5))])
17294 (set (match_dup 0) (match_dup 4))]
17298 [(set (match_operand:DI 0 "memory_operand" "")
17299 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17301 (use (match_operand:HI 2 "memory_operand" ""))
17302 (use (match_operand:HI 3 "memory_operand" ""))
17303 (clobber (match_operand:DI 4 "memory_operand" ""))
17304 (clobber (match_scratch 5 ""))]
17306 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17307 (use (match_dup 2))
17308 (use (match_dup 3))
17309 (clobber (match_dup 5))])]
17312 (define_insn "fist<mode>2_ceil"
17313 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17314 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17316 (use (match_operand:HI 2 "memory_operand" "m"))
17317 (use (match_operand:HI 3 "memory_operand" "m"))]
17318 "TARGET_USE_FANCY_MATH_387
17319 && flag_unsafe_math_optimizations"
17320 "* return output_fix_trunc (insn, operands, 0);"
17321 [(set_attr "type" "fistp")
17322 (set_attr "i387_cw" "ceil")
17323 (set_attr "mode" "<MODE>")])
17325 (define_insn "fist<mode>2_ceil_with_temp"
17326 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17327 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17329 (use (match_operand:HI 2 "memory_operand" "m,m"))
17330 (use (match_operand:HI 3 "memory_operand" "m,m"))
17331 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17332 "TARGET_USE_FANCY_MATH_387
17333 && flag_unsafe_math_optimizations"
17335 [(set_attr "type" "fistp")
17336 (set_attr "i387_cw" "ceil")
17337 (set_attr "mode" "<MODE>")])
17340 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17341 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17343 (use (match_operand:HI 2 "memory_operand" ""))
17344 (use (match_operand:HI 3 "memory_operand" ""))
17345 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17347 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17349 (use (match_dup 2))
17350 (use (match_dup 3))])
17351 (set (match_dup 0) (match_dup 4))]
17355 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17356 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17358 (use (match_operand:HI 2 "memory_operand" ""))
17359 (use (match_operand:HI 3 "memory_operand" ""))
17360 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17362 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17364 (use (match_dup 2))
17365 (use (match_dup 3))])]
17368 (define_expand "lceil<mode>2"
17369 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17370 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17372 (clobber (reg:CC FLAGS_REG))])]
17373 "TARGET_USE_FANCY_MATH_387
17374 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17375 && flag_unsafe_math_optimizations"
17378 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17379 (define_insn_and_split "frndintxf2_trunc"
17380 [(set (match_operand:XF 0 "register_operand" "=f")
17381 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17382 UNSPEC_FRNDINT_TRUNC))
17383 (clobber (reg:CC FLAGS_REG))]
17384 "TARGET_USE_FANCY_MATH_387
17385 && flag_unsafe_math_optimizations
17386 && !(reload_completed || reload_in_progress)"
17391 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17393 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17394 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17396 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17397 operands[2], operands[3]));
17400 [(set_attr "type" "frndint")
17401 (set_attr "i387_cw" "trunc")
17402 (set_attr "mode" "XF")])
17404 (define_insn "frndintxf2_trunc_i387"
17405 [(set (match_operand:XF 0 "register_operand" "=f")
17406 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17407 UNSPEC_FRNDINT_TRUNC))
17408 (use (match_operand:HI 2 "memory_operand" "m"))
17409 (use (match_operand:HI 3 "memory_operand" "m"))]
17410 "TARGET_USE_FANCY_MATH_387
17411 && flag_unsafe_math_optimizations"
17412 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17413 [(set_attr "type" "frndint")
17414 (set_attr "i387_cw" "trunc")
17415 (set_attr "mode" "XF")])
17417 (define_expand "btruncxf2"
17418 [(use (match_operand:XF 0 "register_operand" ""))
17419 (use (match_operand:XF 1 "register_operand" ""))]
17420 "TARGET_USE_FANCY_MATH_387
17421 && flag_unsafe_math_optimizations"
17423 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17427 (define_expand "btruncdf2"
17428 [(use (match_operand:DF 0 "register_operand" ""))
17429 (use (match_operand:DF 1 "register_operand" ""))]
17430 "TARGET_USE_FANCY_MATH_387
17431 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17432 && flag_unsafe_math_optimizations"
17434 rtx op0 = gen_reg_rtx (XFmode);
17435 rtx op1 = gen_reg_rtx (XFmode);
17437 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17438 emit_insn (gen_frndintxf2_trunc (op0, op1));
17440 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17444 (define_expand "btruncsf2"
17445 [(use (match_operand:SF 0 "register_operand" ""))
17446 (use (match_operand:SF 1 "register_operand" ""))]
17447 "TARGET_USE_FANCY_MATH_387
17448 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17449 && flag_unsafe_math_optimizations"
17451 rtx op0 = gen_reg_rtx (XFmode);
17452 rtx op1 = gen_reg_rtx (XFmode);
17454 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17455 emit_insn (gen_frndintxf2_trunc (op0, op1));
17457 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17461 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17462 (define_insn_and_split "frndintxf2_mask_pm"
17463 [(set (match_operand:XF 0 "register_operand" "=f")
17464 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17465 UNSPEC_FRNDINT_MASK_PM))
17466 (clobber (reg:CC FLAGS_REG))]
17467 "TARGET_USE_FANCY_MATH_387
17468 && flag_unsafe_math_optimizations
17469 && !(reload_completed || reload_in_progress)"
17474 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17476 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17477 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17479 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17480 operands[2], operands[3]));
17483 [(set_attr "type" "frndint")
17484 (set_attr "i387_cw" "mask_pm")
17485 (set_attr "mode" "XF")])
17487 (define_insn "frndintxf2_mask_pm_i387"
17488 [(set (match_operand:XF 0 "register_operand" "=f")
17489 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17490 UNSPEC_FRNDINT_MASK_PM))
17491 (use (match_operand:HI 2 "memory_operand" "m"))
17492 (use (match_operand:HI 3 "memory_operand" "m"))]
17493 "TARGET_USE_FANCY_MATH_387
17494 && flag_unsafe_math_optimizations"
17495 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17496 [(set_attr "type" "frndint")
17497 (set_attr "i387_cw" "mask_pm")
17498 (set_attr "mode" "XF")])
17500 (define_expand "nearbyintxf2"
17501 [(use (match_operand:XF 0 "register_operand" ""))
17502 (use (match_operand:XF 1 "register_operand" ""))]
17503 "TARGET_USE_FANCY_MATH_387
17504 && flag_unsafe_math_optimizations"
17506 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17511 (define_expand "nearbyintdf2"
17512 [(use (match_operand:DF 0 "register_operand" ""))
17513 (use (match_operand:DF 1 "register_operand" ""))]
17514 "TARGET_USE_FANCY_MATH_387
17515 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17516 && flag_unsafe_math_optimizations"
17518 rtx op0 = gen_reg_rtx (XFmode);
17519 rtx op1 = gen_reg_rtx (XFmode);
17521 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17522 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17524 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17528 (define_expand "nearbyintsf2"
17529 [(use (match_operand:SF 0 "register_operand" ""))
17530 (use (match_operand:SF 1 "register_operand" ""))]
17531 "TARGET_USE_FANCY_MATH_387
17532 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17533 && flag_unsafe_math_optimizations"
17535 rtx op0 = gen_reg_rtx (XFmode);
17536 rtx op1 = gen_reg_rtx (XFmode);
17538 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17539 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17541 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17546 ;; Block operation instructions
17549 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17552 [(set_attr "type" "cld")])
17554 (define_expand "movmemsi"
17555 [(use (match_operand:BLK 0 "memory_operand" ""))
17556 (use (match_operand:BLK 1 "memory_operand" ""))
17557 (use (match_operand:SI 2 "nonmemory_operand" ""))
17558 (use (match_operand:SI 3 "const_int_operand" ""))]
17559 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17561 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17567 (define_expand "movmemdi"
17568 [(use (match_operand:BLK 0 "memory_operand" ""))
17569 (use (match_operand:BLK 1 "memory_operand" ""))
17570 (use (match_operand:DI 2 "nonmemory_operand" ""))
17571 (use (match_operand:DI 3 "const_int_operand" ""))]
17574 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17580 ;; Most CPUs don't like single string operations
17581 ;; Handle this case here to simplify previous expander.
17583 (define_expand "strmov"
17584 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17585 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17586 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17587 (clobber (reg:CC FLAGS_REG))])
17588 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17589 (clobber (reg:CC FLAGS_REG))])]
17592 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17594 /* If .md ever supports :P for Pmode, these can be directly
17595 in the pattern above. */
17596 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17597 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17599 if (TARGET_SINGLE_STRINGOP || optimize_size)
17601 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17602 operands[2], operands[3],
17603 operands[5], operands[6]));
17607 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17610 (define_expand "strmov_singleop"
17611 [(parallel [(set (match_operand 1 "memory_operand" "")
17612 (match_operand 3 "memory_operand" ""))
17613 (set (match_operand 0 "register_operand" "")
17614 (match_operand 4 "" ""))
17615 (set (match_operand 2 "register_operand" "")
17616 (match_operand 5 "" ""))
17617 (use (reg:SI DIRFLAG_REG))])]
17618 "TARGET_SINGLE_STRINGOP || optimize_size"
17621 (define_insn "*strmovdi_rex_1"
17622 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17623 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17624 (set (match_operand:DI 0 "register_operand" "=D")
17625 (plus:DI (match_dup 2)
17627 (set (match_operand:DI 1 "register_operand" "=S")
17628 (plus:DI (match_dup 3)
17630 (use (reg:SI DIRFLAG_REG))]
17631 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17633 [(set_attr "type" "str")
17634 (set_attr "mode" "DI")
17635 (set_attr "memory" "both")])
17637 (define_insn "*strmovsi_1"
17638 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17639 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17640 (set (match_operand:SI 0 "register_operand" "=D")
17641 (plus:SI (match_dup 2)
17643 (set (match_operand:SI 1 "register_operand" "=S")
17644 (plus:SI (match_dup 3)
17646 (use (reg:SI DIRFLAG_REG))]
17647 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17649 [(set_attr "type" "str")
17650 (set_attr "mode" "SI")
17651 (set_attr "memory" "both")])
17653 (define_insn "*strmovsi_rex_1"
17654 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17655 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17656 (set (match_operand:DI 0 "register_operand" "=D")
17657 (plus:DI (match_dup 2)
17659 (set (match_operand:DI 1 "register_operand" "=S")
17660 (plus:DI (match_dup 3)
17662 (use (reg:SI DIRFLAG_REG))]
17663 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17665 [(set_attr "type" "str")
17666 (set_attr "mode" "SI")
17667 (set_attr "memory" "both")])
17669 (define_insn "*strmovhi_1"
17670 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17671 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17672 (set (match_operand:SI 0 "register_operand" "=D")
17673 (plus:SI (match_dup 2)
17675 (set (match_operand:SI 1 "register_operand" "=S")
17676 (plus:SI (match_dup 3)
17678 (use (reg:SI DIRFLAG_REG))]
17679 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17681 [(set_attr "type" "str")
17682 (set_attr "memory" "both")
17683 (set_attr "mode" "HI")])
17685 (define_insn "*strmovhi_rex_1"
17686 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17687 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17688 (set (match_operand:DI 0 "register_operand" "=D")
17689 (plus:DI (match_dup 2)
17691 (set (match_operand:DI 1 "register_operand" "=S")
17692 (plus:DI (match_dup 3)
17694 (use (reg:SI DIRFLAG_REG))]
17695 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17697 [(set_attr "type" "str")
17698 (set_attr "memory" "both")
17699 (set_attr "mode" "HI")])
17701 (define_insn "*strmovqi_1"
17702 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17703 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17704 (set (match_operand:SI 0 "register_operand" "=D")
17705 (plus:SI (match_dup 2)
17707 (set (match_operand:SI 1 "register_operand" "=S")
17708 (plus:SI (match_dup 3)
17710 (use (reg:SI DIRFLAG_REG))]
17711 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17713 [(set_attr "type" "str")
17714 (set_attr "memory" "both")
17715 (set_attr "mode" "QI")])
17717 (define_insn "*strmovqi_rex_1"
17718 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17719 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17720 (set (match_operand:DI 0 "register_operand" "=D")
17721 (plus:DI (match_dup 2)
17723 (set (match_operand:DI 1 "register_operand" "=S")
17724 (plus:DI (match_dup 3)
17726 (use (reg:SI DIRFLAG_REG))]
17727 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17729 [(set_attr "type" "str")
17730 (set_attr "memory" "both")
17731 (set_attr "mode" "QI")])
17733 (define_expand "rep_mov"
17734 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17735 (set (match_operand 0 "register_operand" "")
17736 (match_operand 5 "" ""))
17737 (set (match_operand 2 "register_operand" "")
17738 (match_operand 6 "" ""))
17739 (set (match_operand 1 "memory_operand" "")
17740 (match_operand 3 "memory_operand" ""))
17741 (use (match_dup 4))
17742 (use (reg:SI DIRFLAG_REG))])]
17746 (define_insn "*rep_movdi_rex64"
17747 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17748 (set (match_operand:DI 0 "register_operand" "=D")
17749 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17751 (match_operand:DI 3 "register_operand" "0")))
17752 (set (match_operand:DI 1 "register_operand" "=S")
17753 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17754 (match_operand:DI 4 "register_operand" "1")))
17755 (set (mem:BLK (match_dup 3))
17756 (mem:BLK (match_dup 4)))
17757 (use (match_dup 5))
17758 (use (reg:SI DIRFLAG_REG))]
17760 "{rep\;movsq|rep movsq}"
17761 [(set_attr "type" "str")
17762 (set_attr "prefix_rep" "1")
17763 (set_attr "memory" "both")
17764 (set_attr "mode" "DI")])
17766 (define_insn "*rep_movsi"
17767 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17768 (set (match_operand:SI 0 "register_operand" "=D")
17769 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17771 (match_operand:SI 3 "register_operand" "0")))
17772 (set (match_operand:SI 1 "register_operand" "=S")
17773 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17774 (match_operand:SI 4 "register_operand" "1")))
17775 (set (mem:BLK (match_dup 3))
17776 (mem:BLK (match_dup 4)))
17777 (use (match_dup 5))
17778 (use (reg:SI DIRFLAG_REG))]
17780 "{rep\;movsl|rep movsd}"
17781 [(set_attr "type" "str")
17782 (set_attr "prefix_rep" "1")
17783 (set_attr "memory" "both")
17784 (set_attr "mode" "SI")])
17786 (define_insn "*rep_movsi_rex64"
17787 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17788 (set (match_operand:DI 0 "register_operand" "=D")
17789 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17791 (match_operand:DI 3 "register_operand" "0")))
17792 (set (match_operand:DI 1 "register_operand" "=S")
17793 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17794 (match_operand:DI 4 "register_operand" "1")))
17795 (set (mem:BLK (match_dup 3))
17796 (mem:BLK (match_dup 4)))
17797 (use (match_dup 5))
17798 (use (reg:SI DIRFLAG_REG))]
17800 "{rep\;movsl|rep movsd}"
17801 [(set_attr "type" "str")
17802 (set_attr "prefix_rep" "1")
17803 (set_attr "memory" "both")
17804 (set_attr "mode" "SI")])
17806 (define_insn "*rep_movqi"
17807 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17808 (set (match_operand:SI 0 "register_operand" "=D")
17809 (plus:SI (match_operand:SI 3 "register_operand" "0")
17810 (match_operand:SI 5 "register_operand" "2")))
17811 (set (match_operand:SI 1 "register_operand" "=S")
17812 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17813 (set (mem:BLK (match_dup 3))
17814 (mem:BLK (match_dup 4)))
17815 (use (match_dup 5))
17816 (use (reg:SI DIRFLAG_REG))]
17818 "{rep\;movsb|rep movsb}"
17819 [(set_attr "type" "str")
17820 (set_attr "prefix_rep" "1")
17821 (set_attr "memory" "both")
17822 (set_attr "mode" "SI")])
17824 (define_insn "*rep_movqi_rex64"
17825 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17826 (set (match_operand:DI 0 "register_operand" "=D")
17827 (plus:DI (match_operand:DI 3 "register_operand" "0")
17828 (match_operand:DI 5 "register_operand" "2")))
17829 (set (match_operand:DI 1 "register_operand" "=S")
17830 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17831 (set (mem:BLK (match_dup 3))
17832 (mem:BLK (match_dup 4)))
17833 (use (match_dup 5))
17834 (use (reg:SI DIRFLAG_REG))]
17836 "{rep\;movsb|rep movsb}"
17837 [(set_attr "type" "str")
17838 (set_attr "prefix_rep" "1")
17839 (set_attr "memory" "both")
17840 (set_attr "mode" "SI")])
17842 (define_expand "setmemsi"
17843 [(use (match_operand:BLK 0 "memory_operand" ""))
17844 (use (match_operand:SI 1 "nonmemory_operand" ""))
17845 (use (match_operand 2 "const_int_operand" ""))
17846 (use (match_operand 3 "const_int_operand" ""))]
17849 /* If value to set is not zero, use the library routine. */
17850 if (operands[2] != const0_rtx)
17853 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17859 (define_expand "setmemdi"
17860 [(use (match_operand:BLK 0 "memory_operand" ""))
17861 (use (match_operand:DI 1 "nonmemory_operand" ""))
17862 (use (match_operand 2 "const_int_operand" ""))
17863 (use (match_operand 3 "const_int_operand" ""))]
17866 /* If value to set is not zero, use the library routine. */
17867 if (operands[2] != const0_rtx)
17870 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17876 ;; Most CPUs don't like single string operations
17877 ;; Handle this case here to simplify previous expander.
17879 (define_expand "strset"
17880 [(set (match_operand 1 "memory_operand" "")
17881 (match_operand 2 "register_operand" ""))
17882 (parallel [(set (match_operand 0 "register_operand" "")
17884 (clobber (reg:CC FLAGS_REG))])]
17887 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17888 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17890 /* If .md ever supports :P for Pmode, this can be directly
17891 in the pattern above. */
17892 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17893 GEN_INT (GET_MODE_SIZE (GET_MODE
17895 if (TARGET_SINGLE_STRINGOP || optimize_size)
17897 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17903 (define_expand "strset_singleop"
17904 [(parallel [(set (match_operand 1 "memory_operand" "")
17905 (match_operand 2 "register_operand" ""))
17906 (set (match_operand 0 "register_operand" "")
17907 (match_operand 3 "" ""))
17908 (use (reg:SI DIRFLAG_REG))])]
17909 "TARGET_SINGLE_STRINGOP || optimize_size"
17912 (define_insn "*strsetdi_rex_1"
17913 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17914 (match_operand:DI 2 "register_operand" "a"))
17915 (set (match_operand:DI 0 "register_operand" "=D")
17916 (plus:DI (match_dup 1)
17918 (use (reg:SI DIRFLAG_REG))]
17919 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17921 [(set_attr "type" "str")
17922 (set_attr "memory" "store")
17923 (set_attr "mode" "DI")])
17925 (define_insn "*strsetsi_1"
17926 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17927 (match_operand:SI 2 "register_operand" "a"))
17928 (set (match_operand:SI 0 "register_operand" "=D")
17929 (plus:SI (match_dup 1)
17931 (use (reg:SI DIRFLAG_REG))]
17932 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17934 [(set_attr "type" "str")
17935 (set_attr "memory" "store")
17936 (set_attr "mode" "SI")])
17938 (define_insn "*strsetsi_rex_1"
17939 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17940 (match_operand:SI 2 "register_operand" "a"))
17941 (set (match_operand:DI 0 "register_operand" "=D")
17942 (plus:DI (match_dup 1)
17944 (use (reg:SI DIRFLAG_REG))]
17945 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17947 [(set_attr "type" "str")
17948 (set_attr "memory" "store")
17949 (set_attr "mode" "SI")])
17951 (define_insn "*strsethi_1"
17952 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17953 (match_operand:HI 2 "register_operand" "a"))
17954 (set (match_operand:SI 0 "register_operand" "=D")
17955 (plus:SI (match_dup 1)
17957 (use (reg:SI DIRFLAG_REG))]
17958 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17960 [(set_attr "type" "str")
17961 (set_attr "memory" "store")
17962 (set_attr "mode" "HI")])
17964 (define_insn "*strsethi_rex_1"
17965 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17966 (match_operand:HI 2 "register_operand" "a"))
17967 (set (match_operand:DI 0 "register_operand" "=D")
17968 (plus:DI (match_dup 1)
17970 (use (reg:SI DIRFLAG_REG))]
17971 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17973 [(set_attr "type" "str")
17974 (set_attr "memory" "store")
17975 (set_attr "mode" "HI")])
17977 (define_insn "*strsetqi_1"
17978 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17979 (match_operand:QI 2 "register_operand" "a"))
17980 (set (match_operand:SI 0 "register_operand" "=D")
17981 (plus:SI (match_dup 1)
17983 (use (reg:SI DIRFLAG_REG))]
17984 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17986 [(set_attr "type" "str")
17987 (set_attr "memory" "store")
17988 (set_attr "mode" "QI")])
17990 (define_insn "*strsetqi_rex_1"
17991 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17992 (match_operand:QI 2 "register_operand" "a"))
17993 (set (match_operand:DI 0 "register_operand" "=D")
17994 (plus:DI (match_dup 1)
17996 (use (reg:SI DIRFLAG_REG))]
17997 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17999 [(set_attr "type" "str")
18000 (set_attr "memory" "store")
18001 (set_attr "mode" "QI")])
18003 (define_expand "rep_stos"
18004 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18005 (set (match_operand 0 "register_operand" "")
18006 (match_operand 4 "" ""))
18007 (set (match_operand 2 "memory_operand" "") (const_int 0))
18008 (use (match_operand 3 "register_operand" ""))
18009 (use (match_dup 1))
18010 (use (reg:SI DIRFLAG_REG))])]
18014 (define_insn "*rep_stosdi_rex64"
18015 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18016 (set (match_operand:DI 0 "register_operand" "=D")
18017 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18019 (match_operand:DI 3 "register_operand" "0")))
18020 (set (mem:BLK (match_dup 3))
18022 (use (match_operand:DI 2 "register_operand" "a"))
18023 (use (match_dup 4))
18024 (use (reg:SI DIRFLAG_REG))]
18026 "{rep\;stosq|rep stosq}"
18027 [(set_attr "type" "str")
18028 (set_attr "prefix_rep" "1")
18029 (set_attr "memory" "store")
18030 (set_attr "mode" "DI")])
18032 (define_insn "*rep_stossi"
18033 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18034 (set (match_operand:SI 0 "register_operand" "=D")
18035 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18037 (match_operand:SI 3 "register_operand" "0")))
18038 (set (mem:BLK (match_dup 3))
18040 (use (match_operand:SI 2 "register_operand" "a"))
18041 (use (match_dup 4))
18042 (use (reg:SI DIRFLAG_REG))]
18044 "{rep\;stosl|rep stosd}"
18045 [(set_attr "type" "str")
18046 (set_attr "prefix_rep" "1")
18047 (set_attr "memory" "store")
18048 (set_attr "mode" "SI")])
18050 (define_insn "*rep_stossi_rex64"
18051 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18052 (set (match_operand:DI 0 "register_operand" "=D")
18053 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18055 (match_operand:DI 3 "register_operand" "0")))
18056 (set (mem:BLK (match_dup 3))
18058 (use (match_operand:SI 2 "register_operand" "a"))
18059 (use (match_dup 4))
18060 (use (reg:SI DIRFLAG_REG))]
18062 "{rep\;stosl|rep stosd}"
18063 [(set_attr "type" "str")
18064 (set_attr "prefix_rep" "1")
18065 (set_attr "memory" "store")
18066 (set_attr "mode" "SI")])
18068 (define_insn "*rep_stosqi"
18069 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18070 (set (match_operand:SI 0 "register_operand" "=D")
18071 (plus:SI (match_operand:SI 3 "register_operand" "0")
18072 (match_operand:SI 4 "register_operand" "1")))
18073 (set (mem:BLK (match_dup 3))
18075 (use (match_operand:QI 2 "register_operand" "a"))
18076 (use (match_dup 4))
18077 (use (reg:SI DIRFLAG_REG))]
18079 "{rep\;stosb|rep stosb}"
18080 [(set_attr "type" "str")
18081 (set_attr "prefix_rep" "1")
18082 (set_attr "memory" "store")
18083 (set_attr "mode" "QI")])
18085 (define_insn "*rep_stosqi_rex64"
18086 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18087 (set (match_operand:DI 0 "register_operand" "=D")
18088 (plus:DI (match_operand:DI 3 "register_operand" "0")
18089 (match_operand:DI 4 "register_operand" "1")))
18090 (set (mem:BLK (match_dup 3))
18092 (use (match_operand:QI 2 "register_operand" "a"))
18093 (use (match_dup 4))
18094 (use (reg:SI DIRFLAG_REG))]
18096 "{rep\;stosb|rep stosb}"
18097 [(set_attr "type" "str")
18098 (set_attr "prefix_rep" "1")
18099 (set_attr "memory" "store")
18100 (set_attr "mode" "QI")])
18102 (define_expand "cmpstrnsi"
18103 [(set (match_operand:SI 0 "register_operand" "")
18104 (compare:SI (match_operand:BLK 1 "general_operand" "")
18105 (match_operand:BLK 2 "general_operand" "")))
18106 (use (match_operand 3 "general_operand" ""))
18107 (use (match_operand 4 "immediate_operand" ""))]
18108 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18110 rtx addr1, addr2, out, outlow, count, countreg, align;
18112 /* Can't use this if the user has appropriated esi or edi. */
18113 if (global_regs[4] || global_regs[5])
18117 if (GET_CODE (out) != REG)
18118 out = gen_reg_rtx (SImode);
18120 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18121 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18122 if (addr1 != XEXP (operands[1], 0))
18123 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18124 if (addr2 != XEXP (operands[2], 0))
18125 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18127 count = operands[3];
18128 countreg = ix86_zero_extend_to_Pmode (count);
18130 /* %%% Iff we are testing strict equality, we can use known alignment
18131 to good advantage. This may be possible with combine, particularly
18132 once cc0 is dead. */
18133 align = operands[4];
18135 emit_insn (gen_cld ());
18136 if (GET_CODE (count) == CONST_INT)
18138 if (INTVAL (count) == 0)
18140 emit_move_insn (operands[0], const0_rtx);
18143 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18144 operands[1], operands[2]));
18149 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18151 emit_insn (gen_cmpsi_1 (countreg, countreg));
18152 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18153 operands[1], operands[2]));
18156 outlow = gen_lowpart (QImode, out);
18157 emit_insn (gen_cmpintqi (outlow));
18158 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18160 if (operands[0] != out)
18161 emit_move_insn (operands[0], out);
18166 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18168 (define_expand "cmpintqi"
18169 [(set (match_dup 1)
18170 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18172 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18173 (parallel [(set (match_operand:QI 0 "register_operand" "")
18174 (minus:QI (match_dup 1)
18176 (clobber (reg:CC FLAGS_REG))])]
18178 "operands[1] = gen_reg_rtx (QImode);
18179 operands[2] = gen_reg_rtx (QImode);")
18181 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18182 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18184 (define_expand "cmpstrnqi_nz_1"
18185 [(parallel [(set (reg:CC FLAGS_REG)
18186 (compare:CC (match_operand 4 "memory_operand" "")
18187 (match_operand 5 "memory_operand" "")))
18188 (use (match_operand 2 "register_operand" ""))
18189 (use (match_operand:SI 3 "immediate_operand" ""))
18190 (use (reg:SI DIRFLAG_REG))
18191 (clobber (match_operand 0 "register_operand" ""))
18192 (clobber (match_operand 1 "register_operand" ""))
18193 (clobber (match_dup 2))])]
18197 (define_insn "*cmpstrnqi_nz_1"
18198 [(set (reg:CC FLAGS_REG)
18199 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18200 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18201 (use (match_operand:SI 6 "register_operand" "2"))
18202 (use (match_operand:SI 3 "immediate_operand" "i"))
18203 (use (reg:SI DIRFLAG_REG))
18204 (clobber (match_operand:SI 0 "register_operand" "=S"))
18205 (clobber (match_operand:SI 1 "register_operand" "=D"))
18206 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18209 [(set_attr "type" "str")
18210 (set_attr "mode" "QI")
18211 (set_attr "prefix_rep" "1")])
18213 (define_insn "*cmpstrnqi_nz_rex_1"
18214 [(set (reg:CC FLAGS_REG)
18215 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18216 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18217 (use (match_operand:DI 6 "register_operand" "2"))
18218 (use (match_operand:SI 3 "immediate_operand" "i"))
18219 (use (reg:SI DIRFLAG_REG))
18220 (clobber (match_operand:DI 0 "register_operand" "=S"))
18221 (clobber (match_operand:DI 1 "register_operand" "=D"))
18222 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18225 [(set_attr "type" "str")
18226 (set_attr "mode" "QI")
18227 (set_attr "prefix_rep" "1")])
18229 ;; The same, but the count is not known to not be zero.
18231 (define_expand "cmpstrnqi_1"
18232 [(parallel [(set (reg:CC FLAGS_REG)
18233 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18235 (compare:CC (match_operand 4 "memory_operand" "")
18236 (match_operand 5 "memory_operand" ""))
18238 (use (match_operand:SI 3 "immediate_operand" ""))
18239 (use (reg:CC FLAGS_REG))
18240 (use (reg:SI DIRFLAG_REG))
18241 (clobber (match_operand 0 "register_operand" ""))
18242 (clobber (match_operand 1 "register_operand" ""))
18243 (clobber (match_dup 2))])]
18247 (define_insn "*cmpstrnqi_1"
18248 [(set (reg:CC FLAGS_REG)
18249 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18251 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18252 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18254 (use (match_operand:SI 3 "immediate_operand" "i"))
18255 (use (reg:CC FLAGS_REG))
18256 (use (reg:SI DIRFLAG_REG))
18257 (clobber (match_operand:SI 0 "register_operand" "=S"))
18258 (clobber (match_operand:SI 1 "register_operand" "=D"))
18259 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18262 [(set_attr "type" "str")
18263 (set_attr "mode" "QI")
18264 (set_attr "prefix_rep" "1")])
18266 (define_insn "*cmpstrnqi_rex_1"
18267 [(set (reg:CC FLAGS_REG)
18268 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18270 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18271 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18273 (use (match_operand:SI 3 "immediate_operand" "i"))
18274 (use (reg:CC FLAGS_REG))
18275 (use (reg:SI DIRFLAG_REG))
18276 (clobber (match_operand:DI 0 "register_operand" "=S"))
18277 (clobber (match_operand:DI 1 "register_operand" "=D"))
18278 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18281 [(set_attr "type" "str")
18282 (set_attr "mode" "QI")
18283 (set_attr "prefix_rep" "1")])
18285 (define_expand "strlensi"
18286 [(set (match_operand:SI 0 "register_operand" "")
18287 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18288 (match_operand:QI 2 "immediate_operand" "")
18289 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18292 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18298 (define_expand "strlendi"
18299 [(set (match_operand:DI 0 "register_operand" "")
18300 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18301 (match_operand:QI 2 "immediate_operand" "")
18302 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18305 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18311 (define_expand "strlenqi_1"
18312 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18313 (use (reg:SI DIRFLAG_REG))
18314 (clobber (match_operand 1 "register_operand" ""))
18315 (clobber (reg:CC FLAGS_REG))])]
18319 (define_insn "*strlenqi_1"
18320 [(set (match_operand:SI 0 "register_operand" "=&c")
18321 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18322 (match_operand:QI 2 "register_operand" "a")
18323 (match_operand:SI 3 "immediate_operand" "i")
18324 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18325 (use (reg:SI DIRFLAG_REG))
18326 (clobber (match_operand:SI 1 "register_operand" "=D"))
18327 (clobber (reg:CC FLAGS_REG))]
18330 [(set_attr "type" "str")
18331 (set_attr "mode" "QI")
18332 (set_attr "prefix_rep" "1")])
18334 (define_insn "*strlenqi_rex_1"
18335 [(set (match_operand:DI 0 "register_operand" "=&c")
18336 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18337 (match_operand:QI 2 "register_operand" "a")
18338 (match_operand:DI 3 "immediate_operand" "i")
18339 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18340 (use (reg:SI DIRFLAG_REG))
18341 (clobber (match_operand:DI 1 "register_operand" "=D"))
18342 (clobber (reg:CC FLAGS_REG))]
18345 [(set_attr "type" "str")
18346 (set_attr "mode" "QI")
18347 (set_attr "prefix_rep" "1")])
18349 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18350 ;; handled in combine, but it is not currently up to the task.
18351 ;; When used for their truth value, the cmpstrn* expanders generate
18360 ;; The intermediate three instructions are unnecessary.
18362 ;; This one handles cmpstrn*_nz_1...
18365 (set (reg:CC FLAGS_REG)
18366 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18367 (mem:BLK (match_operand 5 "register_operand" ""))))
18368 (use (match_operand 6 "register_operand" ""))
18369 (use (match_operand:SI 3 "immediate_operand" ""))
18370 (use (reg:SI DIRFLAG_REG))
18371 (clobber (match_operand 0 "register_operand" ""))
18372 (clobber (match_operand 1 "register_operand" ""))
18373 (clobber (match_operand 2 "register_operand" ""))])
18374 (set (match_operand:QI 7 "register_operand" "")
18375 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18376 (set (match_operand:QI 8 "register_operand" "")
18377 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18378 (set (reg FLAGS_REG)
18379 (compare (match_dup 7) (match_dup 8)))
18381 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18383 (set (reg:CC FLAGS_REG)
18384 (compare:CC (mem:BLK (match_dup 4))
18385 (mem:BLK (match_dup 5))))
18386 (use (match_dup 6))
18387 (use (match_dup 3))
18388 (use (reg:SI DIRFLAG_REG))
18389 (clobber (match_dup 0))
18390 (clobber (match_dup 1))
18391 (clobber (match_dup 2))])]
18394 ;; ...and this one handles cmpstrn*_1.
18397 (set (reg:CC FLAGS_REG)
18398 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18400 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18401 (mem:BLK (match_operand 5 "register_operand" "")))
18403 (use (match_operand:SI 3 "immediate_operand" ""))
18404 (use (reg:CC FLAGS_REG))
18405 (use (reg:SI DIRFLAG_REG))
18406 (clobber (match_operand 0 "register_operand" ""))
18407 (clobber (match_operand 1 "register_operand" ""))
18408 (clobber (match_operand 2 "register_operand" ""))])
18409 (set (match_operand:QI 7 "register_operand" "")
18410 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18411 (set (match_operand:QI 8 "register_operand" "")
18412 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18413 (set (reg FLAGS_REG)
18414 (compare (match_dup 7) (match_dup 8)))
18416 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18418 (set (reg:CC FLAGS_REG)
18419 (if_then_else:CC (ne (match_dup 6)
18421 (compare:CC (mem:BLK (match_dup 4))
18422 (mem:BLK (match_dup 5)))
18424 (use (match_dup 3))
18425 (use (reg:CC FLAGS_REG))
18426 (use (reg:SI DIRFLAG_REG))
18427 (clobber (match_dup 0))
18428 (clobber (match_dup 1))
18429 (clobber (match_dup 2))])]
18434 ;; Conditional move instructions.
18436 (define_expand "movdicc"
18437 [(set (match_operand:DI 0 "register_operand" "")
18438 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18439 (match_operand:DI 2 "general_operand" "")
18440 (match_operand:DI 3 "general_operand" "")))]
18442 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18444 (define_insn "x86_movdicc_0_m1_rex64"
18445 [(set (match_operand:DI 0 "register_operand" "=r")
18446 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18449 (clobber (reg:CC FLAGS_REG))]
18452 ; Since we don't have the proper number of operands for an alu insn,
18453 ; fill in all the blanks.
18454 [(set_attr "type" "alu")
18455 (set_attr "pent_pair" "pu")
18456 (set_attr "memory" "none")
18457 (set_attr "imm_disp" "false")
18458 (set_attr "mode" "DI")
18459 (set_attr "length_immediate" "0")])
18461 (define_insn "*movdicc_c_rex64"
18462 [(set (match_operand:DI 0 "register_operand" "=r,r")
18463 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18464 [(reg FLAGS_REG) (const_int 0)])
18465 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18466 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18467 "TARGET_64BIT && TARGET_CMOVE
18468 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18470 cmov%O2%C1\t{%2, %0|%0, %2}
18471 cmov%O2%c1\t{%3, %0|%0, %3}"
18472 [(set_attr "type" "icmov")
18473 (set_attr "mode" "DI")])
18475 (define_expand "movsicc"
18476 [(set (match_operand:SI 0 "register_operand" "")
18477 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18478 (match_operand:SI 2 "general_operand" "")
18479 (match_operand:SI 3 "general_operand" "")))]
18481 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18483 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18484 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18485 ;; So just document what we're doing explicitly.
18487 (define_insn "x86_movsicc_0_m1"
18488 [(set (match_operand:SI 0 "register_operand" "=r")
18489 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18492 (clobber (reg:CC FLAGS_REG))]
18495 ; Since we don't have the proper number of operands for an alu insn,
18496 ; fill in all the blanks.
18497 [(set_attr "type" "alu")
18498 (set_attr "pent_pair" "pu")
18499 (set_attr "memory" "none")
18500 (set_attr "imm_disp" "false")
18501 (set_attr "mode" "SI")
18502 (set_attr "length_immediate" "0")])
18504 (define_insn "*movsicc_noc"
18505 [(set (match_operand:SI 0 "register_operand" "=r,r")
18506 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18507 [(reg FLAGS_REG) (const_int 0)])
18508 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18509 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18511 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18513 cmov%O2%C1\t{%2, %0|%0, %2}
18514 cmov%O2%c1\t{%3, %0|%0, %3}"
18515 [(set_attr "type" "icmov")
18516 (set_attr "mode" "SI")])
18518 (define_expand "movhicc"
18519 [(set (match_operand:HI 0 "register_operand" "")
18520 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18521 (match_operand:HI 2 "general_operand" "")
18522 (match_operand:HI 3 "general_operand" "")))]
18523 "TARGET_HIMODE_MATH"
18524 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18526 (define_insn "*movhicc_noc"
18527 [(set (match_operand:HI 0 "register_operand" "=r,r")
18528 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18529 [(reg FLAGS_REG) (const_int 0)])
18530 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18531 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18533 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18535 cmov%O2%C1\t{%2, %0|%0, %2}
18536 cmov%O2%c1\t{%3, %0|%0, %3}"
18537 [(set_attr "type" "icmov")
18538 (set_attr "mode" "HI")])
18540 (define_expand "movqicc"
18541 [(set (match_operand:QI 0 "register_operand" "")
18542 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18543 (match_operand:QI 2 "general_operand" "")
18544 (match_operand:QI 3 "general_operand" "")))]
18545 "TARGET_QIMODE_MATH"
18546 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18548 (define_insn_and_split "*movqicc_noc"
18549 [(set (match_operand:QI 0 "register_operand" "=r,r")
18550 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18551 [(match_operand 4 "flags_reg_operand" "")
18553 (match_operand:QI 2 "register_operand" "r,0")
18554 (match_operand:QI 3 "register_operand" "0,r")))]
18555 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18557 "&& reload_completed"
18558 [(set (match_dup 0)
18559 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18562 "operands[0] = gen_lowpart (SImode, operands[0]);
18563 operands[2] = gen_lowpart (SImode, operands[2]);
18564 operands[3] = gen_lowpart (SImode, operands[3]);"
18565 [(set_attr "type" "icmov")
18566 (set_attr "mode" "SI")])
18568 (define_expand "movsfcc"
18569 [(set (match_operand:SF 0 "register_operand" "")
18570 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18571 (match_operand:SF 2 "register_operand" "")
18572 (match_operand:SF 3 "register_operand" "")))]
18573 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18574 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18576 (define_insn "*movsfcc_1_387"
18577 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18578 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18579 [(reg FLAGS_REG) (const_int 0)])
18580 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18581 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18582 "TARGET_80387 && TARGET_CMOVE
18583 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18585 fcmov%F1\t{%2, %0|%0, %2}
18586 fcmov%f1\t{%3, %0|%0, %3}
18587 cmov%O2%C1\t{%2, %0|%0, %2}
18588 cmov%O2%c1\t{%3, %0|%0, %3}"
18589 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18590 (set_attr "mode" "SF,SF,SI,SI")])
18592 (define_expand "movdfcc"
18593 [(set (match_operand:DF 0 "register_operand" "")
18594 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18595 (match_operand:DF 2 "register_operand" "")
18596 (match_operand:DF 3 "register_operand" "")))]
18597 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18598 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18600 (define_insn "*movdfcc_1"
18601 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18602 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18603 [(reg FLAGS_REG) (const_int 0)])
18604 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18605 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18606 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18607 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18609 fcmov%F1\t{%2, %0|%0, %2}
18610 fcmov%f1\t{%3, %0|%0, %3}
18613 [(set_attr "type" "fcmov,fcmov,multi,multi")
18614 (set_attr "mode" "DF")])
18616 (define_insn "*movdfcc_1_rex64"
18617 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18618 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18619 [(reg FLAGS_REG) (const_int 0)])
18620 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18621 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18622 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18623 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18625 fcmov%F1\t{%2, %0|%0, %2}
18626 fcmov%f1\t{%3, %0|%0, %3}
18627 cmov%O2%C1\t{%2, %0|%0, %2}
18628 cmov%O2%c1\t{%3, %0|%0, %3}"
18629 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18630 (set_attr "mode" "DF")])
18633 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18634 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18635 [(match_operand 4 "flags_reg_operand" "")
18637 (match_operand:DF 2 "nonimmediate_operand" "")
18638 (match_operand:DF 3 "nonimmediate_operand" "")))]
18639 "!TARGET_64BIT && reload_completed"
18640 [(set (match_dup 2)
18641 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18645 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18648 "split_di (operands+2, 1, operands+5, operands+6);
18649 split_di (operands+3, 1, operands+7, operands+8);
18650 split_di (operands, 1, operands+2, operands+3);")
18652 (define_expand "movxfcc"
18653 [(set (match_operand:XF 0 "register_operand" "")
18654 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18655 (match_operand:XF 2 "register_operand" "")
18656 (match_operand:XF 3 "register_operand" "")))]
18657 "TARGET_80387 && TARGET_CMOVE"
18658 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18660 (define_insn "*movxfcc_1"
18661 [(set (match_operand:XF 0 "register_operand" "=f,f")
18662 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18663 [(reg FLAGS_REG) (const_int 0)])
18664 (match_operand:XF 2 "register_operand" "f,0")
18665 (match_operand:XF 3 "register_operand" "0,f")))]
18666 "TARGET_80387 && TARGET_CMOVE"
18668 fcmov%F1\t{%2, %0|%0, %2}
18669 fcmov%f1\t{%3, %0|%0, %3}"
18670 [(set_attr "type" "fcmov")
18671 (set_attr "mode" "XF")])
18673 ;; These versions of the min/max patterns are intentionally ignorant of
18674 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18675 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18676 ;; are undefined in this condition, we're certain this is correct.
18678 (define_insn "sminsf3"
18679 [(set (match_operand:SF 0 "register_operand" "=x")
18680 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18681 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18683 "minss\t{%2, %0|%0, %2}"
18684 [(set_attr "type" "sseadd")
18685 (set_attr "mode" "SF")])
18687 (define_insn "smaxsf3"
18688 [(set (match_operand:SF 0 "register_operand" "=x")
18689 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18690 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18692 "maxss\t{%2, %0|%0, %2}"
18693 [(set_attr "type" "sseadd")
18694 (set_attr "mode" "SF")])
18696 (define_insn "smindf3"
18697 [(set (match_operand:DF 0 "register_operand" "=x")
18698 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18699 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18700 "TARGET_SSE2 && TARGET_SSE_MATH"
18701 "minsd\t{%2, %0|%0, %2}"
18702 [(set_attr "type" "sseadd")
18703 (set_attr "mode" "DF")])
18705 (define_insn "smaxdf3"
18706 [(set (match_operand:DF 0 "register_operand" "=x")
18707 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18708 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18709 "TARGET_SSE2 && TARGET_SSE_MATH"
18710 "maxsd\t{%2, %0|%0, %2}"
18711 [(set_attr "type" "sseadd")
18712 (set_attr "mode" "DF")])
18714 ;; These versions of the min/max patterns implement exactly the operations
18715 ;; min = (op1 < op2 ? op1 : op2)
18716 ;; max = (!(op1 < op2) ? op1 : op2)
18717 ;; Their operands are not commutative, and thus they may be used in the
18718 ;; presence of -0.0 and NaN.
18720 (define_insn "*ieee_sminsf3"
18721 [(set (match_operand:SF 0 "register_operand" "=x")
18722 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18723 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18726 "minss\t{%2, %0|%0, %2}"
18727 [(set_attr "type" "sseadd")
18728 (set_attr "mode" "SF")])
18730 (define_insn "*ieee_smaxsf3"
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 "maxss\t{%2, %0|%0, %2}"
18737 [(set_attr "type" "sseadd")
18738 (set_attr "mode" "SF")])
18740 (define_insn "*ieee_smindf3"
18741 [(set (match_operand:DF 0 "register_operand" "=x")
18742 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18743 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18745 "TARGET_SSE2 && TARGET_SSE_MATH"
18746 "minsd\t{%2, %0|%0, %2}"
18747 [(set_attr "type" "sseadd")
18748 (set_attr "mode" "DF")])
18750 (define_insn "*ieee_smaxdf3"
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 "maxsd\t{%2, %0|%0, %2}"
18757 [(set_attr "type" "sseadd")
18758 (set_attr "mode" "DF")])
18760 ;; Make two stack loads independent:
18762 ;; fld %st(0) -> fld bb
18763 ;; fmul bb fmul %st(1), %st
18765 ;; Actually we only match the last two instructions for simplicity.
18767 [(set (match_operand 0 "fp_register_operand" "")
18768 (match_operand 1 "fp_register_operand" ""))
18770 (match_operator 2 "binary_fp_operator"
18772 (match_operand 3 "memory_operand" "")]))]
18773 "REGNO (operands[0]) != REGNO (operands[1])"
18774 [(set (match_dup 0) (match_dup 3))
18775 (set (match_dup 0) (match_dup 4))]
18777 ;; The % modifier is not operational anymore in peephole2's, so we have to
18778 ;; swap the operands manually in the case of addition and multiplication.
18779 "if (COMMUTATIVE_ARITH_P (operands[2]))
18780 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18781 operands[0], operands[1]);
18783 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18784 operands[1], operands[0]);")
18786 ;; Conditional addition patterns
18787 (define_expand "addqicc"
18788 [(match_operand:QI 0 "register_operand" "")
18789 (match_operand 1 "comparison_operator" "")
18790 (match_operand:QI 2 "register_operand" "")
18791 (match_operand:QI 3 "const_int_operand" "")]
18793 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18795 (define_expand "addhicc"
18796 [(match_operand:HI 0 "register_operand" "")
18797 (match_operand 1 "comparison_operator" "")
18798 (match_operand:HI 2 "register_operand" "")
18799 (match_operand:HI 3 "const_int_operand" "")]
18801 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18803 (define_expand "addsicc"
18804 [(match_operand:SI 0 "register_operand" "")
18805 (match_operand 1 "comparison_operator" "")
18806 (match_operand:SI 2 "register_operand" "")
18807 (match_operand:SI 3 "const_int_operand" "")]
18809 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18811 (define_expand "adddicc"
18812 [(match_operand:DI 0 "register_operand" "")
18813 (match_operand 1 "comparison_operator" "")
18814 (match_operand:DI 2 "register_operand" "")
18815 (match_operand:DI 3 "const_int_operand" "")]
18817 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18820 ;; Misc patterns (?)
18822 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18823 ;; Otherwise there will be nothing to keep
18825 ;; [(set (reg ebp) (reg esp))]
18826 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18827 ;; (clobber (eflags)]
18828 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18830 ;; in proper program order.
18831 (define_insn "pro_epilogue_adjust_stack_1"
18832 [(set (match_operand:SI 0 "register_operand" "=r,r")
18833 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18834 (match_operand:SI 2 "immediate_operand" "i,i")))
18835 (clobber (reg:CC FLAGS_REG))
18836 (clobber (mem:BLK (scratch)))]
18839 switch (get_attr_type (insn))
18842 return "mov{l}\t{%1, %0|%0, %1}";
18845 if (GET_CODE (operands[2]) == CONST_INT
18846 && (INTVAL (operands[2]) == 128
18847 || (INTVAL (operands[2]) < 0
18848 && INTVAL (operands[2]) != -128)))
18850 operands[2] = GEN_INT (-INTVAL (operands[2]));
18851 return "sub{l}\t{%2, %0|%0, %2}";
18853 return "add{l}\t{%2, %0|%0, %2}";
18856 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18857 return "lea{l}\t{%a2, %0|%0, %a2}";
18860 gcc_unreachable ();
18863 [(set (attr "type")
18864 (cond [(eq_attr "alternative" "0")
18865 (const_string "alu")
18866 (match_operand:SI 2 "const0_operand" "")
18867 (const_string "imov")
18869 (const_string "lea")))
18870 (set_attr "mode" "SI")])
18872 (define_insn "pro_epilogue_adjust_stack_rex64"
18873 [(set (match_operand:DI 0 "register_operand" "=r,r")
18874 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18875 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18876 (clobber (reg:CC FLAGS_REG))
18877 (clobber (mem:BLK (scratch)))]
18880 switch (get_attr_type (insn))
18883 return "mov{q}\t{%1, %0|%0, %1}";
18886 if (GET_CODE (operands[2]) == CONST_INT
18887 /* Avoid overflows. */
18888 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18889 && (INTVAL (operands[2]) == 128
18890 || (INTVAL (operands[2]) < 0
18891 && INTVAL (operands[2]) != -128)))
18893 operands[2] = GEN_INT (-INTVAL (operands[2]));
18894 return "sub{q}\t{%2, %0|%0, %2}";
18896 return "add{q}\t{%2, %0|%0, %2}";
18899 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18900 return "lea{q}\t{%a2, %0|%0, %a2}";
18903 gcc_unreachable ();
18906 [(set (attr "type")
18907 (cond [(eq_attr "alternative" "0")
18908 (const_string "alu")
18909 (match_operand:DI 2 "const0_operand" "")
18910 (const_string "imov")
18912 (const_string "lea")))
18913 (set_attr "mode" "DI")])
18915 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18916 [(set (match_operand:DI 0 "register_operand" "=r,r")
18917 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18918 (match_operand:DI 3 "immediate_operand" "i,i")))
18919 (use (match_operand:DI 2 "register_operand" "r,r"))
18920 (clobber (reg:CC FLAGS_REG))
18921 (clobber (mem:BLK (scratch)))]
18924 switch (get_attr_type (insn))
18927 return "add{q}\t{%2, %0|%0, %2}";
18930 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18931 return "lea{q}\t{%a2, %0|%0, %a2}";
18934 gcc_unreachable ();
18937 [(set_attr "type" "alu,lea")
18938 (set_attr "mode" "DI")])
18940 (define_expand "allocate_stack_worker"
18941 [(match_operand:SI 0 "register_operand" "")]
18942 "TARGET_STACK_PROBE"
18944 if (reload_completed)
18947 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18949 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18954 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18956 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18961 (define_insn "allocate_stack_worker_1"
18962 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18963 UNSPECV_STACK_PROBE)
18964 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18965 (clobber (match_scratch:SI 1 "=0"))
18966 (clobber (reg:CC FLAGS_REG))]
18967 "!TARGET_64BIT && TARGET_STACK_PROBE"
18969 [(set_attr "type" "multi")
18970 (set_attr "length" "5")])
18972 (define_expand "allocate_stack_worker_postreload"
18973 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18974 UNSPECV_STACK_PROBE)
18975 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18976 (clobber (match_dup 0))
18977 (clobber (reg:CC FLAGS_REG))])]
18981 (define_insn "allocate_stack_worker_rex64"
18982 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18983 UNSPECV_STACK_PROBE)
18984 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18985 (clobber (match_scratch:DI 1 "=0"))
18986 (clobber (reg:CC FLAGS_REG))]
18987 "TARGET_64BIT && TARGET_STACK_PROBE"
18989 [(set_attr "type" "multi")
18990 (set_attr "length" "5")])
18992 (define_expand "allocate_stack_worker_rex64_postreload"
18993 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18994 UNSPECV_STACK_PROBE)
18995 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18996 (clobber (match_dup 0))
18997 (clobber (reg:CC FLAGS_REG))])]
19001 (define_expand "allocate_stack"
19002 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19003 (minus:SI (reg:SI SP_REG)
19004 (match_operand:SI 1 "general_operand" "")))
19005 (clobber (reg:CC FLAGS_REG))])
19006 (parallel [(set (reg:SI SP_REG)
19007 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19008 (clobber (reg:CC FLAGS_REG))])]
19009 "TARGET_STACK_PROBE"
19011 #ifdef CHECK_STACK_LIMIT
19012 if (GET_CODE (operands[1]) == CONST_INT
19013 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19014 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19018 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19021 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19025 (define_expand "builtin_setjmp_receiver"
19026 [(label_ref (match_operand 0 "" ""))]
19027 "!TARGET_64BIT && flag_pic"
19032 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19033 rtx label_rtx = gen_label_rtx ();
19034 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19035 xops[0] = xops[1] = picreg;
19036 xops[2] = gen_rtx_CONST (SImode,
19037 gen_rtx_MINUS (SImode,
19038 gen_rtx_LABEL_REF (SImode, label_rtx),
19039 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19040 ix86_expand_binary_operator (MINUS, SImode, xops);
19043 emit_insn (gen_set_got (pic_offset_table_rtx));
19047 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19050 [(set (match_operand 0 "register_operand" "")
19051 (match_operator 3 "promotable_binary_operator"
19052 [(match_operand 1 "register_operand" "")
19053 (match_operand 2 "aligned_operand" "")]))
19054 (clobber (reg:CC FLAGS_REG))]
19055 "! TARGET_PARTIAL_REG_STALL && reload_completed
19056 && ((GET_MODE (operands[0]) == HImode
19057 && ((!optimize_size && !TARGET_FAST_PREFIX)
19058 /* ??? next two lines just !satisfies_constraint_K (...) */
19059 || GET_CODE (operands[2]) != CONST_INT
19060 || satisfies_constraint_K (operands[2])))
19061 || (GET_MODE (operands[0]) == QImode
19062 && (TARGET_PROMOTE_QImode || optimize_size)))"
19063 [(parallel [(set (match_dup 0)
19064 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19065 (clobber (reg:CC FLAGS_REG))])]
19066 "operands[0] = gen_lowpart (SImode, operands[0]);
19067 operands[1] = gen_lowpart (SImode, operands[1]);
19068 if (GET_CODE (operands[3]) != ASHIFT)
19069 operands[2] = gen_lowpart (SImode, operands[2]);
19070 PUT_MODE (operands[3], SImode);")
19072 ; Promote the QImode tests, as i386 has encoding of the AND
19073 ; instruction with 32-bit sign-extended immediate and thus the
19074 ; instruction size is unchanged, except in the %eax case for
19075 ; which it is increased by one byte, hence the ! optimize_size.
19077 [(set (match_operand 0 "flags_reg_operand" "")
19078 (match_operator 2 "compare_operator"
19079 [(and (match_operand 3 "aligned_operand" "")
19080 (match_operand 4 "const_int_operand" ""))
19082 (set (match_operand 1 "register_operand" "")
19083 (and (match_dup 3) (match_dup 4)))]
19084 "! TARGET_PARTIAL_REG_STALL && reload_completed
19085 /* Ensure that the operand will remain sign-extended immediate. */
19086 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19088 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19089 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19090 [(parallel [(set (match_dup 0)
19091 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19094 (and:SI (match_dup 3) (match_dup 4)))])]
19097 = gen_int_mode (INTVAL (operands[4])
19098 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19099 operands[1] = gen_lowpart (SImode, operands[1]);
19100 operands[3] = gen_lowpart (SImode, operands[3]);
19103 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19104 ; the TEST instruction with 32-bit sign-extended immediate and thus
19105 ; the instruction size would at least double, which is not what we
19106 ; want even with ! optimize_size.
19108 [(set (match_operand 0 "flags_reg_operand" "")
19109 (match_operator 1 "compare_operator"
19110 [(and (match_operand:HI 2 "aligned_operand" "")
19111 (match_operand:HI 3 "const_int_operand" ""))
19113 "! TARGET_PARTIAL_REG_STALL && reload_completed
19114 /* Ensure that the operand will remain sign-extended immediate. */
19115 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19116 && ! TARGET_FAST_PREFIX
19117 && ! optimize_size"
19118 [(set (match_dup 0)
19119 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19123 = gen_int_mode (INTVAL (operands[3])
19124 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19125 operands[2] = gen_lowpart (SImode, operands[2]);
19129 [(set (match_operand 0 "register_operand" "")
19130 (neg (match_operand 1 "register_operand" "")))
19131 (clobber (reg:CC FLAGS_REG))]
19132 "! TARGET_PARTIAL_REG_STALL && reload_completed
19133 && (GET_MODE (operands[0]) == HImode
19134 || (GET_MODE (operands[0]) == QImode
19135 && (TARGET_PROMOTE_QImode || optimize_size)))"
19136 [(parallel [(set (match_dup 0)
19137 (neg:SI (match_dup 1)))
19138 (clobber (reg:CC FLAGS_REG))])]
19139 "operands[0] = gen_lowpart (SImode, operands[0]);
19140 operands[1] = gen_lowpart (SImode, operands[1]);")
19143 [(set (match_operand 0 "register_operand" "")
19144 (not (match_operand 1 "register_operand" "")))]
19145 "! TARGET_PARTIAL_REG_STALL && reload_completed
19146 && (GET_MODE (operands[0]) == HImode
19147 || (GET_MODE (operands[0]) == QImode
19148 && (TARGET_PROMOTE_QImode || optimize_size)))"
19149 [(set (match_dup 0)
19150 (not:SI (match_dup 1)))]
19151 "operands[0] = gen_lowpart (SImode, operands[0]);
19152 operands[1] = gen_lowpart (SImode, operands[1]);")
19155 [(set (match_operand 0 "register_operand" "")
19156 (if_then_else (match_operator 1 "comparison_operator"
19157 [(reg FLAGS_REG) (const_int 0)])
19158 (match_operand 2 "register_operand" "")
19159 (match_operand 3 "register_operand" "")))]
19160 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19161 && (GET_MODE (operands[0]) == HImode
19162 || (GET_MODE (operands[0]) == QImode
19163 && (TARGET_PROMOTE_QImode || optimize_size)))"
19164 [(set (match_dup 0)
19165 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19166 "operands[0] = gen_lowpart (SImode, operands[0]);
19167 operands[2] = gen_lowpart (SImode, operands[2]);
19168 operands[3] = gen_lowpart (SImode, operands[3]);")
19171 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19172 ;; transform a complex memory operation into two memory to register operations.
19174 ;; Don't push memory operands
19176 [(set (match_operand:SI 0 "push_operand" "")
19177 (match_operand:SI 1 "memory_operand" ""))
19178 (match_scratch:SI 2 "r")]
19179 "!optimize_size && !TARGET_PUSH_MEMORY
19180 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19181 [(set (match_dup 2) (match_dup 1))
19182 (set (match_dup 0) (match_dup 2))]
19186 [(set (match_operand:DI 0 "push_operand" "")
19187 (match_operand:DI 1 "memory_operand" ""))
19188 (match_scratch:DI 2 "r")]
19189 "!optimize_size && !TARGET_PUSH_MEMORY
19190 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19191 [(set (match_dup 2) (match_dup 1))
19192 (set (match_dup 0) (match_dup 2))]
19195 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19198 [(set (match_operand:SF 0 "push_operand" "")
19199 (match_operand:SF 1 "memory_operand" ""))
19200 (match_scratch:SF 2 "r")]
19201 "!optimize_size && !TARGET_PUSH_MEMORY
19202 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19203 [(set (match_dup 2) (match_dup 1))
19204 (set (match_dup 0) (match_dup 2))]
19208 [(set (match_operand:HI 0 "push_operand" "")
19209 (match_operand:HI 1 "memory_operand" ""))
19210 (match_scratch:HI 2 "r")]
19211 "!optimize_size && !TARGET_PUSH_MEMORY
19212 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19213 [(set (match_dup 2) (match_dup 1))
19214 (set (match_dup 0) (match_dup 2))]
19218 [(set (match_operand:QI 0 "push_operand" "")
19219 (match_operand:QI 1 "memory_operand" ""))
19220 (match_scratch:QI 2 "q")]
19221 "!optimize_size && !TARGET_PUSH_MEMORY
19222 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19223 [(set (match_dup 2) (match_dup 1))
19224 (set (match_dup 0) (match_dup 2))]
19227 ;; Don't move an immediate directly to memory when the instruction
19230 [(match_scratch:SI 1 "r")
19231 (set (match_operand:SI 0 "memory_operand" "")
19234 && ! TARGET_USE_MOV0
19235 && TARGET_SPLIT_LONG_MOVES
19236 && get_attr_length (insn) >= ix86_cost->large_insn
19237 && peep2_regno_dead_p (0, FLAGS_REG)"
19238 [(parallel [(set (match_dup 1) (const_int 0))
19239 (clobber (reg:CC FLAGS_REG))])
19240 (set (match_dup 0) (match_dup 1))]
19244 [(match_scratch:HI 1 "r")
19245 (set (match_operand:HI 0 "memory_operand" "")
19248 && ! TARGET_USE_MOV0
19249 && TARGET_SPLIT_LONG_MOVES
19250 && get_attr_length (insn) >= ix86_cost->large_insn
19251 && peep2_regno_dead_p (0, FLAGS_REG)"
19252 [(parallel [(set (match_dup 2) (const_int 0))
19253 (clobber (reg:CC FLAGS_REG))])
19254 (set (match_dup 0) (match_dup 1))]
19255 "operands[2] = gen_lowpart (SImode, operands[1]);")
19258 [(match_scratch:QI 1 "q")
19259 (set (match_operand:QI 0 "memory_operand" "")
19262 && ! TARGET_USE_MOV0
19263 && TARGET_SPLIT_LONG_MOVES
19264 && get_attr_length (insn) >= ix86_cost->large_insn
19265 && peep2_regno_dead_p (0, FLAGS_REG)"
19266 [(parallel [(set (match_dup 2) (const_int 0))
19267 (clobber (reg:CC FLAGS_REG))])
19268 (set (match_dup 0) (match_dup 1))]
19269 "operands[2] = gen_lowpart (SImode, operands[1]);")
19272 [(match_scratch:SI 2 "r")
19273 (set (match_operand:SI 0 "memory_operand" "")
19274 (match_operand:SI 1 "immediate_operand" ""))]
19276 && get_attr_length (insn) >= ix86_cost->large_insn
19277 && TARGET_SPLIT_LONG_MOVES"
19278 [(set (match_dup 2) (match_dup 1))
19279 (set (match_dup 0) (match_dup 2))]
19283 [(match_scratch:HI 2 "r")
19284 (set (match_operand:HI 0 "memory_operand" "")
19285 (match_operand:HI 1 "immediate_operand" ""))]
19286 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19287 && TARGET_SPLIT_LONG_MOVES"
19288 [(set (match_dup 2) (match_dup 1))
19289 (set (match_dup 0) (match_dup 2))]
19293 [(match_scratch:QI 2 "q")
19294 (set (match_operand:QI 0 "memory_operand" "")
19295 (match_operand:QI 1 "immediate_operand" ""))]
19296 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19297 && TARGET_SPLIT_LONG_MOVES"
19298 [(set (match_dup 2) (match_dup 1))
19299 (set (match_dup 0) (match_dup 2))]
19302 ;; Don't compare memory with zero, load and use a test instead.
19304 [(set (match_operand 0 "flags_reg_operand" "")
19305 (match_operator 1 "compare_operator"
19306 [(match_operand:SI 2 "memory_operand" "")
19308 (match_scratch:SI 3 "r")]
19309 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19310 [(set (match_dup 3) (match_dup 2))
19311 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19314 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19315 ;; Don't split NOTs with a displacement operand, because resulting XOR
19316 ;; will not be pairable anyway.
19318 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19319 ;; represented using a modRM byte. The XOR replacement is long decoded,
19320 ;; so this split helps here as well.
19322 ;; Note: Can't do this as a regular split because we can't get proper
19323 ;; lifetime information then.
19326 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19327 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19329 && peep2_regno_dead_p (0, FLAGS_REG)
19330 && ((TARGET_PENTIUM
19331 && (GET_CODE (operands[0]) != MEM
19332 || !memory_displacement_operand (operands[0], SImode)))
19333 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19334 [(parallel [(set (match_dup 0)
19335 (xor:SI (match_dup 1) (const_int -1)))
19336 (clobber (reg:CC FLAGS_REG))])]
19340 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19341 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19343 && peep2_regno_dead_p (0, FLAGS_REG)
19344 && ((TARGET_PENTIUM
19345 && (GET_CODE (operands[0]) != MEM
19346 || !memory_displacement_operand (operands[0], HImode)))
19347 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19348 [(parallel [(set (match_dup 0)
19349 (xor:HI (match_dup 1) (const_int -1)))
19350 (clobber (reg:CC FLAGS_REG))])]
19354 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19355 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19357 && peep2_regno_dead_p (0, FLAGS_REG)
19358 && ((TARGET_PENTIUM
19359 && (GET_CODE (operands[0]) != MEM
19360 || !memory_displacement_operand (operands[0], QImode)))
19361 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19362 [(parallel [(set (match_dup 0)
19363 (xor:QI (match_dup 1) (const_int -1)))
19364 (clobber (reg:CC FLAGS_REG))])]
19367 ;; Non pairable "test imm, reg" instructions can be translated to
19368 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19369 ;; byte opcode instead of two, have a short form for byte operands),
19370 ;; so do it for other CPUs as well. Given that the value was dead,
19371 ;; this should not create any new dependencies. Pass on the sub-word
19372 ;; versions if we're concerned about partial register stalls.
19375 [(set (match_operand 0 "flags_reg_operand" "")
19376 (match_operator 1 "compare_operator"
19377 [(and:SI (match_operand:SI 2 "register_operand" "")
19378 (match_operand:SI 3 "immediate_operand" ""))
19380 "ix86_match_ccmode (insn, CCNOmode)
19381 && (true_regnum (operands[2]) != 0
19382 || satisfies_constraint_K (operands[3]))
19383 && peep2_reg_dead_p (1, operands[2])"
19385 [(set (match_dup 0)
19386 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19389 (and:SI (match_dup 2) (match_dup 3)))])]
19392 ;; We don't need to handle HImode case, because it will be promoted to SImode
19393 ;; on ! TARGET_PARTIAL_REG_STALL
19396 [(set (match_operand 0 "flags_reg_operand" "")
19397 (match_operator 1 "compare_operator"
19398 [(and:QI (match_operand:QI 2 "register_operand" "")
19399 (match_operand:QI 3 "immediate_operand" ""))
19401 "! TARGET_PARTIAL_REG_STALL
19402 && ix86_match_ccmode (insn, CCNOmode)
19403 && true_regnum (operands[2]) != 0
19404 && peep2_reg_dead_p (1, operands[2])"
19406 [(set (match_dup 0)
19407 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19410 (and:QI (match_dup 2) (match_dup 3)))])]
19414 [(set (match_operand 0 "flags_reg_operand" "")
19415 (match_operator 1 "compare_operator"
19418 (match_operand 2 "ext_register_operand" "")
19421 (match_operand 3 "const_int_operand" ""))
19423 "! TARGET_PARTIAL_REG_STALL
19424 && ix86_match_ccmode (insn, CCNOmode)
19425 && true_regnum (operands[2]) != 0
19426 && peep2_reg_dead_p (1, operands[2])"
19427 [(parallel [(set (match_dup 0)
19436 (set (zero_extract:SI (match_dup 2)
19447 ;; Don't do logical operations with memory inputs.
19449 [(match_scratch:SI 2 "r")
19450 (parallel [(set (match_operand:SI 0 "register_operand" "")
19451 (match_operator:SI 3 "arith_or_logical_operator"
19453 (match_operand:SI 1 "memory_operand" "")]))
19454 (clobber (reg:CC FLAGS_REG))])]
19455 "! optimize_size && ! TARGET_READ_MODIFY"
19456 [(set (match_dup 2) (match_dup 1))
19457 (parallel [(set (match_dup 0)
19458 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19459 (clobber (reg:CC FLAGS_REG))])]
19463 [(match_scratch:SI 2 "r")
19464 (parallel [(set (match_operand:SI 0 "register_operand" "")
19465 (match_operator:SI 3 "arith_or_logical_operator"
19466 [(match_operand:SI 1 "memory_operand" "")
19468 (clobber (reg:CC FLAGS_REG))])]
19469 "! optimize_size && ! TARGET_READ_MODIFY"
19470 [(set (match_dup 2) (match_dup 1))
19471 (parallel [(set (match_dup 0)
19472 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19473 (clobber (reg:CC FLAGS_REG))])]
19476 ; Don't do logical operations with memory outputs
19478 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19479 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19480 ; the same decoder scheduling characteristics as the original.
19483 [(match_scratch:SI 2 "r")
19484 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19485 (match_operator:SI 3 "arith_or_logical_operator"
19487 (match_operand:SI 1 "nonmemory_operand" "")]))
19488 (clobber (reg:CC FLAGS_REG))])]
19489 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19490 [(set (match_dup 2) (match_dup 0))
19491 (parallel [(set (match_dup 2)
19492 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19493 (clobber (reg:CC FLAGS_REG))])
19494 (set (match_dup 0) (match_dup 2))]
19498 [(match_scratch:SI 2 "r")
19499 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19500 (match_operator:SI 3 "arith_or_logical_operator"
19501 [(match_operand:SI 1 "nonmemory_operand" "")
19503 (clobber (reg:CC FLAGS_REG))])]
19504 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19505 [(set (match_dup 2) (match_dup 0))
19506 (parallel [(set (match_dup 2)
19507 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19508 (clobber (reg:CC FLAGS_REG))])
19509 (set (match_dup 0) (match_dup 2))]
19512 ;; Attempt to always use XOR for zeroing registers.
19514 [(set (match_operand 0 "register_operand" "")
19515 (match_operand 1 "const0_operand" ""))]
19516 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19517 && (! TARGET_USE_MOV0 || optimize_size)
19518 && GENERAL_REG_P (operands[0])
19519 && peep2_regno_dead_p (0, FLAGS_REG)"
19520 [(parallel [(set (match_dup 0) (const_int 0))
19521 (clobber (reg:CC FLAGS_REG))])]
19523 operands[0] = gen_lowpart (word_mode, operands[0]);
19527 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19529 "(GET_MODE (operands[0]) == QImode
19530 || GET_MODE (operands[0]) == HImode)
19531 && (! TARGET_USE_MOV0 || optimize_size)
19532 && peep2_regno_dead_p (0, FLAGS_REG)"
19533 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19534 (clobber (reg:CC FLAGS_REG))])])
19536 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19538 [(set (match_operand 0 "register_operand" "")
19540 "(GET_MODE (operands[0]) == HImode
19541 || GET_MODE (operands[0]) == SImode
19542 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19543 && (optimize_size || TARGET_PENTIUM)
19544 && peep2_regno_dead_p (0, FLAGS_REG)"
19545 [(parallel [(set (match_dup 0) (const_int -1))
19546 (clobber (reg:CC FLAGS_REG))])]
19547 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19550 ;; Attempt to convert simple leas to adds. These can be created by
19553 [(set (match_operand:SI 0 "register_operand" "")
19554 (plus:SI (match_dup 0)
19555 (match_operand:SI 1 "nonmemory_operand" "")))]
19556 "peep2_regno_dead_p (0, FLAGS_REG)"
19557 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19558 (clobber (reg:CC FLAGS_REG))])]
19562 [(set (match_operand:SI 0 "register_operand" "")
19563 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19564 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19565 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19566 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19567 (clobber (reg:CC FLAGS_REG))])]
19568 "operands[2] = gen_lowpart (SImode, operands[2]);")
19571 [(set (match_operand:DI 0 "register_operand" "")
19572 (plus:DI (match_dup 0)
19573 (match_operand:DI 1 "x86_64_general_operand" "")))]
19574 "peep2_regno_dead_p (0, FLAGS_REG)"
19575 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19576 (clobber (reg:CC FLAGS_REG))])]
19580 [(set (match_operand:SI 0 "register_operand" "")
19581 (mult:SI (match_dup 0)
19582 (match_operand:SI 1 "const_int_operand" "")))]
19583 "exact_log2 (INTVAL (operands[1])) >= 0
19584 && peep2_regno_dead_p (0, FLAGS_REG)"
19585 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19586 (clobber (reg:CC FLAGS_REG))])]
19587 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19590 [(set (match_operand:DI 0 "register_operand" "")
19591 (mult:DI (match_dup 0)
19592 (match_operand:DI 1 "const_int_operand" "")))]
19593 "exact_log2 (INTVAL (operands[1])) >= 0
19594 && peep2_regno_dead_p (0, FLAGS_REG)"
19595 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19596 (clobber (reg:CC FLAGS_REG))])]
19597 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19600 [(set (match_operand:SI 0 "register_operand" "")
19601 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19602 (match_operand:DI 2 "const_int_operand" "")) 0))]
19603 "exact_log2 (INTVAL (operands[2])) >= 0
19604 && REGNO (operands[0]) == REGNO (operands[1])
19605 && peep2_regno_dead_p (0, FLAGS_REG)"
19606 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19607 (clobber (reg:CC FLAGS_REG))])]
19608 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19610 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19611 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19612 ;; many CPUs it is also faster, since special hardware to avoid esp
19613 ;; dependencies is present.
19615 ;; While some of these conversions may be done using splitters, we use peepholes
19616 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19618 ;; Convert prologue esp subtractions to push.
19619 ;; We need register to push. In order to keep verify_flow_info happy we have
19621 ;; - use scratch and clobber it in order to avoid dependencies
19622 ;; - use already live register
19623 ;; We can't use the second way right now, since there is no reliable way how to
19624 ;; verify that given register is live. First choice will also most likely in
19625 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19626 ;; call clobbered registers are dead. We may want to use base pointer as an
19627 ;; alternative when no register is available later.
19630 [(match_scratch:SI 0 "r")
19631 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19632 (clobber (reg:CC FLAGS_REG))
19633 (clobber (mem:BLK (scratch)))])]
19634 "optimize_size || !TARGET_SUB_ESP_4"
19635 [(clobber (match_dup 0))
19636 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19637 (clobber (mem:BLK (scratch)))])])
19640 [(match_scratch:SI 0 "r")
19641 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19642 (clobber (reg:CC FLAGS_REG))
19643 (clobber (mem:BLK (scratch)))])]
19644 "optimize_size || !TARGET_SUB_ESP_8"
19645 [(clobber (match_dup 0))
19646 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19647 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19648 (clobber (mem:BLK (scratch)))])])
19650 ;; Convert esp subtractions to push.
19652 [(match_scratch:SI 0 "r")
19653 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19654 (clobber (reg:CC FLAGS_REG))])]
19655 "optimize_size || !TARGET_SUB_ESP_4"
19656 [(clobber (match_dup 0))
19657 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19660 [(match_scratch:SI 0 "r")
19661 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19662 (clobber (reg:CC FLAGS_REG))])]
19663 "optimize_size || !TARGET_SUB_ESP_8"
19664 [(clobber (match_dup 0))
19665 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19666 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19668 ;; Convert epilogue deallocator to pop.
19670 [(match_scratch:SI 0 "r")
19671 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19672 (clobber (reg:CC FLAGS_REG))
19673 (clobber (mem:BLK (scratch)))])]
19674 "optimize_size || !TARGET_ADD_ESP_4"
19675 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19676 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19677 (clobber (mem:BLK (scratch)))])]
19680 ;; Two pops case is tricky, since pop causes dependency on destination register.
19681 ;; We use two registers if available.
19683 [(match_scratch:SI 0 "r")
19684 (match_scratch:SI 1 "r")
19685 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19686 (clobber (reg:CC FLAGS_REG))
19687 (clobber (mem:BLK (scratch)))])]
19688 "optimize_size || !TARGET_ADD_ESP_8"
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)))
19691 (clobber (mem:BLK (scratch)))])
19692 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19693 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19697 [(match_scratch:SI 0 "r")
19698 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19699 (clobber (reg:CC FLAGS_REG))
19700 (clobber (mem:BLK (scratch)))])]
19702 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19703 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19704 (clobber (mem:BLK (scratch)))])
19705 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19706 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19709 ;; Convert esp additions to pop.
19711 [(match_scratch:SI 0 "r")
19712 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19713 (clobber (reg:CC FLAGS_REG))])]
19715 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19716 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19719 ;; Two pops case is tricky, since pop causes dependency on destination register.
19720 ;; We use two registers if available.
19722 [(match_scratch:SI 0 "r")
19723 (match_scratch:SI 1 "r")
19724 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19725 (clobber (reg:CC FLAGS_REG))])]
19727 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19728 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19729 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19730 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19734 [(match_scratch:SI 0 "r")
19735 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19736 (clobber (reg:CC FLAGS_REG))])]
19738 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19739 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19740 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19741 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19744 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19745 ;; required and register dies. Similarly for 128 to plus -128.
19747 [(set (match_operand 0 "flags_reg_operand" "")
19748 (match_operator 1 "compare_operator"
19749 [(match_operand 2 "register_operand" "")
19750 (match_operand 3 "const_int_operand" "")]))]
19751 "(INTVAL (operands[3]) == -1
19752 || INTVAL (operands[3]) == 1
19753 || INTVAL (operands[3]) == 128)
19754 && ix86_match_ccmode (insn, CCGCmode)
19755 && peep2_reg_dead_p (1, operands[2])"
19756 [(parallel [(set (match_dup 0)
19757 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19758 (clobber (match_dup 2))])]
19762 [(match_scratch:DI 0 "r")
19763 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19764 (clobber (reg:CC FLAGS_REG))
19765 (clobber (mem:BLK (scratch)))])]
19766 "optimize_size || !TARGET_SUB_ESP_4"
19767 [(clobber (match_dup 0))
19768 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19769 (clobber (mem:BLK (scratch)))])])
19772 [(match_scratch:DI 0 "r")
19773 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19774 (clobber (reg:CC FLAGS_REG))
19775 (clobber (mem:BLK (scratch)))])]
19776 "optimize_size || !TARGET_SUB_ESP_8"
19777 [(clobber (match_dup 0))
19778 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19779 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19780 (clobber (mem:BLK (scratch)))])])
19782 ;; Convert esp subtractions to push.
19784 [(match_scratch:DI 0 "r")
19785 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19786 (clobber (reg:CC FLAGS_REG))])]
19787 "optimize_size || !TARGET_SUB_ESP_4"
19788 [(clobber (match_dup 0))
19789 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19792 [(match_scratch:DI 0 "r")
19793 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19794 (clobber (reg:CC FLAGS_REG))])]
19795 "optimize_size || !TARGET_SUB_ESP_8"
19796 [(clobber (match_dup 0))
19797 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19798 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19800 ;; Convert epilogue deallocator to pop.
19802 [(match_scratch:DI 0 "r")
19803 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19804 (clobber (reg:CC FLAGS_REG))
19805 (clobber (mem:BLK (scratch)))])]
19806 "optimize_size || !TARGET_ADD_ESP_4"
19807 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19808 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19809 (clobber (mem:BLK (scratch)))])]
19812 ;; Two pops case is tricky, since pop causes dependency on destination register.
19813 ;; We use two registers if available.
19815 [(match_scratch:DI 0 "r")
19816 (match_scratch:DI 1 "r")
19817 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19818 (clobber (reg:CC FLAGS_REG))
19819 (clobber (mem:BLK (scratch)))])]
19820 "optimize_size || !TARGET_ADD_ESP_8"
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)))
19823 (clobber (mem:BLK (scratch)))])
19824 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19825 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19829 [(match_scratch:DI 0 "r")
19830 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19831 (clobber (reg:CC FLAGS_REG))
19832 (clobber (mem:BLK (scratch)))])]
19834 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19835 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19836 (clobber (mem:BLK (scratch)))])
19837 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19838 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19841 ;; Convert esp additions to pop.
19843 [(match_scratch:DI 0 "r")
19844 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19845 (clobber (reg:CC FLAGS_REG))])]
19847 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19848 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19851 ;; Two pops case is tricky, since pop causes dependency on destination register.
19852 ;; We use two registers if available.
19854 [(match_scratch:DI 0 "r")
19855 (match_scratch:DI 1 "r")
19856 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19857 (clobber (reg:CC FLAGS_REG))])]
19859 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19860 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19861 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19862 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19866 [(match_scratch:DI 0 "r")
19867 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19868 (clobber (reg:CC FLAGS_REG))])]
19870 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19871 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19872 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19873 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19876 ;; Convert imul by three, five and nine into lea
19879 [(set (match_operand:SI 0 "register_operand" "")
19880 (mult:SI (match_operand:SI 1 "register_operand" "")
19881 (match_operand:SI 2 "const_int_operand" "")))
19882 (clobber (reg:CC FLAGS_REG))])]
19883 "INTVAL (operands[2]) == 3
19884 || INTVAL (operands[2]) == 5
19885 || INTVAL (operands[2]) == 9"
19886 [(set (match_dup 0)
19887 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19889 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19893 [(set (match_operand:SI 0 "register_operand" "")
19894 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19895 (match_operand:SI 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) (match_dup 1))
19903 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19905 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19909 [(set (match_operand:DI 0 "register_operand" "")
19910 (mult:DI (match_operand:DI 1 "register_operand" "")
19911 (match_operand:DI 2 "const_int_operand" "")))
19912 (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)
19918 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19920 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19924 [(set (match_operand:DI 0 "register_operand" "")
19925 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19926 (match_operand:DI 2 "const_int_operand" "")))
19927 (clobber (reg:CC FLAGS_REG))])]
19930 && (INTVAL (operands[2]) == 3
19931 || INTVAL (operands[2]) == 5
19932 || INTVAL (operands[2]) == 9)"
19933 [(set (match_dup 0) (match_dup 1))
19935 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19937 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19939 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19940 ;; imul $32bit_imm, reg, reg is direct decoded.
19942 [(match_scratch:DI 3 "r")
19943 (parallel [(set (match_operand:DI 0 "register_operand" "")
19944 (mult:DI (match_operand:DI 1 "memory_operand" "")
19945 (match_operand:DI 2 "immediate_operand" "")))
19946 (clobber (reg:CC FLAGS_REG))])]
19947 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19948 && !satisfies_constraint_K (operands[2])"
19949 [(set (match_dup 3) (match_dup 1))
19950 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19951 (clobber (reg:CC FLAGS_REG))])]
19955 [(match_scratch:SI 3 "r")
19956 (parallel [(set (match_operand:SI 0 "register_operand" "")
19957 (mult:SI (match_operand:SI 1 "memory_operand" "")
19958 (match_operand:SI 2 "immediate_operand" "")))
19959 (clobber (reg:CC FLAGS_REG))])]
19960 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19961 && !satisfies_constraint_K (operands[2])"
19962 [(set (match_dup 3) (match_dup 1))
19963 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19964 (clobber (reg:CC FLAGS_REG))])]
19968 [(match_scratch:SI 3 "r")
19969 (parallel [(set (match_operand:DI 0 "register_operand" "")
19971 (mult:SI (match_operand:SI 1 "memory_operand" "")
19972 (match_operand:SI 2 "immediate_operand" ""))))
19973 (clobber (reg:CC FLAGS_REG))])]
19974 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19975 && !satisfies_constraint_K (operands[2])"
19976 [(set (match_dup 3) (match_dup 1))
19977 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19978 (clobber (reg:CC FLAGS_REG))])]
19981 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19982 ;; Convert it into imul reg, reg
19983 ;; It would be better to force assembler to encode instruction using long
19984 ;; immediate, but there is apparently no way to do so.
19986 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19987 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19988 (match_operand:DI 2 "const_int_operand" "")))
19989 (clobber (reg:CC FLAGS_REG))])
19990 (match_scratch:DI 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:DI (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:SI 0 "register_operand" "")
20003 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20004 (match_operand:SI 2 "const_int_operand" "")))
20005 (clobber (reg:CC FLAGS_REG))])
20006 (match_scratch:SI 3 "r")]
20007 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20008 && satisfies_constraint_K (operands[2])"
20009 [(set (match_dup 3) (match_dup 2))
20010 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20011 (clobber (reg:CC FLAGS_REG))])]
20013 if (!rtx_equal_p (operands[0], operands[1]))
20014 emit_move_insn (operands[0], operands[1]);
20018 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20019 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20020 (match_operand:HI 2 "immediate_operand" "")))
20021 (clobber (reg:CC FLAGS_REG))])
20022 (match_scratch:HI 3 "r")]
20023 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20024 [(set (match_dup 3) (match_dup 2))
20025 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20026 (clobber (reg:CC FLAGS_REG))])]
20028 if (!rtx_equal_p (operands[0], operands[1]))
20029 emit_move_insn (operands[0], operands[1]);
20032 ;; After splitting up read-modify operations, array accesses with memory
20033 ;; operands might end up in form:
20035 ;; movl 4(%esp), %edx
20037 ;; instead of pre-splitting:
20039 ;; addl 4(%esp), %eax
20041 ;; movl 4(%esp), %edx
20042 ;; leal (%edx,%eax,4), %eax
20045 [(parallel [(set (match_operand 0 "register_operand" "")
20046 (ashift (match_operand 1 "register_operand" "")
20047 (match_operand 2 "const_int_operand" "")))
20048 (clobber (reg:CC FLAGS_REG))])
20049 (set (match_operand 3 "register_operand")
20050 (match_operand 4 "x86_64_general_operand" ""))
20051 (parallel [(set (match_operand 5 "register_operand" "")
20052 (plus (match_operand 6 "register_operand" "")
20053 (match_operand 7 "register_operand" "")))
20054 (clobber (reg:CC FLAGS_REG))])]
20055 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20056 /* Validate MODE for lea. */
20057 && ((!TARGET_PARTIAL_REG_STALL
20058 && (GET_MODE (operands[0]) == QImode
20059 || GET_MODE (operands[0]) == HImode))
20060 || GET_MODE (operands[0]) == SImode
20061 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20062 /* We reorder load and the shift. */
20063 && !rtx_equal_p (operands[1], operands[3])
20064 && !reg_overlap_mentioned_p (operands[0], operands[4])
20065 /* Last PLUS must consist of operand 0 and 3. */
20066 && !rtx_equal_p (operands[0], operands[3])
20067 && (rtx_equal_p (operands[3], operands[6])
20068 || rtx_equal_p (operands[3], operands[7]))
20069 && (rtx_equal_p (operands[0], operands[6])
20070 || rtx_equal_p (operands[0], operands[7]))
20071 /* The intermediate operand 0 must die or be same as output. */
20072 && (rtx_equal_p (operands[0], operands[5])
20073 || peep2_reg_dead_p (3, operands[0]))"
20074 [(set (match_dup 3) (match_dup 4))
20075 (set (match_dup 0) (match_dup 1))]
20077 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20078 int scale = 1 << INTVAL (operands[2]);
20079 rtx index = gen_lowpart (Pmode, operands[1]);
20080 rtx base = gen_lowpart (Pmode, operands[3]);
20081 rtx dest = gen_lowpart (mode, operands[5]);
20083 operands[1] = gen_rtx_PLUS (Pmode, base,
20084 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20086 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20087 operands[0] = dest;
20090 ;; Call-value patterns last so that the wildcard operand does not
20091 ;; disrupt insn-recog's switch tables.
20093 (define_insn "*call_value_pop_0"
20094 [(set (match_operand 0 "" "")
20095 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20096 (match_operand:SI 2 "" "")))
20097 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20098 (match_operand:SI 3 "immediate_operand" "")))]
20101 if (SIBLING_CALL_P (insn))
20104 return "call\t%P1";
20106 [(set_attr "type" "callv")])
20108 (define_insn "*call_value_pop_1"
20109 [(set (match_operand 0 "" "")
20110 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20111 (match_operand:SI 2 "" "")))
20112 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20113 (match_operand:SI 3 "immediate_operand" "i")))]
20116 if (constant_call_address_operand (operands[1], Pmode))
20118 if (SIBLING_CALL_P (insn))
20121 return "call\t%P1";
20123 if (SIBLING_CALL_P (insn))
20126 return "call\t%A1";
20128 [(set_attr "type" "callv")])
20130 (define_insn "*call_value_0"
20131 [(set (match_operand 0 "" "")
20132 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20133 (match_operand:SI 2 "" "")))]
20136 if (SIBLING_CALL_P (insn))
20139 return "call\t%P1";
20141 [(set_attr "type" "callv")])
20143 (define_insn "*call_value_0_rex64"
20144 [(set (match_operand 0 "" "")
20145 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20146 (match_operand:DI 2 "const_int_operand" "")))]
20149 if (SIBLING_CALL_P (insn))
20152 return "call\t%P1";
20154 [(set_attr "type" "callv")])
20156 (define_insn "*call_value_1"
20157 [(set (match_operand 0 "" "")
20158 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20159 (match_operand:SI 2 "" "")))]
20160 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20162 if (constant_call_address_operand (operands[1], Pmode))
20163 return "call\t%P1";
20164 return "call\t%A1";
20166 [(set_attr "type" "callv")])
20168 (define_insn "*sibcall_value_1"
20169 [(set (match_operand 0 "" "")
20170 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20171 (match_operand:SI 2 "" "")))]
20172 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20174 if (constant_call_address_operand (operands[1], Pmode))
20178 [(set_attr "type" "callv")])
20180 (define_insn "*call_value_1_rex64"
20181 [(set (match_operand 0 "" "")
20182 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20183 (match_operand:DI 2 "" "")))]
20184 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20186 if (constant_call_address_operand (operands[1], Pmode))
20187 return "call\t%P1";
20188 return "call\t%A1";
20190 [(set_attr "type" "callv")])
20192 (define_insn "*sibcall_value_1_rex64"
20193 [(set (match_operand 0 "" "")
20194 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20195 (match_operand:DI 2 "" "")))]
20196 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20198 [(set_attr "type" "callv")])
20200 (define_insn "*sibcall_value_1_rex64_v"
20201 [(set (match_operand 0 "" "")
20202 (call (mem:QI (reg:DI 40))
20203 (match_operand:DI 1 "" "")))]
20204 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20206 [(set_attr "type" "callv")])
20208 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20209 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20210 ;; caught for use by garbage collectors and the like. Using an insn that
20211 ;; maps to SIGILL makes it more likely the program will rightfully die.
20212 ;; Keeping with tradition, "6" is in honor of #UD.
20213 (define_insn "trap"
20214 [(trap_if (const_int 1) (const_int 6))]
20216 { return ASM_SHORT "0x0b0f"; }
20217 [(set_attr "length" "2")])
20219 (define_expand "sse_prologue_save"
20220 [(parallel [(set (match_operand:BLK 0 "" "")
20221 (unspec:BLK [(reg:DI 21)
20228 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20229 (use (match_operand:DI 1 "register_operand" ""))
20230 (use (match_operand:DI 2 "immediate_operand" ""))
20231 (use (label_ref:DI (match_operand 3 "" "")))])]
20235 (define_insn "*sse_prologue_save_insn"
20236 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20237 (match_operand:DI 4 "const_int_operand" "n")))
20238 (unspec:BLK [(reg:DI 21)
20245 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20246 (use (match_operand:DI 1 "register_operand" "r"))
20247 (use (match_operand:DI 2 "const_int_operand" "i"))
20248 (use (label_ref:DI (match_operand 3 "" "X")))]
20250 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20251 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20255 operands[0] = gen_rtx_MEM (Pmode,
20256 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20257 output_asm_insn (\"jmp\\t%A1\", operands);
20258 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20260 operands[4] = adjust_address (operands[0], DImode, i*16);
20261 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20262 PUT_MODE (operands[4], TImode);
20263 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20264 output_asm_insn (\"rex\", operands);
20265 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20267 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20268 CODE_LABEL_NUMBER (operands[3]));
20272 [(set_attr "type" "other")
20273 (set_attr "length_immediate" "0")
20274 (set_attr "length_address" "0")
20275 (set_attr "length" "135")
20276 (set_attr "memory" "store")
20277 (set_attr "modrm" "0")
20278 (set_attr "mode" "DI")])
20280 (define_expand "prefetch"
20281 [(prefetch (match_operand 0 "address_operand" "")
20282 (match_operand:SI 1 "const_int_operand" "")
20283 (match_operand:SI 2 "const_int_operand" ""))]
20284 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20286 int rw = INTVAL (operands[1]);
20287 int locality = INTVAL (operands[2]);
20289 gcc_assert (rw == 0 || rw == 1);
20290 gcc_assert (locality >= 0 && locality <= 3);
20291 gcc_assert (GET_MODE (operands[0]) == Pmode
20292 || GET_MODE (operands[0]) == VOIDmode);
20294 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20295 supported by SSE counterpart or the SSE prefetch is not available
20296 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20298 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20299 operands[2] = GEN_INT (3);
20301 operands[1] = const0_rtx;
20304 (define_insn "*prefetch_sse"
20305 [(prefetch (match_operand:SI 0 "address_operand" "p")
20307 (match_operand:SI 1 "const_int_operand" ""))]
20308 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20310 static const char * const patterns[4] = {
20311 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20314 int locality = INTVAL (operands[1]);
20315 gcc_assert (locality >= 0 && locality <= 3);
20317 return patterns[locality];
20319 [(set_attr "type" "sse")
20320 (set_attr "memory" "none")])
20322 (define_insn "*prefetch_sse_rex"
20323 [(prefetch (match_operand:DI 0 "address_operand" "p")
20325 (match_operand:SI 1 "const_int_operand" ""))]
20326 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20328 static const char * const patterns[4] = {
20329 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20332 int locality = INTVAL (operands[1]);
20333 gcc_assert (locality >= 0 && locality <= 3);
20335 return patterns[locality];
20337 [(set_attr "type" "sse")
20338 (set_attr "memory" "none")])
20340 (define_insn "*prefetch_3dnow"
20341 [(prefetch (match_operand:SI 0 "address_operand" "p")
20342 (match_operand:SI 1 "const_int_operand" "n")
20344 "TARGET_3DNOW && !TARGET_64BIT"
20346 if (INTVAL (operands[1]) == 0)
20347 return "prefetch\t%a0";
20349 return "prefetchw\t%a0";
20351 [(set_attr "type" "mmx")
20352 (set_attr "memory" "none")])
20354 (define_insn "*prefetch_3dnow_rex"
20355 [(prefetch (match_operand:DI 0 "address_operand" "p")
20356 (match_operand:SI 1 "const_int_operand" "n")
20358 "TARGET_3DNOW && TARGET_64BIT"
20360 if (INTVAL (operands[1]) == 0)
20361 return "prefetch\t%a0";
20363 return "prefetchw\t%a0";
20365 [(set_attr "type" "mmx")
20366 (set_attr "memory" "none")])
20368 (define_expand "stack_protect_set"
20369 [(match_operand 0 "memory_operand" "")
20370 (match_operand 1 "memory_operand" "")]
20373 #ifdef TARGET_THREAD_SSP_OFFSET
20375 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20376 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20378 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20379 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20382 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20384 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20389 (define_insn "stack_protect_set_si"
20390 [(set (match_operand:SI 0 "memory_operand" "=m")
20391 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20392 (set (match_scratch:SI 2 "=&r") (const_int 0))
20393 (clobber (reg:CC FLAGS_REG))]
20395 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20396 [(set_attr "type" "multi")])
20398 (define_insn "stack_protect_set_di"
20399 [(set (match_operand:DI 0 "memory_operand" "=m")
20400 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20401 (set (match_scratch:DI 2 "=&r") (const_int 0))
20402 (clobber (reg:CC FLAGS_REG))]
20404 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20405 [(set_attr "type" "multi")])
20407 (define_insn "stack_tls_protect_set_si"
20408 [(set (match_operand:SI 0 "memory_operand" "=m")
20409 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20410 (set (match_scratch:SI 2 "=&r") (const_int 0))
20411 (clobber (reg:CC FLAGS_REG))]
20413 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20414 [(set_attr "type" "multi")])
20416 (define_insn "stack_tls_protect_set_di"
20417 [(set (match_operand:DI 0 "memory_operand" "=m")
20418 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20419 (set (match_scratch:DI 2 "=&r") (const_int 0))
20420 (clobber (reg:CC FLAGS_REG))]
20423 /* The kernel uses a different segment register for performance reasons; a
20424 system call would not have to trash the userspace segment register,
20425 which would be expensive */
20426 if (ix86_cmodel != CM_KERNEL)
20427 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20429 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20431 [(set_attr "type" "multi")])
20433 (define_expand "stack_protect_test"
20434 [(match_operand 0 "memory_operand" "")
20435 (match_operand 1 "memory_operand" "")
20436 (match_operand 2 "" "")]
20439 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20440 ix86_compare_op0 = operands[0];
20441 ix86_compare_op1 = operands[1];
20442 ix86_compare_emitted = flags;
20444 #ifdef TARGET_THREAD_SSP_OFFSET
20446 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20447 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20449 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20450 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20453 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20455 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20457 emit_jump_insn (gen_beq (operands[2]));
20461 (define_insn "stack_protect_test_si"
20462 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20463 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20464 (match_operand:SI 2 "memory_operand" "m")]
20466 (clobber (match_scratch:SI 3 "=&r"))]
20468 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20469 [(set_attr "type" "multi")])
20471 (define_insn "stack_protect_test_di"
20472 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20473 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20474 (match_operand:DI 2 "memory_operand" "m")]
20476 (clobber (match_scratch:DI 3 "=&r"))]
20478 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20479 [(set_attr "type" "multi")])
20481 (define_insn "stack_tls_protect_test_si"
20482 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20483 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20484 (match_operand:SI 2 "const_int_operand" "i")]
20485 UNSPEC_SP_TLS_TEST))
20486 (clobber (match_scratch:SI 3 "=r"))]
20488 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20489 [(set_attr "type" "multi")])
20491 (define_insn "stack_tls_protect_test_di"
20492 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20493 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20494 (match_operand:DI 2 "const_int_operand" "i")]
20495 UNSPEC_SP_TLS_TEST))
20496 (clobber (match_scratch:DI 3 "=r"))]
20499 /* The kernel uses a different segment register for performance reasons; a
20500 system call would not have to trash the userspace segment register,
20501 which would be expensive */
20502 if (ix86_cmodel != CM_KERNEL)
20503 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20505 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20507 [(set_attr "type" "multi")])
20511 (include "sync.md")